Trouble with advanced netlogo code involving a question mark - netlogo

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!

Related

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

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.

How to fix "Nothing named ? has been defined" error in NetLogo 6.0.4

I downloaded the modified random clusters code for generating neutral landscape models using the Millington's version of the modified random clusters approach in the NetLogo modeling commons. When I click the "generate-landscape" button, the "fill-landscape" procedure in the code causes a "Nothing named ? has been defined" error.
When I created the attached interface image and attempted to run the adjoining code below. The problem seems to be related to the question mark in the "occurrences" report function. The reduce function is not working as intended. Is there a work around for this? See interface, then code below:
ifelse ( any? neighbours with [ cluster != nobody ] ) ;; check if there are any assigned patches in neighbourhood
[
let covers []
ask neighbours with [ cluster != nobody ]
[
set covers fput cover covers ;;ask neighbours to add their covers to the list
]
let unique-covers remove-duplicates covers ;;create a list of unique covers
let max-cover-count -1 ;the number of neighbours with the maximum cover
let max-cover -1 ;the maximum cover
ifelse(length unique-covers > 1)
[
;if there is more than one unique-cover
foreach unique-covers ;for each of the unique covers
[
let occ occurrences ? covers ;count how many neighbours had this cover
ifelse(occ > max-cover-count) ;if the count is greater than the current maximum count
[
set max-cover ? ;set this as the dominant cover
set max-cover-count occ ;update the current maximum count
;---------------
to-report occurrences [x the-list]
report reduce
[ifelse-value (?2 = x) [?1 + 1] [?1]] (fput 0 the-list)
end
;---------------
The code is suppose to generate a neutral landscape model using the modified random clusters approach developed by Saura and Martinez-Millan (2000). However, the error "Nothing named ? has been defined" error the code from running smoothly. Looking forward to thoughts ...
The old ? syntax from NetLogo 5.x was replaced with the new -> syntax in NetLogo 6. See https://ccl.northwestern.edu/netlogo/docs/programming.html#anonymous-procedures
So, for example, in NetLogo 5, you would write:
foreach [0 1 2 3] [
print ?
]
in NetLogo 6, you write:
foreach [0 1 2 3] [ x ->
print x
]
A combination of Bryan's answer (first procedure) and the NetLogo Dictionary (second procedure) gives you the following. The comments indicate the new bits. Not tested.
ifelse ( any? neighbours with [ cluster != nobody ] )
[ let covers []
ask neighbours with [ cluster != nobody ]
[ set covers fput cover covers
]
let unique-covers remove-duplicates covers
let max-cover-count - 1 ; added a space around subtraction
let max-cover - 1 ; more spacing
ifelse(length unique-covers > 1)
[ foreach unique-covers
[ this-cover -> ; here's the new bit, calling ? 'this-cover'
let occ occurrences this-cover covers ; passes to the occurrences procedure
ifelse(occ > max-cover-count)
[ set max-cover this-cover ; using the name this-cover again
set max-cover-count occ
And for occurrences, you can take the procedure directly from the NetLogo Dictionary reduce example
to-report occurrences [#x #the-list]
report reduce
[ [occurrence-count next-item] -> ifelse-value (next-item = #x)
[occurrence-count + 1] [occurrence-count] ] (fput 0 #the-list)
end

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

Nothing named ? has been defined

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)]

read-from-string working in NetLogoWeb?

Is there any alternative to read-from-string that works in NetLogoWeb? I need to a string from an input field. The string contains some number of integers and should be converted to a list. Within NetLogo, I use this code:
to-report get-demand
report reverse sort read-from-string ( word "[" the-field-name "]")
end
However, it seems that read-from-string is not implemented yet in NetLogoWeb. Any way around?
Many thanks and best wishes,
Michal
P.S. Many thanks for developping NetLogoWeb. I really missed NetLogo plugins.
Unfortunately, we haven't yet added support for read-from-string to NetLogo Web. It probably won't be there in the near future, either.
Is the code supplied here the real code that's giving you problems? I assume that it isn't, but, if it is, you can just do this for the same effect:
to-report get-demand
report reverse sort (list the-field-name)
end
(That is, if the-field-name is what it sounds like, which would be a string containing only the name of some "field".)
I assume that your real case is more complex. I might be able to offer a better workaround if I saw the true code. Are you sure that you can't solve your problem with tasks?
I'd suggest:
to-report string-to-numbers [s]
if empty? s [ report [] ]
if first s = " " [ report string-to-numbers butfirst s ]
let pos position " " s
ifelse not is-number? pos
[ report (list string-to-number s) ]
[ report fput string-to-number substring s 0 pos
string-to-numbers substring s (pos + 1) length s ]
end
to-report string-to-number [s]
report reduce [10 * ?1 + ?2]
map [position ? "0123456789"]
explode s
end
to-report explode [s]
report map [item ? s] n-values (length s) [?]
end
Sample run:
observer> show string-to-numbers "12 345 67"
observer: [12 345 67]
I verified that this works in both desktop NetLogo and NetLogo Web.
Based on the previous answer (that the command will not be implemented soon), it seems the only solution is to implement a simple parser, i.e. something like this (works for integers separated by spaces):
to-report string-to-list [ s ]
let l []
let ss ""
let n 0
let mode "out"
repeat length s [
set ss first s
set s but-first s
if ( ( ss = " ") and ( mode = "in" ) ) [
set mode "out"
set l lput n l
set n 0
]
if ( member? ss "0123456789") [
set mode "in"
set n ( n * 10 ) + ( position ss "0123456789" )
]
]
if ( mode = "in" ) [ set l lput n l ]
report l
end
The reporter gets a string s and returns a list of integers.
Or is there any simpler way to implement it?
Just to have an up-to-date answer here, as of October 2017, NetLogo Web does support read-from-string. A case like read-from-string (word "[" the-field-name "]") should work just as in desktop and report the list value.