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

Creating a removal option for a file

Started by orik1997, 16 April 2015 - 01:17 PM
orik1997 #1
Posted 16 April 2015 - 03:17 PM
So I have been creating this Script for a mining turtle. It is supposed to save all of the Blocks that the mining turtle should ignore inside a file. For that I have two options either placing that Block in front of the turtle or writing the code of the Block in it. This works fine so far all the information gets saved in my file now my Problem is I want to be able to remove Blocks from that List I do that by typing:


trashBlock = {}
newTrashBlock = {}
load(trashBlockFile,trashBlock)
newTrashBlock = trashBlock
resetScreen()
for i=1,#trashBlock do
stringQuestionAsked = "Remove "..trashBlock.."?"
choices = {"Yes I will","No I won't"}
highlighted = 2
Menu()
if choices[1] == chosenOne then
table.remove(newTrashBlock,i)
end
end

trashBlock = newTrashBlock
local file = fs.open("Data/"..trashBlockFile,"w")
for n=1,#trashBlock,1 do
file.writeLine(trashBlock[n])
end
file.close()

The load function works fine but here it is anyway:

function load(fileName,arrayName) –Loading data that is inside File
file = fs.open("Data/"..fileName,"r") – Open a file for reading.
line = file.readLine() – This function reads the next line in the file, until the end.
repeat – Start a loop which will read lines into a table until no lines are left.
table.insert(arrayName,line) – Puts the value of the current line into the table we have.
line = file.readLine() – read the next line
until line == nil – readLine() returns nil when the end of the file is reached.
file.close() – Close up the file ready for use again.
end

The Menu Functions is just a function that centers the text and let's you choose one of the options with your arrow keys. Then it defines the choice you made with return to be the chosenOne.
The resetScreen Function just clears the screen and sets the cursor Position to 1,1.

The Problem I'm having is that if I let's say I have 3 Blocks in my List the first one is minecraft:dirt ,the second one is: minecraft:grass and the third one is minecraft:stone and I want to remove the first one so minecraft:dirt the Program runns through and says:
Remove minecraft:dirt?
I say Yes I do then it removes that from the table now the problem is then the Program says:
Remove minecraft:stone?
which it shouldn't since minecraft:stone is the third one and not the second one anyway I then say No I won't and then
I get the error : attempt to concatenate nil and string. In line: stringQuestionAsked = "Remove "..trashBlock.."?".
I think the problem is that number two has become number one after removing number one and number 3 has become 2 so there is no 3 left.
The only thing I don't get is why that would happen I have two different tables and I am removing from one of them and printing from the other.
I hope you guys can help me because I can't figure this out.
flaghacker #2
Posted 16 April 2015 - 04:07 PM
Could you put your full code on pastebin? You can go to the site or upload it directly from computercraft, using

pastebin put <fileName>

Just a random guess thought: You're using the variable i in your menu function, or somewhere else in your code?

And why don't you use parameters for your Menu function? That would result in cleaner code…
orik1997 #3
Posted 16 April 2015 - 05:03 PM
Ok sure it's around 500 lines long though the for this code important parts are in the beginning and in the code section after line 315. Here is the Link: http://pastebin.com/PspTuscF
Dragon53535 #4
Posted 16 April 2015 - 05:57 PM
I know the reason why it's doing what it's doing.


for i=1,#trashBlock do
								stringQuestionAsked = "Remove "..nameTrashBlock[i].."?"
								choices = {"Yes I will","No I won't"}
								highlighted = 2
								Menu()
								if choices[1] == chosenOne then
										table.remove(newTrashBlock,i)
								end
						end
This is the loop that you use to remove the blocks from the table. When using table.remove, it shifts the numerical indexes of the table down. Such that when removing the first block. The second block is now in the slot of the first and the third is in the slot of the second. So what's happening in your loop, is that it loops through the first time, you say remove the first entry. So now the entry in the second slot (TrashBlock[2]) is what USED to be in TrashBlock[3], and so when you say, no I don't want to delete that, it moves on to try and look into TrashBlock[3] however nothings in there now.

Now you may think that just because you're using a table called newTrashBlock that it's going to be a different table, that assumption is wrong. TrashBlock and NewTrashBlock both look at the same spot, any change that happens to one, happens to the other. What you will want to do is manually copy the contents of TrashBlock to a new table, without just setting them to be the same.

Edit: Also, why the hell is the nameTrashBlock in there? It's NEVER being set ANYWHERE.

Also to explain that second paragraph better.

local tbl = {"Hi"}
local lbt = tbl
print(tbl[1]) --# "Hi"
print(lbt[1]) --# "Hi"
tbl[1] = "Bye"
print(tbl[1]) --# "Bye"
print(lbt[1]) --# "Bye"
Edited on 16 April 2015 - 03:59 PM
orik1997 #5
Posted 16 April 2015 - 09:48 PM
Thanks for your help with this problem. Replacing the line:
trashBlock = newTrashBlock
with
for m=1,#trashBlock,1 do
table.insert(newTrashBlock,m,trashBlock[m])
end
fixed it. The reason behind the nameTrashBlock was I was trying to fix the problem by adding another table which of course didn't work and I forgot to remove it. But now I have another problem if I enter the 3 Blocks dirt, grass and stone again and I try to remove all of them minecraft:grass remains. When I activate the removing part again with only grass in my list it get's removed. Here is my newest version of the code: http://pastebin.com/Wz2Q8nz5
Dragon53535 #6
Posted 17 April 2015 - 12:12 AM
The problem remains the same, however slightly different.
When using table.remove, it shifts the numerical indexes of the table down. Such that when removing the first block. The second block is now in the slot of the first and the third is in the slot of the second. So what's happening in your loop, is that it loops through the first time, you say remove the first entry. So now the entry in the second slot (TrashBlock[2]) is what USED to be in TrashBlock[3], and so when you say, no I don't want to delete that, it moves on to try and look into TrashBlock[3] however nothings in there now.
Reading that, it means the same here. When you chose to delete the first and second, the second will NEVER be deleted.

local tbl = {"one","two","three"}
table.remove(tbl,1)
--# tbl = {"two","three"}
table.remove(tbl,2)
--# tbl = {"two"}
table.remove(tbl,3)
--# tbl = {"two"}
Edited on 16 April 2015 - 10:14 PM
orik1997 #7
Posted 17 April 2015 - 04:46 PM
Thanks but then I don't really know what to change for this to work?
Dragon53535 #8
Posted 17 April 2015 - 04:54 PM
Setup a variable to keep track of how many times you've removed things.


local removed = 0
local tbl = {"one","two","three"}
for i = 1, #tbl do
  table.remove(tbl,i-removed)
  removed = removed + 1
end

--#Lemme use this to try to explain.
#first iteration, i = 1, removed = 0
#tbl = {"two","three"}
#Lets say I want to get rid of three but not two
#We will be on the third iteration then, so i = 3, however since we removed "one" then removed = 1
#tbl = {"two"}
#Now we're done looping, and we removed exactly what we wanted.

Edit: I'll give an example with more than 3 entries


local tbl = {"one","two","three","four","five","six","seven"}
--# Seven entries.
local removed = 0 --# haven't removed anything
table.remove(tbl,1-removed)
removed = removed + 1
--# tbl = {"two","three","four","five","six","seven"}
--#Lets say I want to remove four now (If I do, i CANNOT remove three or two.
table.remove(tbl,4-removed) --#Four was in the fourth slot at the beginning, and that's the slots i'm going by.
#However since removed is 1, i'm aiming at the third slot, where four is right now
removed = removed + 1
--#tbl = {"two","three","five","six","seven"}
--#Now lets just remove seven. It started at tbl[7] and is now tbl[5]
table.remove(tbl,7-removed) --# 7-2 is 5 so i'm aiming at the right spot, however now I cannot remove anything lower than me REMEMBER THIS.
removed = removed + 1
--#tbl = {"two","three","five","six"}
Edited on 17 April 2015 - 03:01 PM
orik1997 #9
Posted 17 April 2015 - 07:14 PM
Thank you! That fixed it