I am brand new to NetLogo, and trying to use a model written for v5 on v6, and hit some conversion challenges.
From reading the docs, the replacement of ? with anonymous functions seems easy enough to understand, however most examples I have seen seem focused on foreach loops, and not enough mention of sort-by. When I apply the conversion that I think ought to work, I hit an error that suggests a literal is expected.
I have a challenge with these 2 loops in particular
#loop-1
foreach sort-by [[who] of ?1 < [who] of ?2] aset[ ]
#loop-2
foreach sort-by [ ?1 < ?2 ] bset [ ]
If I rewrite both as follows, I get an error that a literal is expected
#loop-1
foreach sort-by [[?1 ?2] -> [[who] of ?1 > [who] of ?2]] aset [ ]
#loop-2
foreach sort-by [[?1 ?2] -> [ ?1 < ?2 ]] bset [ ]
Would appreciate any suggestions.
I don't know all of the context (what is the purpose of the loops?).
I assume, they should sort turtles by their who number.
You don't have to (but can) get rid of the '?'. The error comes from writing the code in brackets after the ->.
If there's another context, the foreach might be usefull, but as far as I understood the purpose, it can be deleted.
This worked:
to go
crt 5
let aset turtles with [who <= 3]
let bset turtles with [who >= 3]
;loop-1
show sort-by [[?1 ?2] -> ?1 > ?2] aset
;loop-2
show sort-by [[?1 ?2] -> ?1 < ?2 ] bset
end
I think I figured this out now. These work ... I needed to get rid of the '?'
#loop-1
foreach sort-by [[a b] -> [[who] of a > [who] of b]] aset [ ]
#loop-2
foreach sort-by [[x y] -> x < y ] bset [ ]
Related
i have a list of links but sometimes within the list two links that are opposite of each other appear in the list. All links have values and the list is organized from highest value to lowest. what i want to do is to make the opposite link with the lower value die.
does any one have any ideas?
not that it would help a great deal but i got my list from this line of code:
set max-links sort-on [(- label)] link-set [max-one-of my-in-links [label]] of turtles
I'm assuming that these are directed links as there can not be two undirected links between any two turtles. The following code is not elegant, but I think it will do what you want. I've embedded it within a working model.
to test
clear-all
create-turtles 10 [fd random 10]
ask turtles [ create-links-to n-of 8 other turtles ]
ask links [set label random 100 ]
let link-list sort links
let to-die []
let remaining link-set link-list
foreach link-list [[m] ->
let opposite (link [who] of [end2] of m [who] of [end1] of m)
if opposite != nobody and member? opposite remaining [
ifelse ([label] of opposite < [label] of m) [
set to-die lput opposite to-die
]
[
set to-die lput m to-die
]
set remaining remaining with [self != m]
]
]
foreach to-die [m ->
set link-list remove m link-list
]
ask link-set to-die [die]
end
For each link in the list, it looks to see if there is an opposite link in the linkset remaining, originally made up of the links in the list. If so, it marks the proper link for deletion and then takes itself out of remaining so that when the opposite link is tested it won't be found. Once all links to be deleted are found, they are removed from the list and asked to die.
Hope this helps,
Charles
I am trying to create a list to be collected with the behaviorspace that reports the color of a turtle's neighbor.
to-report north-color1
set north-color []
foreach sort turtles [the-turtle -> set north-color lput [color] of neighbors4 north-color]
report north-color
end
the "foreach" line is to ensure that the order of the list follows turtle 0, turtle 1, turtle 2, etc in sequential order. However, I want my list to output the color of their neighbor above like [10, 20, 10, 20, 30...] How can I achieve this?
This is a complete model. Just change the print north-color-map to print north-color to try out the foreach version.
to testme
clear-all
ask patches [if random-float 1 < 0.8 [sprout 1]]
print north-color-map
end
to-report north-color
let outlist []
foreach sort-on [who] turtles
[ this-turtle -> ifelse any? turtles-on [patch-at 0 1] of this-turtle
[ set outlist lput [color] of one-of turtles-on [patch-at 0 1] of this-turtle outlist ]
[ set outlist lput "none" outlist ]
]
report outlist
end
to-report north-color-map
report map
[ this-turtle -> ifelse-value any? turtles-on [patch-at 0 1] of this-turtle
[ [color] of one-of turtles-on [patch-at 0 1] of this-turtle ]
[ "none" ]
]
sort-on [who] turtles
end
The foreach version is probably easier to understand. It follows fairly closely what you were trying to do - start with an empty list and then run through a list of all the turtles in who order (the sort-on [who] turtles creates that list) and calculates the colour of the turtle on the north patch. Finding north is done with patch-at 0 1 but you also have to say north of what - hence [patch-at 0 1] of this-turtle. And the one-of is to select one turtle from the set of all turtles on that patch - NetLogo can't tell that it will always have one or none so you would get an error essentially saying 'I don't know which turtle to find the colour of'.
The second version uses map. It does exactly the same but applies the function to all the members of a list without explicitly constructing the loop. The code is a little simpler because you don't need the empty list and the various lput statements. You also need to present everything as a reporter rather than a command. But map can be a little trickier to get your head around.
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!
I have small issue with a NetLogo tutorial.
I have the following situation:
to-report get-best-action
let x xcor
let y ycor
let dir heading
let best-action 0
let best-utility -100000
foreach actions[
set heading dir
run ?
let utility-of-action get-utility xcor ycor heading
if (utility-of-action > best-utility) [
set best-action ?
set best-utility utility-of-action
]
setxy x y
set heading dir
]
report (list best-action best-utility)
end
AND...
ask patches [
foreach headings [
let x pxcor
let y pycor
let dir ?
.......
In any of the presented case, the identifier '?' is considered not defined. It should work because the identifier is used the same way even in the examples of foreach. Check https://ccl.northwestern.edu/netlogo/docs/programming.html .
Did I do something wrong? Does anybody know another solution, because I tried to use an item i and the behavior of the project has been modified. (Check the project: https://www.youtube.com/watch?v=dBDVkPjyYF4 )
I would appreciate your help. Thank you!
In NetLogo before version 6, the symbols ? ?1 ?1 and so on were used as placeholders in some primitives, especially those that processed list items.
In version 6 a new syntax was introduced using "anonymous" procedures. You can make your old code using ? or ?1, etc work with few changes by adding the new syntax elements to the statement block.
Title
Code
Single ? placeholder
Extra space added to emphasize changes
Old syntax
foreach [ 1 2 3 4 ] [ show ? ]
New syntax
foreach [ 1 2 3 4 ] [ ? -> show ? ]
Multiple ?1 ?1 placeholders
Extra space added to emphasize changes
Old syntax
(foreach [1 2] ["a" "b"][ show (word ?1 ?2)]
New syntax
(foreach [1 2] ["a" "b"][ [?1 ?2] -> show (word ?1 ?2)]
i have this code and it's not clear to me what is it doing:
patches-own [ field ]
let a max-one-of patches in-radius b [field]
ifelse ([field] of a > 0.1) and ([field] of a < 0.5)
[
;; do something
]
[
;; do something else
]
Thanks,
Marco
This is apparently code to be run by a turtle or patch, it isn't apparent which.
patches in-radius b is an agentset of the circle of patches, of radius b, around the calling agent. max-one-of ... [field] finds the patch in that agentset that has the largest value for field. That patch is then stored in the new local variable a. (A better name than a might have been winner or peak or best-patch.)
[field] of a is then that maximum value of field, the same one that max-one-of found. The ifelse checks to see if that value is in a certain range or not, and does something different, depending.
Does the code inside the ifelse make any further use of a? If it does, cool. If it doesn't, well, the code could be more easily and simply written as:
let m max [field] of patches in-radius b
ifelse m > 0.1 and m < 0.5
[
;; do something
]
[
;; do something else
]
perhaps seeing it in this form will help making the meaning clear.