Jump to content




variables and API's. How do I properly reference to them?


  • You cannot reply to this topic
12 replies to this topic

#1 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 13 August 2014 - 06:50 PM

Hi,

I am trying to make an API. It is meant to provide movement functions for turtles while keeping track of their relative position.

This is the API:
Spoiler

this is the program I use to test moving forward for 5 blocks.
os.loadAPI("movementAPI")
movementAPI.init()
movementAPI.move(5)

I get the following error:
MovementAPI: 33 : attempt to concatenate string and nil
line 33 shows the following code
location = "" .. x .. "," .. y .. "," .. z

I understand that I am probably not using the references to x, y, z and d properly... however I cannot figure out how to do it x)

Could anyone give me some tips?

Cheers!
Chris

#2 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 13 August 2014 - 07:20 PM

Nah, you're referring to them correctly. Odds are it's to do with the function above - if gx/gy/gz don't represent valid numbers for any reason, then tonumber(gx)/tonumber(gy)/tonumber(gz) will return nil.

#3 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 13 August 2014 - 08:06 PM

 Bomb Bloke, on 13 August 2014 - 07:20 PM, said:

Nah, you're referring to them correctly. Odds are it's to do with the function above - if gx/gy/gz don't represent valid numbers for any reason, then tonumber(gx)/tonumber(gy)/tonumber(gz) will return nil.

Actually, I didn't use that function yet. So I don't know if it will work or not.
I tried to set values for x, y and z in init() and this is not working. Instead of nil, I expected the values to be 0.

Any clue?

maybe you are right...but I have to give it some deeper thought :P

Edited by Crucidal, 13 August 2014 - 08:16 PM.


#4 hilburn

  • Members
  • 153 posts
  • LocationLondon, England

Posted 13 August 2014 - 08:33 PM

why not do:
location=textutils.serialize(locationfile.readall())


much better to use vectors/tables for doing location stuff

Edited by hilburn, 13 August 2014 - 08:33 PM.


#5 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 13 August 2014 - 09:08 PM

 hilburn, on 13 August 2014 - 08:33 PM, said:

why not do:
location=textutils.serialize(locationfile.readall())


much better to use vectors/tables for doing location stuff

Because that's something that I haven't used before and I don't know anything about the serialize function.

This method I intended to use is simple to comprehend for someone who only knows basic programming x)

I'm having trouble with the fs readAll() and readLine() function though.
I have a file "location" with "0,0,0" in it. (without quotes) and both the functions I just mentioned return nothing... but there is no error either... when I do a print(locationFile.readAll()) it prints an empty line... =(

#6 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 13 August 2014 - 09:18 PM

I'm starting to understand my own problem.
I accidently read locationFile twice... and once you read it you cannot read it again unless you save what you read or if you re-open the file.

#7 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 13 August 2014 - 09:34 PM

gx, gy, gz = locationFile.readAll():match("([^,]+),([^,]+), ([^,]+)")

this code doesn't seem to work but I don't know how else to do this... any ideas?

#8 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 14 August 2014 - 02:40 AM

 Crucidal, on 13 August 2014 - 08:06 PM, said:

Actually, I didn't use that function yet.

It sounds like you've already seen your mistake in saying that, but movementAPI.move() calls getLocation() followed by setLocation() again.

Sometimes, when a function fails within an API, it can be handy to intersperse random print statements throughout your main scripts so you can tell exactly how far the script got before making the final call that crashed. Some other languages - eg Java - make this a lot easier by handing you the entire list of functions sitting in the stack along with the lines they were called from and of course your error message as well.

 hilburn, on 13 August 2014 - 08:33 PM, said:

why not do:

Psst, you mean unserialise!

Anyway, to elaborate on this, it'd work along these lines: First you'd initialise a table with your values in it:

local myVars = {["x"] = 0, ["y"] = 0, ["z"] = 0, ["d"] = 0}

You'd now be able to refer to these variables as myVars.x, myVars.y, and so on. textutils.serialise() can then be used to convert the entire table and its contents to a single string (a series of characters - get it?), which you can write to disk like so:

--setLocation and direction
local function setLocation()
	local locationFile = fs.open("location", "w")
	locationFile.write(textutils.serialise(myVars))
	locationFile.close()
end

And then to read it, textutils.unserialise() comes into play:

--getLocation
function getLocation()
	local locationFile = fs.open("location", "r")
	myVars = textutils.unserialise(locationFile.readAll())
	locationFile.close()
end

 Crucidal, on 13 August 2014 - 09:34 PM, said:

gx, gy, gz = locationFile.readAll():match("([^,]+),([^,]+), ([^,]+)")

this code doesn't seem to work but I don't know how else to do this... any ideas?

Something like this:

gx, gy, gz = locationFile.readAll():match("(.*%d*),(.*%d*),(.*%d*)")

The stuff outside the brackets has to be matched verbatim - that includes spaces, so be careful! Within the brackets, ".*" means "get everything until the next match", and "%d*" means "get all digits until the next match".

It may be that you can't apply "match" directly to "locationFile.readAll()". You may need to read the file contents into a variable, then apply "match" to that variable on the following line.

#9 natedogith1

  • Members
  • 110 posts

Posted 14 August 2014 - 05:15 AM

 Bomb Bloke, on 14 August 2014 - 02:40 AM, said:

 Crucidal, on 13 August 2014 - 09:34 PM, said:

gx, gy, gz = locationFile.readAll():match("([^,]+),([^,]+), ([^,]+)")

this code doesn't seem to work but I don't know how else to do this... any ideas?

Something like this:

gx, gy, gz = locationFile.readAll():match("(.*%d*),(.*%d*),(.*%d*)")

The stuff outside the brackets has to be matched verbatim - that includes spaces, so be careful! Within the brackets, ".*" means "get everything until the next match", and "%d*" means "get all digits until the next match".

It may be that you can't apply "match" directly to "locationFile.readAll()". You may need to read the file contents into a variable, then apply "match" to that variable on the following line.

The stuff outside the brackets works in the funny way of regular expressions, it's the stuff inside that's more exact(I think), though it's more of an or(or a nor because of the begining '^').

I'd recomend using something along the lines of '.-(%d+),.-(%d+),.-(%d+)' , as it doesn't return the unnecessary white space characters. The difference between the '*' and the '-' is potentially very important as it's the difference between '12,12,12' returning three twos or three twelves in this case. The '*' is hungry, it eats the string and gives back what's needed, while the '-' isn't hungry, therefore it leaves behind as much of the string as it can.
local str="1234567890"
local dot1,number1=str:match("(.*)(%d*)")
local dot2,number2=str:match("(.-)(%d+)")
print(dot1,"|",number1)
print(dot2,"|",number2)
With the above, dot1 will contain the entire string, while number1 will be an empty string. However, with the second regular expression, dot2 will be an empty string and number2 will be the number, which is much closer to what we want.

Also, checking it out, it seems that your issue was an accidental space, as (I think) Bomb Bloke mentioned.

#10 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 14 August 2014 - 05:58 AM

 natedogith1, on 14 August 2014 - 05:15 AM, said:

I'd recomend using something along the lines of '.-(%d+),.-(%d+),.-(%d+)' , as it doesn't return the unnecessary white space characters.

True, but there shouldn't be any white space. While I'm sure my expression can be improved (I've got a nagging feeling it doesn't need the %d*'s at all), it does have the benefit of being able to handle decimal points and negative values.

Though seriously, I'm no pattern expert. I just bashed stuff into repl.it according to this guide until it worked.

Edited by Bomb Bloke, 14 August 2014 - 06:07 AM.


#11 natedogith1

  • Members
  • 110 posts

Posted 14 August 2014 - 07:04 AM

 Bomb Bloke, on 14 August 2014 - 05:58 AM, said:

 natedogith1, on 14 August 2014 - 05:15 AM, said:

I'd recomend using something along the lines of '.-(%d+),.-(%d+),.-(%d+)' , as it doesn't return the unnecessary white space characters.

True, but there shouldn't be any white space. While I'm sure my expression can be improved (I've got a nagging feeling it doesn't need the %d*'s at all), it does have the benefit of being able to handle decimal points and negative values.

Though seriously, I'm no pattern expert. I just bashed stuff into repl.it according to this guide until it worked.
Good point, I didn't even consider it couldn't handle '.' or '-' in the numbers. And yeah, yours would work just fine without the '%d*'(which actually isn't doing anything, because '.*' is eating up all the characters, leaving the '%d*' with nothing). A better regular expression would probably be replace '%d+' with '[%d-.]+', and maybe replace '.' with '%s-' or '%s*'

#12 Crucidal

  • Members
  • 33 posts
  • LocationThe Netherlands

Posted 15 August 2014 - 04:51 PM

 Bomb Bloke, on 14 August 2014 - 02:40 AM, said:

Anyway, to elaborate on this, it'd work along these lines: First you'd initialise a table with your values in it:

thanks, this was easy to understand and helped a lot. I used this in my implementation now :-)
next up: implementing a version of the a* algorithm to automatically find a path to it's origin!
Looking forward to it! :-)

 natedogith1, on 14 August 2014 - 05:15 AM, said:

 Bomb Bloke, on 14 August 2014 - 02:40 AM, said:

 Crucidal, on 13 August 2014 - 09:34 PM, said:

gx, gy, gz = locationFile.readAll():match("([^,]+),([^,]+), ([^,]+)")

this code doesn't seem to work but I don't know how else to do this... any ideas?

Something like this:

gx, gy, gz = locationFile.readAll():match("(.*%d*),(.*%d*),(.*%d*)")

The stuff outside the brackets has to be matched verbatim - that includes spaces, so be careful! Within the brackets, ".*" means "get everything until the next match", and "%d*" means "get all digits until the next match".

It may be that you can't apply "match" directly to "locationFile.readAll()". You may need to read the file contents into a variable, then apply "match" to that variable on the following line.

The stuff outside the brackets works in the funny way of regular expressions, it's the stuff inside that's more exact(I think), though it's more of an or(or a nor because of the begining '^').

I'd recomend using something along the lines of '.-(%d+),.-(%d+),.-(%d+)' , as it doesn't return the unnecessary white space characters. The difference between the '*' and the '-' is potentially very important as it's the difference between '12,12,12' returning three twos or three twelves in this case. The '*' is hungry, it eats the string and gives back what's needed, while the '-' isn't hungry, therefore it leaves behind as much of the string as it can.
local str="1234567890"
local dot1,number1=str:match("(.*)(%d*)")
local dot2,number2=str:match("(.-)(%d+)")
print(dot1,"|",number1)
print(dot2,"|",number2)
With the above, dot1 will contain the entire string, while number1 will be an empty string. However, with the second regular expression, dot2 will be an empty string and number2 will be the number, which is much closer to what we want.

Also, checking it out, it seems that your issue was an accidental space, as (I think) Bomb Bloke mentioned.

is there any place where they explain these tokens? It's quite unreadable if you don't know what a * + or % is supposed to do.
If I knew this, I could figure out why your solution doesn't return unnecessary white space characters :-)

#13 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 15 August 2014 - 05:15 PM

http://www.lua.org/pil/20.2.html





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users