I have three models: Parent, Child1, Child2.
Child1 generates strings which must then be passed to Child2 for further processing. The strings are generated on the fly when Child1 is executing. Whenever a new string is generated it must be sent immediately to Child2. Sometimes 2 or more strings are generated at the same time (by different agents), and then those 2 or more strings must be sent at the same time (ie. within the same tick).
One solution is to skip the parent model and let Child1 become the Parent-model, which has then access to Child 2. However, that would complicate Child1 as it would then include all the required LevelSpace code. Furthermore the two children models must be useable on their own. The two models are used for educational purposes, and the students should not see the LevelSpace code. Hence the Parent model.
Another solution is to let the Parent model continuously poll the Child 1 model to ask for new strings. Not very pretty. Not very efficient.
So basically I'm looking for some shared memory and/or event functionality in LevelSpace :-)
By the way the strings represent DNA, RNA, etc. and we're illustrating transcription and translation of strings etc.
Any ideas?
Thanks,
Palle
Jasper wrote a really nice solution, though it does rely on behavior that isn't supposed to work. Another way to do it is to have child1 collect the strings as it runs in a global variable. e.g.
Child 1 code:
globals [ strings ]
to go
set strings []
ask turtles [
set strings lput (word "hello from turtle " who) strings
]
tick
end
Then have child2 accept a list of strings in its go method
Child 2 code:
to go [ strings ]
; do stuff with the strings
end
Then the parent passes the list between them:
Parent code:
to go
ls:ask child1 [ go ]
ls:let child1-strings [ strings ] ls:of child1
ls:ask child2 [ go child1-strings ]
tick
end
It is definitely not conventional NetLogo code, but the callback method seems like it works okay, at least for this simple example. You do need to complicate the child models a little bit to add the run callback statement, but it could result in cleaner code overall than the polling method depending on the use case.
Parent model:
extensions [ ls ]
globals [ child1 child2 ]
to setup
ls:reset
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child1 id ])
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child2 id ])
ls:ask ls:models [
child-setup
]
; here we set the callback for the child models
; we could set the callback for just `child1` instead of all `ls:models`
ls:assign ls:models callback [ [id message] -> alert id message ]
ls:assign child1 id child1
ls:assign child2 id child2
end
to go
ls:ask ls:models [
child-go
]
end
; In this case our callback is simple, just taking the caller id
; and a message. We could add more parameters for it if we want to
to alert [id message]
show (word id ": " message)
; this is just to show that we can use the callback to update
; the state of one of the other models
if id = 0 [
ls:ask child2 [ set some-val (some-val + 1) ]
]
end
Child model:
globals [ id callback some-val ]
to child-setup
set some-val 0
; set the callback to an "empty" procedure so we don't have to check
; if it is set while we run the go method.
set callback [ [model-id message] -> ]
end
to child-go
if random 10 < 3 [
(run callback id (word "child alert: " some-val))
]
end
Sample output:
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "0: child alert: 0"
observer: "1: child alert: 1"
observer: "0: child alert: 0"
observer: "1: child alert: 2"
observer: "1: child alert: 2"
observer: "0: child alert: 0"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "0: child alert: 0"
observer: "1: child alert: 4"
observer: "0: child alert: 0"
observer: "1: child alert: 5"
observer: "1: child alert: 5"
observer: "0: child alert: 0"
observer: "1: child alert: 6"
Every time the child1 model runs the callback, the alert procedure increments the some-val global in child2.
Related
I'm a first time user of AG Grid and need some help identifying how to configure Row Grouping for my AG Grid in such a way that allows me to see my data group as a timeline/audit history. Was reading through the docs and haven't found an example on there that resembles what I'm looking for.
I have rowData that contains history and the visual expectation is that, the same base columnDefs assigned to the grid are used for the main "group" row (that contains the expand/collapse chevron) and all the expanded rows as well -- so there is no need for a "group column"
Anyone know how I can achieve this outcome? I have also looked at treeData and masterDetail but those didn't work out for me.
P.S. I don't rule out the possibility that I could be misreading/misunderstanding the AG Grid docs so any help there is appreciated.
EDIT: After fiddling around with things further, I believe I'm looking for a combination of two things:
The isRowMaster to enable expand/collapse on the main parent entry.
The groupDisplayType="groupRows" setting (minus the default row group cell because that would be handled by my master row from Point 1 instead)
After much head banging, turns out the solution was to use treeData. What I ended up creating was treeData containing only one level children.
Parent Node (expand/collapse)
child 1
...
child n
The other key was understanding how to structure your rowData and returning the proper dataPath to feed into the getDataPath handler for treeData. AG Grid expects a flat-list for rowData -- I say this as I was not able to get things working when having a nested tree structure like the following.
const mainRecord = {
id: "abc"
foo: 1,
bar: 2,
history: [
{ foo: 3, bar: 4 },
{ foo: 5, bar: 6 }
]
}
I had to modify my data structure above to return the history items as a flat list alongside the main record that I eventually sent as rowData. The other thing I had to do was add some hierarchy property to my objects to denote its placement in the tree. The hierarchy value is what I supplied to getDataPath
const rowData = [
{ id: "abc", foo: 1, bar: 2, hierarchy: ["abc"] }, // parent
{ foo: 3, bar: 4, hierarchy: ["abc", "34"] }, // child 1
{ foo: 5, bar: 6, hierarchy: ["abc", "56"] }, // child 2
]
After doing the above changes, I was able to get the expected visual outcome I was looking for. I think the big takeaway I got from this is as a first time user of AG Grid is, let it take care of grouping of your data on your behalf (as opposed to doing it yourself via structuring your models with some internal nested children structure)
So I have a Simple UITableView that will display a UILabel and a UISwitch. I need to be able to get the values of each switch update my object then eventually send the data the API. I has a semi working concept. But this only worked if ALL the cells were visible. Before I only had 5 items to be checked. So I could simply loop through everything and get the data. Now my checklist has grown to over 20 items.
I understand to a degree why the current code doesn't work. It finds nil values. That would be the cells that aren't visible.
My big question is how do i go about capturing the value of all the cells and the value of all the UISwitch values and update my object?
I tried to use the KVO method. This is what I have so far, I have never used this before and a bit lost:
private var observation: NSKeyValueObservation?
observation = switchCell.observe(\.switchOne, options: [.old, .new]) { value, change in
print("value: \(value.switchOne.isOn)")
print("change old: \(change.oldValue)")
print("change new: \(change.newValue)")
}
My issue is I am not sure what I am supposed to use for the key path. Iget the following warning:
Passing reference to non-'#objc dynamic' property 'switchOne' to KVO method 'observe(_:options:changeHandler:)' may lead to unexpected behavior or runtime trap
Then the simulator doesn't boot up. What is the easiest way/best way to do this? Like I said I have 2)+ items on my checklist as I completed each item, I turn the switch on. Then I need to get the value for each item, and update the object with the correct value. Then I send the data to the API to store the info to the database. From what I was reading this seemed to be the right direction.
store predefined status of switches in array of dictionary like:
let alreadyYouHaveThis = [["id": 1, "title": "name"...., ], [ "id": 1, "title": "name"....., ],["id": 1, "title": "name"...., ]
just add one more key in the same data like status...
let updatedData = [["status": true, "id": 1, "title": "name"...., ], ["status": true, "id": 1, "title": "name"....., ],["status": false, "id": 1, "title": "name"...., ]
now that status will be used in cellforindexpath method as other:
func cellforindexpath() ..... {
let status = data[indexPath.item]["status"]
swithc.tag = indexpath.item
setswitchstatus on above value
}
and action for switch :
#Objc func switchStatus(_ switch: UISwitch) {
let status = data[switch.tag]
status != status
data[switch.tag]["status"] = status
....
}
or can edit main data source and add these status in that data.
if you cant perform this let me know.
I am trying to solve the below problem in a functional way. Given I have a data structure that looks like below:
final case class ActionConfiguration(
configId: Int,
actions: List[Action],
`type`: String,
time: String,
weekday: Option[List[Int]]
)
And I have a Map that has the following signature: Map[TargetLocation, List[ActionConfiguration]]
As you can see I want to execute some actions at a target location at a configured time and weekday. The way it is currently working is, if I have a set of actions to be performed at the same time and day, I am populating only one action in the actions list and creating many ActionConfiguration objects that may have the same configured time and day. My goal is to utilize the Actions list to populate all the actions that I want to execute inside a single ActionConfiguration.
As an example, given the situation today that I have this:
"ActionConfiguration":[
{
"configId":1,
"actions":[
{
"cmd":"doAction1"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":2,
"actions":[
{
"cmd":"doAction2"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":3,
"actions":[
{
"cmd":"doAction3"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":4,
"actions":[
{
"cmd":"doAction4"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":5,
"actions":[
{
"cmd":"doAction5"
}
],
"type":"weekly",
"time":"22:00",
"weekday":[
4
]
}
]
I want to achieve this:
"ActionConfiguration": [
{
"configId": 1,
"actions": [
{
"cmd": "doAction1"
},
{
"cmd": "doAction2"
},
{
"cmd": "doAction3"
},
{
"cmd": "doAction4"
}
],
"type": "weekly",
"time": "09:00",
"weekday": [
5
]
},
{
"configId": 2,
"actions": [
{
"cmd": "doAction5"
}
],
"type": "weekly",
"time": "22:00",
"weekday": [
4
]
}
]
As you can see I want merge the actions that needs to be performed at the same time into a single list. I am coming from a Java background and currently working on Scala. I know how to solve this problem in Java style, but I am looking for some ways how we can solve this in a functional style as I am very interested to learn functional programming.
Assuming there's a constructor for ActionConfiguration that takes the members in the order below, this probably works (I just typed it here, I didn't compile or test it):
val mergedList = listofActionConfigurations
.groupBy(a => (a.configId, a.time, a.type, a.weekday))
.values
.map(la => (la.head, la.map(_.actions).flatten))
.map(t => new ActionConfiguration(t._1.configId, t._1.time, t._1.type, t._1.weekday, t._2))
.toList
What's happening here?
We group the list of ActionConfigurations by a key created by tupling all fields of ActionConfigurations except the actions list.
Then we throw away the keys and take just the values, which is some Set-like collection containing Lists of ActionConfigurations.
We map over that collection, and for each list of ActionConfigurations in it, we grab the first element of the list (.head) and then we map each ActionConfiguration in the list to its list of actions, and then we flatten the resulting list of lists. We yield a tuple of the head item and the flattened list.
We then map the tuple (head, list of actions) to a new ActionConfiguration with all the members of head except its list of actions, and the flattened list of actions as the new ActionConfiguration's action list.
Finally, since we probably still have a Set-like collection, we explicitly turn it into a List.
It takes much longer to explain than to write. :)
Note that the Scala library docs make no guarantees about the order of the actions in the merged actions list (but the implementation seems to be order-preserving); if you require it to be ordered, sort after flattening then action lists.
It seems all you need is groupMapReduce to create a Map[TargetLocation, List[Action]] which you can later map if you really want a Map[TargetLocation, List[ActionConfiguration]]
configurations.groupMapReduce(
ac => (ac.configId, ac.time, ac.type, ac.weekday)
)(
ac => ac.actions
)(
(l1, l2) => l1 reverse_::: l2 // Similar to l1 ++ l2 but more efficient, although the order changes.
)
I have the following rule
rule One
when
vg1 : Vgdoc(code() in ("IA1003", "IA1004"), colour == "red")
then
.. do something with vg1
end
when I use the vg1 in the then clause I see that it represents one object but what if both ("IA1003", "IA1004") exists? does drools only send the first one or both? and if it sends both how can I check it.
Is it possible to do something like this to
vglist : List() from collect (Vgdok(code() in ("IA1003", "IA1004")))
will this list contain both fact if they exists in the memory?
cheers
es
Your rule will hit for each item in working memory that matches.
Simplifying things, let's say that your model looks like this:
class Vgdoc {
public String getCode() { ... }
public String getColour() { ... }
}
And your rule is like what you have, syntax corrected:
rule "One"
when
vg1: Vgdoc( code in ("IA1003", "IA1004"),
colour == "red" )
then
Systen.out.println("Rule 1 fired");
end
And you have objects in working memory:
Vgdoc{ code: "IA1003", colour: "red" } // A
Vgdoc{ code: "IA1004", colour: "red" } // B
Vgdoc{ code: "IA1005", colour: "red" } // C
Vgdoc{ code: "IA1003", colour: "blue" } // D
Then your rule will fire twice, once for the item I commented as "A" and once for the item I commented as "B". (Eg. there will be two instances of Rule 1 fired printed.) It will not fire for item commented "C" because the code does not match, and it will not fire for item commented "D" because the colour field does not match.
Now, if you want to only fire once and to do something with the collection of all Vgdoc matching the condition (color 'red' and code 'IA1003' or 'IA1004'), then yes you'd use a collect. Something like this:
rule "IA1003 and IA1004 with red"
when
vgList: List() from collect( Vgdoc( code in ("IA1003", "IA1004"), colour == "red" ))
then
System.out.println("Rule fired, match count: " + vgList.size());
// vgList will contain all items that match the conditions for code and colour
end
This version of the rule, with the same inputs from before, will fire exactly once and will print: Rule fired, match count: 2.
Which one you choose to use depends on your use case.
I'm currently designing an API to handle requests from mobile clients. To achieve some degree of decoupling between backend and client I would like to define the webservices in a RESTful way. The challenge that I am facing is returning multiple objects with different types for a single call.
Lets say we have the following Model:
Harbour ... Top level entry
Boat shed ... Assigned to a specific harbour (0..n)
Boat ... Assigned to a specific boat shed (0..n), or directly to a harbour (0..n)
As far as i understand REST, if I now want to display all the boats and sheds in the harbour I would send two requests:
/harbours/{harbour_id}/boats Returning a list of all boats. Boats in a shed would contain an id linking to the shed they are in
/harbours/{harbour_id}/sheds Returning a list of all sheds
As I want to use the web service in a mobile scenario, it would be ideal to combine these two calls into one. This could then either return the list of boats with the shed object nested within, or both object types side by side:
/harbours/22/boats
[
{
"id":1,
"boatName":"Mary",
"boatShed":{
"id":1,
"shedName":"Dock 1",
"capacity":55
}
},
{
"id":2,
"boatName":"Jane",
"boatShed":{
"id":1,
"shedName":"Dock 1",
"capacity":55
}
}
]
or
/harbours/22/boats
{
"boats":[
{
"id":1,
"boatName":"Mary",
"boatShedId":1
},
{
"id":2,
"boatName":"Jane",
"boatShedId":1
}
],
"sheds":[
{
"id":1,
"shedName":"Dock 1",
"capacity":55
}
]
}
My question now is, which of these ways is closer to the idea behind REST, or is it not RESTful at all?
As #Tarken mentioned /boats request should not return sheds in the top level (since the url assumes you're asking for collection of resource Boat)
If you have relations defined as follows
Harbour:
boats: Boat[]
sheds: Shed[]
Shed:
boats: Boat[]
Boat:
harbour: Harbour
shed: Shed
/harbours/ID then returns a Harbour representation with boats and sheds relation set.
{
boats:
[
{ Boat },
{ Boat },
..
],
sheds:
[
{ Shed },
{ Shed },
..
],
...
}
Nothing is against restful principles here - the url uniquely identifies a resource and resource representation can be anything, with links to other resources as well.
Create a Harbour model which contains both Boat Shed and Boat information. If i am implementing the service in Java, then i would have done something like this :
class Boat{
...
}
class BoatShed{
...
}
class Harbour{
List<Boat> boats;
List<BoatShed> boatSheds;
...
}
You can create an API like /api/harbours/{harbourId}.
As per your question you want to display all the boats and sheds in the harbour, say id=1234, you can make a request like this :
GET /api/harbours/1234
This will return list of Boats and list of Boat Sheds like this:
{
"boats":[
{
"id":1,
"boatName":"Mary",
"boatShedId":1
},
{
"id":2,
"boatName":"Mary2",
"boatShedId":2
}
],
"sheds":[
{
"id":1,
"shedName":"Dock 1",
"capacity":55
},
{
"id":2,
"shedName":"Dock 2",
"capacity":50
}
]
}
EDIT
As you want to get boats and Sheds side by side by sending one request, the api/hourbours/{id} looks good according to REST API design principles.
Getting all sheds while requesting for boats is not in accordance with ideal REST API design, but if you want to achieve the same you can d the following.
If you want that way, then first one /api//harbours/{id}/boats looks good to me.