Introductory NetLogo Exercises

author:

Alan G. Isaac

organization:

American University

contact:

aisaac@american.edu

Date:

2023-07-14

The following exercises are meant to help you test and develop your understanding of NetLogo as a programming language.

Expressions, Functions, and Commands

Simple Computations

The simple computations exercises focuses on entering commands at the NetLogo command line.

  1. Open the NetLogo Dictionary. Look up the let command, which can bind a name to a value at NetLogo’s command line. Look up the print command, which can print the value of an expression at NetLogo’s command line.

    Start NetLogo. One line at a time, enter each of the following lines in NetLogo’s Command Center, in the order presented. (Some of these commands will not execute successfully.)

    print 2+2
    print 2 + 2
    let x1 -2
    print x1
    let x2 -2 print x2
    let x3 -2 print -x3
    let x4 -2 print - x4
    let x5 -2 print (- x5)

    In the Info tab, summarize your “lessons learned” from trying to execute these commands. When adding this summary in the Info tab, make your comments self-contained: the code you entered at the command line will not be saved when you save your NetLogo model file.

  2. Go to the NetLogo Dictionary. Look up the set command. In the Info tab, state the difference between let and set? (This is very important!) Enter the following at the NetLogo command line.

    let x 0 set x (1 + x) print x

    Why do we use let and set in this order? (Explain in the Info tab.) Suppose we now again enter

    print x

    at the command line. What do you expect to see, and why? (Explain in the Info tab.)

  3. Repeat the previous exercise, but use show instead of print. What changes? Does the NetLogo Dictionary explain the difference between these two commands? (Add your answers to the Info tab.)

  4. Relying on the NetLogo Dictionary, but carefully avoiding plagiarism, explain (in the Info tab) the difference between show, print, type, and write. Next, read the documentation in the NetLogo Dictionary for repeat. One line at a time, enter the following lines of code at the command line. In each case, if what you see differs from what you expected, explain why in the Info tab.

    repeat 5 [show 1]
    repeat 5 [print 1]
    repeat 5 [type 1]
    repeat 5 [write 1]
  5. Review the documentation of the repeat command in the NetLogo Dictionary. Make sure you understand why the code below will repeatedly increment a variable (x). That is, it will repeatedly increase its integer value by 1.

    let x 0 repeat 50 [set x (x + 1)] print x

    (This introduces a local variable named x, which does not persist after you run this code.) If you enter this code at the NetLogo command line, what result do you expect to see? Why? (Explain in detail in the Info tab.) Enter the code to confirm your expectations.

  6. This exercise makes use of NetLogo’s Code tab. Enter the following at the very top of the Code tab.

    globals [x]

    (This introduces a global variable named x.) Now, switch back to the Interface tab. At the command line, enter exactly the same repeated-increment code as before. Why does it no longer have the same effect? (Explain in the Info tab.)

  7. Next, enter the following at NetLogo’s command line (on three separate lines).

    print x
    repeat 50 [set x (x + 1)]
    print x

    In the Info tab, summarize what you have learned about local and global variables.

Reporter Procedures

Computational functions form the core of many programs. In most programming languages, we say that a function returns value. The equivalent terminology in NetLogo is that a reporter procedure reports a value.

  1. Launch NetLogo and go to the Code tab. Make sure that you still have declared a global variable x at the top of the Code tab.

    We will implement the simple identity function (\(x \mapsto x\)) in the code tab and name it identity. To do so, add the following reporter procedure to your Code tab. (As always, use the Check button to check your work.)

    to-report identity [#x]
      report #x
    end

    Note the use to-report, report, and end, which you will find in every reporter procedure. Add a comment to explain what this very simple function does.

  2. A good rule of thumb is to assume untested code is broken, so always test your function definitions. Here is a simple test to try at the NetLogo command line: enter print (identity 1). You should see the value 1 printed in the Command Center. Note that you do not use brackets when applying a function (here, identity) to an argument (here, 1). Next enter print (identity 99). You should see the value 99 printed in the Command Center. (We will explore better approaches to testing later on.)

  3. In the Code tab, implement the squaring function (\(x \mapsto x * x\)) as a reporter procedure, giving it the name sq. This function takes one parameter and simply reports its square.

    Hopefully, when creating the sq function, you remembered to name its parameter #x. If you instead named it x, what happens when press the Check button? (Temporarily change your code to try it.) What have you learned about the names of global variables and parameters? (This is Netlogo specific.)

  4. A good rule of thumb is to assume untested code is broken, so always test your function definitions. Here is a simple test to try at the NetLogo command line: enter print (sq 5). You should see the value 25 printed in the Command Center. Test your function again at the NetLogo command line: enter print (1 + sq 0). You should see the value 1 printed in the Command Center.

  5. Make sure that you have declared a global variable x at the top of the Code tab. Then, add the following reporter procedure to your Code tab. (As always, use the Check button to check your work.)

    to-report xpsq [#x]
      report x + (#x * #x)
    end

    Enter the following lines at the command line, and add a comment explaining the results.

    print (xpsq 2)
    set x 1
    print (xpsq 2)
  6. Note that xpsq does not change the value of the global variable x. This reporter procedure has no side effects. Based on discussion in the Glossary, does xpsq implement a pure function? Why or why not? (Explain in the Info tab.)

  7. You should now be comfortable creating reporter procedures in order to implement mathematical functions. Implement the bivariate real function \(x \mapsto x + 0.03 * x * (1 - x)\). Call this function nextVP.

Command Procedures

  1. Open the Code tab and enter the following command procedure stub.

    to trystuff
    end

    Here to and end are the NetLogo keywords used to create a command procedure, and trystuff is the name we give the procedure. Call the first line the command declaration. Between the command declaration and end is the procedure body, so this command procedure has an empty body.

    Let’s change that. Start entering each of the commands from the Simple Computations exercise 1. Notice how NetLogo warns you of a syntax error as soon as you enter the first line. Prefix a semicolon to this line to turn it into a comment, which NetLogo ignores.

    Recall that some of these commands would not run and the command line. Each time you add a line, change to the Command Line and run this procedure by entering trystuff. Whenever a line creates a problem, comment it out. Is there any difference between which lines you could run at the Command Line and which work fine in trystuff? In the Info tab, explain.

  2. We often use command procedures to test our functions. For example, approach the simple test of the sq function from the Reporter Procedures exercise in a slightly more formal manner. Copy the following command procedure to the bottom of your Code tab. Then enter test-sq at the NetLogo command line in order run this command procedure and test your sq function. (If your sq function does not pass this test, fix it!)

    to test-sq
      type "Begin test of `sq` ... "
      if (25 != sq 5) [error "error when squaring 5"]
      if (0 != sq 0) [error "error when squaring 0"]
      if (25 != sq -5) [error "error when squaring -5"]
      print "`sq` passed."
    end
  3. Similarly, test your xpsq function from the Reporter Procedures exercises by adding the following test to your Code tab and running it at the command line.

    to test-xpsq
      type "Begin test of `xpsq` ... "
      set x 0
      if (25 != xpsq 5) [error "error when applied to 5"]
      set x 1
      if (26 != xpsq 5) [error "error when applied to 5"]
      print "`xpsq` passed."
    end
  4. We may use command procedures to change the values of global variables. Again, make sure you have declared a global variable x. Add the following command procedure to your Code tab. (As always, use the Check button to check your work.)

    to sqx
      set x (x * x)
    end

    Does this sqx procedure implement a pure function? Why or why not? (Explain in the Info tab.)

  5. Without changing the procedure code, can you find a way to use this sqx command procedure (below) to produce the values we so easily produced with the sq function from the Reporter Procedures exercises? If not, what problems do you run into? For example, what happens if you try to print (sqx 2)?

    What have you learned about the advantages of using functions (reporter procedures) rather than command procedures to produce needed values? Describe some advantages of the reporter procedure (sq) from the Reporter Procedures exercises. over this command procedure (sqx)

  6. At the bottom of the Code tab, create a test-nextVP command procedure to test the nextVP function from the Reporter Procedures exercises. Test that the result is \(0\) when \(x=0\) and \(1\) when \(x=1\). At the NetLogo command line, enter test-nextVP to confirm that your implementation of nextVP behaves as expected. (See the Logistic Growth lecture for details.)

Lists

Introduction to Lists

Basic Lists

  1. NetLogo uses zero-based indexing of lists. Explain what this means.

  2. Show how to create and print the list containing just \(0\) and \(1\) as the two elements

    • using brackets

    • using list

    • using range

  3. Explain the difference between

    let x 1 print [0 x]

    and

    let x 1 print (list 0 x)
  4. Describe the elements of the list range 10. (How many elements are there? What are they?)

  5. Suppose we let xs (range 10). Show how to print the fifth element of xs, using the item command.

More Lists

  1. Suppose we let xs (range 10). Show how to print each of the elements of xs, using the foreach command.

  2. Suppose we let xs (range 10). Show how to create a new list where each element is doubled, using the map command.

  3. Suppose we let xs (range 10). Show how to create a new list of just the elements smaller than 5, using the filter command.

Random Numbers

Basic Random Numbers

  1. Read the documentation for random and random-float, and then guess the results for the following:

    random 1
    random-float 1

    Check your guess at the Command Center.

  2. Read the documentation for random-seed, and then explain how

    random-seed 314
    random-float 1
    random-float 1

    differs from the following.

    random-seed 314
    random-float 1
    random-seed 314
    random-float 1

    Check your understanding at the Command Center.

Basic Random Lists

  1. After reading the documentation for n-values and the notes about lists, execute the following code at the command line. In each case, if what you see differs from what you expected, explain why.

    print n-values 5 [random 1]
    print n-values 5 [random 2]
    print n-values 5 [random-float 1]
  2. After reading the documentation for one-of and the notes about lists, execute the following code at the command line. In each case, if what you see differs from what you expected, explain why.

    random-seed 314
    print n-values 5 [one-of [0 1]]
    random-seed 314
    print n-values 5 [one-of [0 1]]

    What do you notice about the last two lists you produced. Can you explain it?

  3. Here is a more subtle example:

    random-seed 314 show n-values 5 [list random 1 random 2]
    random-seed 314 show n-values 5 [random 2]

    It is perhaps initially surprising that random 1 changes the state of the random number generator.

Patches

Talking to Patches

Do this exercise after reading the Introduction to NetLogo supplement. As you work the exercises, you will also need to read the documentation of specific commands in the NetLogo Dictionary.

Learning to ask Nicely

When we want an agent to do something, we use the ask command. The ask command is a prefix operator that requires two input arguments. The first argument must be an agent or an agentset. The second argument is a `command block`_.

Basic Patch Interactions

  1. Ask the patch at the origin to set its patch color to red. (Hint: In the NetLogo Dictionary, read the documentation for ask, set, and pcolor.)

  2. Ask all patches to turn white.

  3. Print the number of patches in the model. (Hint: In the NetLogo Dictionary, read the documentation for count and print.)

Randomized Patch Interactions

  1. Ask a random patch to turn red. (Hint: In the NetLogo Dictionary, read the documentation for one-of.)

  2. Ask each patch to turn a random color, either red, white, or blue. (Hint: In the NetLogo Dictionary, read the documentation for one-of and list.)

  3. If you do the random color experiment a second time, will the outcome be identical? Why or why not? How could you use the random-seed command to ensure that you get the same outcome each time? (Hint: In the NetLogo Dictionary, read the documentation for random-seed.)

Further Patch Interactions

  1. Ask all patches to the left of the origin to turn red. (Hint: In the NetLogo Dictionary, read the documentation for with and pxcor.)

  2. Make a list of all patches, in random order. (Hint: In the NetLogo Dictionary, read the documentation for of and self.)

Patch Attributes

  1. Give patches a new attribute, wealth. (Hint: In the NetLogo Dictionary, read the documentation for patches-own, and recall from the Introduction to NetLogo supplement that this cannot be used at the command line.)

  2. Set the wealth of each patch to a random integer between 0 and 100 (inclusive). (Hint: In the NetLogo Dictionary, read the documentation for random.)

  3. Print the wealth of the patch at the origin. (Hint: In the NetLogo Dictionary, read the documentation for of.)

  4. Print a list of all patch wealths. (Hint: In the NetLogo Dictionary, reread the documentation for of.)

  5. What is the difference between print [wealth] of patches and ask patches [print wealth]?

  6. Print the total wealth of the patches. (Hint: In the NetLogo Dictionary, read the documentation for sum.)

  7. Advanced: Create a list of all patches, and then create a list of all patch wealths, in the same order as your list of patches. (Hint: In the NetLogo Dictionary, read the documentation for of and map.)

Understanding Execution Context

To illustrate the importance of execution context, create a new NetLogo file containing only the following code.

patches-own [wealth]

to patchSetWealthBad
  ask patches [set wealth 100]
end

to patchSetWealthGood
  set wealth 100
end

to patchesSetWealth
  ask patches [patchSetWealthBad]
  ask patches [patchSetWealthGood]
end

Click the Check button. The code checks! So let us run it: go to the command line and enter patchesSetWealth. What happens? Why?

Next, comment out the first line in patchesSetWealth and again trying running it at the command line. What happens? Why?

NetLogo Times Table

Implement a times table in NetLogo by following along with this video.

Color Scaling

NetLogo modelers often use patch shading to make their models visually informative. In the following exercises, ask each patch to turn a color that represents its wealth.

  1. Let a wealth of 100 be green. Represent lower wealths by darker shades of green, with \(0\) wealth represented by black. (You should not see any white patches.)

  2. Let a wealth of 100 be green. Represent lower wealths by lighter tints of green, with \(0\) wealth represented by white. (You should not see any black patches.)

Prerequisite Background: Color Scaling

Review the discussion of colors in the NetLogo User Manual. A shade of a color adds black to a color; a tint of a color adds white to a color. NetLogo’s scale-color primitive facilitates easy production of both shades and tints. (Review its documentation in the NetLogo Dictionary.)

Next, start NetLogo. Go to File » Models Library » Code Examples » Scale-color example. Read the information under the Info tabs. Experiment with the the shading of different colors. Then examine the code in the Code tab.

Context

To illustrate the importance of context, create a new NetLogo file containing the following code.

patches-own [wealth]

to patchSetWealthBad
  ask patches [set wealth 100]
end

to patchSetWealthGood
  set wealth [100]
end

to patchesSetWealth
  ask patches [patchSetWealthBad]
  ask patches [patchSetWealthGood]
end

Click the Check button. The code checks! So let us run it: go to the command line and enter patchesSetWealth. What happens? Why? Can you find a single line to comment out that will allow the code to run?

Turtles

Talking to Turtles

Basic Turtle Interactions

Try the following at the NetLogo command line.

  1. Enter the clear-all command to start from scratch. http://ccl.northwestern.edu/netlogo/docs/dictionary.html#clear-all

  2. Create 18 turtles http://ccl.northwestern.edu/netlogo/docs/dictionary.html#create-turtles (Where are they?)

  3. Ask your turtles to move forward by 4. http://ccl.northwestern.edu/netlogo/docs/dictionary.html#jump http://ccl.northwestern.edu/netlogo/docs/dictionary.html#forward (Where are they? What do you learn about turtle creation?)

  4. Enter the clear-all command to start from scratch. http://ccl.northwestern.edu/netlogo/docs/dictionary.html#clear-all

  5. Create 18 ordered turtles http://ccl.northwestern.edu/netlogo/docs/dictionary.html#create-ordered-turtles (Where are they?)

  6. Ask your turtles to move forward by 4. http://ccl.northwestern.edu/netlogo/docs/dictionary.html#jump http://ccl.northwestern.edu/netlogo/docs/dictionary.html#forward (Where are they? What do you learn about turtle creation?)

  7. Ask all your turtles to make a 70 degree right turn around their center. http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right What happens?

  8. Review the documentation for the commands used above, then enter the following: ca cro 18 [jump 4 rt 70] Explain the result.

  9. Change the shape of your turtles to "square 2": http://ccl.northwestern.edu/netlogo/docs/dictionary.html#shape What do you notice about the orientation? (Not all shapes are "rotatable'.)

Fun with Turtles

To make a simple mandala, add this code to the code tab, and then enter talk-to-turtles recolor at the command line.

to setup
  ca
  setupTurtles
  setupGUI
end

to setupTurtles
  cro 16 [fd  4]
  cro 32 [fd  8]
  cro 46 [fd 12]
  cro 60 [fd 16]
end

to setupGUI
  ask patches [set pcolor gray]
  ask turtles [
    set color ifelse-value (0 = who mod 2) [black] [white]
  ]
end

Explain why this code produces the outcome you see.

Background:

http://ccl.northwestern.edu/netlogo/docs/dictionary.html#who http://ccl.northwestern.edu/netlogo/docs/dictionary.html#mod

Further Turtle Interactions

  1. Give turtles a new attribute, wealth. (Note that your patches and turtles cannot have identically named attributes.) http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles-own

  2. Write an observer procedure named setup that does the following:

  3. Write an observer procedure named go that does the following:

  4. From the Command Center, call setup, and then call go 50 times. (Try this a few times.)

More Fun with Turtles

In the Tools menu, use the Turtle Shapes Editor to create a new shape named "square 3" that duplicates "square 2" but is rotatable. Run the code from the Fun with Turtles exercise, and then run createIllusion:

to-report isEven [#int]
  report (#int mod 2 = 0)
end

to-report circleNumber ;turtle proc
  report round (distancexy 0 0 / 4)
end

to createIllusion
  ask turtles [
    set size 1.7
    ifelse isEven circleNumber [
      rt 15
    ][
      lt 15
    ]
    set shape "square 3"
  ]
end

NetLogo Puzzlers

Level 0

  1. Produce a list of all patches in random order. Produce a list of all patches in a fixed order. Produce a list of all turtles in random order. Produce a list of all turtles in a fixed order.

  2. After creating two turtles on two different patches, consider the following single line of code.:

    ask turtle 0 [move-to one-of [neighbors] of turtle 1]

    What do you expect to happen if you execute this code?

  3. Consider the following single line of code:

    ask patches [ sprout 1 [ set shape "line" set size sqrt 2 set heading one-of [45 135] ] ]

    What do you expect to happen if you execute this code? What does happen? Can you explain why?

    (ht: Seth Tissue)

Level 1

  1. Suppose you have a list of agents, named myagents. Show how to pick a random agent from this list.

    Side note: an agentset myagents can always be turned into a list with [self] of myagents.

  2. If you run test, what values will be printed? Why?

    patches-own [x]
    to test
      ca
      ask patches with [x = 0] [
        ask other patches [set x x + 1]
      ]
      print max [x] of patches
      print min [x] of patches
    end

Level 2

  1. Set Operations with Agentsets

    Show to to implement the follow set operations for patches. In preparation for this exercies, ask patches [set pcolor one-of [red white blue]]

    subsetting

    From the set of patches, produce the subset red-patches of red patches. From the set of patches, produce the subset left-patches of patches to the left of the origin.

    union

    Produce the set of patches that are either red-patches or left-patches (or both).

    intersection

    Produce the set of red-patches that are also left-patches.

    set difference

    Produce the set of red-patches that are not left-patches.

  2. Write a reporter that returns the band of patches nearest the edges of the world. The reporter should take one argument, which specifies the band width.

  3. In NetLogo, we can represent a vectors as list. The norm of a real vector is its length, computed as the square root of the sum of squares of its elements. Show how to produce the norm of a vector in NetLogo.

  4. Suppose you have a list of agents, named myagents. Devise a way to pick a random sublist of agents from this list. (Each item should be equally likely to appear in the sublist.)

  5. Define a pure function named linspace that takes three arguments, xmin, xmax, and npts, and returns a list of equally spaced points in an interval. The interval is from xmin to xmax. The number of points is npts. Include both endpoints.

  6. Given a number and a list, produce a list of two-element lists, pairing the number with each element of the list.

  7. Write a reporter that accepts two integers (m and n) and reports the list of integers in the closed intverval [m,n].

Level 3

  1. Give a list, use reduce and fput to produce a reversed list.

  2. Given an array a of 5 zeros, what is the result of foreach n-values 5 [[?] -> ? ] [ array:set a ? ? * ? ]. Explain.

  3. Given: a list of 2-element lists (pairs), such as [[1 2] [3 4] [5 6]]. Produce a string consisting of the first element of each pair, separated by a comma. (E.g., "1,3,5".)

    Comment: such a string would be suitable for a CSV file.

    Hint: use reduce, word, map, and first.

  4. Report all the positions where a character appears in a string. (Your report should take two arguments: a character and a string.)

  5. Suppose you represent a bag of items by a list of objects (e.g., ["a" "b" "c"]) and a corresponding list of their multiplicities (e.g., [ 1 2 3 ]). Show how to produce a list where each object occurs with its multiplicity (e.g., ["a" "b" "b" "c" "c" "c"]).

    Hint: you can use n-values inside foreach, but be aware that you cannot then refer back to the foreach arguments with the question-mark notation.

  6. Given a list of items, where some items may occur more than once, produce a list of unique items. The new list should include every item in the original list, but each item should occur only once.

    The object is to use reduce and ifelse-value. Do not just use the remove-duplicates primitive.

  7. Given a list of integers, produce a list of “run” lengths, where a run length is the number of successive items with the same value. For example, an input of [1 2 2 3 3 3 4 4 5] should produce [1 2 3 2 1].

Core Concepts

Neighborhoods

Before attempting this exercise, read about neighborhoods.

For each of the following exercises, write a reporter procedure that returns a list of offsets that is appropriate for use with at-points. In each case, the radius is a nonnegative integer value.

  1. Write a reporter procedure that produces a “cross” neighborhood of radius r. Do not include the center (offset [0 0]).

    Hint: See the documentation for range, remove, and sentence.

  2. Write a reporter procedure that produces a box (Moore) neighborhood or radius r.

    Hint: use nested foreach loops.

    Extra credit: add a second argument, origin, which is a boolean that indicates whether or not to include the center (offset [0 0]).

  3. Write a reporter procedure that produces a diamond (von Neumann) neighborhood or radius r. The diamond neighborhood of a point is the set of points within a Manhattan distance of r. (The diamond neighborhood of radius 1 is called a von Neumann neighborhood.)

    Extra credit: Use your moore-offsets procedure and filter to produce a v-offsets procedure.

Here is one approach to the cross neighborhood. (Try it yourself first!)

Basic Data Export

Before attempting this exercise, work through the notes on File-Based IO in the NetLogo Programming supplement. You will also need to master the foreach command. This exercise asks questions based on these readings.

Export List

Consider the following procedure for exporting a list, taken from the NetLogo Programming supplement.

;WARNING: riskyExportList overwrites #filename without asking permission!
to riskyExportList [
  #filename ;String, the full name of the file
  #header   ;String, the header (if any)
  #items    ;List, the values to be written
  ]
  carefully [file-delete #filename] []
  file-open #filename
  if "" != #header [file-print #header]
  foreach #items [?item -> file-print ?item]
  file-close
end
  1. Explain the purpose and dangers of the following code.

    carefully [file-delete "temp.csv"] []
  2. Explain the use of NetLogo’s foreach command in this procedure.

  3. Use this procedure to write the list [0 1 2 3 4 5] to a file, say temp.csv

  4. Examine the file you created by opening it in a spreadsheet application, then close the spreadsheet.

  5. Examine the file you created by opening it in a text editor, then close the editor.

Extra challenge:

  1. Create a new version of this data-export procedure, with fewer shortcomings.

Export Agent Attribute

Before attempting this exercise, work through the notes on File-Based IO in the NetLogo Programming supplement. Also, do the Basic Data Export exercise above.

Export Attribute 1

Randomly set your patch colors: ask patches [set pcolor one-of [red white blue]] Then:

  1. Produce a list holding the resulting patch colors (which are just numbers). Overwrite temp.csv with the numbers in this list.

  2. Open temp.csv with a text editor to see what it looks like. (Windows users can try NotePad but may need to use WordPad instead: Start menu » All apps » Windows Accessories » WordPad. Wordpad will correctly read and display text files that use only a linefeed code to mark line-endings, as is typically the case with files written by NetLogo. Modern versions of NotePad should also accomplish this.)

  3. Open temp.csv with a spreadsheet to see what it looks like.

Export Attribute 2

Randomly set your patch colors, as above. Then:

  1. Carefully delete temp.csv.

  2. Open temp.csv.

  3. Ask each patch to print its pcolor to the file.

  4. Close temp.csv.

  5. Finally, write an exportAgentAttribute procedure that peforms the the preceding steps, all at one go.

  6. Run this procedure (in observer context) from the command line, and examine the resulting file.

Export Summary Statistic

This exercise illustrates how to export a summary statistic at each iteration of the model. For concreteness, this exercise works with the Segregation Model in the NetLogo Models Library.

Export One Number per Iteration

  1. Copy of the Segregation model (from the NetLogo Models Library) as summaryData.nlogo. You will change this new model file.

  2. Create a folder named out below the folder containing your new model file.

  3. Add to the setup procedure code that carefully deletes out/temp.csv. (This allows your to start afresh with each simulation.)

  4. Add to the go procedure code that opens out/temp.csv, writes the current value of percent-similar to a single line of the file, and then closes the output file.

  5. Run the model and then examine the file you created by opening it in a spreadsheet. Close the spreadsheet without saving any changes.

  6. Open out/temp.csv with a text editor to see what it looks like.

The default text editor on OSX is TextEdit; this should work fine. The default text editor on Windows is Notepad; unfortunately, it may not work well. (Older versions will not correctly handle end of lines marked only with a line-feed character, without an preceding carriage-return character.) Windows users may therefore prefer to use WordPad, not NotePad. (In Windows 10, you can look under Start menu » All apps » Windows Accessories » WordPad.) Wordpad will correctly read and display text files with with alternative line-endings.

Export Two Numbers per Iteration

The CSV format is a text file with comma-separated values on each line of the file. NetLogo’s word primitive can easily create a string that hold comma-separated value. E.g.,

(word 1 "," 2)
  1. Move the data-export code in your go procedure (above) into a procedure called exportIterationData. Your go procedure should now call exportIterationData.

  2. Change exportIterationData so that instead of exporting just percent-similar each iteraction, it exports the current value of ticks as well. Each line should contain the current tick, a comma, and the current value of percent-similar.

  3. Run the model and then examine the file you created by opening it in a spreadsheet. Close the spreadsheet without saving any changes.

  4. Open out/temp.csv with a text editor to see what it looks like.

Explorations

Interval Subdivision

Create a function named subdivide to return the points that evenly divide an interval. The inputs are three numbers: the minimum value (\(x_\text{min}\)), the maximum value (\(x_\text{max}\)), and an integer number of intervals (\(n>0\)). The output is a list of \(n + 1\) points that evenly divide the interval \([x_\text{min}..x_\text{max}]\). (Include the endpoints.)

This subdivide function has some utility past this one exercise. So move them into a separate module, called utilities (plus an appropriate filename extension). Feel free to add these to an exiting utilities module, if you already have one. Make sure your function still works when you import it from this module.

Hints:

  1. First think about subdividing the unit interval. Then scale up the interval to the correct length, \(x_\text{max}-x_\text{min}\). Then shift the resulting values by \(x_\text{min}\).

  2. Use NetLogo’s n-values primitive.

Extension: Function Points

The inputs are a function (f) and three numbers: the minimum value (\(x_\text{min}\)), the maximum value (\(x_\text{max}\)), and an integer number of points (\(n>0\)). Produce 101 points from the function graph, where the values in the domain are evenly-spaced over the iterval?

Hints:

  1. Use our subdivide function, created in the interval subdivision exercise.

  2. Use map to produce the \((x,y)\) pairs.

Extension: Plotting Points

Create a plotPoints procedure that creates a plot from a list of points. This has on input argument: a list of lists, we each inner list has length \(2\) and represents the coordinates of a point.

Hints:

  1. Use our subdivide function, created in the interval subdivision exercise.

  2. Use map to produce the \((x,y)\) pairs.

  3. Use foreach and plotxy to plot the points.

  4. Possibly use first and last.

Function Plotting

To make a line chart of a univariate function, we need a function and collection of points from its domain.

  1. Use our subdivide function from the interval subdivision exerices to subdivide the interval \([-1..1]\) into 100 parts. (How many points is that?) Call this list xs.

  2. Treat the resulting points as the domain of the function \(x \mapsto x*x\). Using the foreach and plotxy commands to produce a lineplot of this function over the xs.

Hints:

  1. Use our subdivide function, created in the interval subdivision exercise.

  2. Use foreach and plotxy.

Function Closure

Function closure provides a way for a function to store information about the environment in which it was created—information that affects how the function behaves.

For example, consider our logistic-growth function, \(x \mapsto x + g x (1 - x)\). We are usually interested in working with one particular value of \(g\) at a time, and this in our treatment of \(g\) as a free variable in the function definition. To make use of this function, we require an environment where g is defined. One approach is to code \(g\) as a global variable. A different approach is to create a particular instance of the logistic functions as a function closure in an environment that defines \(g\).

Create a getLogistic function that takes a single argument (the amplitude parameter, and returns a pure function (the logistic-growth function with that particular amplitude parameter).

Function Iteration

Implement a function, nestList, that builds a list by function iteration. This function takes three arguments: a function (f), an initial value (x0), and the number of iterations (n). Begin your work on nestList with the following stub.

to-report nestList [
  #f  ;(task)   : the function to iterate
  #x0 ;(number) : the initial value
  #n  ;(int)    : the number of iterations
  ]
  let _xs (list #x0) ;start with one-item list
  ;build _xs by appending f(x0), f(f(x0)), etc.
  report _xs  ;TODO: bulid list!
end

Here f is a univariate real function, x0 is an initial value, and n is the number of times to repeatedly apply f. This function should return a list of n + 1 items: all the values from x0 to xn.

The first argument of your nestList function is a function. However, NetLogo does not allow you to pass procedures by name. (Other languages, including Python and Mathematica, do allow this.) In order to pass a function as an argument, you must use a NetLogo task. Here is an illustrative example of task creation.

[?x -> ?x * ?x]

In order to run this task, you must use runresult with appropriate parentheses. For details, see the discussion of tasks in the NetLogo Programming appendix.)

  1. Test your nestList function at the command line:

    print nestList [?x -> 2 * ?x] 1 10

    You should get the following answer:

    [1 2 4 8 16 32 64 128 256 512 1024]
  2. Write a testNestList procedure, which implements the above test (and any others you desire).

More Function Iteration

Think about how you would make a cobweb plot in your favorite spreadsheet. (Excel users can look at https://www.youtube.com/watch?v=Fiy9nXJIAVs for ideas.) We are going to make this much easier by writing the needed data in an appropriate format.

  1. Use nestList for a function iteration of the logistic-growth function. Do 10 iterations, using an amplitude parameter of 2.75 and a starting value of 0.4. Export this data in CSV format as logistic-ts.csv.

  2. Open your logistic-ts.csv file in your favorite spreadsheet (e.g., Calc or Excel). Produce a run-sequence plot from this data. Save your spreadsheet graph as a PNG file named logistic275ts.png.

  3. Next, we will produce a cobweb plot. To do that, we take the following step. First, turn our iterated function values [x0,...,x10] into a list of pairs [[x0,x0],...,[x10,x10]]. These can be thought of as points along the 45 degree line. Then apply the following fstepPoints function to this list of points.

    to-report fstepPoints [
      #pts ;(list of lists) : the initial set of points
      ]
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      ;;Report list of lists, all the original `#pts`
      ;;with fsteps between them.  For example, between
      ;;(x0,y0) and (x1,y1) will be (x0,y1).
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      let _pt0 first #pts      ;get the first point
      let _fpts (list _pt0)    ;add the first point to our list
      let _x0 first _pt0
      foreach butfirst #pts [
        [?] ->
        let _fstep fput _x0 butfirst ?   ;create fstep as [x0 y1]
        set _fpts lput _fstep _fpts      ;add the fstep to our list
        set _fpts lput  ? _fpts          ;add the point to our list
        set _x0 first ?
      ]
      report _fpts
    end
    

    Be sure to add extensive comments explaining what fstepPoints does, and how.

  4. Export your cobweb data in CSV format. The path to your new data file should be out/logistic-cw.csv.

  5. Open your logistic-cw.csv file in your favorite spreadsheet (e.g., Calc or Excel). Produce a cobweb plot from this data. Save your spreadsheet graph as a PNG file named logistic275cw.png.

  6. Change g to 2.25 and recreate your plot. Do you observe any changes in behavior? Change r to 2.75 and recreate your plot. Do you observe any changes in behavior? Experiment with other values as well.

  7. Some final refinements: add new global variables for the names of your output files.

    Global Variables

    name (type)

    initial value

    tsfile (string)

    logistic-ts.csv

    cwfile (string)

    logistic-cw.csv

Data Summary: Quartiles

Produced a pure function that takes a list of numbers as its argument and returns a list of five numbers, which is the standard five number summary of a dataset. (Review the concept of quartiles if you need; use Tukey’s method.) Your function should use the following NetLogo primitives: sort, min, max, and median. To produce the first quartle, collect the numbers below the dataset median, and find their median. (And similarly for the third quartle.)

Once you have written your summarize5 function, write a procedure that provides some simple tests that it is working as you expect. For example:

to testSummarize5
  let _d1 [1 2 3 4 5]
  let _s1 summarize5 _d1
  if (_s1 != _d1) [error "incorrect summary"]
end

Data Export

Preliminary Understanding

Despite its simplicity, the family of functions \(x \mapsto k x (1 - x)\) has been very intensively explored. Given \(k \in [0..4]\), this is usually known as the logistic map. (The term map is a synonym for function.) This logistic map is closely related to the logistic-growth function covered in the chapter on Discrete-Time Dynamical Systems. As we will see, the logistic map can generate surprisingly complex outcomes.

First, develop some preliminary understanding by using your favorite spreadsheet. Figure out how to plot the logistic function. As the function domain (i.e., the x values), create 101 even spaced points of the interval \([0,1]\) (including both endpoints). First use an amplitude parameter of 2.75, then experiment with different values of the parameter between 0 and 4.

Next, we are going to programmatically produce the same kind of data and plots. Repeatedly outputting data and recreating plots can be a bit painful. When our simulations run quickly, we may be able to use dynamic plots for more rapid experimentation.

  1. Create a new program file named logistic01 (plus an appropriate filename extension). This program file will hold the code for Part I.

  2. First we need to produce the same x values as we did in the preliminary spreadsheet exercise. We are going to do this by defining a function that produces all of our x values as a single list. Use your subdvide function from the Interval Subdivision exercise above.

  3. Define a pure function named logisticMap as follows. Your function accepts two separate numbers as input arguments, say x and r. It returns one number, the value from the discrete logistic function. (The amplitude parameter will be r.)

    At the command line, test your logisticMap function. If you enter logisticMap 0.5 2.75, do you get 0.6875?

  4. Create a function called getLogisticPoints, which takes one argument (the value of the amplitude parameter) and returns a list of lists. (The inner lists each contain two numbers: an \(x\) coordinate and an associated \(y\) coordinate.) For 101 evenly spaced \(x\) values of the interval [0,1], getLogisticPoints generates \((x,y)\) pairs of the logistic map.

    Your new getLogisticPoints function must call your linspace function. For simplicity, getLogisticPoints will use hard-coded numbers specifying the interval and the number of points. Produce 101 points in the domain, and use your logisticMap function to produce the values of the logistic map over this domain.

    Support getLogisticPoints with a pure function named functionPoints. This should take two arguments: a function, and a list of values in the domain of the function. The returned value should be a list of \((x,y)\) pairs.

  5. Write a procedure named csvExportData that takes two arguments, say pth and pts. The pth argument should be a string, which is the path to the file that you will write to. The pts argument should be a list of lists, where each inner list contains only numbers. The numbers in each inner list should be written as a row of a CSV file.

    Make an out folder below your working directory. You will save your CSV files in this folder.

  6. Use the work you have done to write out data for the logistic map in CSV format. Write 101 points of the logistic map to out/logistic-fn.csv as 101 rows with two comma-separated values per row. Use an amplitude parameter of 2.75. (Put the code for this in an updateFiles procedure.)

  7. Use your favorite spreadsheet to make a simple line plot of the logistic function, using your exported data. Save the chart as logistic275fn.png.

  8. It seems we have two values that could usefully be global variables:

    Global Variables

    name

    type

    initial value

    r

    float

    2.75

    fnfile

    string

    logistic-fn.csv

    Add a setup function to initialize this, and use them where appropriate. (But make sure your pure functions remain pure!)

  9. Change r to 3.25 and recreate your plot. Do you observe any changes in behavior? Change r to 3.75 and recreate your plot. Do you observe any changes in behavior? Experiment with other values as well.

GUI Extensions

  1. Planning ahead, you can also add a 45 degree line during setup. (This is just a line from (0,0) to (1,1).)

  2. To make it easier to plot for a variety of amplitudes, create a helper procedure named plotLogistic that takes one argument, the amplitude parameter, and uses getLogisticPoints and pointsLinePlot to make each line plot.

    Plot the logistic map for a variety of amplitudes. Comment on anything you notice.

NetLogo Details: Logistic I

foreach

http://ccl.northwestern.edu/netlogo/docs/dictionary.html#foreach

file-print

http://ccl.northwestern.edu/netlogo/docs/dictionary.html#file-print

map

http://ccl.northwestern.edu/netlogo/docs/dictionary.html#map

n-values

http://ccl.northwestern.edu/netlogo/docs/dictionary.html#n-values

NetLogo source files

http://ccl.northwestern.edu/netlogo/docs/interface.html#includes

plot identifier

NetLogo charts are identified by the string that is their title.

simple function plot

https://subversion.american.edu/aisaac/notes/netlogoProgramming.xhtml#simple-function-plot

image files from charts

You can copy a NetLogo chart by using its context menu. Copy your cobweb chart and produce a PNG file from it. (Windows users must first paste into another application, such as Paint.) How does this compare with your spreadsheet chart?

GUI Extensions

  1. Turn your LogisticMap plot into a cobweb plot by adding the following:

    • a 45 degree line (i.e., a line from (0,0) to (1,1)); you should add this line in your setupPlots procedure.

    • a plot of the fstep points that you created (i.e., the same values you saved to logistic-cw.csv) The values plotted against both the vertical axis and the horizontal axis will lie between 0 and 1.

    Set up: set the x and y ranges to [0,1.5]. As background for the data plotted, plot a 45-degree line and your logistic function.

Simple Economy

The Simple Economy model is part of the NetLogo Models Library.

Start up the model and read the Info tab. Then look at the setup procedure in the Code tab. Based on this code, predict what the model’s plots will look like at setup. (The first is a dynamic histogram of wealth, and the second is a time-series plot of the wealth held by the top 10% and bottom 50% of wealth holders.)

Set the model up and examine the plots. (You may have to peer at the time-series plot.) Were your predictions correct or not? If not, can you explain why?

Once you understand the initial state, predict how the plots will look after 100 iterations. (Do exactly \(100\) iterations.) Then run \(100\) iteration os the model schedule. Compare your predictions with the outcomes.

Do you think 100 iterations gave you enough information to predict how the model will look after 1000 iterations? Predict, and then run the model for 1000 iterations. (Do exactly \(900\) more iterations.) Compare your predictions with the outcomes.

Do you think 1000 iterations gave you enough information to predict how the model will look after 10000 iterations? Predict, and then run the model for 10000 iterations. (Do exactly \(9000\) more iterations.) Compare your predictions with the outcomes.

How might we measure wealth inequality? Does this model have any implications for how we understand the emergence of wealth inequality in real economies?

Models Library

After mastering this section, you will be able to:

  • find and make use of the Models Library

  • explain the intent and usefulness of the following models in the Models Library: Traffic (Basic), Party, Segregations

First Look: Models Library

File menu items (top left)

  • File > Models Library

  • models have been vetted, except for those marked “unverified”

  • double-click model name or icon to open

  • start with Info tab

    • says what the model does and how to experiment with it

  • Experiment by interacting with GUI, which typically includes

    • sliders (manipulate to set model parameters)

    • buttons

      • Setup (press to set up the simulation)

      • Go (press to run the simulation; press again to stop it)

Basic Models

Experiment with some basic models from the Models Library:

  • Traffic Basic

  • Party

  • Segregation

Quick Load

Hint: you can use the command line to load a model from the Models Library by entering three underscores and (part of) its name. For example, entering ___party will load the party model.

Reload

Enter __reload at the Command Center to reload a model from disk.

This is useful for resetting sliders and other widgets to their original values.

https://github.com/NetLogo/NetLogo/wiki/Unofficial-features

Models Library Example: Traffic Basic

  • File > Models Library > Social Science > Traffic Basic

  • basic illustration of emergence:

    • cars move forwards

    • emergent traffic jams move backwards

Models Library Example: Party

  • File > Models Library > Social Science > Party

  • two “types” of people (e.g., men and women)

    • otherwise indentical (common attributes)

    • crucial parameter: tolerance

  • question: how does tolerance affect group formation?

  • closely related to the Schelling segregation model

Models Library Example: Segregation

  • File > Models Library > Social Science > Segregation

  • Wilenski’s implementation of the Schelling segregation model

    • two types of people (e.g., geeks and jocks)

      • otherwise indentical (common attributes)

      • crucial parameter: percent-similar-wanted

Models Library: Life

Models Library
  • Computer Science > Cellular Automata > Life

use of patches to implement cellular automaton
  • just patches (cells); no turtles

  • cells have two states: alive and dead

    • Dark = cell alive, background color = dead

Transition rule
  • dead cell with 3 or more live neighbors comes to life

  • live cell with 2 live neighbors continues to live

  • live cell with less than 2 live neighbors dies

Models Library: Heat Bugs

  • File > Models Library > Biology > Heatbugs

  • famous biological model

  • each bug radiates a little heat

  • bugs move if they are too hot or cold

Compare to the 'Collectivities' model.

Models Library: Party

Models Library
  • Social Science > Party (famous in another form)

implements the Schelling segregation model
  • two types of people (e.g., men and women)

    • otherwise the same attributes

Key parameter:
  • how “comfortable” are these agents being in a local minoriy

  • adjustable parameter (slider)

Discovery
  • Even a slight preference can lead to complete segregation

Models Library: Small World

  • Models Library » Networks » Small Worlds

  • famous: six degrees of separation

new tools
  • uses links

  • path along links from one agent to another

Setup

initalize links in a ring (each agent links to an agent each side)

key outcome

average path length for all pairs of agents

  • even a few random new links substantially reduces the average path length

  • potentially significant for organizational design

  • potentially significant for disease transmission

Models Library: El Farol

Readings: [garofalo-2006-wp]_, [Wilensky.Rand-2007-JASSS]_

Models Library: Predation

File » Models Library » Biology » Wolf Sheep Predation
  • use of breeds (wolves, sheep)

  • more interesting variant: patches grow grass that sheep eat (click grass? Switch to On)

  • boom-and-bust cycles common (with sheep and wolves negatively correlated)

Models on NetLogo site

  • URL: ccl.northwestern.edu/netlogo/ > Community

  • possible problems if models are written for earlier versions of NetLogo

Models on NetLogo site

Miller & Page Applause Model

http://luis.izqui.org/models/standingovation/

Readings: [miller.page-2004-complexity]_