Netlogo - default value for turtle variable - default-value

Can I define a default value for variables that turtles own
for example:
turtle-owns[variable1 (default-value true)]

As far as I know it's not possible to define default values via the turtle-owns statement. Here is a workaround I use:
I create another procedure with all turtle-variables I want to define when a new turtle enters the world:
to setup
...
crt 1 [turtle.config]
...
end
to turtle.config
setxy ...
set color ...
set var1 ...
set var2 ...
....
end

Related

Terraform: Set optional resource attribute if condition is met, otherwise don't declare it

Some resources on Terraform support optional attributes. I'm interested in declaring and setting a value for the optional attribute only if a condition is met. Otherwise, don't declare it at all.
All of the suggestions I found was based on declaring the attribute and setting its value to null if the condition isn't satisfied, instead of not declaring the attribute at all.
Is there a way for me to do something like the following? In pseudo-code:
resource "some_resource" "this" {
name = var.name
if var.name == "some_name":
some_optional_attribute = "some_value"
else:
pass # do nothing, don't even declare the optional attribute
}
Let me know, thanks in advance!
I don't believe there is a better method than simply doing the following:
resource "some_resource" "this" {
some_optional_attribute = var.name == "some_name" ? var.name : null
}
When you declare attribute as null that basically means that it is not being used. The above in my opinion is equivalent to your if statement.

Make old and new variables backward compatible

v1- old var, v2 - new var.. Currently if anyone sets v1 it will error out so I am making it backward compataible. So if old var v1 is defined anywhere I want to make those 2 variables the same i.e v2 = v1 (Also value of v1 should be in v2)
set v1 test
For this I have a hash with old and new names
set oldvars(v1) v2
foreach ele [array names oldvars] {
if {([info exists ele] || $ele == "") && $oldvars($ele)!= ""} {
o2n $ele $oldvars($ele) //o2n is a proc defined below
}
}
proc o2n {gvar gval}
global v1
puts "gvar is $gvar, gval is $gval" //prints gvar - v1 and gval - v2
set $gval [set $$gvar] **//Error - Cant read $v1 no such variable. Above line does print gvar = v1 so $$gvar should be $v1 =test**
puts "$gval [set $gvar]" // Has the value of v1 i.e test
}
puts "v2 is $v2" **: Error : Can't read v2 no such variable**
If we assume
set a1 1
set b1 2
set c1 3
set oldvars(a1) a2
set oldvars(b1) b2
set oldvars(c1) c2
All you have to do to copy values from x1 variables to corresponding x2 variables is
foreach {x1 x2} [array get oldvars] {
set $x2 [set $x1]
}
The assignment looks a little off, but what it means is ”assign to the variable whose name is in x2 the value of the variable whose name is in x1.
If you want to do this via a procedure, you need to take into account that the procedure’s code executes in another scope. The uplevel command helps with that, and as a sideeffect the assignment code becomes simpler:
proc o2n {x1 x2} {
upvar 1 $x1 v1 $x2 v2
set v2 $v1
}
foreach {x1 x2} [array get oldvars] {
o2n $x1 $x2
}
Checking existence
If you keep references to variables in the form of variables that store those variables’ names, testing for existence also looks different from the usual. If you have
foreach ele [array names oldvars] {
the variable ele is guaranteed to exist (it is created by foreach as long as the list isn’t empty – but then the body of foreach won’t be executed anyway), but it isn’t the variable you wanted to verify: it only holds the name of the variable you wanted to verify. So you’ll need to write the test like this:
info exists $ele
(you also need to be in the same scope where the variable referenced by ele exists).
This looks very strange since we usually are very careful to verify the name of the variable, not the value. But in this case the value of the variable is the name we want to verify, so.
Inside the procedure it’s easier to write the test. The upvar command creates names in the current scopes that are linked to variables in another scope. If those variables don’t exist, the local names will in effect be names of unset variables.
upvar 1 $x1 v1 $x2 v2
if {[info exists v1]} {
Documentation:
array,
foreach,
if,
info,
proc,
set,
upvar

Robot framework: variable function with dictionary arguments

I have a variable file which defines a variable like dictionary in dictionary and variable functions.
global.py
DEFAULT_VAL=111
TEST_VAR={'key1':{'elem1':'val1', 'elem2':'val2', 'elem3':'val3'}, 'key2':{'elem2':'val2', 'elem3':'val3'}}
def get_elem1_or_default_1(key):
return TEST_VAR[key]['elem1'] if 'elem1' in TEST_VAR[key] else DEFAULT_VAL
def get_elem1_or_default_2(key_dict):
return key_dict['elem1'] if 'elem1' in key_dict else DEFAULT_VAL
From robot I can call variable function 'get_elem1_or_default_1' which accept string as key, like this:
*** Settings ***
Variables Global.py
${var} Set variable ${get_elem1_or_default_1('key2')}
INFO : ${var} = 111
But when I try to call another function 'get_elem1_or_default_2' which accept dict as argument I get an error
${key_dict} Evaluate ${TEST_VAR}['key1']
${var} Set variable ${get_elem1_or_default_2(${key_dict})}
INFO : ${key_dict} = {'elem2': 'val2', 'elem3': 'val3', 'elem1': 'val1'}
FAIL : Invalid variable name '${get_elem1_or_default_2({'elem2': 'val2', 'elem3': 'val3', 'elem1': 'val1'})}'.
Is it possible to do so or something is wrong? May be there is another way?
Thanks!
Your "variable functions" are just functions that should be called as keywords and not as variables. So you you can keep your global.py as it is, but call your functions this way:
*** test cases ***
mytest
${key_dict} = Evaluate ${TEST_VAR}['key1']
${var} = get_elem1_or_default_2 ${key_dict}

How to implement Lua OOP in my example?

I am trying to create a class in Lua, which holds information about who is this class following, and I also want followed class to know about his follower.
But my code fails, and I dont know why.
The error is
lua: OOP.lua:90: attempt to call method 'getName' (a nil value)
Vehicle = {}
--------
--FIELDS
--------
Vehicle.name = ""
Vehicle.vtype = "";
Vehicle.follower = {};
Vehicle.leader = {};
---------------------
--SETTERS AND GETTERS
---------------------
function Vehicle:setName(value)
self.name = value
end
function Vehicle:getName()
return self.name
end
function Vehicle:setType(value)
self.vtype = value
end
function Vehicle:getType()
return self.vtype
end
function Vehicle:setFollower(pVeh)
self.follower = {};
self.follower = pVeh;
end;
function Vehicle:getFollower()
return self.follower;
end;
function Vehicle:getLeader()
return self.leader;
end;
function Vehicle:setLeader(pVeh)
self.leader = pVeh;
if (self.leader ~= nil) then
print ("-- setted leader! --");
end;
end;
-----------
--METHODS--
-----------
function Vehicle:follow(pVeh) --> why does this not work?
self:setLeader(pVeh);
pVeh:setFollower(self);
end;
-- constructor
function newVehicle(pNm,pTp)
tbl = {}
setmetatable(tbl, {__index = Vehicle});
tbl:setName(pNm);
tbl:setType(pTp);
return tbl
end
-----------------------------------------------
-- TEST
-----------------------------------------------
local car1 = newVehicle("Mazda","Car");
local car2 = newVehicle("Harley","Bike");
print("--------------");
print (car1:getName()); --> prints "Mazda"
print (car2:getName()); --> prints "Harley"
car2:follow(car1)
print ("Leader of " .. car1:getName() .. " is " .. car1:getLeader():getName())
The problem is in your test code, from what I can see:
print ("Leader of " .. car1:getName() .. " is " .. car1:getLeader():getName())
car1 does not have a leader defined. (you did car2:follow(car1))
Some pointers:
You need to define field tables in the creation method. This won't apply to your code just yet, but say you wanted to do platoons. You'd do something like Vehicle.platoon = {}; Tank1.platoon[Tank2] = true -- This would add Tank2 to Vehicle's platoon table, and share it with every vehicle. If you define this in the new method: function newVehicle(...) tbl.platoon = {} ... end, then it would be unique to every vehicle.
Don't use accessor (get*, set*) methods unless you have a solid reason for using them. They add clutter, and are not good for performance. A good reason to use them would be if you are accessing a table in your accessor method, and want to simplify the interaction with that. (i.e Obj:addChild(Obj2) obj:hasChild(Obj2)) But then it probably doesn't qualify as an accessor anymore :)
You can use dummy objects for unset fields. This'll prevent errors like yours:
local Dummy = newVehicle("None", "None")
Vehicle.follower = Dummy
Vehicle.leader = Dummy
In your code, this produces:
--------------
Mazda
Harley
-- setted leader! --
Leader of Mazda is None
car2:follow(car1)
car1 is being followed by car2. Whereas, later; you're trying to access car1's leader, which, of course returns nil. Hence the error.
print( "Follower of "..car1:getName().." is "..car1:getFollower():getName() )

lua: module import regarding local scope

There are two script files with the following script
//parent.lua
function scope()
local var = "abc"
require "child"
end
//child.lua
print(var)
This way, child.lua will print a nil value because the scope in parent.lua does not expose its local features to the module. I thought it would, since the require directive is stated within this scope and after the declaration of var. My desire is to practically wholly inject all the lines of the child into the parent. The child script is just exported for better readability. How can I pass the local scope? loadfile() did not work, nor did dofile(). The function environment fenv does not harbor local values. debug.setlocal() does not seem to be able to create new variables (also it would require a receiver in the child). Any method besides recompiling the script?
You can with a bit of effort. If your variables in child are real upvalues you can "link" them to values in your scope function. If they are global variables (which seems to be the case here), you can map them to an environment using setfenv and populate that environment with values from your local variables.
The following will print abc as you'd expect (you can change loadstring to loadfile with the same effect):
function vars(f)
local func = debug.getinfo(f, "f").func
local i = 1
local vars = {}
while true do
local name, value = debug.getlocal(f, i)
if not name then break end
if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
i = i + 1
end
i = 1
while func do -- check for func as it may be nil for tail calls
local name, value = debug.getupvalue(func, i)
if not name then break end
vars[name] = value
i = i + 1
end
return vars
end
function parent()
local var = "abc"
local child = loadstring("print(var)")
local env = vars(2) -- grab all local/upvalues for the current function
-- use these values to populate new environment; map to _G for everything else
setmetatable(env, {__index = _G})
setfenv(child, env)
child()
end
parent()
This is all for Lua 5.1, but it's also possible in Lua 5.2.