thanks to a fellow stack-overflower, i have recently learned how to use 'run-result' to pass patch attributes as input variables to a procedure. However, i am struggling using the same approach when i want to modify the patch attribute. To clarify, in the code below, i am successfully passing the attribute 'attr1' to Export.List.to.file, but when I pass it to Import.List.from.file, i get an 'this isn't something you can use set on' error in the line 'ask datum [set (run-result #attr) file-read]]'
can anyone help?
to setup
clear-all
let patch-list sort patches
ask patches [set attr1 random 10]
Export.List.to.file "attr1" patch-list "attr1.txt"
Import.List.from.file "attr2" patch-list "attr1.txt"
end
to Export.List.to.file [#attr #patch-list #filename]
let list1 map [ p -> [run-result #attr] of p ] #patch-list
carefully [file-delete #filename] []
file-open #filename
foreach list1 [?datum -> file-print ?datum]
file-close
end
to Import.List.from.file [#attr #patch-list #filename]
file-open #filename
foreach #patch-list [datum -> ask datum [set (run-result #attr) file-read]]
file-close
end
To be perfectly honest, I can't explain exactly why it doesn't work in the second case and does work in the first case. My best guess is that in the first case, the attribute is treated as a reporter, something to be used by other processes. In the second case, the attribute is treated as a property, for which different rules apply.
The workaround I would use is to turn the entire set command into a single string, and then turning it back into a command by using run. To combine the different parts of the command into a single string, you can use word: let commandstring (word "set " #attr-name " random 5"). Notice how I use quotation marks for "set " and " random 5" but I don't use them for #attr-name, since I don't want #attr-name in the final string, but rather the string contained within #attr-name. In my case that would be "attr3".
to go-3
change-attribute "attr3" patches
end
to change-attribute [#attr-name patchset]
let commandstring (word "set " #attr-name " random 5")
show commandstring
; this gives "set attr3 random 5"
ask patchset [run commandstring ]
end
Related
this one should be simple, but..
i would like to define a string in Netlogo which I can then send to the 'run' command. The string needs to include double quotes.
the code below gives "visit Paris"
but I want "visit "Paris" "
'''
to setup
clear-all
let str "Paris"
let to-do (word "visit " str)
show to-do
; gives "visit Paris"
end
'''
Netlogo Help claims that I should escape the double quote with a backslash, but this does not seem to work, at least in Netlogo 6.2.
any help? thanks in advance
For me it works perfectly fine if I use a backslash. The difference here is how Netlogo outputs your result. If you use show, it outputs the entire string with quotes around it. In that case the \ is retained since it signals that the following " is part of the string and not the end of the string. If you however use print, the result is shown without quotes around it and the \ is dropped, as it is no longer needed to signal that the following " is a part of the output.
let str "\"Paris\""
let to-do (word "visit " str)
show to-do ; observer: "visit \"Paris\""
print to-do ; visit "Paris"
As used with my answer to your previous quesiton, it would give you the following, which works:
to go-5
run "change-attribute \"attr3\" patches"
end
See also the output section in the Netlogo programming guide
I Googled it but i'm not able to find a GOOD solution.
My goal is to put a string which is composed of 6 lines in one string, and only one, in a variable.
For example, my string can look like :
a
b
c
and I want it to be in one string. I tried the thing witch ^, or with ECHO " " but it doesn't work : the cmd put an error "not recognized as an internal command" (and it's normal, it's just some sentences, not batch commands!)
Thanks, Clément
Not so simple but possible :
#echo off
REM Creating a Newline variable (the two blank lines are required!)
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
REM Example Usage:
setlocal enableDelayedExpansion
set "string_with_new_lines=a!nl!b!nl!c"
echo %string_with_new_lines%
Aacini has a simpler solution for this using empty variable,but I'm struggle to find the link.
Following the comments on the post answer of #npocmaka
It's currently in Python, so the """ thing works.
requete = """
PREFIX resources: <http://www.fluidops.com/resource/>
SELECT DISTINCT ?id ?marque ?modele WHERE {
?voiture resources:uid ?id.
?voiture resources:bpqmqvc ?marque. #myComment
?voiture resources:bpqmodvc ?modele
}
"""
I have a program which sets a variable "x" to the length of a random dictionary word, and then should put "a" into a field x amount of times. However I am unsure whether my syntax is right or wrong. The variable randomword is already defined and works. My non-working code is as follows:
global x
on mouseUp
put length(randomword) into x
put repeatedString("a",x) into field "wordDisplay"
end mouseUp
However, when I look at wordDisplay after clicking my button, it is blank. An explanation of why, and code to fix this would be really beneficial.
Cheers.
You don't say if 'repeatedString' is a function you're calling from somewhere else, but if I understand what you're trying to do, you can try something like this, where you place 'a' into temporary variable:
put length(randomword) into x
repeat x
put "a" after temp
end repeat
set text of field "wordDisplay" to temp
Also, am guessing this is the case, but the only reason to use the global is if you plan to use the value of x across the scripts of multiple objects. If you're just using 'x' in this script, you don't need the variable declaration.
Page 227 of my book "Programming LiveCode for the Real Beginner" contains the following useful function, which does exactly what you want:
function repeatChar theChar,theAmount
local myLongString
set the itemDel to theChar
put theChar into item theAmount of myLongString
return myLongString
end repeatChar
Note that a repeat loop is not necessary.
Use the function in your script like this:
global randomWord
on mouseUp
local x
put length(randomWord) into x
put repeatChar("a",x) into field "wordDisplay"
end mouseUp
I am currently attempting to parse data that is sent from an outside source serially. An example is as such:
DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
This data can come in many different lengths, but the first few pieces are all the same. Each "piece" originally comes in with CRLF after, so I've replaced them with string.gsub(input,"\r\n","|") so that is why my input looks the way it does.
The part I would like to parse is:
4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
The "4" tells me that there will be four lines total to create this file. I'm using this as a means to set the amount of passes in the loop.
The 7x5 is the font height.
The 1 is the xpos.
The 25 is the ypos.
The variable data (172-24 in this case) is the text at these parameters.
As you can see, it should continue to loop this pattern throughout the input string received. Now the "4" can actually be any variable > 0; with each number equaling a set of four variables to capture.
Here is what I have so far. Please excuse the loop variable, start variable, and print commands. I'm using Linux to run this function to try to troubleshoot.
function loop_input(input)
var = tonumber(string.match(val, "DATA|0|(%d*).*"))
loop = string.match(val, "DATA|0|")
start = string.match(val, loop.."(%d*)|.*")
for obj = 1, var do
for i = 1, 4 do
if i == 1 then
i = "font" -- want the first group to be set to font
elseif i == 2 then
i = "xpos" -- want the second group to be set to xpos
elseif i == 3 then
i = "ypos" -- want the third group to be set to ypos
else
i = "txt" -- want the fourth group to be set to text
end
obj = font..xpos..ypos..txt
--print (i)
end
objects = objects..obj -- concatenate newly created obj variables with each pass
end
end
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
print(loop_input(val))
Ideally, I want to create a loop that, depending on the var variable, will plug in the captured variables between the pipe deliminators and then I can use them freely as I wish. When trying to troubleshoot with parenthesis around my four variables (like I have above), I receive the full list of four variables four times in a row. Now I'm having difficulty actually cycling through the input string and actually grabbing them out as the loop moves down the data string. I was thinking that using the pipes as a means to delineate variables from one another would help. Am I wrong? If it doesn't matter and I can keep the [/r/n]+ instead of each "|" then I am definitely all for that.
I've searched around and found some threads that I thought would help but I'm not sure if tables or splitting the inputs would be advisable. Like these threads:
Setting a variable in a for loop (with temporary variable) Lua
How do I make a dynamic variable name in Lua?
Most efficient way to parse a file in Lua
I'm fairly new to programming and trying to teach myself. So please excuse my beginner thread. I have both the "Lua Reference Manual" and "Programming in Lua" books in paperback which is how I've tried to mock my function(s) off of. But I'm having a problem making the connection.
I thank you all for any input or guidance you can offer!
Cheers.
Try this:
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
val = val .. "|"
data = val:match("DATA|0|%d+|(.*)$")
for fh,xpos,ypos,text in data:gmatch("(.-)|(.-)|(.-)|(.-)|") do
print(fh,xpos,ypos,text)
end
I want to match a few lines for a string and a few numbers.
The lines can look like
" Code : 75.570 "
or
" ..dll : 13.559 1"
or
" ..node : 4.435 1.833 5461"
or
" ..NavRegions : 0.000 "
I want something like
local name, numberLeft, numberCenter, numberRight = line:match("regex");
But I'm very new to the string matching.
This pattern will work for every case:
%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)
Short explanation: [] makes a set of characters (for example the decimals). The last to numbers use [set]* so an empty match is valid too. This way the number that haven't been found will effectively be assigned nil.
Note the difference between using + - * in patterns. More about patterns in the Lua reference.
This will match any combination of dots and decimals, so it might be useful to try and convert it to a number with tonumber() afterwards.
Some test code:
s={
" Code : 75.570 ",
" ..dll : 13.559 1",
" ..node : 4.435 1.833 5461",
" ..NavRegions : 0.000 "
}
for k,v in pairs(s) do
print(v:match('%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)'))
end
Here is a starting point:
s=" ..dll : 13.559 1"
for w in s:gmatch("%S+") do
print(w)
end
You may save these words in a table instead of printing, of course. And skip the second word.
#Ihf Thank you, I now have a working solution.
local moduleInfo, name = {};
for word in line:gmatch("%S+") do
if (word~=":") then
word = word:gsub(":", "");
local number = tonumber(word);
if (number) then
moduleInfo[#moduleInfo+1] = number;
else
if (name) then
name = name.." "..word:gsub("%$", "");
else
name = word:gsub("%$", "");
end
end
end
end
#jpjacobs Really nice, thanks too. I'll rewrite my code for synthetic reasons ;-) I'll implement your regex of course.
I have no understanding of the Lua language, so I won't help you there.
But in Java this regex should match your input
"([a-z]*)\\s+:\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?"
You have to test each group to know if there is data left, center, right
Having a look at Lua, it could look like this. No guarantee, I did not see how to escape . (dot) which has a special meaning and also not if ? is usable in Lua.
"([a-z]*)%s+:%s+([%.%d]*)?%s+([%.%d]*)?%s+([%.%d]*)?"