Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

while loop debugging in netlogo

I am having trouble understanding an error emerging from two consecutive while loops in a net logo project.

;;;;;;;;;;;;;;;;;;;;;;;;
;;; 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 an error message

firm 0 is not a HOUSE
error while observer running HOUSE
  called by procedure SETUP
  called by Button 'Setup'

pointing at house it in the code.

Notice that when I only run the first while loop, everything works fine.

I guess there is something I do not understand in the use of while loops in net logo.

  • Why does the second while loop seem to consider that I am calling firms although I asked to call houses?
  • Is there a better way to implement while loops in net logo?

Many thanks in advance for you help

like image 869
Martin Van der Linden Avatar asked May 18 '26 00:05

Martin Van der Linden


1 Answers

What's happening?

who numbers in NetLogo are assigned from the same sequence for all turtles, independently of their breeds. If you do:

create-firms 1
create-houses 1

Then you will have firm 0 and house 1, which you could also address as 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 unique identifiers like that, because the breed of a turtle 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 has kept its who number despite the change of breed.

Why does the second while loop seem to consider that I am calling firms although I asked to call houses?

What you are doing is the equivalent of taking turtle 0 (which is a firm) and trying to cast it to a house. This is why NetLogo complains that firm 0 is not a house.

A better way to do it

Is there a better way to implement while loops in net logo?

Yes: don't use while! More seriously: using while is most often unnecessary. There is usually a better way to do things.

Also, in general, don't use who numbers for anything. If you want to deal with many turtles at once, use a turtle set. If you want to keep track of a turtle, store the reference to it directly (e.g., set my-firm one-of firms). If you find yourself wanting to use the who number, take a step back and rethink about your problem: there is almost certainly another way.

You want to do something with all your houses? Just ask them!

ask houses [
  set color yellow
  fd 15
] 

There is one thing that the snippet above does not address, however: your requirement for evenly spaced turtles. But you can achieve this by using the create-ordered-<breeds> to create your turtles. With it, your entire setup becomes:

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> did not exist, or if you wanted to do something similar that required some sort of index? You still don't need while: a combination of 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 the houses turtle set into a list, but [self] of houses works as well if you want them shuffled.)

That code may look weird at first, but it's actually a pretty common and useful pattern in NetLogo. It "zips" the thing you want to act on with the index that you want to assign to it. It also has a few nice advantages over a while loop: no "off by one" errors, no extra variable and no risk of forgetting to increment the counter or to accidentally mutate it.

like image 61
Nicolas Payette Avatar answered May 21 '26 01:05

Nicolas Payette



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!