| import os |
| import json |
| import random |
|
|
| |
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| JSON_PATH = os.path.join(BASE_DIR, "trained_mdp_policy.json") |
|
|
| def load_policy(): |
| with open(JSON_PATH, "r") as file: |
| return json.load(file) |
|
|
| def save_policy(policy_data): |
| with open(JSON_PATH, "w") as file: |
| json.dump(policy_data, file, indent=2) |
|
|
| |
| policy = load_policy() |
|
|
| def generate_state_id(stress: str, prod_hours: float, sleep: float, screen: float, physical: float) -> str: |
| if prod_hours < 35.0: state_prod = "LOW_PROD" |
| elif 35.0 <= prod_hours <= 45.0: state_prod = "NORMAL_PROD" |
| else: state_prod = "HIGH_PROD" |
|
|
| if sleep < 5.8: state_sleep = "LACK_SLEEP" |
| elif 5.8 <= sleep <= 7.5: state_sleep = "ENOUGH_SLEEP" |
| else: state_sleep = "GOOD_SLEEP" |
|
|
| if screen < 3.0: state_screen = "LOW_SCREEN" |
| elif 3.0 <= screen <= 5.0: state_screen = "MEDIUM_SCREEN" |
| else: state_screen = "HIGH_SCREEN" |
|
|
| if physical < 2.0: state_phys = "LOW_ACT" |
| elif 2.0 <= physical <= 4.0: state_phys = "MEDIUM_ACT" |
| else: state_phys = "HIGH_ACT" |
|
|
| return f"STRESS_{stress.upper()}_{state_prod}_{state_sleep}_{state_screen}_{state_phys}" |
|
|
| def get_stress_management_recommendation(stress: str, prod_hours: float, sleep: float, screen: float, physical: float): |
| global policy |
| user_state = generate_state_id(stress, prod_hours, sleep, screen, physical) |
|
|
| |
| if user_state in policy and len(policy[user_state]) > 0: |
| actions_dict = policy[user_state] |
| sorted_actions = sorted(actions_dict.items(), key=lambda x: x[1], reverse=True) |
| top_5_actions = sorted_actions[:5] |
| else: |
| |
| top_5_actions = [('travelling', 10.0), ('watching sports', 9.0), ('social media engagement', 8.0), ('pilates', 7.0), ('meditation', 6.0)] |
|
|
| action_names = [item[0] for item in top_5_actions] |
| action_scores = [item[1] for item in top_5_actions] |
|
|
| total_score = sum(action_scores) |
| probabilities = [score / total_score for score in action_scores] |
|
|
| |
| chosen_recommendation = random.choices(action_names, weights=probabilities, k=1)[0] |
|
|
| |
| formatted_top_5 = [{"activity": name, "score": round(score, 4)} for name, score in top_5_actions] |
|
|
| return { |
| "state_id": user_state, |
| "chosen_recommendation": chosen_recommendation, |
| "top_5_candidates": formatted_top_5 |
| } |
|
|
| def process_user_feedback(stress: str, prod_hours: float, sleep: float, screen: float, physical: float, action_given: str, feedback_status: str): |
| global policy |
| user_state = generate_state_id(stress, prod_hours, sleep, screen, physical) |
|
|
| |
| policy = load_policy() |
|
|
| if user_state in policy and action_given in policy[user_state]: |
| current_score = policy[user_state][action_given] |
|
|
| |
| if feedback_status.lower() == "negative": |
| new_score = current_score * 0.70 |
| else: |
| new_score = current_score * 1.10 |
|
|
| policy[user_state][action_given] = new_score |
| |
| |
| save_policy(policy) |
| return {"status": "success", "message": f"Skor untuk '{action_given}' pada state '{user_state}' berhasil diperbarui menjadi {round(new_score, 4)}."} |
| |
| return {"status": "ignored", "message": "State atau tindakan tidak ditemukan dalam policy untuk diperbarui."} |