Netlogo use of myself - netlogo

With the use of the myself primitive, I want a patch with a certain land use to make buildings of that type in a specific radius, but it's not working. Here is the code:
patches-own [land-use] ;land-use can take many types: "residential", "industrial", "commercial"
...
to grow
ask patches with [land-use = "residential"]
[ask other patches in-radius 10 [
if [land-use = "residential"] of myself [build-house]]]
end
How can this be fixed?

The problem there is not myself but the use of of. Two things to fix:
of requires the reporter to be in square brackets. Only the reporter that of refers to, not the whole condition being tested (as in your case where you are testing a condition).
You should not specify the value of the variable but just its name. Just as in normal language: you wouldn't say "If your hair colour equals my blonde", but you would say "If your hair colour equals my hair colour".
The resulting syntax is:
if (land-use = [land-use] of myself) [
build-house
]
Parentheses surrounding the condition are optional, I use them as a stylistic choice.
PS Regarding point 2 above... of course you could keep the value of the variable (i.e. "residential") instead of the name of the variable (i.e. land-use), and in that case drop of myself.
You would have:
if (land-use = "residential") [
build-house
]
And as of now it would work because the patches starting this process are just those with land-use = "residential"... but this doesn't look like great code, as it is not extendable to other variable's values and it contains more hard-coding than necessary.

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.

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 Turtles - sharing the difference between two turtles

I am fairly new to Netlogo and have been working through Railsback & Grimms excellent book while trying my own stuff on the side
Currently, I am trying to code a kind of money transfer whereby two turtles meet (e.g. Turtle 1 and Turtle 2), and the two turtles then share money (e.g. T1 has $4 and T2 has $6, they both leave with $5)
The code I have tried using is as below
to currency-share
let neighbor one-of bystanders-here ; identify neighbor around
if neighbor != nobody ;; is there a neighbor? if there is
[ set currency round ((currency + neighbor currency) / 2)] ; share money
end
Unfortunately the code isn't working and I can't find any examples through the forums which use a similar idea. Perhaps I'm searching incorrectly (using key words like turtle exchange, share etc. normally comes up with patch sharing). If anyone has any models they could recommend where such exchanges happen, or if anyone knows how I may improve my code, please let me know. Thank you.
At first glance, this seems like a simple syntax problem. To get the currency of the neighbor, you should be using of:
set currency round ((currency + [ currency ] of neighbor) / 2)
But since you also said that you want both turtles to get the new amount, you also need to add:
ask neighbor [ set currency [ currency ] of myself ]
Or, perhaps less confusingly you could do something like:
set new-amount round ((currency + [ currency ] of neighbor) / 2)
set currency new-amount
ask neighbor [ set currency new-amount ]
One last variant, slightly better in my opinion because more general (and perhaps even clearer) is:
let sharers (turtle-set self one-of bystanders-here)
let new-amount mean [ currency ] of sharers
ask sharers [ set currency new-amount ]
In this last one, you don't even need the if neighbor != nobody check because if there are no bystanders, turtle-set will build an agentset containing only self and the mean currency of that set will just be the present currency value.

How to change agent's variable by passing variable name and value to a function?

How is it possible to change specific variable of an agent by passing variable name to a function?
for example I have turtles with variable MONEY and the following function:
to setVariable [varname varvalue]
[
ask one-of turtles [ set varname varvalue ]
]
end
Now I want to run:
observer> ask one-of turtles [setVariable MONEY 100] ;; I need to ask via another turtle since I cannot use MONEY directly in observer context
And it does not set my variable without giving any errors.
Interestingly, you can read a variable in similar manner:
to showVariable [varname ]
[
ask one-of turtles [ show varname ]
]
end
So the question here is how to "convert" my function input into turtle's variable name it would recognise well for SET purposes.
PS: I don't want to use run function as it would slow down the model.
In a similar situation where there are a number of possible options, I create a task for each and put them in a lookup table (using the table extension) with a string key for each. Then I can lookup the appropriate task for any key. It saves having the nested if/else structures, but I haven't investigated the efficiency of the table lookup.
You're correct that run with strings would slow down your model, but if you use run with tasks, it won't.
Here's your setVariable procedure rewritten to use tasks:
to setVariable [setter value]
ask one-of turtles [ (run setter value) ]
end
When you call it, the call will look like:
setVariable task [ set money ? ] 100
But this won't help you if at the call site, there's no way to avoid using strings.
If you must use strings, and it must be fast, then you have no choice but to write out a big ifelse chain that lists all of the variables that you need to support:
to setVariable [varname varvalue]
ask one-of turtles [
ifelse varname = "money"
[ set money varvalue ]
[ ifelse varname = "food"
[ set food varvalue ]
...
]
end
For reading variables, instead of setting, you can safely use runresult with a string containing the variable name without needing to be concerned about performance, since runresult caches the compiled strings, so it will be fast since you'll be passing the same strings over and over. (The setting case is different because the strings you'd be passing to run would be different all the time.)

Running a function for every present turtle from each of the turtle's perspectives

From each of the turtle's perspectives, I have to run a function for a turtle to decide which turtle it will assign as it's "buddy".
Right now I have the code below but it doesn't achieve the effect.
foreach sort other turtles [
ask ? [
if Smin < Sim myself ? and self != ? [
]
]
]
In C/Java it would've been simple, just a simple for loop and then that's it. Apparently I am having a hard time understanding NetLogo's foreach function and the integration of '?' in looping. How can I do this?
It's unclear from the code sample you posted what exactly you are trying to do.
Some things that may help:
Unless you want to address your turtles in a specific order, it's usually not necessary to use foreach. Just doing ask other turtles [ ... ] can replace the whole foreach sort other turtles [ ask ? [ ... ] ].
Given that you are inside an ask ? block, self != ? will always be false, and thus, so will the and clause of your if. The code inside your inner block is never reached.
myself refers the agent from an "outer" ask block (e.g., in ask x [ ask y [ ... ] ], self would be y and myself would be x). Neither myself nor self is affected by foreach, and ? is not affected by ask.
My guess is that maybe you just want:
ask other turtles [
if Smin < Sim myself self [
]
]
But I can't know for sure, especially since I have no idea what Smin and Sim are. If you post more detail, maybe we can help you further.
Finally: NetLogo code usually ends up being much simpler than the equivalent C/Java code, but you must learn to embrace the "NetLogo way". Thinking in Java/C and then trying to translate in NetLogo will usually lead one astray.