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

[Lua] Problem(s) with

Started by Frederikam, 03 January 2013 - 02:30 AM
Frederikam #1
Posted 03 January 2013 - 03:30 AM
I am having this wierd issue where true =~ true, i have used about 2 on this problem and i haven't yet found a problem. As far as i know there is no "toboolean" in Lua. Where the problem starts is mentioned in the code.



visualTesting = true

boreStatus = "UNKNOWN"


function update()
    if visualTesting then
        term.clear()
        term.setCursorPos(1, 1)
        term.setTextColor(32)
        print("Welcome to the Frederikam Industries main menu!")
        term.setTextColor(1)
        menuOption(3, 1, "Toggle frame bore", boreStatus, getColor(boreStatus))
    else
        print("visual testing is off")
        print(boreStatus)
    end
end

function getColor(variable)
    local color
    if variable == true then
        color = 8192
    elseif variable == false then
        color = 16384
    else
        color = 2
    end
    return color
end

function menuOption(line, key, optionString, status, statusColor)
    term.setCursorPos(1, line)
    term.write(key..":")
    term.setCursorPos(8, line)
    term.write(optionString)
    term.setCursorPos(30, line)
    term.setTextColor(statusColor)
    if status == true then --This is where I am starting to get this first problem.
        term.write("on")
    elseif status == false then
        term.write("off")
    elseif status ~= nil and not status == true and not status == false then
        term.write(status)
    end
    term.setTextColor(1)
end

function changeStatus()
    local validKey = false
    if keyReturned == 2 then
        validKey = true
        rednet.send(16, "before"..tostring(boreStatus))
        if boreStatus == true then
            boreStatus = false
        else
            boreStatus = true
        end
        rednet.send(16, tostring(boreStatus))
    elseif keyReturned == 3 then
        print(testLoadData())
    end
    saveData()
    return validKey
end

function saveData()
    file = fs.open("/data", "w")
    file.writeLine(boreStatus)
    file.close()
end

function loadData()
    file = fs.open("/data", "r")
    boreStatus = file.readLine()
    file.close()
    rednet.send(16, "afterLoad: "..tostring(boreStatus))
end

function testLoadData()
    local toReturn
    file = fs.open("/data", "r")
    toReturn = file.readLine()
    file.close()
    return toReturn
end

-- main function

rednet.open("top")
loadData()
update()
while true do
    event, keyReturned = os.pullEvent("key")
    if changeStatus() then
        update()
    end
end
theoriginalbit #2
Posted 03 January 2013 - 03:44 AM
Firstly you do not need == true or == false, instead say


if status then -- this implies if true
else -- otherwise if false
end
And if you want to check for false

if not status then -- implies not true
end

Secondly the issue is your dont declare status anywhere and in Lua when something is nil it assumes false. Did you mean boreStatus?

Thirdly when toggling boreStatus

if boreStatus == true then
  boreStatus = false
else if boreStatus == fals then
  boreStatus = true
end
You could use

boreStatus = not boreStatus

EDIT: also this

function getColor(variable)
    local color
    if variable == true then
        color = 8192
    elseif variable == false then
        color = 16384
    else
        color = 2
    end
    return color
end

Could become this


function getColor(variable)
  return variable and 8192 or 16384
end
This is the equivalent of a ternary operator in other languages. If variable is true then it will return 8192, if it is nil Lua assumes false, and if false it returns the 16384
Frederikam #3
Posted 03 January 2013 - 04:18 AM
Firstly you do not need == true or == false, instead say


if status then -- this implies if true
else -- otherwise if false
end
And if you want to check for false

if not status then -- implies not true
end

I know, i just tested around with it to see if that was it.

Secondly the issue is your dont declare status anywhere and in Lua when something is nil it assumes false. Did you mean boreStatus?


Thirdly when toggling boreStatus

if boreStatus == true then
boreStatus = false
else if boreStatus == fals then
boreStatus = true
end

You could use

boreStatus = not boreStatus

Hmm, that is quite useful to know.


EDIT: also this
Frederikam, on 02 January 2013 - 03:30 PM, said:


function getColor(variable)
local color
if variable == true then
color = 8192
elseif variable == false then
color = 16384
else
color = 2
end
return color
end



Could become this


function getColor(variable)
return variable and 8192 or 16384
end

This is the equivalent of a ternary operator in other languages. If variable is true then it will return 8192, if it is nil Lua assumes false, and if false it returns the 16384

Good to know, but that is actually meant to also work with strings and ints when the program is finished.

Also where do you see a variable as nil?
remiX #4
Posted 03 January 2013 - 06:45 AM
You if statement for the status, you only need if and else, no elseifs because it can only be true or false (exist or not) (not nil or nil)

    if status == true then --This is where I am starting to get this first problem.
        term.write("on")
    elseif status == false then
        term.write("off")
    elseif status ~= nil and not status == true and not status == false then
        term.write(status)
    end

function menuOption(line, key, optionString, status, statusColor)
    term.setCursorPos(1, line)
    term.write(key..":")
    term.setCursorPos(8, line)
    term.write(optionString)
    term.setCursorPos(30, line)
    term.setTextColor(statusColor)
    write(status and "on" or "off")
    -- But why not just concatenate it onto one line?
    write(key .. ":" .. optionString .. " : " .. (status and "on" or "off"))
    -- Unless you want more spaces between the text
    term.setTextColor(1)
end
 
Frederikam #5
Posted 03 January 2013 - 06:57 AM
You if statement for the status, you only need if and else, no elseifs because it can only be true or false (exist or not) (not nil or nil)

	if status == true then --This is where I am starting to get this first problem.
		term.write("on")
	elseif status == false then
		term.write("off")
	elseif status ~= nil and not status == true and not status == false then
		term.write(status)
	end

function menuOption(line, key, optionString, status, statusColor)
	term.setCursorPos(1, line)
	term.write(key..":")
	term.setCursorPos(8, line)
	term.write(optionString)
	term.setCursorPos(30, line)
	term.setTextColor(statusColor)
	write(status and "on" or "off")
	-- But why not just concatenate it onto one line?
	write(key .. ":" .. optionString .. " : " .. (status and "on" or "off"))
	-- Unless you want more spaces between the text
	term.setTextColor(1)
end


It is made so the function can accept str, int and boolean; basically for displaying like on/off/stats.

For the second code I want it to look more like a table. I want a final distance between everything.
remiX #6
Posted 03 January 2013 - 07:54 AM
Then use type() to check what it is, boolean, int or str.


if type(status) == "boolean" then
    write(status and "on" or "off")
elseif type(status) == "string" then
    write(status)
elseif type(status) == "number" then
    ..
end
Frederikam #7
Posted 03 January 2013 - 08:14 AM
Then use type() to check what it is, boolean, int or str.


if type(status) == "boolean" then
	write(status and "on" or "off")
elseif type(status) == "string" then
	write(status)
elseif type(status) == "number" then
	..
end

I didn't know about that function, that is really useful.

This does not solve my problem, the term.write() does still return false.


function menuOption(line, key, optionString, status, statusColor)
    term.setCursorPos(1, line)
    term.write(key..":")
    term.setCursorPos(8, line)
    term.write(optionString)
    term.setCursorPos(30, line)
    term.setTextColor(statusColor)
    if type(status) == "boolean" and not status == nil then --This is where I am starting to get this first problem.
	    term.write(status and "on" or "off")
    elseif type(status) == "number" or type(status) == "string" then
	    term.write(status)
    end
    term.setTextColor(1)
end
ChunLing #8
Posted 04 January 2013 - 07:58 AM
Where are you getting the return of term.write()?
remiX #9
Posted 04 January 2013 - 08:26 AM
if type(status) == "boolean" and not status == nil then --This is where I am starting to get this first problem. 

If the type of status is a boolean, then it's obviously not going to be nil.
What exactly are you entering for the status?

Also, try this for an advanced print xD

print( ( ( type( status ) == "boolean" ) and ( status and "on" or "off" ) ) or ( ( type( status ) == "string" or type( status ) == "number" ) ) and status )
Frederikam #10
Posted 05 January 2013 - 02:54 AM
Where are you getting the return of term.write()?

What do you mean by that?


if type(status) == "boolean" and not status == nil then --This is where I am starting to get this first problem. 

If the type of status is a boolean, then it's obviously not going to be nil.
What exactly are you entering for the status?

Also, try this for an advanced print xD

print( ( ( type( status ) == "boolean" ) and ( status and "on" or "off" ) ) or ( ( type( status ) == "string" or type( status ) == "number" ) ) and status )

Status is either true or false, but at firsts time i call update() true seems to be a string and not a boolean.
remiX #11
Posted 05 January 2013 - 02:59 AM
Did you make status
true
or
"true"

First one is a boolean,
second is a string

Post the line where you call the function
ChunLing #12
Posted 05 January 2013 - 03:31 AM
This does not solve my problem, the term.write() does still return false.
How do you know it is returning false? How are you even getting it to return false? I wasn't aware it had a return value at all.

Obviously just a communication breakdown. But you are the one that doesn't get effective help if you aren't clear.
Frederikam #13
Posted 05 January 2013 - 04:27 AM
Did you make status
true
or
"true"

First one is a boolean,
second is a string

Post the line where you call the function


menuOption(3, 1, "Toggle frame bore", boreStatus, getColor(boreStatus))

boreStatus is loaded from a file using the function "loadData()".


function loadData()
    file = fs.open("/data", "r")
    boreStatus = file.readLine()
    file.close()
    rednet.send(16, "afterLoad: "..tostring(boreStatus))
end

Does my function read "true" as a string? If so what can i do about that? As far as i know there is no toboolean().


This does not solve my problem, the term.write() does still return false.
How do you know it is returning false? How are you even getting it to return false? I wasn't aware it had a return value at all.

Obviously just a communication breakdown. But you are the one that doesn't get effective help if you aren't clear.

Ohh yeah. What i should have said would be that "term.write()" writes false instead of "off". If status was a boolean and if it is false it should write "off", but because the status is a string with the value of "false" it instead prints "false".

function menuOption(line, key, optionString, status, statusColor)
    term.setCursorPos(1, line)
    term.write(key..":")
    term.setCursorPos(8, line)
    term.write(optionString)
    term.setCursorPos(30, line)
    term.setTextColor(statusColor)
    if type(status) == "boolean" and not status == nil then --This is where I am starting to get this first problem.
		    term.write(status and "on" or "off")
    elseif type(status) == "number" or type(status) == "string" then
		    term.write(status)
    end
    term.setTextColor(1)
end
Lyqyd #14
Posted 05 January 2013 - 04:46 AM
toboolean is easy:


function toboolean(str)
  if type(str) ~= "string" or (str ~= "true" and str ~= "false") then return nil end
  return str == "true"
end
remiX #15
Posted 05 January 2013 - 06:31 AM
Yes, reading text from a file returns it as a string, so boreStatus is "true" and not true. So it is a string.

Or you can just do this when reading the file:

if boreStatus == "true" then boreStatus = true else boreStatus = false end
Lyqyd #16
Posted 05 January 2013 - 06:36 AM
Or, you know, boreStatus = boreStatus == "true"
Frederikam #17
Posted 05 January 2013 - 07:44 AM
Yes, reading text from a file returns it as a string, so boreStatus is "true" and not true. So it is a string.

Or you can just do this when reading the file:

if boreStatus == "true" then boreStatus = true else boreStatus = false end

LIke this?

if typeboreStatus == "true" or "false" then -- Will ignore strings that are not meant to be booleans.
    if boreStatus == "true" then
	    boreStatus = true
    else
	    boreStatus = false
    end
end
Remember; strings other than "true" or "false" must be ignored in this case.
remiX #18
Posted 05 January 2013 - 07:57 AM
remove the type in the first line though.
In what case would it something other than true or false?


if boreStatus == "true" or boreStatus == "false then -- Proper way of using the or comparison
  if boreStatus == "true" then boreStatus = true
  else boreStatus = false
  end
end
Lyqyd #19
Posted 05 January 2013 - 08:52 AM
toboolean is easy:


function toboolean(str)
  if type(str) ~= "string" or (str ~= "true" and str ~= "false") then return nil end
  return str == "true"
end

Was this post visible to anyone else, or just me? Not sure why we are still discussing this, moving closer to this function I posted above.
ChunLing #20
Posted 05 January 2013 - 09:38 AM
I saw it. But I wouldn't even bother with that much.
Lyqyd #21
Posted 05 January 2013 - 09:53 AM
Oh, I wouldn't either. I usually just do myBool = boolStr == "true" or similar. It just doesn't make sense that they'd ignore the valid suggestion and then keep tossing code back and forth that just keeps getting closer to doing the exact same thing, except less compact.