Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add test filler-goal #434

Closed
wants to merge 33 commits into from
Closed
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9617d00
add test filler-goal
Jan 23, 2024
c7078d2
feat: - developed goal.get_parent_goal - passing parent_goal to fun…
moaz-mokhtar Feb 29, 2024
7bd42ff
updated observed file
moaz-mokhtar Feb 29, 2024
b69e2c0
fix: provide min_duration to 1 if not available in a goal.
moaz-mokhtar Feb 29, 2024
5970c02
fix: avoid passing parent_goal to functions which generating activiti…
moaz-mokhtar Mar 2, 2024
401ee93
fix: corrected duration for activity plan a party
moaz-mokhtar Mar 2, 2024
97b5cb1
feature: develop function to adjust activities for related to parent …
moaz-mokhtar Mar 6, 2024
3f616ee
ref: call function adjust_parent_activities in test template
moaz-mokhtar Mar 6, 2024
217bbb9
ref: observed feedback after developing function adjust_parent_activi…
moaz-mokhtar Mar 6, 2024
26699be
fix: Now Daily habits activity can be shows in the activities
moaz-mokhtar Mar 6, 2024
d09ee20
fix: children of parent goal to match child goal id instead of child …
moaz-mokhtar Mar 8, 2024
bc635f7
fix: avoid panics when no child activity match
moaz-mokhtar Mar 8, 2024
711e5e0
fix: avoid generate activities for goals which have children and have…
moaz-mokhtar Mar 8, 2024
7567aaf
test: update expected and observed output for default-budgets test case
moaz-mokhtar Mar 8, 2024
45484d8
fix: remove dbg statements
moaz-mokhtar Mar 8, 2024
ef22885
ref: clippy applied
moaz-mokhtar Mar 8, 2024
781790c
Merge pull request #449 from tijlleenders/moaz/-/add-filler-goal-test
tijlleenders Mar 9, 2024
80ba7b0
remode redundant comment
Mar 9, 2024
09f9537
remove unnecessary code
Mar 9, 2024
98e9504
Merge branch 'main' into tijl/-/add-filler-goal-test
Mar 9, 2024
f0a3908
Merge branch 'main' into tijl/-/add-filler-goal-test
Mar 9, 2024
a346673
fix: call function to adjust activities for parent goals adjust_paren…
moaz-mokhtar Mar 9, 2024
6d829cd
fix: avoid filter out goals which have children to be able to generat…
moaz-mokhtar Mar 9, 2024
faf1c5d
fix: corrected observed.json after passing test filler_goal
moaz-mokhtar Mar 9, 2024
75360db
fix: avoid adjust goal deadline when parent deadline is empty "meansy…
moaz-mokhtar Mar 9, 2024
8fc2831
test: changed expected output for test budget-and-goal-one-day to ac…
moaz-mokhtar Mar 9, 2024
b220f89
fix: clippy nots
moaz-mokhtar Mar 9, 2024
1df487c
fix: remove dbg statements
moaz-mokhtar Mar 9, 2024
72bbd5f
fix: hidden clippy issue
moaz-mokhtar Mar 9, 2024
1bf1222
ref: update wasm-bindgen version to avoid CI error for wasm-bindgen
moaz-mokhtar Mar 9, 2024
17082c1
adjusting activities inside generate_activities
Mar 19, 2024
8f7d6de
adjust expected.json
Mar 19, 2024
e7db504
remove unused import
Mar 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ chrono = { version = "0.4.31", features = ["wasmbind", "serde"] }
lazy_static = "1.4.0"

# simple WASM codegen
wasm-bindgen = { version = "0.2.84" }
wasm-bindgen = { version = "0.2.92" }
# instead of wasm-bindgen::serde-serialize feature that may lead to a cyclic package dependency
serde-wasm-bindgen = "0.5.0"

4 changes: 1 addition & 3 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use chrono::NaiveDateTime;
use serde::Deserialize;
use serde_json::{self, Value};
use serde_json::Value;
use std::{fs, path::Path};
extern crate scheduler;
use scheduler::{models::goal::Goal, run_scheduler};
@@ -9,9 +9,7 @@ fn main() {
let path = Path::new("./tests/jsons/stable/algorithm-challenge/input.json");
let file = fs::File::open(path).expect("file should open read only");
let json: Value = serde_json::from_reader(file).expect("file should be proper JSON");
dbg!(&json);
let input: Input = serde_json::from_value(json).unwrap();
dbg!(&input);
run_scheduler(input.start_date, input.end_date, &input.goals);
}

6 changes: 2 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ use chrono::NaiveDateTime;
use models::{activity::Activity, calendar::Calendar, goal::Goal, task::FinalTasks};
use serde_wasm_bindgen::{from_value, to_value};
use services::activity_generator;
use services::activity_generator::adjust_parent_activities;
use services::activity_placer;
use technical::input_output::Input;
use wasm_bindgen::prelude::*;
@@ -90,20 +91,17 @@ pub fn run_scheduler(
goals: &[Goal],
) -> FinalTasks {
let mut calendar = Calendar::new(start_date, end_date);
dbg!(&calendar);

calendar.add_budgets_from(goals);

//generate and place simple goal activities
let simple_goal_activities =
activity_generator::generate_simple_goal_activities(&calendar, goals);
dbg!(&simple_goal_activities);
let simple_goal_activities = adjust_parent_activities(&simple_goal_activities, goals);
tijlleenders marked this conversation as resolved.
Show resolved Hide resolved

//generate and place budget goal activities
let budget_goal_activities: Vec<Activity> =
activity_generator::generate_budget_goal_activities(&calendar, goals);
dbg!(&budget_goal_activities);
dbg!(&calendar);

activity_placer::place(&mut calendar, simple_goal_activities);
activity_placer::place(&mut calendar, budget_goal_activities);
15 changes: 10 additions & 5 deletions src/models/activity.rs
Original file line number Diff line number Diff line change
@@ -181,11 +181,17 @@ impl Activity {
pub(crate) fn get_activities_from_simple_goal(
goal: &Goal,
calendar: &Calendar,
parent_goal: Option<Goal>,
) -> Vec<Activity> {
if goal.children.is_some() || goal.filters.as_ref().is_some() {
if goal.filters.as_ref().is_some() {
return vec![];
}
let (adjusted_goal_start, adjusted_goal_deadline) = goal.get_adj_start_deadline(calendar);
if goal.children.is_some() && goal.min_duration.is_none() {
return vec![];
}

let (adjusted_goal_start, adjusted_goal_deadline) =
goal.get_adj_start_deadline(calendar, parent_goal);
let mut activities: Vec<Activity> = Vec::with_capacity(1);

if let Some(activity_total_duration) = goal.min_duration {
@@ -218,7 +224,6 @@ impl Activity {
duration_left: min_block_size, //TODO: Correct this - is it even necessary to have duration_left?
status: Status::Unprocessed,
};
dbg!(&activity);
activities.push(activity);
}

@@ -237,7 +242,8 @@ impl Activity {
return vec![];
}
}
let (adjusted_goal_start, adjusted_goal_deadline) = goal.get_adj_start_deadline(calendar);
let (adjusted_goal_start, adjusted_goal_deadline) =
goal.get_adj_start_deadline(calendar, None);
let mut activities: Vec<Activity> = Vec::with_capacity(1);

for day in 0..(adjusted_goal_deadline - adjusted_goal_start).num_days() as u64 {
@@ -283,7 +289,6 @@ impl Activity {
duration_left: config.min_per_day,
status: Status::Unprocessed,
};
dbg!(&activity);
activities.push(activity);
}
}
1 change: 0 additions & 1 deletion src/models/budget.rs
Original file line number Diff line number Diff line change
@@ -166,6 +166,5 @@ pub fn get_time_budgets_from(calendar: &Calendar, goal: &Goal) -> Vec<TimeBudget
start_pointer = hour_index
}
}
dbg!(&time_budgets);
time_budgets
}
4 changes: 2 additions & 2 deletions src/models/calendar.rs
Original file line number Diff line number Diff line change
@@ -168,8 +168,8 @@ impl Calendar {
task_counter += 1;
}
current_task.duration = 1;
current_task.goalid = activity_goalid.clone();
current_task.title = activity_title.clone();
current_task.goalid.clone_from(activity_goalid);
current_task.title.clone_from(activity_title);
current_task.start = self
.start_date_time
.add(Duration::hours(hour_offset as i64 - 24)); // TODO: Fix magic number offset everywhere in code
32 changes: 31 additions & 1 deletion src/models/goal.rs
Original file line number Diff line number Diff line change
@@ -46,7 +46,11 @@ pub struct BudgetConfig {
}

impl Goal {
pub fn get_adj_start_deadline(&self, calendar: &Calendar) -> (NaiveDateTime, NaiveDateTime) {
pub fn get_adj_start_deadline(
&self,
calendar: &Calendar,
parent_goal: Option<Goal>,
) -> (NaiveDateTime, NaiveDateTime) {
let mut adjusted_goal_start = self.start;
if self.start.year() == 1970 {
adjusted_goal_start = calendar.start_date_time;
@@ -55,6 +59,19 @@ impl Goal {
if self.deadline.year() == 1970 {
adjusted_goal_deadline = calendar.end_date_time;
}

// Make sure child goal not fall outside of parent goal start and deadline
if let Some(parent_goal) = parent_goal {
// means this is a child goal
if adjusted_goal_start < parent_goal.start {
adjusted_goal_start = parent_goal.start;
}
if adjusted_goal_deadline > parent_goal.deadline && parent_goal.deadline.year() != 1970
{
adjusted_goal_deadline = parent_goal.deadline;
}
}

if self.filters.is_none() {
return (adjusted_goal_start, adjusted_goal_deadline);
}
@@ -78,4 +95,17 @@ impl Goal {
}
(adjusted_goal_start, adjusted_goal_deadline)
}

/// Get parent goal of this goal based in provided list of goals
pub fn get_parent_goal(&self, goals: &[Goal]) -> Option<Goal> {
let parent_goal = goals.iter().find(|goal| {
if let Some(childs) = &goal.children {
childs.contains(&self.id)
} else {
false
}
});

parent_goal.cloned()
}
}
71 changes: 68 additions & 3 deletions src/services/activity_generator.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@ use crate::models::{activity::Activity, budget::TimeBudgetType, calendar::Calend
pub fn generate_simple_goal_activities(calendar: &Calendar, goals: &[Goal]) -> Vec<Activity> {
goals
.iter()
.flat_map(|goal| Activity::get_activities_from_simple_goal(goal, calendar))
.flat_map(|goal| {
Activity::get_activities_from_simple_goal(goal, calendar, goal.get_parent_goal(goals))
})
.collect::<Vec<_>>()
}

@@ -54,7 +56,6 @@ pub fn generate_get_to_week_min_budget_activities(
}
}
}
dbg!(&get_to_week_min_budget_activities);
Some(get_to_week_min_budget_activities)
}

@@ -79,6 +80,70 @@ pub fn generate_top_up_week_budget_activities(
}
}
}
dbg!(&top_up_activities);
top_up_activities
}

pub fn adjust_parent_activities(activities: &[Activity], goals: &[Goal]) -> Vec<Activity> {
let mut activities_to_return = vec![];
// >>>

let mut child_activities: Vec<Activity> = vec![];

// Get activities for parent and child goals
let mut parent_activities: Vec<Activity> = goals
.iter()
.filter_map(|goal| {
if let Some(children) = &goal.children {
let activities_for_parent: Vec<Activity> = activities
.iter()
.filter(|activity| activity.goal_id == goal.id)
.cloned()
.collect();
let child_activities_for_parent: Vec<Activity> = children
.iter()
.filter_map(|child_id| {
activities
.iter()
.find(|activity| activity.goal_id == *child_id)
.cloned()
})
.collect();
child_activities.extend(child_activities_for_parent);
return Some(activities_for_parent);
}
None
})
.flatten()
.collect();

if parent_activities.is_empty() {
return activities.to_owned();
}

// For each parent_activity
parent_activities.iter_mut().for_each(|parent_activity| {
let mut parent_duraton = parent_activity.total_duration;

// For each child_activity
// get total_duration of child goals
// deduct it from parent_activity.total_duration
child_activities.iter().for_each(|child_activity| {
let child_duration = child_activity.total_duration;
parent_duraton -= child_duration;
});
parent_activity.total_duration = parent_duraton;
parent_activity.min_block_size = parent_duraton;
parent_activity.max_block_size = parent_duraton;
parent_activity.duration_left = parent_duraton;
});

// Unify parent_activities and child_activities based on Activity.id into single list which is activities_to_return
activities_to_return.extend(parent_activities);
activities_to_return.extend(child_activities);

// Sort activities_to_return like the incoming parameter activities
// activities_to_return.sort_by_key(|activity| activities.iter().position(|&x| x == activity));

// <<<
activities_to_return
}
3 changes: 0 additions & 3 deletions src/services/activity_placer.rs
Original file line number Diff line number Diff line change
@@ -75,10 +75,7 @@ pub fn place(calendar: &mut Calendar, mut activities: Vec<Activity>) -> Option<(
activities[act_index_to_schedule?].status = Status::Scheduled;
(activities[act_index_to_schedule?]).release_claims();
}

dbg!(&calendar);
}
dbg!(&calendar);
Some(())
}

18 changes: 13 additions & 5 deletions tests/jsons/stable/budget-and-goal-one-day/expected.json
Original file line number Diff line number Diff line change
@@ -29,18 +29,26 @@
},
{
"taskid": 3,
"goalid": "free",
"title": "free",
"duration": 2,
"start": "2022-09-01T13:00:00",
"deadline": "2022-09-01T15:00:00"
},
{
"taskid": 4,
"goalid": "2",
"title": "work",
"duration": 4,
"start": "2022-09-01T13:00:00",
"deadline": "2022-09-01T17:00:00"
"start": "2022-09-01T15:00:00",
"deadline": "2022-09-01T19:00:00"
},
{
"taskid": 4,
"taskid": 5,
"goalid": "free",
"title": "free",
"duration": 7,
"start": "2022-09-01T17:00:00",
"duration": 5,
"start": "2022-09-01T19:00:00",
"deadline": "2022-09-02T00:00:00"
}
]
18 changes: 13 additions & 5 deletions tests/jsons/stable/budget-and-goal-one-day/observed.json
Original file line number Diff line number Diff line change
@@ -29,18 +29,26 @@
},
{
"taskid": 3,
"goalid": "free",
"title": "free",
"duration": 2,
"start": "2022-09-01T13:00:00",
"deadline": "2022-09-01T15:00:00"
},
{
"taskid": 4,
"goalid": "2",
"title": "work",
"duration": 4,
"start": "2022-09-01T13:00:00",
"deadline": "2022-09-01T17:00:00"
"start": "2022-09-01T15:00:00",
"deadline": "2022-09-01T19:00:00"
},
{
"taskid": 4,
"taskid": 5,
"goalid": "free",
"title": "free",
"duration": 7,
"start": "2022-09-01T17:00:00",
"duration": 5,
"start": "2022-09-01T19:00:00",
"deadline": "2022-09-02T00:00:00"
}
]
Loading