Reputation: 806
following my previous post, I would like to ask the reason why a variable is being initialised when I try to update its value. I am trying to find a way to fix this issue.
What I am wishing to do is updating the variable's original value by adding a small random quantity q = random-float 0.1
, only when I add this-item
to the neighbours' lists.
My expected output would be:
(object 16) with original attribute 0.147 neigh: 0 (object 16) with updated attribute 0.167 with random-float 0.02
i.e. without initialising the original value:
(object 16) with original attribute 0.147 neigh: 0 (object 16) with updated attribute 0.02 with random-float 0.02
The latter is my current output, and this is wrong.
I do not know how to fix this issue within my code. I am still trying to understand what is going wrong, but I have not found yet a way to fix it, so I hope you can help me to understand more. My code is the following:
if breed = breed1 [
set selected people
hatch-items 1 [
hide-turtle
set chosen selected
set attribute1 random-float 1
set attribute2 attribute1
set this-item self
print (word " attribute1 " attribute1 " attribute2 " attribute2)
ask myself [
set my-list fput this-item my-list
] ;; close ask myself
] ;; close hatch
; ADD NEW ITEM TO NEIGHBOURS' LISTS ;
print (word " Before updating value, attribute1 " attribute1 " attribute2 " attribute2)
ask link-neighbors with [breed = breed1] [
let q random-float 0.1
set attribute1 (attribute1 + q)
print (word " After updating value, attribute1 " attribute1 " attribute2 " attribute2 " q " q)
] ;; close ask link-neighbors
] ;; close if
I put some print function to see the outputs:
the first print returns me attribute1 0.85 and attribute2 0.85
print (word " attribute1 " attribute1 " attribute2 " attribute2)
the second output returns me attribute1 0 and attribute2 0
print (word " Before updating value, attribute1 " attribute1 " attribute2 " attribute2)
the third output returns me attribute1 0 attribute2 0 and q 0.08
print (word " After updating value, attribute1 " attribute1 " attribute2 " attribute2 " q " q)
What is happening is that attribute1
is initialised within the ask link-neighbors
, so I am adding the quantity q
to 0
, and not to the original value of attribute, defined in the hatch.
Could you please help me to update it, without initialising the value?
Many thanks
Upvotes: 0
Views: 61
Reputation: 1473
Nothing is being initialized. Your problem is that you have two different scopes.
The variable "attribute1" that you set within the hatch block belongs to the hatched agent. The variables of the same name "attribute1" in your "ask link-neighbors" block belong to the link-neighbors.
So your ask link-neighbors statement
set attribute1 (attribute1 + q)
is asking each link-neighbor to set its own "attribute1" to its own attribute1 plus q. What you want instead is to ask each link neighbor to set its own attribute1 to the recently-hatched agent's variable "attribute1" plus q.
If we had dot notation, which we don't, you'd want something like
set neigbhor.attribute1 ( hatched_agent.attribute1 + q )
Since your ask link-neighbor code is outside the scope of the hatched agent, there's no way to use something like "self" or "myself" to point to the right variable of that name.
One way around this problem would be to define a new global variable, maybe call it "passed-ball"
globals [ passed-ball ]
Then inside the hatch block you could
set passed-ball attribute1
And then in your ask link-neighbors block of code, you could say
set attribute1 (passed-ball + q)
Alternatively,instead of making this passed-ball totally global, which violates the guidelines of using as few global variables as possible, you could use another method to persist the value you want between the hatch block and the ask link-neighbors block: "passed-ball" could be an variable owned by the agent that is the one referred to at the very top of the code you posted, about which you are asking whether breed = breed1.
I think that both the hatch code and the ask-link-neighbors code could see and implicitly refer to a variable called "passed ball" that was owned by this high-level agent. Just don't name it "attribute1" yet again or there would then be three different "attribute1" meanings floating around and it would be even more likely that you or some later person modifying the code would make some error and refer implicitly to the wrong one.
Upvotes: 2