patterncppMinor
Scheduling a task into a period within a day, depending on whether or not it is a weekend
Viewed 0 times
schedulingperiodintoweekendwithindependingwhetherdaytasknot
Problem
I have a function which needs to detect part of the day depending on whether it's the weekend or not (the weekend affects the lunch time indication). The method is quite long and I'd like to know how it can be better.
```
double PartOfDayRule::ExtractFeature(dto::ActionableItem & item) {
double morning, firstWorkPart, lunch, secondWorkPart, afterWork, beforeSleep, sleepTime;
morning = 0;
firstWorkPart = 1;
lunch = 2;
secondWorkPart = 3;
afterWork = 4;
beforeSleep = 5;
sleepTime = 6;
double result = -1;
dto::DateTime itemTime = item.scheduledStart;
if(util::time::inRange(item.ctx->sleepTimeEnd, item.ctx->workTimeStart, itemTime)){
result = morning;
goto result;
}
dto::DateTime lunchStart;
dto::DateTime lunchStop;
if(!item.ctx->isWorkingDay){
lunchStart = item.ctx->workTimeStart;
lunchStop = item.ctx->workTimeFinished;
}else{
long firstWorkPartLength = util::time::between(item.ctx->workTimeStart, item.ctx->workTimeFinished) / 2;
lunchStart = item.ctx->workTimeStart + std::chrono::hours{firstWorkPartLength};
lunchStop = lunchStart + std::chrono::hours{1};
}
if(util::time::inRange(lunchStart, lunchStop, itemTime)){
result = lunch;
goto result;
}
if(util::time::inRange(item.ctx->workTimeStart, lunchStart, itemTime)){
result = firstWorkPart;
goto result;
}
if(util::time::inRange(lunchStop, item.ctx->workTimeFinished, itemTime)){
result = secondWorkPart;
goto result;
```
double PartOfDayRule::ExtractFeature(dto::ActionableItem & item) {
double morning, firstWorkPart, lunch, secondWorkPart, afterWork, beforeSleep, sleepTime;
morning = 0;
firstWorkPart = 1;
lunch = 2;
secondWorkPart = 3;
afterWork = 4;
beforeSleep = 5;
sleepTime = 6;
double result = -1;
dto::DateTime itemTime = item.scheduledStart;
if(util::time::inRange(item.ctx->sleepTimeEnd, item.ctx->workTimeStart, itemTime)){
result = morning;
goto result;
}
dto::DateTime lunchStart;
dto::DateTime lunchStop;
if(!item.ctx->isWorkingDay){
lunchStart = item.ctx->workTimeStart;
lunchStop = item.ctx->workTimeFinished;
}else{
long firstWorkPartLength = util::time::between(item.ctx->workTimeStart, item.ctx->workTimeFinished) / 2;
lunchStart = item.ctx->workTimeStart + std::chrono::hours{firstWorkPartLength};
lunchStop = lunchStart + std::chrono::hours{1};
}
if(util::time::inRange(lunchStart, lunchStop, itemTime)){
result = lunch;
goto result;
}
if(util::time::inRange(item.ctx->workTimeStart, lunchStart, itemTime)){
result = firstWorkPart;
goto result;
}
if(util::time::inRange(lunchStop, item.ctx->workTimeFinished, itemTime)){
result = secondWorkPart;
goto result;
Solution
You return what is effectively an enum as a double. Why? create the enum and return that it's much clearer that way wat the return value means:
If you still want a single point of return (for whatever reason) then you can use an if-else chain:
Or you can sort the ranges and then use
If you still want a single point of return (for whatever reason) then you can use an if-else chain:
enum PartOfDay{
morning = 0,
firstWorkPart = 1,
lunch = 2,
secondWorkPart = 3,
afterWork = 4,
beforeSleep = 5,
sleepTime = 6
}
PartOfDay PartOfDayRule::ExtractFeature(dto::ActionableItem & item) {
dto::DateTime lunchStart;
dto::DateTime lunchStop;
if(!item.ctx->isWorkingDay){
lunchStart = item.ctx->workTimeStart;
lunchStop = item.ctx->workTimeFinished;
}else{
long firstWorkPartLength = util::time::between(item.ctx->workTimeStart, item.ctx->workTimeFinished) / 2;
lunchStart = item.ctx->workTimeStart + std::chrono::hours{firstWorkPartLength};
lunchStop = lunchStart + std::chrono::hours{1};
}
dto::DateTime itemTime = item.scheduledStart;
dto::DateTime sleepPreparationTime = item.ctx->sleepTimeStart - std::chrono::hours{1};
PartOfDay result = sleepTime;
if(util::time::inRange(item.ctx->sleepTimeEnd, item.ctx->workTimeStart, itemTime)){
result = morning;
} else if(util::time::inRange(item.ctx->workTimeStart, lunchStart, itemTime)){
result = firstWorkPart;
} else if(util::time::inRange(lunchStart, lunchStop, itemTime)){
result = lunch;
} else if(util::time::inRange(lunchStop, item.ctx->workTimeFinished, itemTime)){
result = secondWorkPart;
}else if(util::time::inRange(item.ctx->workTimeFinished, sleepPreparationTime, itemTime)){
result = afterWork;
}else if(util::time::inRange(sleepPreparationTime, item.ctx->sleepTimeStart, itemTime)){
result = beforeSleep;
}else {
result = sleepTime;
}
return result;
}Or you can sort the ranges and then use
std::find to get the range you want.Code Snippets
enum PartOfDay{
morning = 0,
firstWorkPart = 1,
lunch = 2,
secondWorkPart = 3,
afterWork = 4,
beforeSleep = 5,
sleepTime = 6
}
PartOfDay PartOfDayRule::ExtractFeature(dto::ActionableItem & item) {
dto::DateTime lunchStart;
dto::DateTime lunchStop;
if(!item.ctx->isWorkingDay){
lunchStart = item.ctx->workTimeStart;
lunchStop = item.ctx->workTimeFinished;
}else{
long firstWorkPartLength = util::time::between<std::chrono::hours>(item.ctx->workTimeStart, item.ctx->workTimeFinished) / 2;
lunchStart = item.ctx->workTimeStart + std::chrono::hours{firstWorkPartLength};
lunchStop = lunchStart + std::chrono::hours{1};
}
dto::DateTime itemTime = item.scheduledStart;
dto::DateTime sleepPreparationTime = item.ctx->sleepTimeStart - std::chrono::hours{1};
PartOfDay result = sleepTime;
if(util::time::inRange(item.ctx->sleepTimeEnd, item.ctx->workTimeStart, itemTime)){
result = morning;
} else if(util::time::inRange(item.ctx->workTimeStart, lunchStart, itemTime)){
result = firstWorkPart;
} else if(util::time::inRange(lunchStart, lunchStop, itemTime)){
result = lunch;
} else if(util::time::inRange(lunchStop, item.ctx->workTimeFinished, itemTime)){
result = secondWorkPart;
}else if(util::time::inRange(item.ctx->workTimeFinished, sleepPreparationTime, itemTime)){
result = afterWork;
}else if(util::time::inRange(sleepPreparationTime, item.ctx->sleepTimeStart, itemTime)){
result = beforeSleep;
}else {
result = sleepTime;
}
return result;
}Context
StackExchange Code Review Q#146676, answer score: 4
Revisions (0)
No revisions yet.