OptaPlanner nurse rostering - constraints

Discovered OptaPlanner whilst working on a roster generator for a hospital in Malawi, and it would be a perfect fit for the problem. So some newbie questions:
1) I can't see a way to easily enter holidays (apart from multiple day off requests), can see how to add this but don't wish to reinvent the wheel.
2) I can't see a way to add a constraint giving nurses a day off before and 2 days off after a night shift (there are just two shifts, day and night) any suggestions gratefully received, not sure where to start on this one.
Many thanks

It's a matter of adding or editing score rules in the DRL file. For some of them, you'll need to expand the domain model to include extra information (such as holiday start/end etc) and also adjust the XML dataset to include that information.
1) Add a HolidayRequest domain object and do something like this (warning: pseudo code):
rule "holidayRequest"
when
$holidayRequest : HolidayRequest($employee : employee, $startShiftDate : startShiftDate, $endShiftDate : startShiftDate, $weight : weight)
$assignment : ShiftAssignment(employee == $employee, shiftDate >= $startShiftDate, shiftDate <= $endShiftDate)
then
scoreHolder.addSoftConstraintMatch(kcontext, - $weight); // Maybe you want it hard instead of soft?
end
2) I'd rephrase that as (very very pseudo code)
ShiftAssignment(type = DAY, $date)
ShiftAssignment(type = NIGHT, date = $date + 1)
And also don't have this
ShiftAssignment(type = NIGHT, $date)
ShiftAssignment(type = DAY, date = $date + 1)
or this:
ShiftAssignment(type = NIGHT, $date)
ShiftAssignment(type = DAY, date = $date + 2)

Related

How to check if the device's time is between two times in Flutter from Firebase/Firestore?

In the Firestore project, I have documents in a collection containing data for shops, having fields like shopName, shopAddress, startTime(eg. 10 AM) and closeTime(eg. 10 PM) . (all strings for now)
When the user is browsing the app, i have retrieved the data from Firestore of the shops displayed in the app, now i wanna show that the shop is closed when the device's time is not between the startTime and closeTime of the shop. How do i achieve this?
So far I can detect the device's current time using dart package intl using this code:
print("${DateFormat('j').format(DateTime.now())}");
It gives output as follows:
I/flutter (14877): 6 PM
This is in DateFormat, and the data types stored in Firestore are strings.. I dont know how to compare them.. Do let me know if i have to change the data types in Firestore too.
Thank You
I think if you use 24 Hour Time Format and convert startTime, closeTime and actualTime to int or double ( if the shop close at 20:30/8:30pm), then you can easily compare them with if. On your firebase server string format is perfect.
For example you make a map and iterate it, and check if the actualTime is higher than startTime and lower than closeTime.
I have never tried this code, but i think it is going to work.
Map map = {'1am': 1, '2am': 2, '3am': 3, ... , '11pm': 23};
map.entries.forEach((e) {
if(e.key == actualTime) {
if(e.value >= startTime && e.value < closeTime) {
print('Open');
}
else{
print('Closed');
}
}
});
By the way, I think you should use UTC, because if you change the time-zone on your device, your app is going to show that the shop is closed, but in fact the shop is open, just you are in a different time-zone. You can easily implement this with this code.
var now = DateTime.now().toUtc();
Maybe you can create a hash map like this:
hashMap=['12 AM', '1 AM', '2 AM', ... , '11 PM', '12 AM'];
After that you can get the positions of startTime, closeTime and actualTime, and see if the actualTime is between start and close times positions.
Let me know if you want to give you a code example.

Cant get a math.random to work in two different places

function INV:DeleteInventoryItem( ply, pos, item)
local rarity = INV.PLAYERS[ply:SteamID64()][pos].quality
---print(rarity)
local value = "credits"
if(rarity == "Common")then
local amount = math.floor(math.random(1, 30))
table.remove( INV.PLAYERS[ply:SteamID64()], pos)
local var = ply:ChatPrint("You got ".. amount .." credits from deconstructing!")
ply:INVAddCredits( amount )
self.SAVE:SendInventory( ply )
local updatevalue = INV.PLAYERS[ply:SteamID64()].inventorydata.credits
UpdateDatabase(value, ply:SteamID(), updatevalue)
end
end
The problem I am having is that I cannot get the same value from the amount variable, so it says that you got a certain amount when it actually gave you a different amount.
I am really confused on how I can make it the same amount... Any help would be appreciated!
Thanks for all the help you guys have been, I since have fixed the issue and it was something wrong with the adding of the inventory credits.
-Thanks D12

How to color a row in table depending on time?

I am creating an application that will help our employees manage tasks. Tasks are submited via form. OnBeforeCreate I'm taking a date of task subbmission:
record.Data_Zlozenia = new Date();
The task falls into view for region (table widget), from where employees can pick it up.
The task that is submmited has 48 hour deadline.
Problem: How to color the row of task that exceed the deadline?
I know that I can color the row via adding a class in style editor and then on the row "Display" styles the binding. But I don't know how to make it depend on time.
`.red {
background-color: red;
}
#widget.descendants.Field3.text === "OczekujÄ…cy - zwrot" ? ['red','app-ListTableRow','hoverAncestor'] : ['app-ListTableRow','hoverAncestor']`
EDIT 1: Here I give U screenshots how it looks and what I tried.
CSS
Bindings
EDIT 2: With #Markus help I found a solution. I should put a binding like this:
(#datasource.item.Data_Zlozenia)/3600000 < ((new Date())/3600000 - 48) ? ['red','app-ListTableRow','hoverAncestor'] : ['app-ListTableRow','hoverAncestor']
This is untested, but I would try the following in your row styles binding:
setInterval(function() {(new Date() - #widget.datasource.item.Data_Zlozenia)/3600000;}, 60000) > 48 ? ['red','app-ListTableRow','hoverAncestor'] : ['app-ListTableRow','hoverAncestor']
Hypothetically speaking this will take the current Date/Time minus your field Date/Time and convert it to hours by dividing it by 3.6 million (JS date minus a date will return milliseconds so you have to convert to hours) and it will repeat this function every minute (60000 milliseconds). As stated, this is untested so you might need to refine a little

Only incremental values - PowerBI Calculate between dates

this might look simple.. but dk how to do it
this is the information:
So.. i got the Cumulative Total using this function:
CumulativeTotal = CALCULATE(
SUM(vnxcritical[Used Space GB]),
FILTER(ALL(Datesonly[Date]),
Datesonly[Date] <= MAX(Datesonly[Date])))
But what i need is to get the differences between the dates, in the first date and the second the difference will be of 210. I need to get another column with that information. know the formula to do that?
ok..
So.. i used this:
IncrmentalValueTEST =
VAR CurrDate = MAX(vnxcritical[Date])
VAR PrevDate = CALCULATE(LASTDATE(vnxcritical[Date]), vnxcritical[Date] < CurrDate)
RETURN SUM(vnxcritical[Used Space GB]) -
CALCULATE(SUM(vnxcritical[Used Space GB]), vnxcritical[Date] = PrevDate)
and this is the result:
Ok, so this is is my data table:
You can see all the dates that i have for now, this is a capacity report for diferents EMC Storage Arrays, for diferentes Pools. The idea would be to have the knolwdge to review the incremental space used in a determinated portion of time.
allready tried another idea to get this, but the result was the same.. i used this:
Diferencia =
Var Day = MAX(Datesonly[Month])
Var Month = MAX(Datesonly[Year])
RETURN
SUM('Used Space'[used_mb])
- CALCULATE(
SUM('Used Space'[used_mb])
,FILTER(ALL(Datesonly[Date]),Datesonly[Date] <= Max(Datesonly[Date])))
But the return is the same.. "47753152401"
i'm using graphical filters, and other things to get a minimal view, because there are only 5 weekly reports and the sql database got more than 150.000 rows.
and this is the relation that i made with a only a table full of "dates" in order to invoke the function in a better way, but the result is the same..
Try something along these lines:
IncrmentalValue =
VAR CurrDate = MAX(Datesonly[Date])
VAR PrevDate = CALCULATE(LASTDATE(Datesonly[Date]), Datesonly[Date] < CurrDate)
RETURN SUM(vnxcritical[Used Space GB]) -
CALCULATE(SUM(vnxcritical[Used Space GB]), Datesonly[Date] = PrevDate)
First, calculate the current date and then find the previous date by taking the last date that occurred before it. Then take the difference between the current value and the previous value.

Error in Rfacebook getPost - Argument has length 0

Whenever i'm trying to get a post with a lot of comments from Facebook with Rfacebook's getPost-function, i get the following error:
Error in while (n.l < n.likes & length(content$data) > 0 & !is.null(url <- content$paging$`next`)) { :
Argument has length 0
The code i'm trying to run looks like this:
post <- getPost(post = "Post-ID", token = token, n = 200)
I've also tried playing around with the different arguments of the function but nothing so far has worked... Anyone has an idea what could have caused this error? Any help is greatly appreciated!
Here's the link to the documentation of the getPost function: https://www.rdocumentation.org/packages/Rfacebook/versions/0.6.15/topics/getPost
I have a way that attacks your problem from a slightly different angle.
Instead of tackling the post ID you could, extract it from the 'Page' angle, and also this is an easier way of getting the Post ID
Step1:
see what 'Page' the post is on then you can extract the 'post' but making sure to use time parameters - for example:
"If you want to extract a post form the Nike FB page that has a massive amount of comments - which happened to fall on June, 6th 2016"
nike_posts <- getPage("nike", token = fboauth, n=100000, since = '2016/06/05', until = '2016/06/07')
Step 2:
You will then have a data frame of posts - lets say example 7 observations for that time (they possibly post multiple times a day)
If the post you are looking for is observation #3, then extract the comments by:
Comments <- getPost(nike_posts$id[3], token = fboauth, n = 10000, comments = TRUE, likes = FALSE, n.likes = 1, n.comments = 100000)
to convert this output to a DataFrame
library(plyr)
Comments <- ldply(Comments, data.frame)

Resources