Local variable in map task? - netlogo

Is there a way to define a local variable in an inline reporter task with map?
This
to go
show map [? * ?] [1 2 3]
end
displays [1 4 9], as expected. What's in the first set of brackets is a "reporter task".
What if I want to use let in the task?
to go
show map [
let sq ? * ?
sq + 1
]
[1 2 3]
end
Error: "Expected a reporter task here, rather than a list or block." The entire first bracketed expression is highlighted as what's producing the syntax error.
Maybe I need to add the task keyword to tell NetLogo that this is a task? The Programming Guide says that "the task primitive is optional" for map but it's worth a try. This works:
to go
show map (task [? * ?]) [1 2 3]
end
but this doesn't:
to go
show map (task [
let sq ? * ?
sq + 1
])
[1 2 3]
end
The second instance of sq is highlighted, with the error message "Expected command." It's odd the error is different this time.
Maybe I need to add report?
to go
show map (task [
let sq ? * ?
report sq + 1
])
[1 2 3]
end
This is syntactically acceptable, but when I run it I get a runtime error: "MAP expected input to be a reporter task but got the command task (command task from: procedure GO) instead."
The only alternative I've found that works is to define a separate reporter:
to go
show map square-plus-one [1 2 3]
end
to-report square-plus-one [n]
let sq n * n
report sq + 1
end
This's easy enough. However, I'm curious whether there's something I'm missing. Is there a way to use local variables in an inline reporter task?

Reporter tasks with complex reporters are not currently possible. See the “Limitations” section in the Programming Guide, under "Tasks":
Reporter tasks can't contain commands, only a single reporter expression.
https://github.com/NetLogo/NetLogo/issues/351 is related — it specifically discusses the problem of needing to refer to a ? variable from an outer scope.

Related

How to read formula including turtle values from a input box?

Im having trouble including a formula in the input box into my model and hoped someone could help. In short I want the global variable "subsidy_absolute_threshold" to be read as "100 + m2 / 1600". So that wherever that variable is implemented, that code is implemented instead. The current code reads something like
turtles-own [m2 subsidy_eligible]
globals [subsidy_absolute_threshold]
[...]
set subsidy_absolute_threshold "100 + m2 / 1600"
[...]
ask turtles [
if ambition < read-from-string subsidy_absolute_threshold [set subsidy_eligible true]
]
Technically the global value is an input box set as a string, but it should be functionally the same thing. The error message I get is "Extra characters after literal." which I struggle to understand.
I have tried all the "types" of input boxes, but none work. I have also tried directly writing in the formula, as in replacing subsidy_absolute_threshold with 100 + m2 / 1600, which works.
Use the native command runresult instead of read-from-string.
I'm somewhat unsure exactly why read-from-string does not work, so if someone wants to present an explanation please do.

How can I simulate the same scenario 3 times on NetLogo?

I have a simulation for a fire-evacuation, and the fire starts form different sources.
I want to simulate the exit with the least number of injuries, while having 3 exits it's 3 scénarios.
But my issue, is that the simulate each exit with different fire sources. How can I fix the same scenario for three simulations ?
Here is the code :
to run-all
clear-all
let temp (list ("left") ("right") ("top"))
foreach temp [
[a] ->
setup
set finished 1
if a = "left" [
while [finished = 1] [
go-to-left
]
]
if a = "right" [
while [finished = 1] [
go-to-right
]
]
if a = "top" [
while [finished = 1] [
go-to-top
]
]
]
end
I don't think that you need to change the code you posted here. The place to look is in your "setup" code, which you did not post.
Probably in your setup code you use "random" to create places for people to stand, so what you need is to have "random" generate the exact same locations for each of many different passes, so you can compare the different exits with the same starting conditions.
The way to do that is to set the "seed" that "random" will use ( secretly ) to exactly the same seed at the start of each pass you want to be identical.
Then if you want a new series of runs with different random locations, change the seed to a different number and use that at the start of each run
The command to do that is described in the User dictionary under "random-seed", where it also tells you See the Random Numbers section of the Programming Guide for more details.

Create an "itinerary" agentset of patches

I'm building a model where turtles "search" a subset of patches for a resource according to different search criteria.
I'm trying to build reports that return a sorted list or agentset of patches that a turtle can then use as an itinerary for it's search.
For some reason I'm having trouble storing the itinerary in a turtle owned variable.
an example reporter is:
to-report availability
let sorted-patches sort-on [ ( (space - occupants) / space ) ] patches with [space > 0]
report sorted-patches
end
when I do show availability in the console, it prints out what I expect, an ordered list of patches.
But if I do
let test-variable availability
show test-variable
it returns
ERROR: Nothing named TEST-VARIABLE has been defined.
is this a problem of scope somehow, can I not use let as an observer?
Is it a problem of type? Can I not store an agentset as a named turtle-owned variable?
Is there a way to do the same thing with a list instead of an agent set?
Thanks
From your description, it's a scoping problem. But the problem is not that you are trying to use let with an observer, it's the scope of let. NetLogo is not really interactive in the sense you are trying to do - the variable created by let is thrown away at the end of the line.
If you type let test 3, hit enter, then type show test, you will get the same error. However if you type let test 3 show test, then it will return 3.
Why are you needing this from the console? If it's for testing, then you can look at it the way you have already found - simply by show availability. If you are using it for turtles while the model is running, then it is not interactive and there's no problem.

NetLogo 6 and the rnd extension

I am trying to update my model to NL 6 because the automatic update failed (mostly due to syntax for anonymous procedures). My model uses the rnd extension which now apparently comes bundled with NetLogo, but the example from the manual still mentions this:
extensions[rnd]
to go
let pairs [ [ "A" 0.2 ] [ "B" 0.8 ] ]
repeat 25 [
; report the first item of the pair selected using
; the second item (i.e., `last ?`) as the weight
type first rnd:weighted-one-of-list pairs [ last ? ]
]
end
This results in an error because "nothing named ? has been defined". I have been able to convert other things like foreach and n-values, but I am struggling with this example to the new notation required by NetLogo 6. Can someone help?
We missed a few cases when converting the rnd extension manual for bundling it with NetLogo. This will be fixed in NetLogo 6.0.1. In the meanwhile, you can refer to the most current version of the manual on GitHub:
https://github.com/NetLogo/Rnd-Extension/blob/hexy/README.md
In your specific case, the NetLogo 6 syntax would be:
rnd:weighted-one-of-list pairs [ [p] -> last p ]

Expected input to be a number but got TRUE/FALSE

I have got this block of code:
to catch-rose
let prey one-of roses-here
if prey != nobody
[
set energy energy + 1
set rose_ramasse rose_ramasse + 1
ask prey [ die ]
]
end
When I launch the simulation, I get the following error message
+ expected input to be a number but got the TRUE/FALSE false instead.
error while unefeebleue 2 running +
called by procedure CATCH-ROSE
called by procedure GO
called by Button 'go'*
I've been trying to solve out my problem myself but I can't. Why it does not want to recognize the second SET command? Why does it think it is true/false statement?
The error message is telling you the following:
It starts with the operation that failed. Often this is a procedure name, in this case it is +. So you know that it is one of the inputs to + that is failing.
It's telling you that one of the inputs to + is a TRUE/FALSE value.
Now, you've told us that the line it refers to is the second set statement. There are two inputs to the + on that line, rose_ramasse and 1
So, your problem is that rose_ramasse is a TRUE/FALSE (boolean) value. Without the rest of your code, it's not clear whether rose_ramasse is a global variable or not, so it is hard to go any further to help you work out where rose_ramasse is being assigned a boolean value.
I can replicate the error message with a simple function like the following:
globals [age]
to go
set age TRUE
set age age + 1