How to convert of Stream of Mono to Flux or reduce a stream of Mono to a Mono using sum operation - spring-webflux

My code is as below. I need to get a fare from mongo db for each trip, and then sum all the fares for each trip to get the total fare. I am stuck with a stream of Mono that I do not know how to read from. I tried converting this to a Flux, but I am getting a Flux<Mono>, which is not what I want. Please help!! Or how can we reduce a Stream of Mono to a Mono?
private int calculateDailyRate(final Entry<LocalDate, List<Trip>> entry) {
int dailyFare = 0;
List<Trip> trips = entry.getValue();
// Get the fare for each trip, and then sum up the list of fares to get the daily total fare
trips.stream().map(trip->fareLookupRepo.getFareRules(trip.getSecondOfDay(), trip.getTripDate().getDayOfWeek().getValue(),
trip.getFromZone(), trip.getToZone()).sort(Comparator.comparing(FareRule::getRate)).next().map(FareRule::getRate));
return dailyFare;
}
'''

I am not sure if your logic is correct, because your can be dates with entires.
But here is hint how to do what you try to achive.
return Flux.fromIterable(trips)
.flatMap(trip-> fareLookupRepo.getFareRules(trip.getSecondOfDay(), trip.getTripDate().getDayOfWeek().getValue(),
trip.getFromZone(), trip.getToZone())
.flatMap(trip-> Mono.just(trip.getRate())))
.reduce(0, (x1, x2)-> x1 + x2)
Note: fareLookupRepo.getFareRules it should return mono

Related

Trying to build a PC (counter) for the nand2tetris , but I'm having some trouble with the logic

The project aims to build a program counter.
The description are as follows:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/03/a/PC.hdl
/**
* A 16-bit counter with load and reset control bits.
* if (reset[t] == 1) out[t+1] = 0
* else if (load[t] == 1) out[t+1] = in[t]
* else if (inc[t] == 1) out[t+1] = out[t] + 1 (integer addition)
* else out[t+1] = out[t]
*/
I figured out all the possibilities as follows
All possible output
Then here I go:
CHIP PC
{
IN in[16],load,inc,reset;
OUT out[16];
PARTS:
// Put your code here:
Register(in=in, load=true, out=thein);
Register(in=in, load=false, out=theout);
Inc16(in=theout, out=forinc);
Register(in=forinc, load=true, out=theinc);
Mux8Way16(a=theout, b=false, c=theinc, d=false, e=thein, f=false, g=thein, h=false, sel[2]=load, sel[1]=inc, sel[0]=reset, out=out);
}
I tried many times but all failed when the clock load to time 1+ or something like this.
Since the register defined here is out(t+1) = out(t)
what is the output of time ?+.I found it really annoying.
Any suggestions will be appreciated.
Some observations:
You're storing the output in a register, which is good. However, note that the register output is also one of your inputs -- it is out[t].
You don't need a big Mux8Way16. There are 4 possible different outputs, so you can either use multiple Mux16s in a cascade or (extra credit) a single Mux4Way16 with some extra logic to compute the two selection bits.
I usually found that the simplest way to do things was first compute all the possible outputs (in this case, 0, input, register+1 or register) and then have the logic to decide which one of those actually gets output.
Good luck. You are very close.

Getting metrics out of AWS Cloudwatch using Java API:

I am trying to get metrics out of Amazon CloudWatch using the Java SDK.
I can find examples of listing out metrics. But just can't find any full example showing how to retrieve values for a metric for a given period.
Any pointers will be highly appreciated.
Thanks
Have you seen the GetMetricDataRequest documentation?
Should be straight forward. Something along these lines. (Note, I haven't tested the code).
final GetMetricDataRequest getMetricDataRequest = new GetMetricDataRequest();
final MetricDataQuery metricDataQuery = new MetricDataQuery();
metricDataQuery.setId("METRIC_ID");
final MetricStat metricStat = new MetricStat();
final Metric metric = new Metric();
final Dimension dimension = new Dimension();
nodeCountMetric.setNamespace(namespace);
dimension.setName("DIMENSION_KEY");
dimension.setValue("value");
metric.setDimensions(Collections.singletonList(dimension));
metric.setMetricName(metricName);
metricStat.setMetric(metric);
metricStat.setPeriod(SECONDS_60);
metricStat.setStat(SAMPLE_COUNT_STATISTIC);
metricDataQuery.setMetricStat(metricStat);
getMetricDataRequest.setMetricDataQueries(Collections.singletonList(metricDataQuery));
final Date endTime = new Date();
getMetricDataRequest.setEndTime(endTime);
getMetricDataRequest.setStartTime(new Date(endTime.getTime() - HOURS_3));
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
GetMetricDataResult metricData = cw.getMetricData(metricDataRequest);

How to carry out multiple SI acquisition automatically?

I would like to write a Gatan DigitalMicrograph script to acquire multiple EELS spectrum images continuously. If there is a command to obtain Spectrum Image (SI) data, and store the three-dimensional image to an array, I will achieve my plan. However, I could not find appropriate commands for SI imaging mode from reference manual. What command should I use in this case? Do you have a helpful knowledge for my purpose? It will be appreciated if you share some wisdom.
A short demo-script of how to use the SIAcquisition commands for multiple iterations of SI acquisition and "renaming" the acquired data sets.
// Assumptions:
// - GMS 2.3 used
// - Valid survey image and ROI already assigned
// - SI array size already defined
// - Signals and other SI settings made
number SIx, SIy
SIGetFieldValue( "2D Array, X samples", SIx )
SIGetFieldValue( "2D Array, Y samples", SIy )
Result("\n SI size:"+ SIx + "x" + SIy )
// Start SI
number nSI = 3
for (number i=0; i<nSI; i++ )
{
SIInvokeButton( "Start/Stop", 1 )
while(SIIsAcquisitionActive()) yield()
sleep(0.5) // Small delay needed to allow DM finish SI acquisition clean-up
// Find (and rename) SI DataSets
number nImgDoc = CountImageDocuments()
string findStr = "Spectrum Image"
for (number d=0; d<nImgDoc; d++ )
{
string docName = GetImageDocument(d).ImageDocumentGetName()
if ( find(docName,findStr) == (len(docName)-len(findStr)) )
{
GetImageDocument(d).ImageDocumentSetName( docName + "#"+(d+1) )
}
}
}
OKDialog( "Done" )
If you have the spectrum-imaging plugin installed, then the F1 help file will have a section on STEM SI scripting commands here...
However, the commands described there will allow the acquisition of one SI after the other. Each will start anew with the same overhead you get when repeatedly starting SI acquisition via the UI.
I've got the impression you want to get a "faster" repeated SI.
Unfortunately, no commands exist which could easily give you that.
However, you might be able to create a "work-arround" solution by the following idea (untested):
Set up a STEM SI with multiple-frames (Each frame pass will be summed into the same container)
Use the "SI HookUP Scripts" on a per-pixel basis (Pixel end) to catch the "last" acquired SI point (before the new frame starts). Use this to copy the existing data into a new container and set the orignal back to zero.
Alternative:
You might also be able to use the "Correction start" HookUp script point, if you set spatial drift-correction to perform at end of frame...
The above will only work with software-synchronized SI's. For hardware-synchronized, it becomes more tricky, but you might be able to do something similar with a "ImageUpdate" event-listener.

Google maps route tracking

I'm using Google Maps to generate driving directions. I'd like to have a feature that would estimate where in the route someone is, based on the elapse time, and the total time from Google, and drop a pin (possibly a moving pin) where they're estimated to by.
I know how to generate the map in Google, but that's about where the limit of my knowledge is. How would I drop the pin in the approx location.
I'm thinking converting the total time into seconds, the elapse time into seconds and divide to get the percentage completed on the route. How would I drop a pin to the route location where this would be? Moreover, could I move the pin maybe updated every 30 - 60 seconds?
The duration attribute of Maps results is already in seconds. With that in mind, you can, in a sense, follow the route -> legs -> steps duration to give you a rough idea of how far along the trip each step is.
Now that you know the rough idea of how far into the trip each step is, you can do a comparison with the elapsed time to see which step they should be on. Once you've verified the correct step, you can use the step's lat_lngs to place a marker. lat_lngs is the array of points passed during that step, so you can work out which lat_lng to place the marker at based on the elapsed time compared to the time they should have been starting the step and the time when they should be finishing it.
Here's some code that won't run on your application, and doesn't include any real elapsed time logic, so it's best to treat it as pseudocode:
// route is a directionsService (google.maps.DirectionsService()) result
route = response.routes[0];
route.legs.forEach(function(leg) {
var counter = 0;
leg.steps.forEach(function(step) {
counter = counter + step.duration.value;
console.log("Route progress in seconds: " + counter);
if (elapsed >= counter) {
// percent would take the beginning and end time for the step
// and compare it to the elapsed duration to get a percentage
// that would be used to get the index of the appropriate lat_lng
var marker = new google.maps.Marker({
position: step.lat_lngs[percent],
map: map,
title: "Current Location"
});
}
});
});
You'd have to create your own logic for actually updating the map and such, but hopefully this is a decent starting point.

twiiter4j when to STOP when no more tweets available?

So, I've figured out how to be able to get more than 100 tweets, thanks to How to retrieve more than 100 results using Twitter4j
However, when do I make the script stop and print stop when maximum results have been reached? For example, I set
int numberOfTweets = 512;
And, it finds just 82 tweets matching my query.
However, because of:
while (tweets.size () < numberOfTweets)
it still continues to keep on querying over and over until I max out my rate limit of 180 requests per 15 seconds.
I'm really a novice at java, so I would really appreciate if you could show me how to resolve this by modifying the first answer script at How to retrieve more than 100 results using Twitter4j
Thanks in advance!
You only need to modify things in the try{} block. One solution is to check whether the ID of the last tweet you found on the previous loop(previousLastID) in the while is the same as the ID of the last tweet (lastID) in the new batch collected (newTweets). If it is, it means the new batch's elements already exist in the previous array, and that that we have reached the end of possible tweets for this hastag.
try {
QueryResult result = twitter.search(query);
List<Status> newTweets = result.getTweets();
long previousLastID = lastID;
for (Status t: newTweets)
if (t.getId() < lastID) lastID = t.getId();
if (previousLastID == lastID) {
println("Last batch (" + tweets.size() + " tweets) was the same as first. Stopping the Gathering process");
break;
}