From 18c997dd1bbc7f642b030805220e1848a804042d Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 16:22:07 -0700 Subject: [PATCH 01/17] multiple agents --- server/src/main/java/swim/tutorial/DataSource.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index 1f23965..bcb0b87 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -39,7 +39,14 @@ void sendCommands() throws InterruptedException { // *CommandLane* addressable by "publish" OF the // *Web Agent* addressable by "/unit/master" RUNNING ON the // *(Swim) server* addressable by hostUri - this.ref.command(this.hostUri, "/unit/master", "publish", msg); + this.ref.command(this.hostUri, "/unit/master1", "publish", msg); + + // add agents by following the format of the hostURI specified in TutorialPlane + // line 12: @SwimRoute("/unit/:id") + + // this.ref.command(this.hostUri, "/unit/master2", "publish", msg); + // this.ref.command(this.hostUri, "/unit/master3", "publish", msg); + indicator = (indicator + 1) % 1000; // Throttle events to four every three seconds From 6be26515695424adea4e6c0fe73ae1229963ff37 Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 16:27:22 -0700 Subject: [PATCH 02/17] clarify instructions to add agents --- server/src/main/java/swim/tutorial/DataSource.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index bcb0b87..c4a14ca 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -39,13 +39,14 @@ void sendCommands() throws InterruptedException { // *CommandLane* addressable by "publish" OF the // *Web Agent* addressable by "/unit/master" RUNNING ON the // *(Swim) server* addressable by hostUri - this.ref.command(this.hostUri, "/unit/master1", "publish", msg); + this.ref.command(this.hostUri, "/unit/master", "publish", msg); - // add agents by following the format of the hostURI specified in TutorialPlane - // line 12: @SwimRoute("/unit/:id") + // To instantiate more agents, follow the format of the URI pattern specified in TutorialPlane + // see line 12: @SwimRoute("/unit/:id") - // this.ref.command(this.hostUri, "/unit/master2", "publish", msg); - // this.ref.command(this.hostUri, "/unit/master3", "publish", msg); + // EXAMPLES: + // this.ref.command(this.hostUri, "/unit/secondAgent", "publish", msg); + // this.ref.command(this.hostUri, "/unit/thirdAgent", "publish", msg); indicator = (indicator + 1) % 1000; From a588c8cea878697bb87bd0a8f254a7b332317b82 Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 16:45:09 -0700 Subject: [PATCH 03/17] add exercise instructions to read.me --- server/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/README.md b/server/README.md index 8a81b54..95cd9db 100644 --- a/server/README.md +++ b/server/README.md @@ -10,6 +10,11 @@ Swim implements a general purpose distributed object model. The "objects" in thi [Creating a class](http://github.com/swimos/tutorial/tree/master/server/src/main/java/swim/tutorial/UnitAgent.java#L13) that extends `swim.api.agent.AbstractAgent` defines a *template* for Web Agents (though not a useful one until we add some [lanes](#lanes)). +#### *Try it yourself:* +- [ ] *Navigate to [swim.tutorial.DataSource.java](https://github.com/swimos/tutorial/blob/master/server/src/main/java/swim/tutorial/DataSource.java)* +- [ ] *Create additional web agents using the instructions in the code* +- [ ] *Compare your answer with those in the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch* + Visit the [documentation](https://developer.swim.ai/concepts/agents/) for further details about Web Agents. ## Lanes From 8ffe6c380f722ac097a080a6e1b3186453279488 Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 17:12:10 -0700 Subject: [PATCH 04/17] make exercise into actionable with TODO --- server/src/main/java/swim/tutorial/DataSource.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index c4a14ca..f7f1154 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -44,6 +44,8 @@ void sendCommands() throws InterruptedException { // To instantiate more agents, follow the format of the URI pattern specified in TutorialPlane // see line 12: @SwimRoute("/unit/:id") + // TODO: create two new web agents using the above format + // EXAMPLES: // this.ref.command(this.hostUri, "/unit/secondAgent", "publish", msg); // this.ref.command(this.hostUri, "/unit/thirdAgent", "publish", msg); From 1a268a139238acc6df840049052959fedee22772 Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 17:15:43 -0700 Subject: [PATCH 05/17] add second try it yourself about stats lane --- server/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/README.md b/server/README.md index 95cd9db..4dd9b71 100644 --- a/server/README.md +++ b/server/README.md @@ -25,6 +25,12 @@ Continuing our analogy, *lane callback* functions serve as the "methods" of Web Each lane type defines a set of overridable (default no-op) lifecycle callbacks. For example, [sending a command message](#sending-data-do-swim) to any command lane will trigger its [`onCommand` callback](http://github.com/swimos/tutorial/tree/master/server/src/main/java/swim/tutorial/UnitAgent.java#L51-L54). On the other hand, [setting a value lane](http://github.com/swimos/tutorial/tree/master/server/src/main/java/swim/tutorial/UnitAgent.java#L53) will trigger its `willSet` callback, then update its value, then trigger its [`didSet` callback](http://github.com/swimos/tutorial/tree/master/server/src/main/java/swim/tutorial/UnitAgent.java#L40-L47). +#### *Try it yourself:* +- [ ] *Navigate to [swim.tutorial.UnitAgent.java](https://github.com/swimos/tutorial/blob/master/server/src/main/java/swim/tutorial/UnitAgent.java)* +- [ ] *Fill in the remaining code to create a new value lane called `stats` which gets populated by changes to the `histogram` map lane* +- [ ] *Experiment with ways to transform the data entries in histogram. Ideas: mean, median, range, standard deviation, variance, etc!* +- [ ] *Compare your answer with those in the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch* + Visit the [documentation](https://developer.swim.ai/concepts/lanes/) for further details about lanes. ## Standing a Swim Server From 237a080a99de6863bd276c5e6246386b95fcad4d Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 17:33:39 -0700 Subject: [PATCH 06/17] revise comment wording so I know what to separate out in the solutions branch --- server/src/main/java/swim/tutorial/DataSource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index f7f1154..0020601 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -44,9 +44,9 @@ void sendCommands() throws InterruptedException { // To instantiate more agents, follow the format of the URI pattern specified in TutorialPlane // see line 12: @SwimRoute("/unit/:id") - // TODO: create two new web agents using the above format + // TODO: Create two new web agents using the above format - // EXAMPLES: + // EXAMPLE SOLUTION: // this.ref.command(this.hostUri, "/unit/secondAgent", "publish", msg); // this.ref.command(this.hostUri, "/unit/thirdAgent", "publish", msg); From 41748f26788514849ae99e71bc93ae0ce337e47d Mon Sep 17 00:00:00 2001 From: Crista Falk Date: Tue, 7 Jul 2020 17:34:38 -0700 Subject: [PATCH 07/17] empty template with TODOs and hints (w/o solutions) --- .../main/java/swim/tutorial/UnitAgent.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index faed0a5..eb7c03e 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -12,14 +12,27 @@ import java.util.Iterator; public class UnitAgent extends AbstractAgent { + + // TODO: complete the stats Value Lane + // @SwimLane("stats") + + // HINT: Use the valueLane() method to instantiate the lane + // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats + + @SwimLane("histogram") + private final MapLane histogram = this.mapLane() + .didUpdate((k, n, o) -> { + logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); + // TODO: update stats with update logic + + dropOldData(); - @SwimLane("histogram") - private final MapLane histogram = this.mapLane() - .didUpdate((k, n, o) -> { - logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); - dropOldData(); - }); + }) + .didRemove((k,o) -> { + // TODO: update stats with remove logic + }); + @SwimLane("history") private final ListLane history = this.listLane() .didUpdate((idx, newValue, oldValue) -> { From 93730e4c01603932370e05bf3cf377392d4d4dae Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 13:50:17 -0700 Subject: [PATCH 08/17] calculate basic average with stats value lane --- .../main/java/swim/tutorial/UnitAgent.java | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index eb7c03e..6f4b29b 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -12,26 +12,66 @@ import java.util.Iterator; public class UnitAgent extends AbstractAgent { - - // TODO: complete the stats Value Lane - // @SwimLane("stats") + // instance variables to track metrics going into stats + private long count_sum = 0; + private int count_total = 0; + + @SwimLane("stats") + private final ValueLane stats = this.valueLane() + .didSet((n, o) -> { + logMessage("stats: mean updated to " + n + " from " + o); + }); - // HINT: Use the valueLane() method to instantiate the lane - // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats - @SwimLane("histogram") - private final MapLane histogram = this.mapLane() - .didUpdate((k, n, o) -> { - logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); - // TODO: update stats with update logic - - dropOldData(); - - }) - .didRemove((k,o) -> { - // TODO: update stats with remove logic - - }); + @SwimLane("histogram") + private final MapLane histogram = this.mapLane() + .didUpdate((k, n, o) -> { + logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); + + // calculating mean to send to stats + count_sum += n.getItem(0).longValue(); + // logMessage(count_sum); + + count_total ++; + // logMessage(count_total); + + final long avg = count_sum / count_total; + // logMessage(avg); + + stats.set(avg); + + dropOldData(); + }) + .didRemove((k,o) -> { + // update stats with remove logic + logMessage("histogram: removed <" + k + "," + Recon.toString(o) + ">"); + count_sum = 0; + count_total = 0; + }); + + + + // tutorial outline + +// // TODO: complete the stats Value Lane +// // @SwimLane("stats") +// +// // HINT: Use the valueLane() method to instantiate the lane +// // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats +// +// @SwimLane("histogram") +// private final MapLane histogram = this.mapLane() +// .didUpdate((k, n, o) -> { +// logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); +// // TODO: update stats with update logic +// +// dropOldData(); +// +// }) +// .didRemove((k,o) -> { +// // TODO: update stats with remove logic +// +// }); @SwimLane("history") private final ListLane history = this.listLane() From d6bd22c48f070b39bb4267618049dccdd3549a94 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 14:45:17 -0700 Subject: [PATCH 09/17] added second stats metric (local mean) --- .../main/java/swim/tutorial/UnitAgent.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index 6f4b29b..355463e 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -15,12 +15,28 @@ public class UnitAgent extends AbstractAgent { // instance variables to track metrics going into stats private long count_sum = 0; private int count_total = 0; + private int index = 0; + private long local_sum = 0; + private long[] recent_data = new long[5]; - @SwimLane("stats") - private final ValueLane stats = this.valueLane() + + @SwimLane("stats_1") + private final ValueLane stats_1 = this.valueLane() + .didSet((n, o) -> { + logMessage("stats_1: mean updated to " + n + " from " + o); + }); + + @SwimLane("stats_2") + private final ValueLane stats_2 = this.valueLane() .didSet((n, o) -> { - logMessage("stats: mean updated to " + n + " from " + o); + logMessage("stats_2: local median (last 5 entries) updated to " + n + " from " + o); }); + +// @SwimLane("stats_3") +// private final ValueLane stats_3 = this.valueLane() +// .didSet((n, o) -> { +// logMessage("stats_3: local ___ (last 5 entries) updated to " + n + " from " + o); +// }); @SwimLane("histogram") @@ -28,17 +44,24 @@ public class UnitAgent extends AbstractAgent { .didUpdate((k, n, o) -> { logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); - // calculating mean to send to stats + // calculating overall mean to send to stats1 count_sum += n.getItem(0).longValue(); - // logMessage(count_sum); - count_total ++; - // logMessage(count_total); - final long avg = count_sum / count_total; - // logMessage(avg); + stats_1.set(avg); + + // appending new data too the recent_data array + if (index >= recent_data.length-1) { + index = 0; + } + recent_data[index] = n.getItem(0).longValue(); + index ++; - stats.set(avg); + // calculating local mean to send to stats2 + local_sum = 0; + for (long d : recent_data) local_sum += d; + final long local_avg = local_sum / (long) recent_data.length; + stats_2.set(local_avg); dropOldData(); }) @@ -47,6 +70,7 @@ public class UnitAgent extends AbstractAgent { logMessage("histogram: removed <" + k + "," + Recon.toString(o) + ">"); count_sum = 0; count_total = 0; + index = 0; }); From 96a3716e0730b89844802073fe7e944549fcac48 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 15:00:34 -0700 Subject: [PATCH 10/17] add variance and std deviation calculations --- .../main/java/swim/tutorial/UnitAgent.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index 355463e..5424823 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -16,7 +16,6 @@ public class UnitAgent extends AbstractAgent { private long count_sum = 0; private int count_total = 0; private int index = 0; - private long local_sum = 0; private long[] recent_data = new long[5]; @@ -32,11 +31,17 @@ public class UnitAgent extends AbstractAgent { logMessage("stats_2: local median (last 5 entries) updated to " + n + " from " + o); }); -// @SwimLane("stats_3") -// private final ValueLane stats_3 = this.valueLane() -// .didSet((n, o) -> { -// logMessage("stats_3: local ___ (last 5 entries) updated to " + n + " from " + o); -// }); + @SwimLane("stats_3") + private final ValueLane stats_3 = this.valueLane() + .didSet((n, o) -> { + logMessage("stats_3: local variance (last 5 entries) updated to " + n + " from " + o); + }); + + @SwimLane("stats_4") + private final ValueLane stats_4 = this.valueLane() + .didSet((n, o) -> { + logMessage("stats_4: local std deviation (last 5 entries) updated to " + n + " from " + o); + }); @SwimLane("histogram") @@ -50,7 +55,7 @@ public class UnitAgent extends AbstractAgent { final long avg = count_sum / count_total; stats_1.set(avg); - // appending new data too the recent_data array + // appending new data to the recent_data array if (index >= recent_data.length-1) { index = 0; } @@ -58,11 +63,21 @@ public class UnitAgent extends AbstractAgent { index ++; // calculating local mean to send to stats2 - local_sum = 0; + long local_sum = 0; for (long d : recent_data) local_sum += d; final long local_avg = local_sum / (long) recent_data.length; stats_2.set(local_avg); + // calculating local variance to send to stats3 + long squared_dif_sum = 0; // (sum of local mean - each value)^2 + for (long d : recent_data) squared_dif_sum += (d - local_avg)*(d - local_avg); + long local_variance = squared_dif_sum/recent_data.length; + stats_3.set(local_variance); + + // calculating local standard deviation to send to stats4 + double local_std_dev = Math.sqrt(local_variance); + stats_4.set((long)local_std_dev); + dropOldData(); }) .didRemove((k,o) -> { From 15a584b4e3c6bd4be02c27e4cbf280933979bda4 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 15:11:36 -0700 Subject: [PATCH 11/17] include more descriptive hints for logic to update stats --- .../main/java/swim/tutorial/UnitAgent.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index 5424823..0db298a 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -92,25 +92,31 @@ public class UnitAgent extends AbstractAgent { // tutorial outline -// // TODO: complete the stats Value Lane -// // @SwimLane("stats") -// -// // HINT: Use the valueLane() method to instantiate the lane -// // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats -// -// @SwimLane("histogram") -// private final MapLane histogram = this.mapLane() -// .didUpdate((k, n, o) -> { -// logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); -// // TODO: update stats with update logic -// -// dropOldData(); -// -// }) -// .didRemove((k,o) -> { -// // TODO: update stats with remove logic -// -// }); + // TODO: complete the stats Value Lane + // @SwimLane("stats") + + // HINT: Use the valueLane() method to instantiate the lane + // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats + + @SwimLane("histogram") + private final MapLane histogram = this.mapLane() + .didUpdate((k, n, o) -> { + logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); + // TODO: update stats with update logic + + // HINT: access new data sent to histogram with + // n.getItem(0).longValue() + // HINT: use this data to calculate stats such as mean, variance, std dev, etc + // HINT: send new data to stats lane by calling + // stats.set($TRANSFORMED_DATA) + + dropOldData(); + + }) + .didRemove((k,o) -> { + // TODO: update stats with remove logic + + }); @SwimLane("history") private final ListLane history = this.listLane() From 2515c3d96f553c691bc3557c48c6f65f734b5760 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 15:14:41 -0700 Subject: [PATCH 12/17] made tutorial vs solutions code clearer --- .../main/java/swim/tutorial/DataSource.java | 2 +- .../main/java/swim/tutorial/UnitAgent.java | 54 ++++++++++--------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index 0020601..c281b26 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -46,7 +46,7 @@ void sendCommands() throws InterruptedException { // TODO: Create two new web agents using the above format - // EXAMPLE SOLUTION: + // ***** EXAMPLE SOLUTION ****** // this.ref.command(this.hostUri, "/unit/secondAgent", "publish", msg); // this.ref.command(this.hostUri, "/unit/thirdAgent", "publish", msg); diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index 0db298a..b643702 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -12,6 +12,8 @@ import java.util.Iterator; public class UnitAgent extends AbstractAgent { + + // ***** EXAMPLE SOLUTION ****** // instance variables to track metrics going into stats private long count_sum = 0; private int count_total = 0; @@ -90,33 +92,33 @@ public class UnitAgent extends AbstractAgent { - // tutorial outline - - // TODO: complete the stats Value Lane - // @SwimLane("stats") - - // HINT: Use the valueLane() method to instantiate the lane - // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats + // ***** TUTORIAL TEMPLATE ****** - @SwimLane("histogram") - private final MapLane histogram = this.mapLane() - .didUpdate((k, n, o) -> { - logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); - // TODO: update stats with update logic - - // HINT: access new data sent to histogram with - // n.getItem(0).longValue() - // HINT: use this data to calculate stats such as mean, variance, std dev, etc - // HINT: send new data to stats lane by calling - // stats.set($TRANSFORMED_DATA) - - dropOldData(); - - }) - .didRemove((k,o) -> { - // TODO: update stats with remove logic - - }); +// // TODO: complete the stats Value Lane +// // @SwimLane("stats") +// +// // HINT: Use the valueLane() method to instantiate the lane +// // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats +// +// @SwimLane("histogram") +// private final MapLane histogram = this.mapLane() +// .didUpdate((k, n, o) -> { +// logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); +// // TODO: update stats with update logic +// +// // HINT: access new data sent to histogram with +// // n.getItem(0).longValue() +// // HINT: use this data to calculate stats such as mean, variance, std dev, etc +// // HINT: send new data to stats lane by calling +// // stats.set($TRANSFORMED_DATA) +// +// dropOldData(); +// +// }) +// .didRemove((k,o) -> { +// // TODO: update stats with remove logic +// +// }); @SwimLane("history") private final ListLane history = this.listLane() From a40e4930568fa9f8e5417c020f632f2bbfca7938 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 15:54:08 -0700 Subject: [PATCH 13/17] remove solutions on this branch --- .../main/java/swim/tutorial/DataSource.java | 9 +- .../main/java/swim/tutorial/UnitAgent.java | 132 ++++-------------- 2 files changed, 30 insertions(+), 111 deletions(-) diff --git a/server/src/main/java/swim/tutorial/DataSource.java b/server/src/main/java/swim/tutorial/DataSource.java index c281b26..5f30ad4 100644 --- a/server/src/main/java/swim/tutorial/DataSource.java +++ b/server/src/main/java/swim/tutorial/DataSource.java @@ -41,14 +41,11 @@ void sendCommands() throws InterruptedException { // *(Swim) server* addressable by hostUri this.ref.command(this.hostUri, "/unit/master", "publish", msg); - // To instantiate more agents, follow the format of the URI pattern specified in TutorialPlane - // see line 12: @SwimRoute("/unit/:id") - // TODO: Create two new web agents using the above format - // ***** EXAMPLE SOLUTION ****** - // this.ref.command(this.hostUri, "/unit/secondAgent", "publish", msg); - // this.ref.command(this.hostUri, "/unit/thirdAgent", "publish", msg); + // To instantiate more agents, follow the format of the URI pattern specified in TutorialPlane + // HINT: see line 12: @SwimRoute("/unit/:id") + indicator = (indicator + 1) % 1000; diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index b643702..a0c1836 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -12,113 +12,35 @@ import java.util.Iterator; public class UnitAgent extends AbstractAgent { + + // TODO: complete the stats Value Lane + // @SwimLane("stats") - // ***** EXAMPLE SOLUTION ****** - // instance variables to track metrics going into stats - private long count_sum = 0; - private int count_total = 0; - private int index = 0; - private long[] recent_data = new long[5]; - - - @SwimLane("stats_1") - private final ValueLane stats_1 = this.valueLane() - .didSet((n, o) -> { - logMessage("stats_1: mean updated to " + n + " from " + o); - }); - - @SwimLane("stats_2") - private final ValueLane stats_2 = this.valueLane() - .didSet((n, o) -> { - logMessage("stats_2: local median (last 5 entries) updated to " + n + " from " + o); - }); - - @SwimLane("stats_3") - private final ValueLane stats_3 = this.valueLane() - .didSet((n, o) -> { - logMessage("stats_3: local variance (last 5 entries) updated to " + n + " from " + o); - }); - - @SwimLane("stats_4") - private final ValueLane stats_4 = this.valueLane() - .didSet((n, o) -> { - logMessage("stats_4: local std deviation (last 5 entries) updated to " + n + " from " + o); - }); + // HINT: Use the valueLane() method to instantiate the lane + // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats - - @SwimLane("histogram") - private final MapLane histogram = this.mapLane() - .didUpdate((k, n, o) -> { - logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); - - // calculating overall mean to send to stats1 - count_sum += n.getItem(0).longValue(); - count_total ++; - final long avg = count_sum / count_total; - stats_1.set(avg); - - // appending new data to the recent_data array - if (index >= recent_data.length-1) { - index = 0; - } - recent_data[index] = n.getItem(0).longValue(); - index ++; - - // calculating local mean to send to stats2 - long local_sum = 0; - for (long d : recent_data) local_sum += d; - final long local_avg = local_sum / (long) recent_data.length; - stats_2.set(local_avg); - - // calculating local variance to send to stats3 - long squared_dif_sum = 0; // (sum of local mean - each value)^2 - for (long d : recent_data) squared_dif_sum += (d - local_avg)*(d - local_avg); - long local_variance = squared_dif_sum/recent_data.length; - stats_3.set(local_variance); - - // calculating local standard deviation to send to stats4 - double local_std_dev = Math.sqrt(local_variance); - stats_4.set((long)local_std_dev); - - dropOldData(); - }) - .didRemove((k,o) -> { - // update stats with remove logic - logMessage("histogram: removed <" + k + "," + Recon.toString(o) + ">"); - count_sum = 0; - count_total = 0; - index = 0; - }); - - - - // ***** TUTORIAL TEMPLATE ****** - -// // TODO: complete the stats Value Lane -// // @SwimLane("stats") -// -// // HINT: Use the valueLane() method to instantiate the lane -// // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats -// -// @SwimLane("histogram") -// private final MapLane histogram = this.mapLane() -// .didUpdate((k, n, o) -> { -// logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); -// // TODO: update stats with update logic -// -// // HINT: access new data sent to histogram with -// // n.getItem(0).longValue() -// // HINT: use this data to calculate stats such as mean, variance, std dev, etc -// // HINT: send new data to stats lane by calling -// // stats.set($TRANSFORMED_DATA) -// -// dropOldData(); -// -// }) -// .didRemove((k,o) -> { -// // TODO: update stats with remove logic -// -// }); + @SwimLane("histogram") + private final MapLane histogram = this.mapLane() + .didUpdate((k, n, o) -> { + logMessage("histogram: replaced " + k + "'s value to " + Recon.toString(n) + " from " + Recon.toString(o)); + + // TODO: update stats with update logic + + // HINT: access new data sent to histogram with + // n.getItem(0).longValue() + + // HINT: use this data to calculate stats such as mean, variance, std dev, etc + + // HINT: send new data to stats lane by calling + // stats.set($TRANSFORMED_DATA) + + dropOldData(); + + }) + .didRemove((k,o) -> { + // TODO: update stats with remove logic + + }); @SwimLane("history") private final ListLane history = this.listLane() From 1df90860f11a827f58ebe08738af3953ebb00cf7 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 17:29:51 -0700 Subject: [PATCH 14/17] add suggestions to change UI after server exercises --- ui/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/README.md b/ui/README.md index 6821f30..049348c 100644 --- a/ui/README.md +++ b/ui/README.md @@ -4,6 +4,11 @@ The minimum you need to visualize Swim data is a Swim client. That said, Swim comes with additional tools that let you see your data right away with no extra work. +#### *Try it yourself:* + +- [ ] *Based on changes suggested in* [*the server README*](https://github.com/swimos/tutorial/blob/tutorial_solutions/server/README.md) *, update the UI code to accommodate your new server-side* +- [ ] *See the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch for an example of this* + Read [chart.html](http://github.com/swimos/tutorial/tree/master/ui/chart.html) to build your own line chart. Read [gauge.html](http://github.com/swimos/tutorial/tree/master/ui/gauge.html) to build your own gauge. From 0ba42c3ac1e35a56595a257e35af8d216394acf1 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Wed, 8 Jul 2020 17:30:43 -0700 Subject: [PATCH 15/17] add suggestions to change UI after server exercises --- server/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/README.md b/server/README.md index 4dd9b71..9492f62 100644 --- a/server/README.md +++ b/server/README.md @@ -54,3 +54,10 @@ Visit the [documentation](https://developer.swim.ai/concepts) for further detail Swim client instances use Swim **links** to pull data from a Swim lanes. Like their corresponding lanes, links have overridable callback functions that can be used to [populate UIs](http://github.com/swimos/tutorial/tree/master/ui/index.html#L116-L141). Visit the [documentation](https://developer.swim.ai/concepts/links/) for further details about links. + +## *Visualizing Your Changes in the UI* + +- [ ] *Consider how the above changes to the server code may change the way you'd want to visualize your data* +- [ ] *Navigate to the [ui folder](https://github.com/swimos/tutorial/tree/master/ui)* +- [ ] *Experiment with the UI code to accommodate for your server-side changes* +- [ ] *See the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch for an example of this* From 5d0c0181e7510612914a54f005d6f7b156ac49b8 Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Tue, 14 Jul 2020 11:31:36 -0700 Subject: [PATCH 16/17] clarify instructions for creating stats lane(s) and .get('count') for histogram --- .../main/java/swim/tutorial/UnitAgent.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/swim/tutorial/UnitAgent.java b/server/src/main/java/swim/tutorial/UnitAgent.java index a0c1836..435b869 100644 --- a/server/src/main/java/swim/tutorial/UnitAgent.java +++ b/server/src/main/java/swim/tutorial/UnitAgent.java @@ -13,12 +13,22 @@ public class UnitAgent extends AbstractAgent { - // TODO: complete the stats Value Lane - // @SwimLane("stats") + // TODO: implement new Value Lane(s) for stats + // HINT: start by declaring @SwimLane("name") // HINT: Use the valueLane() method to instantiate the lane // HINT: Use the .didSet() lifecycle callback to log a message showing updates to stats + + // consider creating more value lanes for stats with single values such as + // @SwimLane("avg") + // private final ValueLane avg = this.valueLane() + + + // you may also prefer one value lane with more than one statistic stored as a Value + // @SwimLane("stats") + // private final ValueLane stats = this.valueLane() + @SwimLane("histogram") private final MapLane histogram = this.mapLane() .didUpdate((k, n, o) -> { @@ -27,12 +37,19 @@ public class UnitAgent extends AbstractAgent { // TODO: update stats with update logic // HINT: access new data sent to histogram with - // n.getItem(0).longValue() + + // RECOMMENDED, to get a value by specifying its key: + // n.get("count").longValue() + + // ALTERNATIVELY, to get the first Item slot (equivalent result here as ^): + // n.getItem(0).longValue() + // HINT: use this data to calculate stats such as mean, variance, std dev, etc + // HINT: send new data to stats lane by calling - // stats.set($TRANSFORMED_DATA) + // stats.set($TRANSFORMED_DATA) dropOldData(); From 5f018400a98518fe799c526fe5e8fe5af120656e Mon Sep 17 00:00:00 2001 From: Crista2019 Date: Tue, 14 Jul 2020 15:49:47 -0700 Subject: [PATCH 17/17] update paths to solutions branch --- server/README.md | 6 +++--- ui/README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/README.md b/server/README.md index 9492f62..07c6c4f 100644 --- a/server/README.md +++ b/server/README.md @@ -13,7 +13,7 @@ Swim implements a general purpose distributed object model. The "objects" in thi #### *Try it yourself:* - [ ] *Navigate to [swim.tutorial.DataSource.java](https://github.com/swimos/tutorial/blob/master/server/src/main/java/swim/tutorial/DataSource.java)* - [ ] *Create additional web agents using the instructions in the code* -- [ ] *Compare your answer with those in the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch* +- [ ] *Compare your answer with those in the [**solutions**](https://github.com/swimos/tutorial/tree/solutions) branch* Visit the [documentation](https://developer.swim.ai/concepts/agents/) for further details about Web Agents. @@ -29,7 +29,7 @@ Each lane type defines a set of overridable (default no-op) lifecycle callbacks. - [ ] *Navigate to [swim.tutorial.UnitAgent.java](https://github.com/swimos/tutorial/blob/master/server/src/main/java/swim/tutorial/UnitAgent.java)* - [ ] *Fill in the remaining code to create a new value lane called `stats` which gets populated by changes to the `histogram` map lane* - [ ] *Experiment with ways to transform the data entries in histogram. Ideas: mean, median, range, standard deviation, variance, etc!* -- [ ] *Compare your answer with those in the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch* +- [ ] *Compare your answer with those in the [**solutions**](https://github.com/swimos/tutorial/tree/solutions) branch* Visit the [documentation](https://developer.swim.ai/concepts/lanes/) for further details about lanes. @@ -60,4 +60,4 @@ Visit the [documentation](https://developer.swim.ai/concepts/links/) for further - [ ] *Consider how the above changes to the server code may change the way you'd want to visualize your data* - [ ] *Navigate to the [ui folder](https://github.com/swimos/tutorial/tree/master/ui)* - [ ] *Experiment with the UI code to accommodate for your server-side changes* -- [ ] *See the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch for an example of this* +- [ ] *See the [**solutions**](https://github.com/swimos/tutorial/tree/solutions) branch for an example of this* diff --git a/ui/README.md b/ui/README.md index 049348c..9c43679 100644 --- a/ui/README.md +++ b/ui/README.md @@ -7,7 +7,7 @@ The minimum you need to visualize Swim data is a Swim client. That said, Swim co #### *Try it yourself:* - [ ] *Based on changes suggested in* [*the server README*](https://github.com/swimos/tutorial/blob/tutorial_solutions/server/README.md) *, update the UI code to accommodate your new server-side* -- [ ] *See the [**tutorial_solutions**](https://github.com/swimos/tutorial/tree/tutorial_solutions) branch for an example of this* +- [ ] *See the [**solutions**](https://github.com/swimos/tutorial/tree/solutions) branch for an example of this* Read [chart.html](http://github.com/swimos/tutorial/tree/master/ui/chart.html) to build your own line chart.