Trying to ask n-of 10 turtles to do a random procedure out of a list of three - netlogo

This is currently what I am struggling with. I am new to netlogo so any help is nice. This is a modification on the 'virus' tutorial.
ifelse-value
choice = 0 [ go-quarantine ]
choice = 1 [ wear-mask ]
[ get-sick ] ) ]

Brandon, and welcome! Yeah the documentation is a little fuzzy on this.
I think you want just "ifelse", to branch to some action, not "ifelse-value" which returns a value.
you need a "(" before "ifelse" or it won't work. You have the closing ")".
you do not need a closing "]"
"choice" is not a necessary magic word. You can use any logical test.
So the command you're looking for would be this pattern, where white space is flexible in NetLogo and "..." means zero or more things may go there. I'm old-school and prefer to put parentheses around conditional tests but you don't need to.
(ifelse
( test-1 ) [ actions 1 ...]
( test-2 ) [ actions 2 ...]
...
( test-n ) [ actions n ...]
;; else
[ default actions ]
)
So say this person has 33.3% chance of going each of those ways.
you could code an instance of this pattern as follows:
let mood random 3 ;; returns integer values of 0, 1, or 2
( ifelse
( mood = 0 ) [ go-quarantine]
( mood = 1 ) [ wear-mask ]
[ get-sick ]
)
where implicitly that code would expect those actions to be defined later:
to go-quarantine [ do this ] end
to wear-mask [ do that] end
to get-sick [ do other stuff ] end
And the choices of values of 0, 1, 2 etc. and having them in that order is not required.

Related

How do I do a SWITCH or SELECT CASE in NetLogo?

NetLogo does not have a native SWITCH, SWITCH-CASE, or SELECT-CASE type of multiple condition, how do I do the same thing without having a giant mess of nested IF-ELSE statements?
Since NetLogo 6.1, NetLogo has supported multi-case ifelse, which can be used similarly to other languages' switch statements. Here is an example from the docs:
ask patches [
let choice random 4
(ifelse
choice = 0 [
set pcolor red
set plabel "r"
]
choice = 1 [
set pcolor blue
set plabel "b"
]
choice = 2 [
set pcolor green
set plabel "g"
]
; elsecommands
[
set pcolor yellow
set plabel "y"
])
]
And here is the example from the other answer rewritten to use it:
;; example of SWITCH style conditional block
(ifelse
(criteria-1) [ action-1 ]
(criteria-2) [ action-2 ]
(criteria-3) [ action-3 ]
[ default-action ]
)
This does not need to have the "multi-close" of the ] on the last line, so it overall seems cleaner to me.
We can simulate a SWITCH statement with a chain of nested IF-ELSE statements, formatted so it's not a big mess, and actually easy to read and edit.
We will format the chain of IF-ELSE statement with the following goals:
avoid excessive indenting,
avoid overly long code lines
make it look more like switch in other languages
rearranging the cases does not break the syntax
there is a default case
A SWITCH Statement
Here's how it looks:
;; example of SWITCH style conditional block
if-else [ criteria 1 ] [ action-1 ][
if-else [ criteria 2 ] [ action-2 ][
if-else [ criteria 3 ] [ action-3 ][
if-else [ true ] [ default-action ][
]]]]
Other considerations
Some programmers may find it offensive to have a default action that tests for true, and leaves the "else block" if the final "IF" empty. You can do what you like. I find making the default case explicit, makes all the actions formatted exactly the same, and avoids an awkward cluster of punctuation at the end.
Avoid overly long lines--it makes it harder to read
Keep conditions short--wrap them in reporter if needed.
Keep actions short--wrap them in procedures if needed.
This helps the code read more like a story and less like code.

How to flip the sign of a variable depending on a condition, in Netlogo

The following doesn't work (there must also be a more succinct way of doing it):
ask turtles
[
ifelse return > 0
[
set tot-demand-contrarians (-(tot-demand-contrarians))
set tot-demand-followers ((tot-demand-followers))
]
[
set tot-demand-contrarians ((tot-demand-contrarians))
set tot-demand-followers (-(tot-demand-followers))
]
]
Half of your clauses set a variable to itself anyway so they're not needed. I suspect NetLogo is reading the '-' as an instruction to subtract, but you haven't said what to subtract it from. You could do something like:
set x (0 - x) ; the brackets are optional, for clarity
But personally I feel that it is more readable to multiply by -1
ask turtles
[ ifelse return > 0
[ set tot-demand-contrarians (-1 * tot-demand-contrarians) ]
[ set tot-demand-followers (-1 * tot-demand-followers) ]
]

Trouble with advanced netlogo code involving a question mark

I am using Netlogo v6.0.4 and I'm getting the following error message when I try to run sample code from an answer I found here on Stack Overflow.
Nothing named ? has been defined
In this answer the following netlogo code is proposed as an answer:
to-report split [ string delim ]
report reduce [
ifelse-value (?2 = delim)
[ lput "" ?1 ]
[ lput word last ?1 ?2 but-last ?1 ]
] fput [""] n-values (length string) [ substring string ? (? + 1) ]
end
The specific ? it does like is the first one in this section substring string ? (? + 1) .
When this answer was written in 2014, Netlogo v5 was in active use and it had a feature called tasks that were lambda methods. But in v6 tasks were replaced by anonymous-procedures.
Is that what the ? are here? How can I fix this error?
You got it in one- the ? in the versions were essentially placeholders for whatever variable was being passed to the task. The 5.3 dictionary entry for foreach has a good example:
foreach [1.1 2.2 2.6] [ show (word ? " -> " round ?) ]
=> 1.1 -> 1
=> 2.2 -> 2
=> 2.6 -> 3
In that case, foreach was taking the input list of [1.1 2.2 2.6] and iterating over it, where the ? takes the place in the command block of the current item being processed. As I understand it, the main syntactical difference in 6.X is that now you explicitly state what that placeholder is, by using the -> operator. So, the exact same idea as above, translated to 6.0 in the foreach example in the 6.0 dictionary entry, looks like this:
foreach [1.1 2.2 2.6] [ x -> show (word x " -> " round x) ]
=> 1.1 -> 1
=> 2.2 -> 2
=> 2.6 -> 3
There, you can see that the x is explicitly being defined as the placeholder. This really improves the clarity of code- you can define the placeholder however you like to be as clear and explicit as you'd like- this (over the top) example works just as well:
foreach [ 1.1 2.2 2.6 ] [ round_me -> show (word round_me " -> " round round_me) ]
If you're using multiple lists, do note that you have to surround the anonymous procedure with ( ) and your placeholder declaration with [ ]- for example:
( foreach [ 1 2 3 ] [ 10 20 30 ] [ [ a b ] -> print a * b ] )
If you're translating your code example, then, you can just focus on explicitly stating the placeholders. It also might help to break it down into the component parts to clarify- more detail in comments:
to-report split2 [ string delim ]
; split the string up into individual characters
let characters fput [""] n-values ( length string ) [ a -> substring string a ( a + 1 ) ]
; build words, cutting where the delimiter occurs
let output reduce [ [ b c ] ->
ifelse-value ( c = delim )
[ lput "" b ]
[ lput word last b c but-last b ]
] characters
report output
end
Now, to follow Nicolas' example from your linked answer, you can call that to-report to split up your text:
to read-example
let line "Example\tof\tsome\ttext"
show split2 line "\t"
end
Gives you:
observer: ["Example" "of" "some" "text"]
Hope that is helpful!

Netlogo - Sum of lists of turtles

I would like to sum several lists of turtles. Lets call each variable turtle-list. There is only one list per variable, each list has the same number of items. If I have n turtles, I know that I can write
show (map + [turtle-list] of turtle 0 [turtle-list] of turtle 1 ... [turtle-
list] of turtle n)
Nevertheless, it may be very long and does not work if the number of turtles changes.
Is it possible to do it without writing the variable of each turtle ? Thank you for your help
I think you want to use reduce and sentence to convert a list of lists (from [turtle-list] of turtles) to a single list of values, then just sum that list:
turtles-own [ turtle-list ]
to setup
ca
crt 5 [
set turtle-list map [ i -> ( who + 1 ) * i ] [ 1 2 3 ]
]
reset-ticks
end
to sum-turtle-lists
show sum reduce sentence [turtle-list] of turtles
end
Let me know if that's not quite what you're after.
Edit:
Based on your comment, try this version:
to sum-turtle-lists
show reduce [ [ i a ] -> ( map + i a ) ] [turtle-list] of turtles
end

Netlogo BehaviorSpace Optmization - Delete Aborted Runs - Final Command

I am working with quite a lot of runs and most of them will be aborted. Can I write a Final Command that deletes aborted runs in order to speed up the process and/or make my csv files smaller?
There is nothing allowing you to do that in a straightforward way. And it wouldn't really speed things up anyway.
Unless the size of your csv files is really a problem, the easiest thing is just to filter out aborted runs in whichever data analysis program you use.
The only alternative I can think of is to write your own experiment code. Assuming you have a stop-condition? reporter and you set aborted? true when a run is aborted, you could do something along the lines of:
extensions [ csv ]
globals [ aborted? ]
to experiment
let run-number 1
let file-name "experiment.csv"
if file-exists? file-name [ file-delete file-name ]
file-open file-name
foreach [ 1 2 3 ] [ ; vary x
set x ?
foreach [ "a" "b" "c" ] [ ; vary y
set y ?
set run-number run-number + 1
setup
while [ not stop-condition? ] [ go ]
if not aborted? [
file-print csv:to-row (list
run-number
x
y
(count turtles)
; whatever else you want to measure...
)
]
if run-number mod 10 = 0 [ file-flush ]
]
]
file-close-all
end
This assumes that x and y are, respectively, a slider and a chooser widget. If you want to vary global variables, you'll have to be careful not to override them with a call to clear-all in setup.
As you can see, all of this is far from ideal and probably error-prone.