Laravel Carbon - Calculate time between database entries - laravel

I am trying to calculate de difference between two datetimes.
I have two Models, tasks and task_interactions, they are related like this: tasks has many task_interactions, and task_interactions belongs to tasks.
The user can change the status of a task to one of these: "In progress", "Paused" and Finished. The user change the status several times between "In Progress" and "Paused", but once it's finished, the user cannot change the task status anymore.
All interactions are saved in the task_interactions table, with created_by as user_id and created_at as the datetime. the table has these columns: id ; task_id ; status ; comments ; created_by ; created_at.
Here's na exemple for task id = 1:
# id, task_id, status, comments, created_by, created_at
144, 1, In Progress, , 1, 2017-11-14 09:42:20
145, 1, Paused, , 1, 2017-11-14 09:45:53
146, 1, In Progress, , 1, 2017-11-14 09:46:57
147, 1, Paused, , 1, 2017-11-14 09:49:57
148, 1, In Progress, , 1, 2017-11-14 10:00:10
149, 1, Paused, , 1, 2017-11-14 10:06:25
150, 1, In Progress, , 1, 2017-11-14 10:07:26
151, 1, Paused, , 1, 2017-11-14 10:08:11
153, 1, Paused, , 1, 2017-11-14 11:27:04
154, 1, In Progress, , 1, 2017-11-14 11:27:21
155, 1, Paused, , 1, 2017-11-14 11:57:38
The thing is, for me to have the total time spent in one task, i have to determine the time between In Progress and Paused. The time between Paused and In Progress is not relevant.
I am strugling with this. Is there anyone who can help me?
Thanks in advance.
Just one more thing, i am not very experienced, so pardon if my questions sound a bit dummer, I believe that i should do a #foreach loop through all task_interactions where task_id = X, and thats all i know.
As asked, here's the data i am passing for the view:
public function mytasks()
{
$users = User::all();
$mytasks = Task::where('assigned_to','=', Auth::id())->where('status','!=','Finished')->get();
$mytaskscount = Task::where('assigned_to','=', Auth::id())->count();
$tasksinprogress = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->get();
$tasksinprogresscount = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->count();
$taskspaused = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->get();
$taskspausedcount = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->count();
$tasksfinished = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->get();
$tasksfinishedcount = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->count();
$tasktypes = Tasktype::all();
$chapters = Chapter::all();
return view('pages.tasks_my', compact('mytasks','tasktypes','chapters','tasksinprogress','taskspaused','tasksfinished','mytaskscount','tasksinprogresscount','taskspausedcount','tasksfinishedcount'));
}
And one more thing, what i know so far
#foreach ($tasks as $task)
#foreach ($task->interactions as $interactions)
{{ In here, every time my loop returns a status = "In progress" i should mark that time, and if that the next loop returns a "Paused", i should count the difference between these two. And sum all other equal cases in the loop. }}
#endforeach
#endforeach
I realy have no idea on how to do that

I would recommend David's answer. If you are not comfortable doing it using MySQL. You may have to do it like this:
Calculate difference between first time a task was started & when it was paused:
$start = Carbon::parse($startTask->created_at);
$pause = Carbon::parse($endTask->created_at);
$diffInSeconds = $pause->diffInSeconds($start)
This should give you the total difference in seconds as to when a tasks was started & then paused. Now you have to repeat this approach for when again a task was started & then paused.

This is strict Mysql, but should do the trick.
You can call this in laravel directly using raw sql instruction, or you should probably rework this into Laravel code.
select SEC_TO_TIME(
sum(
timediff(
if(task_end.created_at is null,
NOW(),
task_end.created_at),
task_start.created_at)))
from task_interactions task_start
left join task_interactions task_end
ON task_end.task_id = task_start.task_id
AND task_end.status IN ('Pause', 'Finished')
AND task_end.created_at = (
SELECT min(created_at)
FROM task_interactions
WHERE status = task_end.status
AND created_at >= task_start.created_at
)
WHERE task_start.task_id = 1
AND task_start.status = 'In Progress'

Related

what to do to make shinyapp give me my output

The primary variable is AgeGroup which has 2 levels. I am trying to get the sample size to output, but for some reason the app either gives error or wont output anything. Can anyone help? The are some comments in the code to help with confusion
Code:
library(shiny)
library(shinyWidgets)
library(survival)
library(shinyjs)
library(survminer)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("ProMBA Haslam Ad Sample Size"),
#Put in all key5 inputs as numeric inputs that the user will type in and choose starting, default values for these inputs
tabPanel("Inputs",
div( id ="form",
column(4,
numericInput("power", label=h6("Power"), value = .9),
numericInput("alpha", label=h6("Alpha"), value = .05),
numericInput("precision", label=h6("Precision"), value =0.05),
numericInput("Delta", label=h6("Delta"), value=.3),
column(4,
numericInput("sample", label=h6("Starting Sample Size"), value = 40),
numericInput("reps", label=h6("Number of Replications"), value=1000)),
),
column(4,
#title of output
h4("Calculated Sample Size"),
verbatimTextOutput(("n"),placeholder=TRUE)),
#create action buttons for users to run the form and to reset the form
textOutput("Sample Size (n)"),
column(4,
actionButton("action","Calculate"))
)))
server = function(input,output,session){
buttonGo = eventReactive(input$action, {withProgress(message = "Running", {
#relist the key inputs and save them to be able to be used in the rest of the code
n<-input$sample/2
alpha<-input$alpha
power <- input$power
beta<-1-input$power
precision<-input$precision
delta <- input$Delta +1
rep <- input$reps
nincrease<-10
#manually5 load in the data from the baseline data .xlxs file
Reporting <- c("12/13/21","12/14/21","12/15/21","12/16/21","12/17/21","12/18/21","12/19/21","12/20/21","12/21/21","12/22/21","12/23/21","12/24/21","12/25/21","12/26/21","12/27/21","12/28/21","12/29/21","12/30/21","12/31/21","1/1/22")
AdSet <- "Status Quo"
Results <- c(70,52, 33, 84, 37, 41, 22, 53, 78, 66, 100, 110, 52, 43, 63, 84, 16, 64, 21, 69)
ResultIndicator <- "actions:link_click"
Budget <- 100
CostPerClick<- c(1.43, 1.92, 3.03, 1.19, 2.70, 2.44, 4.55, 1.89, 1.28, 1.52, 1.00, 0.91, 1.92, 2.33, 1.59, 1.19, 6.25, 1.56, 4.76, 1.45)
Impressions <- c(7020, 8430, 5850, 7920, 6890, 7150, 6150, 7370, 8440, 6590, 6750,8720, 6410,7720, 6940, 8010, 7520, 7190, 6540, 6020)
df <- data.frame(Reporting, AdSet, Results, ResultIndicator,Budget,CostPerClick,Impressions)
#define the standard deviation of the results as well as the mean for group 1 of the 2 level variable and the mean for group 2
mean1 = mean(df$Results)
sd1 = sd(df$Results)
mean2 = delta*mean1
click=rep(0,n)
#Create 2 level variable
AgeGroup <- rep(c("Age21-35","Age36-50"),each=n)
#create new data frame with 2 level variable and click repetitions
DataFrame2 <- data.frame(AgeGroup,click)
#create new data frame binding all of the input variables together
DataFrame3 <- data.frame(cbind(n,alpha,power,precision,delta,rep))
#create for loop to find the pvalue of the ttest run with click~AgeGroup
trials=function(){
for(i in 1:nrow(DataFrame2)){
if(any(DataFrame2$AgeGroup[i]=="Age21-35")){DataFrame2$click[i] =rnorm(1,mean1,sd1)}else{DataFrame2$click[i] =rnorm(1,mean2,sd1)}
}
pvalttest=t.test(click~AgeGroup, data=DataFrame2)
return(pvalttest$p.value)
}
p_values=replicate(200,trials())
p_values=replicate(input$rep,trials())
#find if the p value is significance
significance=p_values[p_values<alpha]
#find the power of the signifiance and the pvalue
power <- length(significance)/length(p_values)
print(c(power,n))
#run a while loop to find the n within the goal power limits
goalpower<-1-beta
lowergoal<-goalpower-input$precision
uppergoal<-goalpower+input$precision
while (power<lowergoal||power>uppergoal){
if (power<lowergoal){
n=n+nincrease
AgeGroup=c()
click=c()
AgeGroup=rep(c("Age21-35","Age36-50"), each=n)
click=rep(NA,2*n)
Dataframe2=data.frame(AgeGroup,click)
p_values=replicate(input$reps, trials())
significance=p_values[p_values<alpha]
power=length(significance)/length(p_values)
print(c(n, power))
}else{
nincrease=nincrease%/%(10/9) #%/% fixes issue of rounding
n=n-nincrease
AgeGroup=c()
click=c()
AgeGroup=rep(c("Age21-35","Age36-50"), each=n)
click=rep(NA,2*n)
DataFrame2=data.frame(AgeGroup,click)
p_values=replicate(input$reps, trials())
significance=p_values[p_values<alpha]
power=length(significance)/length(p_values)
print(c(n, power))
}
}
#n is defined as the sample size of one of the levels of the 2 level variable, so mulitply by 2 to get full sample size
n*2
})
}
shinyApp(ui, server)
i dont need the app to be pretty. I just want it to run whenever someone clicks the calculate button

How to calculate average for each tumbling window?

I’m new in kafka streams and I’m really going crazy. I have a stream of counter values represented by <counter-name, counter-value, timestamp>. I want to calculate the average value for each day, like this:
counterValues topic content:
“cpu”, 10, “2022-06-03 17:00”
“cpu”, 20, “2022-06-03 18:00”
“cpu”, 30, “2022-06-04 10:00”
“memory”, 40, “2022-06-04 10:00”
and I want to obtain this output:
“cpu”, “2022-06-03”, 15
“cpu”, “2022-06-04”, 30
“memory”, “2022-06-04”, 40
This is a snippet of my code that it doesn’t work (it seems to calculate count)…
Duration windowSize = Duration.ofDays(1);
TimeWindows tumblingWindow = TimeWindows.of(windowSize);
counterValueStream
.groupByKey().windowedBy(tumblingWindow)
.aggregate(StatisticValue::new, (k, counterValue, statisticValue) -> {
statisticValue.setSamplesNumber(statisticValue.getSamplesNumber() + 1);
statisticValue.setSum(statisticValue.getSum() + counterValue.getValue());
return statisticValue;
}, Materialized.with(Serdes.String(), statisticValueSerde))
.toStream().map((Windowed<String> key, StatisticValue sv) -> {
double avgNoFormat = sv.getSum() / (double) sv.getSamplesNumber();
double formattedAvg = Double.parseDouble(String.format("%.2f", avgNoFormat));
return new KeyValue<>(key.key(), formattedAvg) ;
}).to("average", Produced.with(Serdes.String(), Serdes.Double()));
But the aggregation result is:
“cpu”, 1, “2022-06-03 17:00”
“cpu”, 1, “2022-06-03 18:00”
“cpu”, 1, “2022-06-04 10:00”
“memory”, 1, “2022-06-04 10:00”
Note that I use a TimestampExtractor that use counter timestamp instead of kafka record. What am I doing wrong?

use for loop to call multiple functions in lua

I want to call multiple methods in lua that are very similar except their parameters change by one character. The way I'm doing it now works but is extremely in efficient.
function scene:createScene(event)
screenGroup = self.view
level1= display.newRoundedRect( 50, 110, 50, 50, 5 )
level1:setFillColor( 100,0,200 )
level2= display.newRoundedRect( 105, 110, 50, 50, 5 )
level2:setFillColor (100,200,0)
--and so on so forth
screenGroup:insert (level1)
screenGroup:insert (level2)
screenGroup:insert (level3)
screenGroup:insert (level4)
end
I plan on extending the screenGroop:insert method to hundreds of levels, maybe up to (level300). As you can see the way I'm doing it now is inefficient. I tried doing
for i=1, 4, 1 do
screenGroup:insert(level..i)
end
but I get the error "table expected."
The best way in this case is to probably use a table:
local levels = {}
levels[1] = display.newRoundedRect( 50, 110, 50, 50, 5 )
levels[1]:setFillColor( 100,0,200 )
levels[2] = display.newRoundedRect( 105, 110, 50, 50, 5 )
levels[2]:setFillColor (100,200,0)
--and so on so forth
for _, level in ipairs(levels) do
screenGroup:insert(level)
end
For other alternatives check the SO answer from #EtanReisner's comment.
If your 'level' tables are global, which is appears they are, you can use getfenv to index them.
for i = 1, number_of_levels do
screenGroup:insert(getfenv()["level" .. i])
end
getfenv returns the environment, with all global variables, in the form of a dictionary. Therefore, you can index it like a normal table like getfenv()["key"]

Sum field in sub query in Linq giving Cannot Assign Method error

I want to be able to group a sub-linq query, but LinqPad is giving an error at this line:
ratetocharge =rtc.rate.Sum
The error is: Cannot assign method group to anonymous type property.
Could anyone advise what I should enter in that line, to give me a sum of the rate within the rates table?
Thank you,
Mark
var mtgRooms = RoomUnit
.Where(r => r.building_id==1)
.GroupBy(p => p.Type)
.Select(g => new
{
TypeName = g.Key.type_name,
TypeID = g.Key.type_id,
TypeCount = g.Count(),
rates = rates
.Select ( rtc =>
new
{
occ = rtc.occ,
ratetocharge =rtc.rate.Sum // this is the line which errors
}
)
.GroupBy(pe => pe.occ)
}
);
mtgRooms.Dump();
EDIT: To add further detail
Tables:
Table RoomUnit
type_id (key - int)
type_name (string - eg. large room, small room, medium room)
building_id (int - denotes a number of buildings this room could be within)
Rates
rate_id
type_id (foreign key to RoomUnit)
occ (type of rate - ie. Desk, FullRoom)
The idea is I want to provide a model that looks like this:
Type of Room
Number of Types of Room available
Type of Occ/Desks available
Sum of Rate (rate to charge) for each type of desk
Currently what shows is:
LargeRoom, Type 3049, Type Count 18 (or whatever is available)
occ FullRoom, ratetocharge 250, numOfOcc 1
occ FullRoom, ratetocharge 250, numOfOcc 1
occ FullRoom, ratetocharge 250, numOfOcc 1
occ Single Desk, ratetocharge 45, numOfOcc 1
occ Single Desk, ratetocharge 45, numOfOcc 1
SmallRoom, Type 3093, Type Count 4 (or whatever is available)
occ FullRoom, ratetocharge 150, numOfOcc 1
occ FullRoom, ratetocharge 150, numOfOcc 1
occ Single Desk, ratetocharge 45, numOfOcc 1
occ Single Desk, ratetocharge 45, numOfOcc 1
occ Single Desk, ratetocharge 45, numOfOcc 1
Whereas I would like the model to sum the rateToCharge by Occ in the sub table, eg:
LargeRoom, Type 3049, Type Count 18 (or whatever is available)
occ FullRoom, ratetocharge 750, numOfOcc 3
occ Single Desk, ratetocharge 90, numOfOcc 2
SmallRoom, Type 3093, Type Count 4 (or whatever is available)
occ FullRoom, ratetocharge 300, numOfOcc 2
occ Single Desk, ratetocharge 135, numOfOcc 3
change ratetocharge =rtc.rate.Sum to ratetocharge =rtc.rate.Sum(). Using Sum the compiler thinks you are trying to make the ratetocharge variable assigned the method group; the set of methods (including overloads) of the Sum method. Instead you need to make the call Sum() which actually calls the method.
--- Edit --- looking at your further information, I am going with this as the way to implement
var mtgRooms = RoomUnit
.Where(r => r.building_id==1)
.GroupBy(p => p.Type)
.Select(g => new
{
TypeName = g.Key.type_name,
TypeID = g.Key.type_id,
TypeCount = g.Count(),
rates = Rates.Where(rt => rt.type_id == g.type_id).GroupBy(rt => rt.occ)
.Select(proj => new {
occ = proj.Key,
ratetocharge = proj.Sum(s => s.rate),
numOfOcc = proj.count())
})
}
);

magento - Update product default image to first image in image gallery

I have an import script that imports well over 2000+ products including their images. I run this script via CLI because I feel that this is the best way to go speed-wise even though I have the same import script available and executable at the magento admin as an extension. The script runs pretty well. Almost perfect! However, sometimes the addToImageGallery somehow malfunctions and results into some images having No Image as the default product image and the only other image as not selected as defaults at all. How do I mass-update all products to set the first image in the media gallery for the product to the default 'base', 'image' and 'thumbnail' image(s)?
I found a couple of tricks on doing this (and more) on this link:
http://www.magentocommerce.com/boards/viewthread/59440/ (Thanks transio!)
Although, for Magento 1.6.2.0 (which I use), the first SQL trick there (Trick 1 - Auto-set default base, thumb, small image to first image.) needs a bit of modification.
On the second-to-the last-line there is a AND ev.attribute_id IN (70, 71, 72) part. This should point to attribute ID's which will probably not be relevant in Magento 1.6.2.0 anymore. To fix this, using any MySQL query tool (PHPMyAdmin or MySQL Query Browser), I took a look at the catalog_product_entity_varchar table. There should be entries like:
value_id, entity_type_id, attribute_id, store_id, entity_id, value
..
146649, 4, 116, 0, 1, '2'
146650, 4, 76, 0, 1, ''
146651, 4, 78, 0, 1, ''
146652, 4, 79, 0, 1, '/B/0/B05-01.jpg'
146653, 4, 80, 0, 1, '/B/0/B05-01.jpg'
146654, 4, 81, 0, 1, '/B/0/B05-01.jpg'
146655, 4, 96, 0, 1, ''
146656, 4, 100, 0, 1, ''
146657, 4, 102, 0, 1, 'container2'
..
My money was on the group of three image paths as possible replacements. So the resulting SQL now should be:
UPDATE catalog_product_entity_media_gallery AS mg,
catalog_product_entity_media_gallery_value AS mgv,
catalog_product_entity_varchar AS ev
SET ev.value = mg.value
WHERE mg.value_id = mgv.value_id
AND mg.entity_id = ev.entity_id
AND ev.attribute_id IN (79, 80, 81) # <-- attribute IDs updated here
AND mgv.position = 1;
So I committed to it, ran it and.. presto! All fixed! You might also want to encapsulate this in a transaction if you want. But this is out of this question's scope.
Well, this is the fix that worked for me so far! If there are any more out there, please share!
There was:
146652, 4, 79, 0, 1, '/B/0/B05-01.jpg'
146653, 4, 80, 0, 1, '/B/0/B05-01.jpg'
146654, 4, 81, 0, 1, '/B/0/B05-01.jpg'
So it should be:
AND ev.attribute_id IN (79, 80, 81) # <-- attribute IDs updated here
instead of:
AND ev.attribute_id IN (78, 80, 81) # <-- attribute IDs updated here
Is looking for something similar.
UPDATE catalog_product_entity_media_gallery AS mg,
catalog_product_entity_media_gallery_value AS mgv,
catalog_product_entity_varchar AS ev
SET ev.value = mg.value
WHERE mg.value_id = mgv.value_id
AND mg.entity_id = ev.entity_id
AND ev.attribute_id IN (79, 80, 81) # <-- attribute IDs updated here
AND mgv.position = 1;

Resources