Abe
Abe

Reputation: 415

Creating conditional links between two breeds

I am writing a NetLogo model of a housing market and its political ramifications. There are two breeds in the model: households and houses. An early step in my development with which I am having difficulty is having households match to houses via one of two types of links, own or rent, defined by nested conditional statements. This has resulted in two difficulties I haven't been able to overcome as of yet.

  1. Within the command setup-market command, I'm trying to define a set of possible houses to purchase for each household which, if they meet a set of conditions, the household then buys (and creates a link). If it cannot afford to buy, then it will try to rent. If it cannot afford to rent the household will die.

My code continually results in the following error:

IFELSE expected input to be a TRUE/FALSE but got the turtle (house XXX) instead.

  1. There is a further issue I'm having as well later in the code (in the two lines commented out with ";") where I attempt to set the variables owner-occupied and renter to 1 based on the presence of the appropriate link (they should remain 0 and the household should die if it remains unlinked).

The full code is below. The line with ";; This is the line giving me trouble" denotes where the error seems to be occurring.

UPDATE: Code has been updated with JenB's solution. Resulting error is now: CREATE-LINK-WITH expected input to be a turtle but got NOBODY instead. which occurs at the line: create-link-with one-of potentialHomes [ set color red

undirected-link-breed [own-links own-link]
undirected-link-breed [rent-links rent-link]
breed [city-centers city-center]
breed [households household]
households-own 
[ 
  age 
  money 
  income 
  monthly-income 
  consumption 
  monthly-consumption 
  hh-size race 
  preference 
  net-income
  net-monthly-income
  myHouse
]
breed [houses house]
houses-own 
[ 
  cost 
  down-payment 
  mortgage-payment 
  rent 
  rent-premium 
  rooms 
  onMarket
  owner-occupied
  rental
  onMarket?
]
patches-own [ 
  seed?  ;;district seed
  district  ;;district number
  full? ;;is the district at capacity?
  quadrant 
]

to setup
  clear-all
  reset-ticks
  setup-patches
  set-default-shape households "person"
  create-households num-households [ setxy random-xcor random-ycor ]
  set-default-shape houses "house"
  create-houses num-houses [ setxy random-xcor random-ycor ]
  setup-households
  setup-houses
  setup-market
  generate-cities
end

to generate-cities
  let center-x random-xcor / 1.5 ;;keep cities away from edges
  let center-y random-ycor / 1.5
end

to setup-patches
  ask patches with [pxcor > 0 and pycor > 0] [set quadrant 1 set pcolor 19 ]
  ask patches with [pxcor > 0 and pycor < 0] [set quadrant 2 set pcolor 49 ]
  ask patches with [pxcor < 0 and pycor < 0] [set quadrant 3 set pcolor 139 ]
  ask patches with [pxcor < 0 and pycor > 0] [set quadrant 4 set pcolor 89 ]
end

to setup-households
  ask households
    [ set age random-poisson 38
      set money random-exponential 30600
      set income random-exponential 64324
      set monthly-income income / 12
      set consumption .5 * income
      set monthly-consumption consumption / 12 
      set hh-size random 6 + 1
      set net-income income - consumption
      set net-monthly-income monthly-income - monthly-consumption
    ]
end

to setup-houses
  ask houses
    [ set cost random-normal 300000 50000
      set down-payment cost * down-payment-rate
      set mortgage-payment (cost - down-payment) / 360 
      set rooms random-exponential 3
      set onMarket 1
      set rent mortgage-payment + mortgage-payment * .25
      set owner-occupied 0
      set rental 0
    ]
end

to setup-market
  ask houses
    [ set onMarket? TRUE ]
  ask households 
    [ ifelse any? houses with [ [money] of myself > down-payment and [net-monthly-income] of myself > mortgage-payment ]
      [ let potentialHomes houses with [[money] of myself > cost and onMarket? ] 
        create-link-with one-of potentialHomes [ 
          set color red
        ]
      ] 
      [ 
        ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [ [net-monthly-income] of myself > rent and onMarket? ] 
  create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
      ]
  ]
  ask houses 
    [ if any? link-neighbors [set onMarket FALSE ] 
      ;if any? link-neighbors and color red [ set owner-occupied 1 ]
      ;if any? link-neighbors and color blue [ set rental 1 ]
  ]
end

to go
  move-households
  tick
end

to move-households
  ask households [
    move-to myHouse
  ]
end

Upvotes: 0

Views: 246

Answers (1)

JenB
JenB

Reputation: 17678

You don't need to "suspect" where the problem is, NetLogo points to the problem line. Running your code, the problem is actually ifelse one-of houses with [ [net-monthly-income] of myself > rent]. Looking at that line, you pull out a randomly selected house from the pool with rent less than income. But you don't have a condition for the ifelse to test.

In previous constructions you have had != nobody at the end but you forgot that in this line. That will fix the error, but your code would be much less error prone if you used any? instead. You seem to be using one-of .... != nobody to test whether there are any turtles that satisfy the condition. That's what any? is for.

So instead of:

ifelse one-of houses with [ [net-monthly-income] of myself > rent] != nobody
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ] 
  create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]

you can have:

ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ] 
  create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]

I should add that there is a potential logic problem here. Say there are houses with rent lower than income, the code goes to the first (true) actions. But there's no guarantee that there are any houses that satisfy the new conditions, which are different.

Also, NetLogo has the concept of true and false so you don't need to use 1 and 0. By convention (but not required), boolean variable names end with a question mark. So you could have set onMarket? true instead of set onMarket 1. Why would you do this? It makes logical operators cleaner and easier to read (which reduces bugs). Your line:

let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]

would look like:

let potentialRentals houses with [[money] of myself > rent and onMarket? ]

And you can do things like if not onMarket? instead of if onMarket? = false or if onMarket = 0

Upvotes: 1

Related Questions