Getting strings from a list into VID in Red language - list

I am trying to create a panel with dynamically created gui elements:
sentlist: ["A" "B" "C"]
main: function [slist] [
view collect [
keep [below]
repeat i length? slist [
keep[
text slist/i ; THIS STEP IS NOT WORKING
field "" ] ] ] ]
(main sentlist)
A series of strings is sent to the function for putting text labels from it. The GUI window/panel is opening all right but text elements do not have any label on it. Where is the problem and how can it be solved? Thanks for your help.

sentlist: ["A" "B" "C"]
main: function [slist] [
view collect [
keep 'below
repeat i length? slist [
keep compose [text (slist/:i) field "" ]
]
]
]
main sentlist

Related

Netlogo web extension "expected a literal value"

I have a model which is meant to interact with an api using web extension. So after each move, I will send my current location, heading to the API.
This is the code I am using:
to follow-path
let choice web:make-request "http://127.0.0.1:8000/predict_get" "GET" [] []
(ifelse
choice = 0 [
forward 1
]
choice = 1 [
right 90
]
choice = 2 [
left 90
]
; elsecommands
[
stop
])
let data web:make-request "http://127.0.0.1:8000/netlogo" "POST" [["data" (list xcor ycor heading)]] []
end
to move-agent
ask turtle (count turtles - 1) [follow-path]
end
Then when I checked, it said "Expected a literal value" at the list part. How can I post the list of data to the api correctly ?
I think you are struggling with the [[ ]] notation in NetLogo. This notation allows creating lists with only actual values but doesn't work with variables.
I recommend you to test the following explanation in the Command Center for an illustration.
Creating lists with just values:
The following code: show [ [ "name" "john"] ["surname" "doe"] ]
Would print the following outcome: [["name" "john"] ["surname" "doe"]]
This way, you can create lists with literal values. However, you cannot use variables instead of literal values. For example, the following code would give the same error you are seeing in your code:
let name "john"
let surname "doe"
show [ [ "name" name] ["surname" surname] ]
Creating lists with variables
You should use the list primitive in a nested manner to create your arguments for the web:make-request command to solve your problam.
Here's an example usage:
let name "john"
let surname "doe"
show (list (list "name" name) (list "surname" surname))
which would print:
[["name" "john"] ["surname" "doe"]]

Iterate through list to update particular items in the list

How can I update the values in a list for the indices that are equal to everyone in the selected group agents?:
persons-own [
grouped
flockmates
]
to create-trustConnection
set nrPersons count persons
set vector []
repeat nrPersons [set vector 0.4 vector]
end
to updateVector
let alonePersons (count persons with [grouped = false])
set flockmates n-of (random alonePersons) persons
ask flockmates [
foreach vector [ i ->
set item i vector 0.6
]
]
end
You can use the replace-item reporter to update an item in a list.
Let this [ 1 2 3 4 ]
Let new-list replace-item 3 this “a”
Print new-list
Note that this does not affect the original list: it reports a new list with the specified item replaced with the given value.
Changing an item in a list of lists of similar.. but again, the entire list
Of lists is created anew.
But maybe use links?
In the case of using a list for a turtle to track its relationship with other turtles, or of groups, links are useful, and simplify managing those relationships, and enable things that are very difficult with lists.
LINKS are just another kind of agent, specifically for recording a relationship between two turtles. They have a pair of built-in variables, end1 and end2 that refer to those two turtles. The -own variables of the link can be used to record properties of the relationship. Like “anniversary” or “affinity” or whatever! Links can be directional, so the “intimacy” value can be different depending on the “direction” of the relationship.
Directed-link-breed [ relationships relationship]
Relationships-own [ intimacy ]
to setup-all-relationships
Ask protestors
[ setup-relationship ]
End
To setup-relationship
;; link with everyone else
Create-relationships-to other protestor
[ set intimacy .5 ]
End
The relationship between two turtles can be obtained in several ways.
(Link (this turtle) (that turtle))
Refers to the link from this turtle to that turtle.
Out-Link-neighbors is used to get the set of all turtles linked to from this turtle.
You can also use turtles to represent groups, and links to record membership in that group.
In that case, the members of the group are link-neighbors of the group.
While perhaps not a feature of your model, this opens up the possibility of multiple groups and of agents being members of more than one group, or of tracking things like former members.
Here is a complete, minimal reproducible example of what I think you are looking for. Note that one can just paste it into NetLogo and it compiles and runs. I've made some assumptions here - in particular that intimacy is a protesters-own variable, which it was not in the code you provided, but which your textual description seemed to indicate. Again, using who numbers is not a good idea, but that is a different question and answer. If I have time tomorrow, I might be able to provide you with an example of how one might use agentsets, but if intimacy values can vary from agent-pair to agent-pair, then links is really the way to go.
breed [protesters protester]
globals [numberOfProtesters intimacyVector]
protesters-own [
intimacy
partOfGroup ;initially set to false for all agents
myNRelatedProtesters
]
to setup
clear-all
create-protesters 10
create-intimacyRelationship
reset-ticks
end
to create-intimacyRelationship
ask protesters [
set numberOfProtesters count protesters
set intimacy []
repeat numberOfProtesters [set intimacy lput 0.2 intimacy]
set partOfGroup false
]
end
to updateIntimacy
let nrUngroupedProtesters (count protesters with [partOfGroup = false])
let NRelatedProtesters n-of (random nrUngroupedProtesters) protesters
ask NRelatedProtesters [
foreach ([who] of NRelatedProtesters) [ i -> set intimacy replace-item i intimacy 0.8 ]
set partOfGroup true
]
ask NRelatedProtesters [ show intimacy ]
end
to go
let ProportionProtestersInSubgroup (count protesters with [partOfGroup = true])/ numberOfProtesters
ifelse ((count protesters with [partOfGroup = false])/
numberOfProtesters) > ProportionProtestersInSubgroup
[
updateIntimacy
]
[
stop
]
tick
end
Hope this gets you started.

Create accumulative list over time

I want to store values from a variable in a list, adding new variable output for every tick. Lets say the variable outputs a different value every tick. For simplicity this is determined by the formula; 2 * ticks (var = 2 * ticks), thus the list should look something like this after five ticks [0 2 4 6 8]. I cannot get this to work however. Since NetLogo does not allow taking values from the past, how would I go about this?
I now have something like this:
ask turtles[
let var_list [ ]
foreach var_list [
set var_list lput var var_list
]
print var_list
]
This however only gives empty lists or lists only showing the most recent var value (when I change let var_list [] to let var_list [ 0 ]. How can I get it to correctly input the variable value in the table for every tick?
You are using let to create a temporary local variables. There's no problem in retaining values across ticks, but you do need to use global or turtle/patch/link variables.
Here's a complete model to demonstrate
turtles-own [my-list]
to setup
clear-all
create-turtles 1
[ set my-list []
]
reset-ticks
end
to go
ask turtles
[ set my-list fput random 10 my-list
print my-list
]
tick
end

Grouping lists by elements in Netlogo

Let us say I have a model in Netlogo and am now interested in developing a reporter/procedure that groups lists according to their first element.
For the sake of example, let's say
globals[list1 list2 list3 listoflists
ordered-list-a
ordered-list-b
]
to setup
set list1 ["a" "b" "c"]
set list2 ["a" "c" "d"]
set list3 ["b" "a" "c"]
set listoflists (list list1 list2 list3)
end
I want to create a list of lists such that in each list you have lists starting with the same element. Hence, the desired output is
[[["a" "b" "c"]["a" "c" "d"]]["b" "a" "c"]]]
i.e, where the first element aggregates all lists with an a in first place, and the second all those starting with a "b".
Ideally, this should be scalable for a large number. I tried
to create-list
set ordered-list-a []
set ordered-list-b []
(foreach listoflists [[i] ->
if item 0 i = "a" [set ordered-list-a lput i ordered-list-a]
if item 0 i = "b" [set ordered-list-b lput i ordered-list-b]
])
end
and then creating a list from a and b, which does the trick, but a) it's incredibly messy, b) requires that I know beforehand the length of the list, which I don't in the real case (it's a turtle procedure) and c) it seems like a lot of unnecessary coding.
Is there some way to extend the procedure above to any number of starting elements (maybe inside a while cycle?) and does not require the creation of a list for each initial list element?
Many thanks
I'm assuming the desired output is supposed to be: [[["a" "b" "c"]["a" "c" "d"]][["b" "a" "c"]]]. I believe you were missing a [ before the second group.
Anyway, a simple, but somewhat inefficient way would be:
; items is a list of items to be grouped
; key is an anonymous reporter that extracts the group label from a single item
to-report group-by [ items key ]
let keys remove-duplicates map key items
report map [ k -> filter [ x -> (runresult key x) = k ] items ] keys
end
Note that the above is a completely generalized grouping function. To use it in your case, you would do:
group-by listoflists [ l -> first l ]
A more efficient way would be to use the table:group-items reporter from the table extension.
table:group-items listoflists [ l -> first l ]

NETLOGO: adding lists of agents' attributes to a list of lists

Hello I am using Netlogo and I am trying to create a list of lists in which every sublist is a couple of agents' attributes. In particular I declare the list as a global variable and I initialize it to an empty list. Then I ask every agent to add a list of their attribute_1 and attribute_2 to the main list. Like this:
globals[mainlist]
set mainlist []
ask agents[
set mainlist sentence [mainlist] [attribute_1 attribute_2 ]
]
This should create a new list composed by the previous mainlist and the list [attribute_1 attribute_2].
Unfortunately this doesn't work and I get the error: EXPECTED LITERAL VALUE referring to "mainlist".
How should I write my code to create my list of lists in the correct way?
Tyr's answer is technically correct, but I would like to suggest a more netlogoish way to do it. Usually, in NetLogo, you don't have to build lists one element at a time. If you find yourself doing that, you might want to stop and try to approach the problem differently.
In this particular case, you can simply take advantage of the of primitive:
[ (list attribute_1 attribute_2) ] of agents
Here is a fully working example:
breed [agents an-agent]
agents-own [attribute_1 attribute_2]
globals [mainlist]
to setup
clear-all
create-agents 10 [
set attribute_1 random 10
set attribute_2 random 10
]
set mainlist [ (list attribute_1 attribute_2) ] of agents
print mainlist
end
You can use lput or fput to add further elements to a list (lput will add the new list item at the end (l=last), whereas fput will add the new item at front (f=first)).
Additionally, you have to use the (list ... ...) primitive instead of [ ] brackets when you want to store variables in a list (brackets only work with constants).
Here is a working example:
globals[mainlist]
to test
ask n-of 20 patches [sprout 1]
set mainlist []
ask turtles
[
set mainlist lput (list xcor ycor) mainlist
]
print mainlist
end