Netologo Behavior Space: have each agent report values - netlogo

I'd like to run a Behavior Space sweep in my model and have each agent report the respective values that they own in the results.
Here is the code I am using to ask each agent to report values.
to-report wrapup
ask artcollectors
[
type who
type " "
type num-artcollectors
type " "
type num-subjectmatters
type " "
type c-artcollection-size
type " "
type c-self-reference-bias
type " "
type c-artdisposal-rate
type " "
type c-random-bias
type " , "
print clist
]
end
When I do this and report to the Console, Netlogo will make the first run and report results to the console, then Nelogo stops at the end of the first run and reports
"Reached end of reporter procedure without REPORT being called.
error while observer running END
called by procedure WRAPUP
called by procedure __EVALUATOR"
So I get that I am not running the right syntax in my wrapup procedure. Can anyone suggest the magic words I need to use?

A to-report procedure is a reporter and must therefore return some value to the caller. Your wrapup procedure is actually a command - the agent does something and then stops. So, you should use the declaration for a command procedure, to wrapup rahter than to-report wrapup.
Hope this helps,
Charles

Related

Are Ada function arguments evaluated if the body is empty?

According to this statement :
Trace.Debug("My String" & Integer'Image(x) & "is evaluated" & "or not" & "if my logger is disabled ?" & Boolean'Image(YesOrNo) );
And this implementation of Trace.Debug:
procedure Debug (Message : in String) is
begin
if Logger.Enabled then -- This boolean is defined during runtime by reading a value in a file
Put_Line(Message);
else
null; -- Do nothing
end if;
end Debug;
I have a software which can manage several levels of logs, and I would like to know what is the behavior in case of Logger.Enabled equals False.
I have a lot of logs calls, with sometimes complex strings to evaluate and I'm on a real time system, so I don't want to lost time to evaluate a string which will not printed.
I would like to know if compiler optimize the code in order to not evaluate the string in parameter of Trace.Debug while Logger.enabled is False, knowing that this boolean is set at the begging of runtime by reading a value in a file.
I am using gnat 7.3.2.
You can ensure that evaluation doesn't happen by providing a callback:
procedure Debug (Message : access function return String) is
begin
if Logger.Enabled then
Put_Line(Message.all);
end if;
end Debug;
Then to call it, do
declare
function Msg return String is
("My String" & Integer'Image(x) & "is evaluated" & "or not" & "if my logger is disabled ?" & Boolean'Image(YesOrNo));
begin
Debug (Msg'Access);
end;
In your original code, the only way that the compiler could skip the evaluation is when it inlines the Debug procedure and re-arranges the code so that the Message object is only assigned inside the if-block. You cannot force this; even pragma Inline is only a hint for the compiler.

Create an "itinerary" agentset of patches

I'm building a model where turtles "search" a subset of patches for a resource according to different search criteria.
I'm trying to build reports that return a sorted list or agentset of patches that a turtle can then use as an itinerary for it's search.
For some reason I'm having trouble storing the itinerary in a turtle owned variable.
an example reporter is:
to-report availability
let sorted-patches sort-on [ ( (space - occupants) / space ) ] patches with [space > 0]
report sorted-patches
end
when I do show availability in the console, it prints out what I expect, an ordered list of patches.
But if I do
let test-variable availability
show test-variable
it returns
ERROR: Nothing named TEST-VARIABLE has been defined.
is this a problem of scope somehow, can I not use let as an observer?
Is it a problem of type? Can I not store an agentset as a named turtle-owned variable?
Is there a way to do the same thing with a list instead of an agent set?
Thanks
From your description, it's a scoping problem. But the problem is not that you are trying to use let with an observer, it's the scope of let. NetLogo is not really interactive in the sense you are trying to do - the variable created by let is thrown away at the end of the line.
If you type let test 3, hit enter, then type show test, you will get the same error. However if you type let test 3 show test, then it will return 3.
Why are you needing this from the console? If it's for testing, then you can look at it the way you have already found - simply by show availability. If you are using it for turtles while the model is running, then it is not interactive and there's no problem.

Expected input to be a number but got TRUE/FALSE

I have got this block of code:
to catch-rose
let prey one-of roses-here
if prey != nobody
[
set energy energy + 1
set rose_ramasse rose_ramasse + 1
ask prey [ die ]
]
end
When I launch the simulation, I get the following error message
+ expected input to be a number but got the TRUE/FALSE false instead.
error while unefeebleue 2 running +
called by procedure CATCH-ROSE
called by procedure GO
called by Button 'go'*
I've been trying to solve out my problem myself but I can't. Why it does not want to recognize the second SET command? Why does it think it is true/false statement?
The error message is telling you the following:
It starts with the operation that failed. Often this is a procedure name, in this case it is +. So you know that it is one of the inputs to + that is failing.
It's telling you that one of the inputs to + is a TRUE/FALSE value.
Now, you've told us that the line it refers to is the second set statement. There are two inputs to the + on that line, rose_ramasse and 1
So, your problem is that rose_ramasse is a TRUE/FALSE (boolean) value. Without the rest of your code, it's not clear whether rose_ramasse is a global variable or not, so it is hard to go any further to help you work out where rose_ramasse is being assigned a boolean value.
I can replicate the error message with a simple function like the following:
globals [age]
to go
set age TRUE
set age age + 1

Progress 4GL BUFFER-COPY FAILS

DO ON ENDKEY UNDO, LEAVE:
FIND FIRST STUDENT NO-LOCK WHERE ST-ID = "TEST" NO-ERROR.
IF AVAILABLE STUDENT THEN
DO:
CREATE SCHOOL no-error.
BUFFER-COPY STUDENT EXCEPT STUDENT.Location
SCHOOL ASSIGN SCHOOL.Location = "MY LOCATION" NO-ERROR.
IF ERROR-STATUS:ERROR THEN
DO:
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:
MESSAGE
" Error no " ERROR-STATUS:GET-NUMBER(i)
" txt: " ERROR-STATUS:GET-MESSAGE(i) VIEW-AS ALERT-BOX.
STOP.
END.
END.
END.
END.
This query is working fine but some time it was creating Empty Record. buffer-copy through some error that why it create empty record but i am not able verify the error because code was happen in LIVE. please help me how to FIX the problem. what type of error buffer-copy will through. 1000 times working fine 1 time it will FAIL. i know this is data defect but how to FIX. otherwise what type of errors BUFFER-COPY through.
Since you really don't know what errors occur - you need to start there.
To track general errors after a NO-ERROR statement you can do something like:
IF ERROR-STATUS:ERROR THEN DO:
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:
/* Replace MESSAGE with some kind of logging */
MESSAGE
"Error number " i
" error no " ERROR-STATUS:GET-NUMBER(i)
" txt: " ERROR-STATUS:GET-MESSAGE(i) VIEW-AS ALERT-BOX.
END.
END.
Once you have the specific error number(s) you can search the Progress Knowledge Base for more information.
I would write the code as follow. If you use no-error always handle the error. When assigning/buffer copy check if no error then do a validate to confirm that triggers fire correctly. The error handling code can be put in its own procedure and then just called every time you wish to process error messages. (amended it a bit as I would write it, I do not always trap all errors, but error handling depends on various things, but it is a good way during testing to make sure code is setup correctly. Afterwards can remove error handling where not needed before deploying.)
FIND FIRST STUDENT NO-LOCK WHERE ST-ID = "TEST" NO-ERROR.
IF AVAILABLE STUDENT THEN
DO:
CREATE SCHOOL.
BUFFER-COPY STUDENT EXCEPT STUDENT.Location
TO SCHOOL ASSIGN SCHOOL.Location = "MY LOCATION"
NO-ERROR.
IF ERROR-STATUS:ERROR THEN
DO:
/* insert error handling - for example as as per #Jensd */
/* this is in case there is something wrong with buffer copy */
/* maybe a required field is left empty? */
END.
ELSE DO:
VALIDATE SCHOOL NO-ERROR. /* good idea as it raises any issues with triggers */
IF ERROR-STATUS:ERROR THEN
DO:
/* insert error handling - for example as as per #Jensd */
END.
END.
END.
I will not make a buffer-copy from one to other table stright, you might have index issues as i think you are having.
Better define a temp-table like the target table.
Then make a buffer copy to the temp-table.
Set the rigth key into the temp-table.
Then make a buffer copy from the temp table with the right key fields to the target table.
Try as follow:
Define temp-table t-school like school.
find first student no-lock and so on.
buffer-copy student to t-school.
Assign t-school.location = "whatever".
buffer-copy t-school to school.
Voila!
One possible way to debug the issue is to use "Recent Messages" under Help in AppBuilder provided you are able to run the code directly from it.

DisplayString in Crystal Report

What if we want to use DisplayString Method in Crystal Report but we want to apply this only on the basis of some parameter value ! ?
Like we will pass in parameter whether the use can see the purchase rate or not !
If not then we will print Asterisk instead of actual rate else do nothing !
Assumes a boolean parameter named {?hide}:
If {?hide} Then
Replace(Space(Len(ToText(CurrentFieldValue,"#"))), " ", "*")
Else
ToText(CurrentFieldValue)