Netlogo foreach nested list - netlogo

I am trying to port an older code to the latest (6.0.1), the following foreach loop works fine on Netlogo 4.1.3 but when copy and paste the code into version 6.0.1 the "item 0 ?" does not work. It says the "?" is undefined. That line of code is suppose to retrieve the item of the list inside the segment
to setup-row [row colour segments]
foreach segments
[
if pycor = row * row-patches-width and
(pxcor >= col-patches-width * (item 0 ?)) and (pxcor <= col-patches-
width * (item 1 ?))
[set pcolor colour
output-print item 0 ?]
]
end
The passed in "segments" variable contains the following lists:
setup-row 4 blue [[-8 -5] [-3 -1] [0 3] [5 9]]
If the code is working correctly, it should retrieve the -8 with (item 0 ?) and -5 with (item 1 ?) and so on. What I assumed in the old code is that the "?" are the first list retrieved from segments which is [-8 -5] and (item 0 ?) retrieved the -8 and (item 1 ?) retrieved the -5.
I have tried to read through the new user manual to find something that works similarly but to no avail or maybe I didn't look in the right place. Hope some of you can point me in the right direction.

Yep, that's been changed in Netlogo 6.0- see the transition guide page. For more detail on the new foreach syntax, see the dictionary entry. Basically, instead of using ? now, you explicitly define the variable names to use in the foreach procedure. Following your list example above:
to foreach-example
let ex [ [-8 -5] [-3 -1] [0 3] [5 9] ]
foreach ex [
[ xy_coords ] ->
ask patches with [ pxcor = (item 0 xy_coords) and pycor = ( item 1 xy_coords) ] [
set pcolor white
]
]
end
Here, I explicitly state that the list items will be called "xy_coords" throughout the procedure. It's a nice change that allows for more readable code since your variables can have more meaningful names.

Related

Functions of One Turtle Prevents another Breed of Turtle from Executing Function

In my model, I have multiple breeds of turtle. One is a macrophage and another is a fibroblast. Each has specific variables and specific functions to carry out. When I comment out the fibroblast function, the macrophages are able to successfully carry out their function. However, when I add the fibroblast function to the model, neither its function nor the macrophages function is properly executed. Any advice on how to resolve this?
To clarify the components of this code, activation, phagocytosis-counter, and phagocytosis-time are variables of macrophages. Repair-counter and Repair-time are variables of fibroblasts and tissue-life and collagen are variables of the patch. Thank you in advance.
`
to Macrophage-function
if activation > 1 and [tissue-life] of patch-at 0 0 < Phagocytosis and phagocytosis-counter = 0 and [tissue-life] of patch-at 0 0 > 0
[ set phagocytosis-time 50
set phagocytosis-counter 1 ]
ifelse phagocytosis-time > 0
[ set phagocytosis-time phagocytosis-time - 1 ]
[ set phagocytosis-counter 0]
if phagocytosis-time = 1
[ask patch-at 0 0 [set tissue-life 0]]
to Fibroblast-function
fibroblast-movement
if ([tissue-life] of patch-at 0 0) < 5 and ([collagen] of patch-at 0 0 ) < 100 and repair-counter = 0
[set repair-time 100
set repair-counter 1 ]
ifelse repair-time > 0
[ set repair-time repair-time - 1 ]
[ set repair-counter 0]
if repair-time = 1
[ ask patch-at 0 0
[set collagen 25
]
]
`
I expected for the two functions to carry out independently, however, they are for some reason impairing the other.
In general, the way to diagnose perplexing problems is to create test output: create file output that reports the variables of each agent on each time step. You will always find mistakes that need to be corrected, and that will likely make your problem go away. (You will need to do this anyway to test your code before putting it to use.)
By the way: do not use "[tissue-life] of patch-at 0 0". You should know that turtles can use the variables of the patch they are on as if they were the turtle's own variables. Replace "[tissue-life] of patch-at 0 0" with "tissue-life". This is explained in the Variables section of NetLogo's Programming Guide.

How to separate values from a list using commas in netlogo?

Situation: I have a code that exports turtle coordinates according to the code below:
to path
file-open (word fileName ".csv")
file-print (word self xcor " " ycor)
file-close
end
The result is something like:
(turtle 1)[1 1 1 1 1 2] [4 4 4 2 1 5]
Question: How can I export this same list, but with its items separated by commas?
From [1 2 1 1 1] to [1,2,1,1,1], for example.
Thanks in advance
If you are trying to process this in R or something after the fact, I'd recommend potentially reporting in long format (ie, each line indicates a turtle, a tick [or similar], and the coordinates)- I find it simpler to process.
To answer your actual question- one way would be to manually collapse each list of coordinates into a string separated by commas. For example, see the toy model below.
Simple setup:
extensions [csv]
globals [ test ]
turtles-own [ xcor-list ycor-list ]
to setup
ca
crt 10 [
set xcor-list []
set ycor-list []
]
repeat 5 [
ask turtles [
rt random 90 - 45
fd 1
set xcor-list lput pxcor xcor-list
set ycor-list lput pycor ycor-list
]
]
reset-ticks
end
This reporter is what's actually doing the work of collapsing the list into a simple string for output:
to-report collapse-string-list [str-list]
report reduce word ( sentence map [ str -> word str ", " ] but-last str-list last str-list )
end
And this chunk pulls the desired turtle variables into a list of lists, calls the collapse-string-list reporter on them, then exports to a csv:
to output-coord-file
let all-turtles sort turtles
; Pull coordinates from each turtle
let who-coord-list map [
current-turtle ->
(list
[who] of current-turtle
collapse-string-list [xcor-list] of current-turtle
collapse-string-list [ycor-list] of current-turtle
)] all-turtles
; Add headers
set who-coord-list fput ["who" "x" "y"] who-coord-list
; Export
csv:to-file "toy.csv" (map [ row -> (map [i -> (word i)] row ) ] who-coord-list)
end
Output:

Counting turtles after a chunk of code has executed

In my model currently, I have a monitor on the Interface that counts the total number of turtles (deer in my case) every tick. Is it possible to have another monitor that counts the number of deer after a certain line of code is executed? For example, here's a snippet of code:
to catch-fawns-source
let fawn-hunting-rate (fawn-harvest-rate-source)
if any? fawns-on source-patches
[ ask fawns-on source-patches [
if random-float 1.0001 < (fawn-hunting-rate)
[ set harvest (harvest + 1)
set fawn-harvest (fawn-harvest + 1)
set source-harvest (source-harvest + 1)
die ] ]
]
end
In this case, this is where I have fawns being harvested. This code is the same for my male and female adult and juvenile deer. So is there a way I could track my population specifically after that snippet of code (and the other identical ones for the juveniles and adults) is executed?
I'm not sure if I would need any sort of Netlogo extension (if there are any applicable to this) or if I could somehow add in another global variable and lines of code that accomplishes this task.
Thanks for all of your help as always!
I think you can get away with another global variable that you just update however often you want. For a very simple example, consider this setup:
globals [ most-recent-pop-check ]
to setup
ca
crt 10
set most-recent-pop-check count turtles
reset-ticks
end
Here, most-recent-pop-check will only be updated when needed, then you can just set a monitor to display that variable. In this example, the value will only change every 25 ticks- see comments for more detail:
to go
ask turtles [
; Turtles may die
if random-float 1 < 0.25 [
die
]
; Throw in some density-dependence to control population size
if random-float 1 < ( 0.5 * ( 1 - ( count turtles / 500 ) ) ) [
hatch random 2 + 1
]
]
; If the ticks are not 0, and if the remainder after dividing
; the ticks by 0 is 0, update the most-recent-pop-check
; variable to reflect the current turtle population.
if ticks != 0 and ticks mod 25 = 0 [
set most-recent-pop-check count turtles
]
tick
end
Of course, in your case rather than having the update occur based on the number of ticks, just have it occur whenever you run the code chunk you're after.

Seed dispersal around a tree provokes an infinite loop?

I've just started a project in which I intend to simulate (among other things) the seed dispersal around trees (named zsps). Neighboring patches can already be settled or unable for seeding due to low fertility.
I wrote code that runs (at the begining of simulation) but that made the code enter into an infinite loop (I think) because some trees attempt to spread seeds but cannot find any available place.
Does anyone have a solution to escape from this trap (in case the number of places is < the number of seeds or in case there are no places at all)?
Here is the procedure I wrote :
to check-seed-dispersal
ask zsps[
let nb-seeds 0
ifelse (age > 4) [set NFemFlowers 100]
[set NFemFlowers 0]
let temp-color color
if Tot_pol > 0
[set nb-seeds round ((NFemFlowers / Tot_pol) * 6 ) ]
if (nb-seeds > 0 )[
ask patches in-radius 5 with [fertility > 8 and not any? zsps-here]
[sprout-zsps nb-seeds
[ifelse (temp-color = yellow)
[set color gray set age 0 ]
[set color red set age 0 ]
]
]
]
]
end

Perspective based ranking?

I have a program where each peer has their own ranking system of other peers, what is the best way to implement this is NetLogo?
Normally, I would solve this with a 2D list:
[[turtle 1, score], [turtle 2, score], ...]
But this seems very troubling in NetLogo. This is my code for creating and modifying a 2D list:
to test
clear-all
crt 10
;Create a list of turtles
let agents-list [self] of turtles
;Create empty list, which will be the top level of the TwoD list
let TwoD-list []
;Populate the TwoD-list: [[turtle 0, 0], [turtle 1, 0], ...]
foreach agents-list [
set TwoD-list (lput (list ? 0) TwoD-list)
]
show TwoD-list
repeat 5 [
;Change a value in the TwoD-list
let rand-index random (length TwoD-list) ;select a random index
;The next line is what makes it a huge headache, basically you have to select a list at the top level to replace, and then select the list at the lower level to replace it.
;This entire line of code is just adding one to an element
set TwoD-list (replace-item rand-index TwoD-list (replace-item 1 (item rand-index TwoD-list) (item 1 (item rand-index TwoD-list) + 1)))
show TwoD-list
]
end
What else can I do? Or is there a better way to implement this method?
If you want to model relations between agents, NetLogo has the perfect thing for that: links!
Having each turtle assign a score to all other turtles can be quite naturally expressed as:
directed-link-breed [ rankings ranking ]
rankings-own [ score ]
to setup
clear-all
create-turtles 10
ask turtles [ create-rankings-to other turtles ]
; increment 5 random rankings by one:
ask n-of 5 rankings [ set score score + 1 ]
; display the rankings of each turtle:
ask turtles [ show [ (word end2 " " score) ] of my-out-rankings ]
end
If you don't want the links to show up in the view, you can hide them with:
ask links [ set hidden? true ]