While debugging a loop in netlogo
I am having trouble understanding the error that comes from two consecutive loops in a network logo.
;;;;;;;;;;;;;;;;;;;;;;;;
;;; Global variables ;;;
;;;;;;;;;;;;;;;;;;;;;;;;
globals [it]
;;;;;;;;;;;;;;;;;;;;;;
;;; Breedin agents ;;;
;;;;;;;;;;;;;;;;;;;;;;
breed [houses house]
breed [firms firm]
;;;;;;;;;;;;;
;;; Setup ;;;
;;;;;;;;;;;;;
to setup
clear-all
reset-ticks
create-firms F
create-houses H
;; sets position of the firms in the space for better visualisation
set it 0
while [it < F ]
[ask firm it [
set color yellow
set heading it * 360 / F
fd 5
]
set it it + 1
]
;; sets position of the households in the space for better visualisation
set it 0
while [it < H ]
[ask house it [
set color yellow
set heading it * 360 / H
fd 15
]
set it it + 1
]
When I run the above code, I get the error
firm 0 is not a HOUSE
error while observer running HOUSE
called by procedure SETUP
called by Button 'Setup'
pointing to house it
in the code.
Note that when I only run the first while loop everything works fine.
I guess I don't understand how to use loops in a network logo.
- Why does the second cycle seem to think that I am calling firms when I asked to call houses?
- Is there a better way to implement while the loops are in the network logo?
Thanks in advance for your help
source to share
What's happening?
who
numbers in NetLogo are assigned from the same sequence for all turtles, regardless of their breed. If you do:
create-firms 1
create-houses 1
Then you will have firm 0
and house 1
, which you can also call turtles. For example, in the command center:
observer> show turtle 0
observer: (firm 0)
observer> show turtle 1
observer: (house 1)
It makes sense to have such unique identifiers, because the turtle breed is a very transient thing. It can be changed:
observer> ask firm 0 [ set breed houses ]
observer> show turtle 0
observer: (house 0)
The turtle retained the number who
despite the breed change.
Why does the second while loop seem to think that I am calling businesses when I asked to call houses?
What you are doing is equivalent to taking (which is a firm) and trying to send it home. This is why NetLogo complains that it is not home. turtle
0
firm 0
The best way to do it
Is there a better way to implement while the loops are in the network logo?
Yes: don't use while
! More seriously: use while
is often unnecessary. There is usually a better way to do something.
Also, in general, don't use numbers who
for anything . If you want to deal with many turtles at the same time, use the turtles set. If you want to follow the turtle, store a link to it directly (for example set my-firm one-of firms
). If you find you want to use a number who
, take a step back and rethink your problem: there is almost certainly another way.
Do you want to do something with all your houses? Just ask them!
ask houses [
set color yellow
fd 15
]
There is one thing the above snippet does not cover: your requirement for evenly spaced turtles. But you can achieve this by using create-ordered-<breeds>
to create your turtles. With its help, all yours setup
will become as follows:
clear-all
create-ordered-firms F [
set color yellow
fd 15
]
create-ordered-houses H [
set color yellow
fd 15
]
But what if you really need an index?
But what if create-ordered-<breeds>
doesn't exist, or if you want to do something like this that requires some sort of index? You still don't need the while
: combination foreach
and n-values
will get you there:
create-houses H
(foreach sort houses n-values H [ ? * 360 / H ] [
ask ?1 [
set color yellow
set heading ?2
fd 15
]
])
(We use sort
to turn a set of turtles houses
into a list, but [self] of houses
works if you want to shuffle them.)
This code may look strange, but it is actually a fairly common and useful pattern in NetLogo. It zips up what you want to use with the index you want to assign to it. It also has several nice advantages over the while loop: no single-handed errors, no extra variable, and no risk of forgetting to increment the counter or accidentally mutating it.
source to share