Netlogo Land-use change model: foreach list command - iterator

I have made a code for a land use change model but one part does not work properly. I'm not very experienced with Netlogo and and can't manage to find my mistake(s).
problem:
the foreach part will not work although I copied it from the NETLOGO dictionary.
Netlogo dictionary (http://ccl.northwestern.edu/netlogo/docs/dict/foreach.html) gives:
(foreach list (turtle 1) (turtle 2) [3 4]
[ [the-turtle num-steps] -> ask the-turtle [ fd num-steps ] ])
;; turtle 1 moves forward 3 patches
;; turtle 2 moves forward 4 patches
I re-wrote this to my own models needs but Netlogo then reports " expected an anonymous command here, rather than a list or block"
my code:
to go
;; Sets Willingness to change true if patches are with more fellow patches than the scenario describes
(foreach list (Land-use = 1) (Land-use = 2) (Land-use = 3) (Land-use = 4) (Land-use = 5) (Land-use = 6) (Land-use = 7) [Senario1N Senario1L Senario1A Senario1B Senario1I Senario1R Senario1W]
[ [the-Land-use the-Scenario] - > ask patches [if count patches with [the-Land-use] > the-Scenario [ set Willingstochange True ] ] ])
;; Gives a score to atractivenesstochangein based on the ratio patches vs scenario
(foreach list (Land-use = 1) (Land-use = 2) (Land-use = 3) (Land-use = 4) (Land-use = 5) (Land-use = 6) (Land-use = 7) [Senario1N Senario1L Senario1A Senario1B Senario1I Senario1R Senario1W]
[ [the-Land-use the-Scenario] - > set atractivenesstochangein (count patches with [the-Land-use]/the-Scenario) ]
end
But also when I use the exact Netlogo dictionary example Netlogo reports the same problem

There are multiple problems with this code. StackOverflow procedure is that you ask a separate question for each error that you are trying to fix. But this is more than just a procedure to assist other people trying to find answers to their problems, it is also related to good programming practice.
You need to code much more gradually. Write a piece of code, test it does what you want, fix it, then move on only once it works properly. It is much more difficult to debug when you have added a lot of code because it is no longer easy to work out where the error was introduced. This is even more important in NetLogo, where the interactions between elements can lead to subtle errors.
Having said that, I can at least identify some syntax problems.
1/ I have no idea what you mean by the 'iterations' part
2/ change procedure
ask patches [set Land-use (Land-use of Atractiveneigbor]
should be
ask patches [set Land-use ([Land-use] of Atractiveneigbor]
3/ setup-patches
Not sure, but I suspect this is about the ordering in your setup procedure. You run the load-gis procedure later than the setup-patches procedure. Your load-gis procedure starts with a clear-all command, which deletes everything you have already done.

Related

Netlogo - Turtles on more than one Patch - Item vs Who

How are you? I guess there is no way to visually represent in the Netlogo Interface a system with a "many-to-many" relationship, where turtles belong to more than one patch, and of course patches host more than one turtle. Correct?
I have a model where Banks (my turtles) operate on more than one Country (my patches). So I think my only option is to have two breeds of turtles, i.e. Banks and Countries, and connect Banks to Countries with link agents. Correct?
(I will also need interbank links, so I will need to set up a different breed of links. Correct?)
Now: I need to identify countries by name (i.e. Italy, France, Spain, etc.). I am reading a CSV file with country names and feeding it into a Netlogo list, but I am not sure how to have a country agent "be" a name. I created a country breed-specific variable called "country-name", and I am trying to use "item" to sequentially access each next name in the list of country names and assign it to the country-name variable of the next country agent in the Countries breed. However, I cannot relate "item" to "who" here, because "who" is not breed-specific. So I am thinking of setting up a separate breed-specific numbered index, but something like this has been asked in a previous question (trying to create a sequential ID variable for breeds in netlogo) and it was strongly suggested NOT to do so. Any suggestions on how to proceed?
I agree with the comment by Matteo. That said,
You don't ever need to use "who". Identify your banks and your countries with a "name" field that the breed owns. For example
banks-own [ name ]
counties-own [ name ]
;; then somewhere in your loop as you read them in...
create-banks 1 [ set name "Chase" ... ]
create-countries 1 [ set name "England" ...]
Below I use 'one-of' but there will only be one hit.
This makes the syntax work converting a list item to a specific turtle.
You never should need to know or care about the "who" value of a bank
or country.
to make-branches
;; read this list in from a csv file, etc. or hard code it
set branchlist [[ "Lloyds" "England"] ["Lloyds" "France"] [ "Chase" "USA"]["Chase" "France" ]]
;; then work the list. Again, you never need "who".
foreach branchlist [
z -> ask one-of banks with [name = item 0 z ]
[ create-link-with one-of countries with [ name = item 1 z ]]
]
end

Trying to build a PC (counter) for the nand2tetris , but I'm having some trouble with the logic

The project aims to build a program counter.
The description are as follows:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/03/a/PC.hdl
/**
* A 16-bit counter with load and reset control bits.
* if (reset[t] == 1) out[t+1] = 0
* else if (load[t] == 1) out[t+1] = in[t]
* else if (inc[t] == 1) out[t+1] = out[t] + 1 (integer addition)
* else out[t+1] = out[t]
*/
I figured out all the possibilities as follows
All possible output
Then here I go:
CHIP PC
{
IN in[16],load,inc,reset;
OUT out[16];
PARTS:
// Put your code here:
Register(in=in, load=true, out=thein);
Register(in=in, load=false, out=theout);
Inc16(in=theout, out=forinc);
Register(in=forinc, load=true, out=theinc);
Mux8Way16(a=theout, b=false, c=theinc, d=false, e=thein, f=false, g=thein, h=false, sel[2]=load, sel[1]=inc, sel[0]=reset, out=out);
}
I tried many times but all failed when the clock load to time 1+ or something like this.
Since the register defined here is out(t+1) = out(t)
what is the output of time ?+.I found it really annoying.
Any suggestions will be appreciated.
Some observations:
You're storing the output in a register, which is good. However, note that the register output is also one of your inputs -- it is out[t].
You don't need a big Mux8Way16. There are 4 possible different outputs, so you can either use multiple Mux16s in a cascade or (extra credit) a single Mux4Way16 with some extra logic to compute the two selection bits.
I usually found that the simplest way to do things was first compute all the possible outputs (in this case, 0, input, register+1 or register) and then have the logic to decide which one of those actually gets output.
Good luck. You are very close.

Setting Qtile Margins Dynamically Through Keyboard Input

I'm looking to set up keybindings to increase/decrease gaps and margins in Qtile similar to what the following does in i3-gaps:
bindsym $mod+equal gaps inner current plus 5
bindsym $mod+minus gaps inner current minus 5
bindsym $mod+Shift+equal gaps outer current plus 5
bindsym $mod+Shift+minus gaps outer current minus 5
I can somewhat get the equivalent of outer-gaps to work with the following code:
def increase_gap(qtile):
qtile.screens[0].top.size = screens[0].top.size+5
qtile.screens[0].right.size = screens[0].top.size+5
qtile.screens[0].left.size = screens[0].top.size+5
#margs = screens[0].bottom.margin
screens[0].bottom.margin[0] = screens[0].bottom.margin[0]+5
screens[0].bottom.size=20
qtile.screens[0].cmd_resize()
def decrease_gap(qtile):
qtile.screens[0].top.size = max(screens[0].top.size-5, 0)
qtile.screens[0].right.size = max(screens[0].top.size-5, 0)
qtile.screens[0].left.size = max(screens[0].top.size-5, 0)
#margs = screens[0].bottom.margin
screens[0].bottom.margin[0] = max(screens[0].bottom.margin[0]-5, 0)
screens[0].bottom.size=20
qtile.screens[0].cmd_resize()
Key([mod, "shift"], "equal", lazy.function(increase_gap), desc="Increase gap"),
Key([mod, "shift"], "minus", lazy.function(decrease_gap), desc="Decrease gap"),
I'm not sure this is the right way to do things, though. I'm not sure if this is supposed to be manipulated this way. I'm not really sure that the cmd_resize() function is what I should be using, however from trial and error it's what I've found to work. I'm not sure why the screen[0].bottom.size=20 (20 is the size of my bottom bar. I know I shouldn't hardcode, but I'm trying to produce a proof of concept before I clean the code) is needed, but the bar starts floating if I don't have that there. Finally, increasing and decreasing the gap gets close, but not quite to the original configuration. The gaps look slightly different than the original. So, I'm not sure this is the right way to accomplish this, and I could use the advice.
Secondly, though that gets close to accomplishing what I want on the outer gaps, I have not been able to make any headway to getting the inner gaps to work. I initially tried changing the margin parameter of a layout, and when that didn't work I tried simply initializing a new layout and replacing the old one as posted below, but neither approach worked.
def column_increase_margin(qtile):
current_margin = current_margin + 5
layouts[0] = layout.Columns(border_focus_stack='#d75f5f', margin=current_margin, border_width=0)
screens[0].bottom.size=20
qtile.screens[0].cmd_resize()
I've tried going through the code here, but it's a big project and I'm struggling to make heads or tails from it.
Any advice would be appreciated.
If I understand what you want, you can add the following to the Layout class in libqtile/layout/base.py:
def cmd_increase_margin(self):
self.margin += 10
self.group.layout_all()
def cmd_decrease_margin(self):
new_margin = self.margin - 10
if new_margin < 0:
new_margin = 0
self.margin = new_margin
self.group.layout_all()
You can then add some keys in your config.py to increase and decrease margins. e.g.
KeyChord([mod], "m", [
Key([], "Up", lazy.layout.increase_margin()),
Key([], "Down", lazy.layout.decrease_margin())
],
mode="Margins"
),
I'm new to qtile, so maybe there is something wrong with the above approach, but it seems to work.

Moving parameters for variable to set up - model behaviour changes

This one stumping me...
I have an ABM which generates new patients arriving to a hospital unit by random-poisson on a single patch (spout procedure). Each patient is assigned an area to go to and a time to spend in the unit according to the area and other assigned variables. When I created this with the distributions embedded in the procedures or reporters it worked fine every time, but when I code the random variables into the set up to make it easier to manipulate it regularly generates grossly abnormally low/high values (ranges not seen when run in original format) and sometimes the creation of new patients doesn't happen at all though the model still ticks on... The only things changed are the placement of the variables in set up and and not in the body of the code.
I can't figure out why it would randomly have no patients entering the system which makes me mistrusting of anything else it generates. Is this just a formatting style that Netlogo doesn't like? Or am I missing something?
Thanks for any advice/help in solving this one
original code:
if ticks = 1000 [stop]
ask arrivals
[
assess
crowding-check
relocate
]
end
to assess
sprout-patients random-poisson 1.5
[set time_arrived ticks
set condition random-float 1.0
set NEWS2 random-float 7.0
set shape "person"
]
end
to-report AEC_treatment_time ;; gamma dist
let result random-gamma 3.478 0.525
if result < 2 [ report 2 ]
if result > 20 [ report 20]
report result
end
to-report AMU_treatment_time ; gamma dist
let result random-gamma 5.7716 0.3
if result < 4 [ report 4]
if result > 48 [ report 48]
report result
end
new code:
ca
set new-patients random-poisson 1.5
set AEC-los random-gamma 3.478 0.525
set AMU-los random-gamma 5.7716 0.3
reset-ticks
end
to go
if ticks = 1000 [stop]
ask arrivals
[
sprout-patients new-patients
assess
crowding-check
relocate
]
end
to assess
ask patients-here
[set time_arrived ticks
set condition random-float 1.0
set NEWS2 random-float 7.0
set shape "person"
]
end
...
to-report AEC_treatment_time ;; gamma dist
let los-AEC AEC-los
if los-AEC < 2 [ report 2 ]
if los-AEC > 20 [ report 20]
report los-AEC
end
to-report AMU_treatment_time ; gamma dist ;; reports treatment time for patients in AMU
let los-AMU AMU-los
if los-AMU < 4 [ report 4]
if los-AMU > 48 [ report 48]
report los-AMU
end
ps trying multiple iterations, it seems to be the random-poisson change that is the one causing the issues
It's pretty hard to see without the full code as it looks to be a problem with the way procedures connect, but your new structure has ask patients-here (at the start of the assess procedure) inside a loop through ask arrivals (go procedure). Is arrivals a breed?
Generally it is a bad thing to have nested ask turtles type structures because each turtle ask all turtles that satisfy the conditions so you can get subtle errors. Anyway, this will probably get you back to what you were doing before:
to go
if ticks = 1000 [stop]
ask arrivals
[ sprout-patients new-patients [assess]
crowding-check
relocate
]
end
to assess
set time_arrived ticks
set condition random-float 1.0
set NEWS2 random-float 7.0
set shape "person"
end
This structure makes the assess procedure into a procedure that runs from the turtle's perspective (or context) and has it run immediately as the turtle calling it is created.

pseudo randomization in loop PsychoPy

I know other people have asked similar questions in past but I am still stuck on how to solve the problem and was hoping someone could offer some help. Using PsychoPy, I would like to present different images, specifically 16 emotional trials, 16 neutral trials and 16 face trials. I would like to pseudo randomize the loop such that there would not be more than 2 consecutive emotional trials. I created the experiment in Builder but compiled a script after reading through previous posts on pseudo randomization.
I have read the previous posts that suggest creating randomized excel files and using those, but considering how many trials I have, I think that would be too many and was hoping for some help with coding. I have tried to implement and tweak some of the code that has been posted for my experiment, but to no avail.
Does anyone have any advice for my situation?
Thank you,
Rae
Here's an approach that will always converge very quickly, given that you have 16 of each type and only reject runs of more than two emotion trials. #brittUWaterloo's suggestion to generate trials offline is very good--this what I do myself typically. (I like to have a small number of random orders, do them forward for some subjects and backwards for others, and prescreen them to make sure there are no weird or unintended juxtapositions.) But the algorithm below is certainly safe enough to do within an experiment if you prefer.
This first example assumes that you can represent a given trial using a string, such as 'e' for an emotion trial, 'n' neutral, 'f' face. This would work with 'emo', 'neut', 'face' as well, not just single letters, just change eee to emoemoemo in the code:
import random
trials = ['e'] * 16 + ['n'] * 16 + ['f'] * 16
while 'eee' in ''.join(trials):
random.shuffle(trials)
print trials
Here's a more general way of doing it, where the trial codes are not restricted to be strings (although they are strings here for illustration):
import random
def run_of_3(trials, obj):
# detect if there's a run of at least 3 objects 'obj'
for i in range(2, len(trials)):
if trials[i-2: i+1] == [obj] * 3:
return True
return False
tr = ['e'] * 16 + ['n'] * 16 + ['f'] * 16
while run_of_3(tr, 'e'):
random.shuffle(tr)
print tr
Edit: To create a PsychoPy-style conditions file from the trial list, just write the values into a file like this:
with open('emo_neu_face.csv', 'wb') as f:
f.write('stim\n') # this is a 'header' row
f.write('\n'.join(tr)) # these are the values
Then you can use that as a conditions file in a Builder loop in the regular way. You could also open this in Excel, and so on.
This is not quite right, but hopefully will give you some ideas. I think you could occassionally get caught in an infinite cycle in the elif statement if the last three items ended up the same, but you could add some sort of a counter there. In any case this shows a strategy you could adapt. Rather than put this in the experimental code, I would generate the trial sequence separately at the command line, and then save a successful output as a list in the experimental code to show to all participants, and know things wouldn't crash during an actual run.
import random as r
#making some dummy data
abc = ['f']*10 + ['e']*10 + ['d']*10
def f (l1,l2):
#just looking at the output to see how it works; can delete
print "l1 = " + str(l1)
print l2
if not l2:
#checks if second list is empty, if so, we are done
out = list(l1)
elif (l1[-1] == l1[-2] and l1[-1] == l2[0]):
#shuffling changes list in place, have to copy it to use it
r.shuffle(l2)
t = list(l2)
f (l1,t)
else:
print "i am here"
l1.append(l2.pop(0))
f(l1,l2)
return l1
You would then run it with something like newlist = f(abc[0:2],abc[2:-1])