I have edited the code to focus on the issue:
globals [num_periods]
breed [observeds observe]
observeds-own [potential0 potential1 potential2 potential3 potential4 potential5 potential6 potential7 potential8 potential9
]
to setup
clear-all
reset-ticks
ask patches [set pcolor white]
create-observeds 1 [ setxy random-xcor random-ycor set shape "square" set color green
set potential0 random 0 set potential1 random 0 set potential2 random 0 set potential3 random 0 set potential4 random 0
set potential5 random 0 set potential6 random 0 set potential7 random 0 set potential8 random 0 set potential9 random 0
]
end
to go
ask observeds [
let test1 (word "potential" who) ;; this should output potential0 a variable
let test2 runreport [test1]
print test1 ;;prints potential0
ask observeds with [test2 = who][
move ]] ;; trying to move the turtle
end
to move
right random 360
fd 1
end
As there is only one agent it's who = 0. I have set all of the variables potentialx, x = [0,9], to zero. I have then 'created' the word 'potential0' by concatenating the work potential + who of the agent. Then I have asked all agents with potential0 to move and nothing happens.
Thanks,
Kevin
You will want to use runresult for this.
runresult takes whatever string it is applied to and treats it as a reporter rather than a string. If that string contains a number it returns a number. If it contains a variable name, it treats it as a variable.
So the following should solve your problem
ask observeds with [runresult test1 = who][
move
]
Use let test1 runresult (word ("potential" who) to form the string potential0. Subsequent commands will then recognise this as a reporter
So I have been trying to create a pause menu for the past few hours. However, I cannot figure out how to stop the rigidbodies from moving. If there is a way to stop all rigidbodies at once, please tell me, if not, I can set it to each and every script with a rigid body. Here is my code so far:
extends Position3D
onready var charCamera = get_viewport().get_camera()
##var direction = Camera.global_transform.basis.get_euler()
signal spawned(spawn)
export(PackedScene) var spawnling_scene
var linear_velocity_on_pause = 0
var not_paused_anymore = false
var paused = false
#var Popup1 = self.get_parent().get_parent().get_parent().get_node("Popup")
func _physics_process(_delta):
if self.get_parent().get_parent().get_parent().get_node("Popup").visible == false:
if Input.is_action_pressed("leftClick"):
spawn()
if paused == true:
not_paused_anymore = true
paused = false
if self.get_parent().get_parent().get_parent().get_node("Popup").visible == true:
linear_velocity_on_pause = spawnling_scene.instance().linear_velocity
paused = true
spawnling_scene.instance().set_mode(1)
spawnling_scene.instance().linear_velocity = get_parent().get_parent().get_parent().get_node("LinearVelocityOf0").linear_velocity
if not_paused_anymore == true:
spawnling_scene.instance().set_mode(0)
spawnling_scene.instance().linear_velocity = linear_velocity_on_pause
not_paused_anymore = false
func spawn():
var spawnling = spawnling_scene.instance()
spawnling.linear_velocity = charCamera.global_transform.basis.z * -100
#spawnling.global_transform.basis = charCamera.global_transform.basis
add_child(spawnling)
spawnling.set_as_toplevel(true)
emit_signal("spawned", spawnling)
##insert pause system
return spawnling
##var spawnling = spawnling_scene.instance()
##
## add_child(spawnling)
## spawnling.set_as_toplevel(true)
I'm not answering the question of how to set the velocity of all rigid bodies to zero.
If you want to make a pause menu, this is what you should know:
Godot has a puse system, which you can use like this to pause:
get_tree().paused = true
And to resume:
get_tree().paused = false
See Pausing Games.
Which Nodes gets to execute when get_tree().paused is set to true depend on their pause_mode property. By default they will all stop, but if you set their pause_mode to PAUSE_MODE_PROCESS they will continue to work when get_tree().paused is set to true. And that is what you want to do with the Node that make up your pause menu UI.
However, that system will not pause shaders. Their TIME will continue to tick. If you want to "freeze" shaders you can set a 0 to their time scaling like this:
VisualServer.set_shader_time_scale(0)
Set it to 1 for normal speed:
VisualServer.set_shader_time_scale(0)
And you can set other values to have them slow down or speed up.
Speaking of slow down and speed up. If you want to do that for the rest of the game (not just shaders), you can use Engine.time_scale. And if there is some timing that you don't want to be affected, you would have to write it using the time functions in the OS class.
I have a Mathematica notebook that employs a fairly complicated user interface for controlling a long-running calculation. Among other things, the interface takes liberal advantage of Button, RadioButtonBar, Checkbox, and InputField.
When the effect of clicking a Button is an intermediate calculation that may take more than a couple seconds to complete, I like to provide a visual indication that the code hasn't crashed and is, in fact, doing something useful. A good way to do this is to start up a ProgressIndicator just before the intermediate calculation starts and then turn it off once the calculation is done. I have found this to be straightforward for calculations started by a Button click.
The same method does not work, however, for calculations that are initiated by changes to an InputField value. The simplified code below was written to do this but fails. The last two rows of the Grid are supposed to change automatically when updatingQ changes to True in the inner Dynamic command and then change back when updatingQ reverts to True, but it never happens. It appears that the outer Dynamic code is being blocked while the inner Dynamic code runs so it never even notices the changes to updatingQ.
On the other hand, the last two lines of the Grid respond as expected if one manually sets updatingQ=True on a separate input line.
(BTW, i) Pause[2] is just a stand-in for the intermediate calculation and ii) I multiply the input value by Pi is just to make it more obvious when the stand-in calculation is done.)
Apparently, the action portion of a Button behaves differently. Other pieces of code within the same Dynamic block can see and quickly respond when flags are changed there. It may be notable that I use Method->"Queued" in such cases. I tried the same with InputField (for which it is not a documented option) but to no effect.
I've tried various other things not shown here also without success.
A way to make this work would be much appreciated.
Clear[ProgressIndicatorTest]
updatingQ = False;
ProgressIndicatorTest = {
TextCell["ProgressIndicatorTest", "Subsubsection", Background -> LightBlue],
DynamicModule[
{filterTypes = {"Max energy", "Max length"}, filterValue, workingOn = "", iter = 0},
Scan[(filterValue[#[[1]]] = #[[2]]) &, Transpose#{filterTypes, {0.1, 100.}}];
Dynamic[
Grid[
Join[
Map[
Function[
filterType,
{filterType,
Dynamic#
InputField[
Dynamic[
filterValue[filterType],
Function[
value,
If[value > 0,
updatingQ = True;
Pause[2];
filterValue[filterType] = \[Pi] value;
updatingQ = False
]
]
], FieldSize -> 5, Alignment -> Right
]
}
], filterTypes
],
{{updatingQ, "-------"}},
{If[updatingQ,
{"Updating ... ",
ProgressIndicator[Appearance -> "Indeterminate"]},
Nothing
]}
], Alignment -> Left,
Background -> {None, {LightGreen, LightGreen, LightYellow, LightYellow}}
]
]
]
};
CellGroup[ProgressIndicatorTest]
As Forrest Gump never said, "Stackoverflow/Stackexchange is like a box of chocolates ... you never know what you'll get". And so today I found this answer which solves my problem.
Adapted to my particular case, the resulting code is as follows:
Clear[ProgressIndicatorTest]
calculation[n_] := Module[{a = .3}, Do[a = a (1 - a), {i, n 10^6}]]
updatingQ = False;
ProgressIndicatorTest = {
TextCell["ProgressIndicatorTest", "Subsubsection", Background -> LightBlue],
DynamicModule[{filterTypes = {"Max energy", "Max length"}, filterValue, upToDateQ = True},
Scan[(filterValue[#[[1]]] = #[[2]]) &, Transpose#{filterTypes, {0.1, 100.}}];
Dynamic[
Grid[
Join[
Map[
Function[
filterType,
{filterType,
DynamicWrapper[
InputField[
Dynamic[
filterValue[filterType],
Function[
value,
If[value > 0,
upToDateQ = False;
filterValue[filterType] = value
]
]
], FieldSize -> 5, Alignment -> Right
],
If[! upToDateQ,
Refresh[
updatingQ = True; calculation[2]; updatingQ = False;
upToDateQ = True,
None
]
],
SynchronousUpdating -> False
]
}
], filterTypes
],
{
If[updatingQ,
{"Updating ... ",
ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 80]},
Nothing
]
}
], Alignment -> Left,
Background -> {None, {LightGreen, LightGreen, LightYellow,}}]
]]
};
CellGroup[ProgressIndicatorTest]
This code does exactly what I want.
The key to success is wrapping DynamicWrapper around InputField and inserting a cleverly constructed second argument that performs the flag reset (upToDate=False in my case) that triggers the ProgressIndicator located elsewhere.
A couple more points.
Pause turns out not to be a good stand-in for a calculation. You may observe that the code behaves differently with a real function such as calculation.
It is interesting to note that upToDateQ can be a local variable whereas updatingQ cannot.
Kudos to Albert Retey for providing the code back in 2013.
The documentation for InputField says
"An InputField of type Expression [the default] replaces its
contents with the fully evaluated form every time the contents are
updated".
This seems to mean that InputField privately evaluates its content and all connected dynamics before releasing value changes, probably to prevent circular evaluations.
The following example condenses the problem. The first part works ok ...
changed = processing = False;
Column[{InputField[Dynamic[x, (changed = True; x = 2 #) &], FieldSize -> 5],
Dynamic[changed],
Dynamic[processing]}]
... until the dynamic below is also evaluated. Then changed never shows True because it is changed back to False before the update concludes.
Dynamic[If[changed,
processing = True;
Pause[2];
changed = processing = False]]
A alternative strategy would be to use a Button, e.g.
changed = False;
processing = Spacer[0];
Column[{InputField[Dynamic[y, (changed = True; y = #) &], FieldSize -> 5],
Button["Enter",
If[changed,
processing = ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 120];
Pause[2];
y = 2 y;
changed = False;
processing = Spacer[0]], Method -> "Queued", Enabled -> Dynamic[changed]],
Dynamic[changed],
Dynamic[processing]}]
This shorter version avoids the need to tab out of the input field.
changed = False;
processing = Spacer[0];
Column[{InputField[Dynamic[y], FieldSize -> 5],
Button["Enter",
processing = ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 120];
Pause[2];
y = 2 y;
processing = Spacer[0], Method -> "Queued"], Dynamic[processing]}]
Note the use of Method -> "Queued" gives Button the advantage over InputField. Without it Button appears to have the same problem.
I'm tryna improve my RSpec skills following the bests practices.
I have a simple method is_multiple_of_3_or_5? and I'm implementing a test for it using simple testing values. My first approach was:
describe '#is_multiple_of_3_or_5?' do
context "when input is multiple of 3 or 5" do
expect(is_multiple_of_3_or_5?(3)).to be true
expect(is_multiple_of_3_or_5?(5)).to be true
expect(is_multiple_of_3_or_5?(51)).to be true
expect(is_multiple_of_3_or_5?(45)).to be true
end
end
I like it because it's very short and the test cases are simple, so no need to complicate it.. But I've read in the RSpec style guide that it should be only one expectation per example.
So I refactored in 2 other ways:
One it per example:
describe '#is_multiple_of_3_or_5?' do
context 'when input is multiple of 3 or 5' do
it "is true for 3" do
expect(is_multiple_of_3_or_5?(3)).to be true
end
it "is true for 5" do
expect(is_multiple_of_3_or_5?(5)).to be true
end
it "is true for 51" do
expect(is_multiple_of_3_or_5?(51)).to be true
end
it "is true for 45" do
expect(is_multiple_of_3_or_5?(45)).to be true
end
end
end
Drying up with a subject block
describe '#is_multiple_of_3_or_5?' do
context 'when input is multiple of 3 or 5' do
subject { is_multiple_of_3_or_5?(input) }
context 'when input is 3' do
let(:input) { 3 }
it { is_expected.to be true }
end
context 'when input is 5' do
let(:input) { 5 }
it { is_expected.to be true }
end
context 'when input is 51' do
let(:input) { 51 }
it { is_expected.to be true }
end
context 'when input is 45' do
let(:input) { 45 }
it { is_expected.to be true }
end
end
end
So I have 2 questions:
In the case of theses 2 last versions, the test became really bigger, is it really worth it? Considering that the values tested are simple integers?
Which one of these 2 versions are better formatted?
Thank you for anyone who could help me take better perspective on RSpec!
I am very new to Netlogo.
Linking a GIS file, I want to make a model simulating people's spending on food in reaction to the air pollution such as PM (particular matter). Of course, I also need to consider other variables such as air temperature, precipitation, and so forth. I have a panel data of food-consumption spending, air pollution and all other variables, collected by neighborhood.
My question is whether we can make a variable that changes by time, meaning when tick advances, the value of the variable changes. For example, agent may react to the air pollution in their neighborhood, and alter their food consumption behavior. I want to make a variable of "air pollution" for the neighborhood (patch) and that would change by time (following the data I collected). So somehow, I would like to link a text file of each variable and let net logo read it through when tick advances.
Is there any way to do that? Your advice would be very much appreciated.
I don't know how to link to a file and just pull one item. That sounds like accessing a database and I don't see or know of ( yet, just me ) a direct interface from netlogo to a database system.
Someone could write such a thing using Python, say, and use the interface to Python to pull the data you need. Or you could use the interface to R again with a little tweaking as certainly R has some very nice ways to read in CSV files and make them accessible on an item by item basis by the right clever statement in R.
Both of those would be fun to write. Anyone?
Lacking that, you COULD just read ALL of your data into NetLogo and populate , say, a list (indexed conceptually by tick) of lists ( of the 4 or 5 variables that change by tick ), then use a Netlogo statement to pull the right list indexed by tick ( plus or minus one, watch the zero versus one indexing. ) when you need it, and then parse that list to pull the variables out of it. That would certainly work.
I might write and post such a list of list solution this afternoon. Depends on the weather. Meanwhile, here's a related example I wrote once of reading in a CSV file and writing the variables to some patches-own variables, which is most of what you need.
I think this code works ( with a file to read of course. )
extensions [csv ]
globals [ XC YC ]
patches-own [
country
population
emissions_mass
vulnerability
jetfuel_civilian
climate_finance
]
to setup
clear-all
file-close
;; double the slashes so this works on a Windows computer
;; set-current-directory "C:\\Users\\wades\\Documents\\netlogo\\countries" ;
;; but simpler once just the let the user navigate to the file
;; file-open "countries.csv"
let mypath "???"
set-current-directory user-directory
file-open user-file
let headers file-read-line
print (word "There are the columns: " headers);
let headlist csv:from-row headers
let colcount length headlist
print (word "this many columns: " colcount)
let i 0
repeat colcount [
let determ item i headlist
print (word "column " i " is " determ)
set i ( i + 1 )
]
print "================================"
let nextline file-read-line
print ("skipping the second row of header info")
print nextline
print " "
while [ not file-at-end? ]
[
set nextline file-read-line
let mydata csv:from-row nextline
print "=============================================="
print (word "next incoming line to process is: " nextline )
print mydata;
set XC item 1 mydata
set YC item 2 mydata
print (word " data for patch (" XC ", " YC " )" )
let mytarget one-of patches with [ pxcor = XC and pycor = YC ]
ask mytarget
[
set country item 0 mydata
set population item 3 mydata
set emissions_mass item 4 mydata
set vulnerability item 5 mydata
set jetfuel_civilian item 6 mydata
set climate_finance item 7 mydata
set pcolor blue
set plabel country
]
print " that patch should now be blue"
]
file-close;
reset-ticks
end
to go
stop
tick
end
Here's sample code that reads time-series data from a csv file and puts it into a list-of-lists to pull later.
extensions [csv ]
globals [ list-of-lists ]
to setup
clear-all
reset-ticks
;; let max-rows-to-read 3 ;; for testing purposes
file-close
;; double the slashes so this works on a Windows computer
;; set-current-directory "C:\\Users\\wades\\Documents\\netlogo\\countries" ;
;; but simpler once just the let the user navigate to the file
;; file-open "countries.csv"
let mypath "???"
;; set-current-directory user-directory
file-open user-file
let headers file-read-line
print (word "There are the columns: " headers);
let headlist csv:from-row headers
let colcount length headlist
print (word "Found this many columns: " colcount)
let i 0
repeat colcount [
let determ item i headlist
print (word "column " i " is " determ)
set i ( i + 1 )
]
print "================================"
;; skip lines if you need to
; let nextline file-read-line
; print ("skipping the second row of header info")
; print nextline
; print " "
let rowcount 0
set list-of-lists [ ]
while [ not file-at-end? ]
[
set rowcount rowcount + 1
; if rowcount > max-rows-to-read [ print "list of lists: " show list-of-lists file-close stop]
let nextline file-read-line
let mydata csv:from-row nextline
print "=============================================="
print (word "next incoming line to process is: " nextline )
print mydata;
let onelist ( list
item 0 mydata
item 1 mydata
item 2 mydata )
set list-of-lists lput onelist list-of-lists
]
show list-of-lists
file-close;
end
to go
let indexer ticks ;; maybe you want this offset from ticks by some amount.
ifelse ( indexer < length list-of-lists )
[
let datalist item indexer list-of-lists
let time item 0 datalist
let temp item 1 datalist
let smog item 2 datalist
print (word "At tick " indexer " processing this list: " datalist )
print "yielding: "
print (word "At tick " indexer " time = " time " temp= " temp " and smog=" smog "\n")
]
[
print "All done. Have a nice day!"
]
tick
end