Difference in defining a variable - netlogo

I would like to define a new object, and I do not know what could be the best approach.
I know that let is used for local variables and this should be the main difference.
I am creating a list in NetLogo that stores elements with some attributes/properties. Since later I will need to pick one of this item up from the list created, what I would need to understand if I need to create the object as a local variable or a global(turtle’s own) variable to do this.
The two possible cases should be:
1) Create object as a global variable:
globals [object
attribute]
turtles-own[
my-list]
to setup
create-turtles 5
ask turtles [
set my-list []
]
end
to-go
ask one-of turtles[
set attribute 5
set my-list lput object my-list]
end
2) Create object as a local variable:
turtles-own[
my-list]
to setup
create-turtles 5
ask turtles [
set my-list []
]
end
to-go
ask one-of turtles[
let object “New object”
let attribute 5 ; this should be assigned to object
set my-list lput object my-list]
end`
There should be also another case, i.e. object and attribute defined in turtles-own (this is the case that I would prefer):
turtles-own[
object
attribute
my-list]
to setup
create-turtles 5
ask turtles [
set my-list []
]
end
to-go
ask one-of turtles[
set object “New object”
set attribute 5 ; this should be assigned to object
set my-list lput object my-list]
end
What I would need to implement is the following:
Turtles who have objects stored in a list
Objects who have attributes (or also you can interpret it as turtles that create objects with attributes)
Turtles that can choose to pick an object up from that list depending on the attribute. (This is the most important point as I need to work with the object and its attributes later).
Could you please help me to understand how I need to implement it?
I would like to avoid hatch or create a breed for object because I am not sure to be able to manage it throughout the code.
However, if this is the only right way to proceed, I will do it.
Thank you for your time.

Val, I realize you initially asked "I would like to ask you the difference in using let and set." but later you explain what you need implemented, which is what I answered. So, the title of this question is not very accurate.
I'm not sure this is the only way to proceed but I tried to solve your problem, as I understand it, using two breeds ( people and objects ). I hope you can see from the code below how to do that -- just don't use "ask-turtles" anywhere unless you want to affect both people and objects.
Of course post questions here if you run into problems.
Working code is below.
The way I interpreted your question,
objects are persistent and global,
changes to an object's attributes by anyone at any time will update
the value of that attribute for that object in every agent's my-list
each person has their own my-list of objects, possibly empty.
the my-lists of different agents will be different
each person might search for one of the objects from their list, based on the attribute, and I stored the resulting object, if any, in their current-choice.
each person should be able to select any of the objects and add that object
to their my-list
Implementation design choices:
Use two breeds, "people" and "objects" which own different variables.
Each object owns an attribute and an object-type ( such as "apple" or "orange")
Each person owns a my-list and current-choice. my-list is a list, and
current-choice is an agent ( possibly = nobody )
Features of the code below
The code creates 5 people and 6 objects for testing purposes. All of them are just left sitting at the origin on the display.
At each iteration of the "go" step, a random person selects two random objects and adds them to their my-list, and then locates one of them based on an attribute value.
the code makes a list of all objects in my-list that have the desired attribute,
which may have zero, one, or more objects in it, and does something sensible based on
the length of the list.
no items are ever removed from my-list, or checked to see if they are already there.
that's all this does. run setup, run go (once), and inspect the results.
I hope this is helpful. Let me know here if I didn't answer your question.
Wade
;; this is the second version of the code. It has some comments removed or
;; corrected, and initializes current-choice to nobody instead of []
globals [found?] ;; keep track of whether we found an object
breed [objects object]
breed [people person]
objects-own [
object-type ; say "apple" or "orange" or "widget"
attribute ; user defined, apparently an integer
]
people-own[
current-choice ; an agent
my-list] ; a list of objects
to setup
clear-all
make-people
make-objects
reset-ticks
end
to go
;; for debugging we'll push two objects onto the my-list for a random agent
;; then find one of them with the right attributes and pull it into current-choice
ask one-of people[
;; select a random apple, set its attribute to 111,
;; and push it onto this turtle's my-list
set current-choice one-of objects with [object-type = "apple"]
ask current-choice [set attribute 111 ]
set my-list ( lput current-choice my-list )
;; select a random orange, set its attribute to 222,
;; and push it onto this turtle's mylist
set current-choice one-of objects with [object-type = "orange"]
ask current-choice [set attribute 222 ]
set my-list ( lput current-choice my-list )
;; ok, let's see if we can find an object in my-list with attribute 111
let want-attribute 111 ;; for debugging purposes
;; make a list of ALL objects on the list with the desired attribute
;; as far as we know,there may be many, one, or zero objects with this attribute
let found-list filter [ i -> want-attribute =[attribute] of i ] my-list
if-else length found-list > 0
[ ;; we found at least one match
set found? true
;; pick a random object from the list of objects which have the desired attribute
set current-choice one-of found-list
]
[ ;; we didn't find any matches
set current-choice nobody
set found? false
;; do whatever you do when there is no matching object
]
;; if desired, check out how things ended up by uncommenting the next
;; two lines:
;; inspect current-choice
;; inspect self
]
tick ;; update the tick counter
end
to make-people
create-people 5
[
set current-choice nobody
set my-list []
]
end
to make-objects
create-objects 3 ; create 3 apples
[ set object-type "apple"
set attribute 333 ]
create-objects 3 ; create 3 oranges
[ set object-type "orange"
set attribute 555 ]
end
;; Above code was created by Wade Schuette, 3-November-2019
;; modified sightly 4-November-2019
;; No copyright is claimed. Enjoy!

Related

how to set a string in netlogo ? how to add charachters to a string in netlogo

i was coding with netlogo 3.1.5 and i wrote the next code and it works (the S was already declared in globals [])
set S ""
ifelse (color = green)
[set S S + "0"][set S S + "1"]
the problem is when i wanted to work in netlogo 6.1.1 i copied and past the same code and it shows me an error which is the following:
+expected this input to be a number, but got a string instead
so can you please tell me how to set a string and add other strings in it ?
I wasn't using NetLogo back at v3 but I'm assuming the + is to concatenate. If so, the primitive you want is word. Here's a complete model for demonstration. Note that you need the bracket version if there are more than two inputs.
to testme
let S "A"
print S
set S word S "B"
print S
set S (word S 1 2)
print S
end

Count number of occurrences in a list from same turtle

I would like to know how to find the 'source' of an item in a list. The actions that I need to consider for this task are the following:
1) an item is added in a list created by a turtle;
2) as each turtle has its own list with items created by different turtles, I would like to set a counter that says how often this turtle has picked turtle A's item.
APPROACH & CODE:
This piece of code adds an item (local variable) called 'this_item' in the selected turtle's list:
ask one-of turtles [
set archive fput this_item archive
]
and this other code adds the same item to the neighbours' lists:
ask in-link-neighbors [
set archive fput this_item archive
]
I would set set a local variable, e.g. picked, as the first item from the list.
let picked first archive
To find the source of the item, I thought to use who. However, who is used for the turtle who adds the item to its own list, after extracted it.
print (word "Source: " who " has this list " list " after added item " picked)
If I consider a variable source defined as the source of the item by using myself when a turtle creates a new item, this reports me only the breed of the source (student), but not the corresponding turtle of the source (e.g. student 2).
This makes impossible to count how many times one source's item has been selected.
QUESTION:
How can I count the number of time an item by the same turtle was selected?
Thanks in advance for your help and suggestions.
The easiest way I can think of to do this is to have each this-item be a two-element list, item 0 being the "item" itself and item 1 being the source turtle. this-item would then be created by a turtle with
set this-item list x self
(Note that "item" itself is a reserved keyword, so my "item" is x.) Any turtle that puts this-item in its list would then know that item 0 this-item was the thing itself and that item 1 this-item was the turtle from which it came. To count the number of entries in a list, say archive, owned by a given turtle, say turtle 1, from a given turtle, say turtle 3, you could use
ask turtle 1 [show length filter [a -> item 1 a = turtle 3] archive]
If you need the number of times turtle 3 has made entries in all turtles' archives, you can do it in steps. First create a list of all the archive lists.
let all-archives [archives] of turtles
Then use map to go through that list to make a list of the number of entries in each archive and sum that list.
show sum map [t -> length filter [a -> item 1 a = turtle 3] t ] all-archives
(I can't test this right now so check the syntax.) Of course, turtles could be a subset of all turtles if you like.

Pick an item from a list based on a condition

I have an agent's list made up by elements from its neighbours' lists. I would need to pick an item from it based on a parameter: the higher the parameter h is, the more probable is to pick that item.
To pick the item I tried with: print one-of list, where list contains all the items collected from a neighbour (set list lput item list).
However, I do not know how to add the condition about the parameter.
I tried with max (list item), but this does not consider the value of the parameter h (it can take values from 1 to 10).
Could you please suggest me how to consider it?
Many thanks
The rnd extension does exactly what you need. Put extensions [rnd] at the top of your code. Then use rnd:weighted-one-of-list to do the selection. Here is a complete program that demonstrates. Put it in an empty NetLogo model and then run the testme procedure several times.
extensions [rnd]
to testme
let mylist [1 3 5]
repeat 10
[ type rnd:weighted-one-of-list mylist [ [ii] -> ii ]
type " "
]
end

Error in foreach statement in NetLogo

I downloaded cruise.nlogo file from NetLogo models community. But when I run this file I got errors in this line.
foreach values-from patches [self] patchcolors [set pcolor-of ?1 ?2]
First it asked "values-from" not defined: I declared it as patches-own variable.
Second it asked "pcolor-of" not defined: I again declared it as another patches-own variable.
Third it asked at "?2": expected command.
So I am unable to understand why this error is there. please help, I am using netlogo5.2 version. Do I need the background image file for this?
This is very old style code. See the NetLogo Transition Guide. Now we write
(foreach sort patches patchcolors [ask ?1 [set pcolor ?2]])
Using sort patches eliminates randomization. If you want it, you can use [self] of patches instead.

Giving values using a switch

I want to set two values for a patch using a switch, I mean if the switch is "on" set 1 if it´s "off" set 0. First of all I created the switch, then I wrote the next code.
SET LL 1 if (lluvia = "on") and 0 if (lluvia = "off")
But it did not work.
Switch gives you a boolean value and you can use it directly in ifelse:
ifelse lluvia [set LL 1] [set LL 0]
BTW, in NetLogo it is common to name a boolean variable with a question mark. Name lluvia? would be more in NetLogo style.
Another possible solution:
set LL ifelse-value lluvia [1] [0]
I think bergant's answer actually reads better, though.