import os import json import random # Tentukan path file JSON secara global agar bisa dibaca dan ditulis ulang 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) # Load policy ke dalam memori aplikasi 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) # Logika Cell 4 dari kode Syifa 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: # Fallback jika state tidak ditemukan 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] # Ambil 1 rekomendasi utama secara acak berdasarkan bobot probabilitas chosen_recommendation = random.choices(action_names, weights=probabilities, k=1)[0] # Format output top 5 agar rapi di API 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) # Reload data terbaru dari file sebelum memodifikasi (mencegah desinkronisasi) policy = load_policy() if user_state in policy and action_given in policy[user_state]: current_score = policy[user_state][action_given] # Logika Cell 6 penyesuaian skor berdasarkan feedback status 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 # Simpan kembali perubahan ke file JSON 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."}