Instead of hard coding (contrived example here):
f1: func[][print "f1"]
f100: func[][print "f100"]
etc...
Is it possible to do something like this
for num 1 100 1 [
set to-word rejoin ["f" num] func[][
print rejoin ["f" num]
]
]
except it doesn't work, it always give "f100" (why in fact num is equal to 100 is a mystery for me though it's not the question here: closure ?).
for num 1 100 1 [
set to-word rejoin ["f" num] func[] compose/deep [
print rejoin ["f" (num)]
]
]
>> f1
f1
>> f2
f2
>> f99
f99
The result of your functions is always f100, because they all share the same word num with the outcome of your for loop. You can see that if you do e.g.source f1.
Related
Very basic question, I can't see why my foreach code doesn't do anything (no error message but no effect whatsoever). So my turtles have a 3-dimensionnal variable (intention) that is preset to [0 0 0]. My final problem is much more complex than this, but in simple terms I am now trying to get every dimension of this vector to change to one, that is [1 1 1].
I have created a procedure called change-intention that uses foreach to produce this, to no effect:
to change-intention
ask turtles [
(foreach intention [ x -> set x 1])
]
end
I have tried this on the observer & turtle command line as well as on individual turtles' to no results nor errors..
Thanks!
Several problems. The first is that lists are not mutable - if you want to change the value in a list, you have to create a new list with that value. The second is that you can't use set to do that, you have to use replace-item.
The code is self contained - open a new model and try it out, changing the call in the testme procedure to different implementations. The procedure change-intention1 is the way you are currently thinking about it (my interpretation anyway). The procedure change-interpretation2 is the way to implement your approach, replacing each item and creating the new list (addressing the problems identified).
However, a better way to do this is with the map procedure instead of foreach because all the values are changed at once rather than looping through the list and dealing with each. Of course, that may not be so easy to implement in your real model.
turtles-own [intention]
to testme
clear-all
create-turtles 1
[ set intention [0 0 0]
]
ask turtles [ type "before call:" print intention ]
change-intention2
ask turtles [ type "after call:" print intention ]
reset-ticks
end
to change-intention1
ask turtles
[ foreach intention
[ x ->
print "here"
set intention 1
]
]
end
to change-intention2
ask turtles
[ foreach intention
[ x ->
let pp position x intention
type "here:" print pp
set intention replace-item pp intention 1
]
]
end
to change-intention3
ask turtles
[ set intention map [ x -> 1 ] intention
]
end
The use of the special ? variable which takes the values of each of the items in the list as we iterate over the list.
what is the alternative use in the new version of NetLogo software???
The new arrow syntax was introduced with NetLogo 6. Instead of just referring things as ?, this allows you to actually name your variables:
foreach [ 0 1 2 3 ] [ x ->
print x
]
This also allows you to nest these types of blocks and still refer to all the values:
foreach [ 0 1 2 3 ] [ x ->
foreach [ 4 5 6 7 ] [ y ->
print x + y
]
]
Previously, you would have to do this with, for instance, let x ?. With primitives like map and filter, you couldn't do this at all, so it's a big improvement. Note that, if you have more than one variable, you have to wrap the arguments with []:
(foreach [0 1 2 3] [4 5 6 7] [ [x y] ->
print x + y
])
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.
I want to create a list of count values of some variable (tot-turtles) increasing with each tick. I tried the below code but all time list is having single element of length 1. neither i is getting incremented. please correct me.
set tot-turtles count turtles
to go
let mylist [ ]
set mylist lput tot-turtles mylist ; show mylist
set i 1
foreach mylist [ ; print ? ;show i
set x ? - i ; print x
set i (i + 1) ;show i
]
end
I want to subtract elements of list in the following fashion where the length of list depends on the number of simulation run or till simulation ends, then
i need subtraction of element as element at (i + 1)th - element at ith position till the end of the list.
In the above code i is 1 then increments by 1 ie 2 and then continue to 1 2 1 2 1 2. mylsit always shows single element. Confused with "?" , it gives element of current position if i am not wrong, but how we know the current position?
Please help me out of these doubts and code. thanks a lot.
Thank you sir, yes i was doing mistake with local and global variable i checkd it later. and the thing i wanted is as below.
to setup
set mylist [ 0]
set item-difference 0
end
to go
set tot-turtles count tutles set
mylist lput tot-turtles mylist
let _n (length mylist)
set item-difference (( item ( _n - 1 ) mylist - item ( _n - 2 ) mylist )
end
I hope you got Allan sir.
It's a bit difficult to tell what you are after, but it seems you are using a local variable when you want a global variable. See if this offers some help:
globals [mylist]
to setup
ca
set mylist []
crt 10
end
to go
crt 1
set mylist lput (count turtles) mylist ; show mylist
end
to test
let _n (length mylist)
(foreach mylist n-values _n [? + 1] [
print ?1 - ?2
])
end
In my code all turtles own n-features represented by a n-tuple (a1,a2,...,an). where each ai can take values 0 or 1.
I have created some links between turtles. If two turtles share k-features (coordinate-wise matching) and there is a link between them then we call the link as k-link.
How can I find for each k (between 0 to n) how many k-links are there in total?
You don't tell us much about how you have structured your code, so I'm going to assume that your n-tuples are implemented as lists (which would make the most sense in NetLogo).
Here is a full example:
turtles-own [ a ]
links-own [ k ]
globals [ n ]
to setup
ca
set n 5
crt 10 [ ; create turtles with random feature lists
set a n-values n [ random 2 ]
]
ask turtles [ ; make a full network
create-links-with other turtles
]
ask links [ ; calculate k for all links
set k k-of-feature-lists ([a] of end1) ([a] of end2)
]
foreach n-values (n + 1) [ ? ] [ ; display number of k-links
show (word ? "-links: " count links with [ k = ? ])
]
end
to-report k-of-feature-lists [ a1 a2 ]
report length filter [?] (map = a1 a2)
end
Apart from k-of-feature-lists, this is fairly trivial code. What k-of-feature-lists does is to:
transform two lists of features into a single list of booleans containing a true value if the corresponding element is equal in both feature lists and false if it is not. This is accomplished using map and the concise task syntax for =;
filter the list of booleans to keep only the true values;
report the length of that filtered list, which is equal to the number of features that where the same in a1 and a2;
There are plenty of other ways to do that (some more efficient) but this one is nice and concise.