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

sense:40: attempt to concatenate string and nil

Started by Sirc23, 21 June 2014 - 05:23 PM
Sirc23 #1
Posted 21 June 2014 - 07:23 PM
Hi, so my program titled "sense" is having some awkward issues with proper behavior. Despite what I see as having all proper values defined at any moment, the print statement at line 40 refuses to work and instead produces the error message above. I've tried modifying every function ever so slightly in attempts to make it work… I think as a result there may be other issues as well. Who knows.

I'm playing Tekkit Classic for Minecraft 1.2.5 (because my computer can't handle anything higher up… :V ).The program is designed to detect BatBox's, MFE's and MFSU's using code from ccSensors. It doesn't need the Sensor blocks around it, I can only assume it's because of a ccSesnor coding flaw. So I have 1 MFE with no energy and a BatBox that does have energy in it, and I want to show in vertical format each item on a list and some information concerning it. An example would be as follows:

1: BatBox : 30378 | 40000 : [//////// ]
2: MFE : 0 | 600000 : [ ]

So as it stands it will only print one thing (assuming it works), which is fine since I want to ensure I can properly list one thing before listing multiple. Now that you understand what I'm going for, I'll post the code:


--Variables
len = 1
num = 0
percentEnergy = ""
box = 1


--Tables
currentEnergy = {}
currentEnergy[0] = 0
totalEnergy = {}
totalEnergy[0] = 0
bar = {}
bar[0] = 0
data = {}
possibleUnits = {("Batbox"),("MFE"),("MFSU")}

--Functions

iB = tostring(targets)


local function cursor()
  term.clear()
  term.setCursorPos(1,1)
end

local function detectObject()
  if string.sub(iB,22,35) == "ElectricBatBox" then
	box = 1
  elseif string.sub(iB,22,33) == "ElectricMFE" then
	box = 2
  elseif string.sub(iB,22,34) == "ElectricMFSU" then
	box = 3
  end
end

local function list()
  detectObject(targets)	  
  print(len..": "..possibleUnits[box].." :"..currentEnergy[len].." | "..totalEnergy[len]..": "..bar[len])
end

local function labelBar(len)
  percentEnergy = currentEnergy[len] / (totalEnergy[len] / 10)
  p = string.sub(tostring(percentEnergy,1,2))
  if	 p < 1 then pic = "[ -Low-	]"
	elseif p < 2 then pic = "[/		 ]"
	elseif p < 3 then pic = "[//		]"
	elseif p < 4 then pic = "[///	   ]"
	elseif p < 5 then pic = "[////	  ]"
	elseif p < 6 then pic = "[/////	 ]"
	elseif p < 7 then pic = "[//////	]"
	elseif p < 8 then pic = "[///////   ]"
	elseif p < 9 then pic = "[////////  ]"
	elseif p < 10 then pic = "[///////// ]"
	elseif p >= 10 then pic = "[/-Full-///]"
	else pic = "[ -Empty-  ]"
  end
  bTable(len)
end
tablea = ""
tableb = ""
local function inserX(len,r)
  table.insert(currentEnergy,len,r)
end

local function inserY(len,r)
  table.insert(totalEnergy,len,r)
end

local function bTable(len)
  bar[len] = pic
end
local function getValues()
  if	 num == 1 then a = tostring(v) inserY(1,a)
  elseif num == 2 then b = tostring(v) inserX(1,B)/>/>/>
  elseif num == 7 then c = tostring(v) inserY(2,c)
  elseif num == 8 then d = tostring(v) inserX(2,d)
  end
end



--First Time
cursor()
os.unloadAPI("sensorsData")
os.loadAPI("/rom/apis/sensorsData")
os.unloadAPI("sensors")
os.loadAPI("/rom/apis/sensors")
os.unloadAPI("sensorsUI")
os.loadAPI("/rom/apis/sensorsUI")

--Main Loop --
function main()

  while true do
	num = 0
	local side = sensors.getController()
	local targets = sensors.getAvailableTargetsforProbe(side,"Sensor","EUStorage")
	for t,target in pairs(targets) do
	  local data = sensors.getSensorReadingAsDict(side,"Sensor",target,"EUStorage")
	  --sensorsUI.printPaged(target)
	  for i,v in pairs(data) do
		--sensorsUI.printPaged(tostring(i)..":"..tostring(v))
		getValues()
		list()
		num = num + 1
	  end
	  if len == 1 then
		len = 2
	  else if len == 2 then
		len = 1
		end
	  end
	  sleep(1)
	end
  end
end
main()

So yea, any help would be greatly appreciated. Thanks!
Bomb Bloke #2
Posted 21 June 2014 - 09:01 PM
Line 40 reads:

print(len..": "..possibleUnits[box].." :"..currentEnergy[len].." | "..totalEnergy[len]..": "..bar[len])

This tries to take the variables len, possibleUnits[box], currentEnergy[len], totalEnergy[len] plus bar[len], and merge them with the strings ": ", " :", " | " and ": ". It's saying that some of the variables are equal to nil, and hence can't be merged with the strings.

Try printing out the values of len, box, #possibleUnits, #currentEnergy, #totalEnergy and #bar just before running the problematic line. Then have a think about why you're seeing the values that shows you.
Sirc23 #3
Posted 22 June 2014 - 03:20 AM
Try printing out the values of len, box, #possibleUnits, #currentEnergy, #totalEnergy and #bar just before running the problematic line. Then have a think about why you're seeing the values that shows you.

Done, here are the results in respective order to your post before the program crashes:

1
1
3
0
0
0

and from what I can tell, the tables currentEnergy and totalEnergy are at that point registering 0. What I see is that the program is running through the function and calling it before the code calls it, because unless there's another problem in the code (which there very well may be), when the function is called for the first time I would think every value is answered. len is set in the beginning along with bar, box and, by that extension, possibleUnits would be too. current and totalEnergy are also set as tables in the beginning, as well as potential initial variables at value 0 are set as a failsafe. bar[len] is determined by the values of current and totalEnergy, so if current and totalEnergy are defined, so would bar[len]. Perhaps it's my understanding of table.insert() that is wrong…