Why does using two variables give me an error message when using an if statement? - lua

I'm attempting to write a script in LUA for the Minecraft mod ComputerCraft. It's supposed to send a turtle down, mine a hole, and place ladders before returning to the surface. I'm trying to make an error display when the turtle doesn't have enough ladders, but I'm receiving an error that prevents it from running. "mineDown :18: attempt to compare string with number expected, got string."
-- This gets the user to tell the turtle how far to dig down
print('How far down should I go?')
distDown = io.read()
distMoved = 0
ladders = turtle.getItemCount(13)
-- Check if the number of ladders is less than the distance needed to move. If so, returns error.
turtle.select(13)
if ladders < distDown then
error('Not enough ladders!')
end

The error means that ladders is number and distDown is a string. You need to convert them to the same type. For example to convert ladders to a string use tostring or distDown to a number use tonumber:
if ladders < tonumber(distDown) then

Related

Lua function returns 768 values - how to put these into a table

I am programming an instrument that uses Lua with extensions for accessing the instrument controls and displays.
The instrument has a command to read the analyzer plotted points for frequency and amplitude:
:analyzer:trace:frequency?
and
:analyzer:trace:amplitude?
Whenever either of the above is executed, 768 values are returned (frequency or amplitude). This is an embedded test system running Lua for user apps - I can't change the command.
I tried to use table.pack() to put these returned values into a table, but the syntax of the command with the ":" causes an error.
Code I tried --
freq = {};
freq = table.pack(:analyzer:trace:frequency?);
Error message is -- tests.lua:2428: unexpected symbol near ':'
Whenever the :analyzer:trace:frequency? is run stand alone (from PuTTY) or as a line in the Lua code, there is no error.
PuTTY receives 768 frequency values, each separated by a comma.
Looking for ways to direct the return into an array/table or to wrap the command so that it will execute similarly as above.
Thanks

I am looking for a Lua find and replace logic

enter image description here
I just started working on lua scripting since a week. I have a lua file where in the logic needs to be written for a certain condition.
The condition when gets triggered
it does an iteration on one of the fields to change value from
(ABC123-XYZ) to this value
(ABC123#1-XYZ) and it keeps increasing whenever iterations happens (ABC123#2-XYZ)
I need to run a function that removes the # followed by number to change it back to (ABC123-XYZ). Looking for any advice!
Edit 1:
Below is the updated code that is written Thanks to #Piglet
I have another scenario if therr are two hashes in the variable.
local x = 'BUS144611111-PNB_00#80901#1555-122TRNHUBUS'
local b = x:gsub("#%d+","")
function remove_char(a) a=a:gsub("#%d+","")
return a;
end if string.match(x,"#")
then print('function')
print(remove_char(x));
else print(x);
end
Expected output should be
x = 'BUS144611111-PNB_00#80901-122TRNHUBUS' for the aforesaid variable
local a = "ABC123#1-XYZ"
local b = a:gsub("#%d+", "")
this will remove any # followed by or one more digits from your string.

My code doesn't do anything

game:GetService("Players").PlayerAdded:connect(function()
for _, Player in pairs(game:GetService("Players"):GetPlayers()) do
Player.Chatted:connect(function(msg)
if string.sub(msg,1,5) == "oofergang" then
Player:Kick("no no no cringe baby")
end
end)
end
end)
return ''
How do I fix this? It doesn't do anything, no errors nothing.
Your issue seems to be in your string.sub() usage. (I'm assuming this is Roblox, which I don't know much about).
The string.sub(a, b, c) method takes the substring of the string a, starting from index b and going to index c.
Your problem is that you're trying to get the substring from characters 1-5. Character 1 is the first character and character 5 is the 5th character in the string. Your if block is checking the first 5 characters of the player's message. The issue is that the string you're comparing it to, "oofergang", is longer than 5 characters.
If the player does correctly type oofergang, the string.sub() that you're using will output oofer, which is the first 5 characters of the message. Essentially, this is what the program will see when running:
if "oofer" == "oofergang" then
oofer is never going to equal oofergang.
If you want to check if the player starts their message with oofergang then you should use the following if block instead:
if (string.sub(msg, 1, 9) == "oofergang") then
--Whatever you want to do here, in your case kick the player
end
EDIT: As suggested, the following code allows you to find a string within another string ANYwhere, not just a the start:
if (string.find(msg, "oofergang")) then
--Whatever you want to do here, in your case kick the player
end

Logic behind COBOL code

I am not able to understand what is the logic behind these lines:
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
Data definition:
000330 01 VAR1 COMP-1 VALUE 3.4E38. // 3.4 x 10 ^ 38
Here are those lines in context (the sub-program returns a square root):
MOVE VAR1 TO PARM1.
CALL "SQUAREROOT_ROUTINE" USING
BY REFERENCE PARM1,
BY REFERENCE RESULT.
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
DISPLAY "OK"
ELSE
DISPLAY "False"
END-IF.
These lines are just trying to test if the result returned by the SQUAREROOT_ROUTINE is correct. Since the program is using float-values and rather large numbers this might look a bit complicated. Let's just do the math:
You start with 3.4E38, the squareroot is 1.84390889...E19.
By subtracting 1.843E19 (i.e. the approximate result) and comparing the difference against 1.0E16 the program is testing whether the result is between 1.843E19 and 1.843E19+1.0E16 = 1.844E19.
Not that this test would not catch an error if the result from SQUAREROOT_ROUTINE was too low instead of too high. To catch both types of wrong results you should compare the absolute value of the difference against the tolerance.
You might ask "Why make things so complicated"? The thing is that float-values usually are not exact and depending on the used precision you will get sightly different results due to rounding-errors.
well the logic itself is very straight forward, you are subtracting 1.843*(10^19) from the result you get from the SQUAREROOT_ROUTINE and putting that value in the variable called temp and then If the value of temp is less than 1.0*(10^16) you are going to print a line out to the SYSOUT that says "OK", otherwise you are going to print out "False" (if the value was equal to or greater than).
If you mean the logic as to why this code exists, you will need to talk to the author of the code, but it looks like a debugging display that was left in the program.

Lua: Working with the Modbus TCP/IP Protocol

This question is based off a previous question I asked concerning a similar topic: Lua: Working with Bit32 Library to Change States of I/O's . I'm trying to use a Lua program that, when a PLC changes the state of a coil at a given address (only two addresses will be used) then it triggers a reaction in another piece of equipment. I have some code that is basically the exact same as my previous topic. But this has to do with what this code is actually doing and not so much the bit32 library. Usually I run code I don't in understand in my Linux IDE and slowly make changes until I finally can make sense of it. But this is producing some weird reactions that I can't make sense of.
Code example:
local unitId = 1
local funcCodes = {
readCoil = 1,
readInput = 2,
readHoldingReg = 3,
readInputReg = 4,
writeCoil = 5,
presetSingleReg = 6,
writeMultipleCoils = 15,
presetMultipleReg = 16
}
local function toTwoByte(value)
return string.char(value / 255, value % 255)
end
local coil = 1
local function readCoil(s, coil)
local req = toTwoByte(0) .. toTwoByte(0) .. toTwoByte(6) .. string.char(unitId, funcCodes.readCoil) .. toTwoByte(coil - 1) .. toTwoByte(1)
s:write(req) --(s is the address of the I/O module)
local res = s:read(10)
return res:byte(10) == 1 -- returns true or false if the 10th bit is ==1 I think??? Please confirm
end
The line that sets local req is the part I'm truly not making sense of. Because of my earlier post, I understand fully about the toTwoByte function and was quickly refreshed on bits & byte manipulation (truly excellent by the way). But that particular string is the reason for this confusion. If I run this in the demo at lua.org I get back an error "lua number has no integer representation". If I separate it into the following I am given back ascii characters that represent those numbers (which I know string.char returns the ascii representation of a given digit). If I run this in my Linux IDE, it displays a bunch of boxes, each containing four digits; two on top of the other two. Now it is very hard to distinguish all of the boxes and their content as they are overlapping.
I know that there is a modbus library that I may be able to use. But I would much rather prefer to understand this as I'm fairly new to programming in general.
Why do I receive different returned results from Windows vs Linux?
What would that string "local req" look like when built at this point to the I/O module. And I don't understand how this req variable translates into the proper string that contains all of the information used to read/write to a given coil or register.
If anyone needs better examples or has further questions that I need to answer, please let me know.
Cheers!
ETA: This is with the Modbus TCP/IP Protocol, not RTU. Sorry.

Resources