Coding Seasons

139 views
Skip to first unread message

Laura

unread,
Nov 2, 2021, 12:39:59 PM11/2/21
to netlogo-users
I could really use some code advice. 
I want to code a 365 day year where 1/2 of the year, cows eat the meadow, or the "summer" and the other 1/2 of the year, the grass regrows because cows are fed hay, or the "winter".

I am trying to look at sustainability of the cow population and whether the grass would replenish itself enough in the winter to support cows for another summer, and what amount of cows could fatten up on summer grazing to survive the winter on just hay.

I want to run the model for 5 years to see if the cows survive and the grass replenishes. 

One tick is a day, 365 days to a year.

Some ideas I have are

To setup
set cycle = 365 ticks
set summer = 365 / 2 ticks
set winter = 365 / 2 ticks
ifelse summer [eat-grass]
[regrow-grass]
if cycle >= 365 * 5 ticks
stop

It doesn't seem to be going in turn though, i.e. summer  to winter to summer to winter. 

Anyone got some ideas?

Swannack, Todd M CIV USARMY CEERD-EL (USA)

unread,
Nov 2, 2021, 2:07:26 PM11/2/21
to Laura, netlogo-users

Hi Laura,

 

Do you have a counter in your code that resets the day of year value to 1 on January 1st each year? If not, that should do the trick. Here is some example code

 

Globals [day]

 

To setup

Set day 1

End

 

to go

 

<model actions>

Ifelse day <=365[

[Set day day + 1]

[set day 1]

 

End

 

If you do, could you please paste the rest of the code so we can take a look at it?

--
You received this message because you are subscribed to the Google Groups "netlogo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netlogo-users/b4b065cb-a159-4c6d-9bcf-e53d6312661an%40googlegroups.com.

Laura Lazorski

unread,
Nov 2, 2021, 2:15:49 PM11/2/21
to Swannack, Todd M CIV USARMY CEERD-EL (USA), netlogo-users
Well our code right now is a bit cumbersome. I am trying to find a more elegant way of differentiating, and if we want to look at more season past 5 years (or 10 seasons) we can change one number instead of adding another season bracket and iteration of x + 182.5.

Under To setup we've set season to 0, and the following is under to go:

to go
 if not any? turtles [stop]

 ; if it's summer, let the cows eat
 ifelse (season = 0) or (season = 2) or (season = 4) or (season = 6) or (season = 8)
 [
    ;show season
    ask turtles [
      move-cows
      check-if-dead
      eat-grass
    ]
 ]
 [
  ;show season
  ; winter season
  regrow-grass
  ask turtles [
   live-through-winter
   check-if-dead
  ]
 ]

 (ifelse
  ticks = 182.5 [
   set season 1
  ]
  ticks = 365 [
   set season 2
  ]
  ticks = 547.5 [
   set season 3
  ]
  ticks = 730 [
   set season 4
  ]
  ticks = 912.5 [
   set season 5
  ]
  ticks = 1095 [
   set season 6
  ]
  ticks = 1277.5 [
   set season 7
  ]
  ticks = 1460 [
   set season 8
  ]
  ticks = 1642.5 [
   set season 9
  ]
  ticks = 1825 [
   stop
  ]
 )
 tick
end
--
Thank You, 

L. Lazorski

Innovation & Intellectual Property
Research & Graduate Studies



James Steiner

unread,
Nov 2, 2021, 10:52:18 PM11/2/21
to netlogo-users


---------- Forwarded message ---------
From: James Steiner <grego...@gmail.com>
Date: Tue, Nov 2, 2021 at 10:51 PM
Subject: Re: [EEMSG-SPAM: Suspect] [Non-DoD Source] [netlogo-users] Coding Seasons
To: Laura Lazorski <lazo...@pdx.edu>



    ;; do season-specific stuff
    (if-else 
        ( season-number = 0 ) [ go-spring ]
        ( season-number = 1 )  [ go-summer ]
        ( season-number = 2 ) [ go-winter ]
        ( season-number = 3 ) [ go-fall ]
    ) 
  

So, I just wanted to ask this…

Looks pretty good. Would it be better as an array of tasks…er… I mean stored anonymous procedures?

Like 
;; in setup, day-to-day is global
Set day-to-day (list
[ -> do-spring-day ]
[ -> do-summer-day ]
[ -> do-fall-day ]
[ -> do-winter-day ]
)

;; in go… season is the number 0..3
Set season floor ( day-of-year / ( 365 / 4))
Run item season day-to-day

No less code, probably same or worse execution speed, but pretty cool. 

Yay? Nay?

~~James. 





Swannack, Todd M CIV USARMY CEERD-EL (USA)

unread,
Nov 3, 2021, 10:19:11 AM11/3/21
to Laura Lazorski, netlogo-users

Hi Laura,

 

I’d approach this by creating a calendar procedure where you define the day of year and the season. This will make it generic, so you don’t have to keep adding numbers to your season bracket. Then, you call your calendar procedure in your go procedure. I’ve written an example below

 

Globals[day eating-season?]

 

To setup

Set day 0

End

 

To calendar

Set day day + 1

If day >= 366 set day 1

 

;define eating season

Ifelse day >= 50 and day <= 182 ;determines when the eating season is

[set eating-season? TRUE] ;if it’s eating season, then this variable is set to TRUE

[set eating-season? FALSE] if it’s not the eating season, then this variable is set to FALSE

 

 

End ;to calendar

 

To go

Calendar ;calls calendar procedure

 

Ifelse eating-season?

[ask turtles [  ;procedures called during the summer
      move-cows
      check-if-dead
      eat-grass
    ]
]

[regrow-grass   ;[procedures called during the winter
  ask turtles [
   live-through-winter
   check-if-dead
  ]

]

Tick

 

 

End ;to go

Image removed by sender.

 

 

--
You received this message because you are subscribed to the Google Groups "netlogo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-user...@googlegroups.com.

Michael Tamillow

unread,
Nov 3, 2021, 10:46:43 AM11/3/21
to Swannack, Todd M CIV USARMY CEERD-EL (USA), Laura Lazorski, netlogo-users
You are right. This is not good:

 (ifelse
  ticks = 182.5 [
.......
  ticks = 1825 [
   stop

use modulo instead:

season = (ticks / 365) % 1 

The first quarter (0-.25) is season one next quarter, 0.25 - 0.5, etc, etc.

Any time you have a cycle that goes on to infinity you should use modulo - that or a trigonometric function.

James Steiner

unread,
Nov 3, 2021, 10:49:48 AM11/3/21
to netlogo-users
Sorry, folks, I accidentally sent this only to Laura directly yesterday. 

——-

You will be able to make use of some math things that will help you.

# 1 is the MOD reporter. MOD is short for "modulus." It is a weird function that does a division, but gives you the remainder.  Look it up. So useful.
# 2 is the FLOOR reporter to turn decimal results into plain numbers.

If you do DAYS mod 365 you will always get a value between 0 and 364.
    
    let day-of-year  days mod 365

If you do FLOOR (day-of-year / (365 / 4) ) you get a number from 0 to 3

    let season-number  floor (day-of-year / (365 / 4)) 

That's your season number... but wait:

   let season-name item season-number [ "spring" "summer" "fall" "winter" ]

That's how you get your season names.

And then there is more.

Put your seasonal activities in reporters. like "go-summer", then you can run your seasons like this:

to go
    set day tick
    set day-of-year day mod 360
    set season floor (day-of-year / 90)
    ;; do season-specific stuff
    (if-else 
        ( season-number = 0 ) [ go-spring ]
        ( season-number = 1 )  [ go-summer ]
        ( season-number = 2 ) [ go-winter ]
        ( season-number = 3 ) [ go-fall ]
    ) 
   tick
end

Finally, it looks like you are trying to run the whole season at once? Think if each run through go as a single day, so your other procedures only have to handle a single day. To get a year, you just run GO 365 times.


Steve Railsback

unread,
Nov 3, 2021, 3:28:17 PM11/3/21
to netlogo-users
Once again, the new time extention bundled with NetLogo makes this easy. You can:

- Create a global variable for the date and initialize it for your first simulation date, in setup:
 set sim-date time:create "2020/01/01"

- Also in setup, connect that variable to the tick counter so one tick equals one day (or week, etc.)
set sim-date time:anchor-to-ticks 1 "days"

Now, every time your go procedure executes "tick", the value of sim-date automatically advances by one day.

Then one way to identify seasons is by day-of-year (the Julian date, which is 1 on January 1, etc.):

let day-of-year time:get "dayofyear" sim-date
if-else 
        ( day-of-year < day-spring-starts ) [ go-winter ]
        ( day-of-year < day-summer-starts ) [ go-spring ]
        ( day-of-year < day-fall-starts ) [ go-summer ]
        ( day-of-year < day-winter-starts ) [ go-fall ]
        ( true ) [ go-winter ]

(Note that sim-date automatically includes leap days.)

You can get the current date via:
show (time:show sim-date "yyyy-MM-dd")

loveth atansi

unread,
Nov 10, 2021, 1:37:16 PM11/10/21
to netlogo-users
Hi Everyone,
how do you restrict the movement of about 20 turtles to the center of the patch/environment?

James Steiner

unread,
Nov 10, 2021, 2:51:07 PM11/10/21
to netlogo-users
On Wed, Nov 10, 2021 at 1:37 PM loveth atansi <latan...@gmail.com> wrote:
Hi Everyone,
how do you restrict the movement of about 20 turtles to the center of the patch/environment?

Ask n-of 20 turtles [ home ]

They will be restricted to the center (patch 0 0)

Is that not what you meant?

LOL this is probably not what you meant. You have to give more information about your model and what you want to happen. 

Step one is to describe what you want to happen in human language. Be detailed. Don’t worry about code or turtles or how it’s done in NetLogo.  Just talk about it like it’s a game or a story. What are the rules of the game? What happens in the story?

“There are cows in several distinct pastures. The pasture is fenced. There is grass on the ground. There is a water trough in the center of each pasture. Every minute, during daylight, a cow may decide to do nothing, eat grass, drink water, shove another cow, or move 6 feet to a new spot. if it is full and not thirsty, it moves to be closer to other cows. If thirsty, if moves toward the water, or drinks if at the water. If hungry, it eats if there is grass, or moves to another spot, preferring a spot with grass. Cows will not usually move to a spot that has another cow, on it. If there is no empty spot, the cow does nothing, unless it is very thirsty or was shoved. then it will move to a spot with a cow on it and shove that cow to encourage to move. If a cow is shoved by too many other cows it dies. A cow can not cross a fence. When a cow is at a fence, it can only move along or away from the fence. A live cow will ignore a dead cow, but if a spot has more than 1 dead cow on it, no cow will cross that spot”

Once you can describe your model this way, it becomes easier to turn it into code, or to ask for help. 

Where are the turtles?
Which turtles are moving?
How do they move when not restricted?
How do you define “the center”
How do you define “not in the center”
What do you want them to do to prevent  or respond to violating the restriction?

You can use a rule based on 

distance from some patch, other turtle, or coordinate

a defined area of patches 

the condition of patches

A defined border of patches or turtles

A geometric are

And so on…

Looking forward to your revised question. 

—James
Turtlezero on stack overflow  

Michael Tamillow

unread,
Nov 10, 2021, 3:12:35 PM11/10/21
to James Steiner, netlogo-users
You are too nice, James!

I was going to advise not to pick the turtles up. My son tried that and it peed all over him.

Sent from my iPhone

On Nov 10, 2021, at 1:51 PM, James Steiner <grego...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "netlogo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-user...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages