vincentiusyoshuac commited on
Commit
45d1fb4
Β·
verified Β·
1 Parent(s): 27ed2e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +185 -137
app.py CHANGED
@@ -4,187 +4,235 @@ import numpy as np
4
  from datetime import datetime, timedelta
5
  import networkx as nx
6
  import plotly.express as px
7
- from transformers import pipeline
8
 
9
- class AIProjectOptimizer:
 
10
  def __init__(self):
11
- # Model AI untuk generasi dan klasifikasi
12
- try:
13
- self.text_generator = pipeline('text-generation', model='distilgpt2')
14
- self.task_classifier = pipeline('zero-shot-classification',
15
- model='facebook/bart-large-mnli')
16
- except Exception as e:
17
- st.warning(f"Gagal memuat model AI: {e}")
18
- self.text_generator = None
19
- self.task_classifier = None
20
 
21
- def generate_sample_tasks(self) -> pd.DataFrame:
22
  """
23
- Generate contoh tugas default jika tidak ada data
24
  """
25
- default_tasks = [
26
- {
27
- 'Task Name': f'Tugas {i}',
28
- 'Start Date': datetime.now() + timedelta(days=i*5),
29
- 'End Date': datetime.now() + timedelta(days=(i+1)*5),
30
- 'Duration': 5,
31
- 'Complexity': np.random.choice(['Low', 'Medium', 'High']),
32
- 'Progress': np.random.randint(0, 100),
33
- 'Cost': np.random.randint(1000, 10000)
34
- } for i in range(5)
35
- ]
36
- return pd.DataFrame(default_tasks)
37
 
38
- def optimize_project(self, tasks: pd.DataFrame):
39
  """
40
- Optimasi proyek dengan handling kasus kosong
41
  """
42
- # Gunakan sample tasks jika input kosong
43
- if tasks is None or tasks.empty:
44
- tasks = self.generate_sample_tasks()
 
 
45
 
46
- # Graph untuk dependency
47
- G = nx.DiGraph()
48
 
49
- # Tambahkan nodes
50
- for idx, task in tasks.iterrows():
51
- G.add_node(task['Task Name'],
52
- duration=task['Duration'],
53
- complexity=self._complexity_to_weight(task['Complexity']))
54
 
55
- # Tambahkan edges sederhana
56
- for i in range(len(tasks)-1):
57
- G.add_edge(tasks.iloc[i]['Task Name'], tasks.iloc[i+1]['Task Name'])
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- # Hitung jalur kritis
60
- try:
61
- critical_path = list(nx.dag_longest_path(G))
62
- except nx.NetworkXError:
63
- critical_path = list(G.nodes)
 
64
 
65
- # Optimasi tasks
66
- tasks['Priority'] = tasks['Task Name'].apply(
67
- lambda x: 'Critical' if x in critical_path else 'Normal'
68
- )
 
 
 
 
 
 
 
 
69
 
70
- # Hitung efisiensi
71
- tasks['Efficiency'] = tasks.apply(self._calculate_task_efficiency, axis=1)
 
 
 
72
 
73
- # Urutkan berdasar prioritas dan efisiensi
74
- optimized_tasks = tasks.sort_values(
75
- ['Priority', 'Efficiency'],
76
- ascending=[False, False]
77
- )
 
 
 
 
78
 
79
  return optimized_tasks, critical_path
80
-
81
- def _complexity_to_weight(self, complexity: str) -> float:
82
- """Konversi kompleksitas ke bobot"""
83
- return {
84
- 'Low': 1.0,
85
- 'Medium': 1.5,
86
- 'High': 2.0
87
- }.get(complexity, 1.0)
88
-
89
- def _calculate_task_efficiency(self, task):
90
- """Hitung efisiensi tugas"""
91
- complexity_factor = {
92
- 'Low': 1.0,
93
- 'Medium': 1.5,
94
- 'High': 2.0
95
- }
96
-
97
- # Skor efisiensi dengan faktor kompleksitas
98
- return complexity_factor.get(task['Complexity'], 1.0)
99
-
100
- def visualize_project(self, tasks: pd.DataFrame):
101
- """Visualisasi proyek"""
102
- # Gantt Chart
103
- fig = px.timeline(
104
- tasks,
105
- x_start='Start Date',
106
- x_end='End Date',
107
- y='Task Name',
108
- color='Complexity',
109
- title='Project Timeline'
110
- )
111
- return fig
112
 
113
- class StreamlitProjectApp:
114
  def __init__(self):
115
- self.optimizer = AIProjectOptimizer()
116
 
117
  def run(self):
118
- st.title("πŸš€ AI Project Optimizer")
 
 
 
 
119
 
120
- # Sidebar untuk input tugas
121
- st.sidebar.header("Input Proyek")
122
 
123
- # Input tugas manual
124
- with st.sidebar.form("task_input"):
125
- task_name = st.text_input("Nama Tugas")
126
- start_date = st.date_input("Tanggal Mulai")
127
- duration = st.number_input("Durasi (Hari)", min_value=1, value=5)
128
- complexity = st.selectbox("Kompleksitas", ['Low', 'Medium', 'High'])
129
-
130
- submit = st.form_submit_button("Tambah Tugas")
131
-
132
- if submit:
133
- # Tambahkan ke session state
134
- if 'tasks' not in st.session_state:
135
- st.session_state.tasks = pd.DataFrame(columns=[
136
- 'Task Name', 'Start Date', 'End Date',
137
- 'Duration', 'Complexity', 'Progress', 'Cost'
138
- ])
139
 
140
- new_task = pd.DataFrame([{
141
- 'Task Name': task_name,
142
- 'Start Date': start_date,
143
- 'End Date': start_date + timedelta(days=duration),
144
- 'Duration': duration,
145
- 'Complexity': complexity,
146
- 'Progress': 0,
147
- 'Cost': duration * 500
148
- }])
149
 
150
- st.session_state.tasks = pd.concat([
151
- st.session_state.tasks,
152
- new_task
153
- ], ignore_index=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  # Tampilkan daftar tugas
156
- if hasattr(st.session_state, 'tasks') and not st.session_state.tasks.empty:
157
- st.subheader("Daftar Tugas")
158
  st.dataframe(st.session_state.tasks)
159
 
160
- # Tombol Optimasi
161
- if st.button("Optimasi Proyek"):
162
  try:
163
- optimized_tasks, critical_path = self.optimizer.optimize_project(
 
164
  st.session_state.tasks
165
  )
166
 
167
  # Tampilkan hasil optimasi
168
- st.subheader("Tugas Teroptimasi")
169
  st.dataframe(optimized_tasks)
170
 
171
- # Visualisasi
172
- st.subheader("Visualisasi Proyek")
173
- fig = self.optimizer.visualize_project(optimized_tasks)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  st.plotly_chart(fig)
175
 
176
- # Informasi jalur kritis
177
- st.subheader("Jalur Kritis")
178
- st.write("Tugas Kritis:", critical_path)
 
 
 
 
 
 
 
 
 
 
179
 
180
  except Exception as e:
181
  st.error(f"Gagal mengoptimasi: {e}")
182
  else:
183
- st.info("Tambahkan tugas untuk memulai optimasi")
184
 
185
  def main():
186
- app = StreamlitProjectApp()
187
- app.run()
188
 
189
  if __name__ == "__main__":
190
  main()
 
4
  from datetime import datetime, timedelta
5
  import networkx as nx
6
  import plotly.express as px
7
+ import plotly.graph_objs as go
8
 
9
+ # Simulasi Model AI Sederhana
10
+ class AIProjectAnalyzer:
11
  def __init__(self):
12
+ # Model sederhana untuk klasifikasi dan prediksi
13
+ self.complexity_weights = {
14
+ 'Low': 1.0,
15
+ 'Medium': 1.5,
16
+ 'High': 2.0
17
+ }
 
 
 
18
 
19
+ def predict_task_duration(self, task):
20
  """
21
+ Prediksi durasi tugas berdasarkan kompleksitas
22
  """
23
+ base_duration = task['Duration']
24
+ complexity_factor = self.complexity_weights.get(task['Complexity'], 1.0)
25
+
26
+ # Prediksi durasi dengan faktor kompleksitas
27
+ predicted_duration = base_duration * complexity_factor
28
+
29
+ return max(1, round(predicted_duration))
 
 
 
 
 
30
 
31
+ def calculate_risk_score(self, task):
32
  """
33
+ Hitung skor risiko berdasarkan kompleksitas dan dependencies
34
  """
35
+ complexity_risk = {
36
+ 'Low': 0.2,
37
+ 'Medium': 0.5,
38
+ 'High': 0.8
39
+ }
40
 
41
+ base_risk = complexity_risk.get(task['Complexity'], 0.5)
 
42
 
43
+ # Pertimbangkan dependencies dalam skor risiko
44
+ dependency_multiplier = 1 + (len(task.get('Dependencies', [])) * 0.1)
 
 
 
45
 
46
+ return round(base_risk * dependency_multiplier, 2)
47
+
48
+ class AdvancedTaskDependencyManager:
49
+ def __init__(self):
50
+ # Inisialisasi graph ketergantungan dengan NetworkX
51
+ self.dependency_graph = nx.DiGraph()
52
+ self.ai_analyzer = AIProjectAnalyzer()
53
+
54
+ def add_task_dependency(self, tasks_df, task_name, predecessors=None, successors=None):
55
+ """
56
+ Tambahkan dependencies antar tugas dengan validasi kompleks
57
+ """
58
+ # Validasi tugas
59
+ if task_name not in tasks_df['Task Name'].values:
60
+ raise ValueError(f"Tugas {task_name} tidak ditemukan")
61
 
62
+ # Tambahkan dependencies
63
+ if predecessors:
64
+ for pred in predecessors:
65
+ if pred not in tasks_df['Task Name'].values:
66
+ raise ValueError(f"Predecessor {pred} tidak ditemukan")
67
+ self.dependency_graph.add_edge(pred, task_name)
68
 
69
+ if successors:
70
+ for succ in successors:
71
+ if succ not in tasks_df['Task Name'].values:
72
+ raise ValueError(f"Successor {succ} tidak ditemukan")
73
+ self.dependency_graph.add_edge(task_name, succ)
74
+
75
+ def optimize_project_timeline(self, tasks_df):
76
+ """
77
+ Optimasi timeline proyek dengan pertimbangan dependencies
78
+ """
79
+ # Clone dataframe untuk manipulasi
80
+ optimized_tasks = tasks_df.copy()
81
 
82
+ # Hitung jalur kritis
83
+ try:
84
+ critical_path = list(nx.dag_longest_path(self.dependency_graph))
85
+ except:
86
+ critical_path = list(self.dependency_graph.nodes)
87
 
88
+ # Analisis dan optimasi durasi
89
+ for index, task in optimized_tasks.iterrows():
90
+ # Prediksi durasi dengan AI
91
+ predicted_duration = self.ai_analyzer.predict_task_duration(task)
92
+ optimized_tasks.at[index, 'Predicted Duration'] = predicted_duration
93
+
94
+ # Hitung skor risiko
95
+ risk_score = self.ai_analyzer.calculate_risk_score(task)
96
+ optimized_tasks.at[index, 'Risk Score'] = risk_score
97
 
98
  return optimized_tasks, critical_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ class AIProjectDashboard:
101
  def __init__(self):
102
+ self.dependency_manager = AdvancedTaskDependencyManager()
103
 
104
  def run(self):
105
+ st.set_page_config(
106
+ page_title="πŸš€ AI Project Dependency Optimizer",
107
+ page_icon="πŸ“Š",
108
+ layout="wide"
109
+ )
110
 
111
+ st.title("πŸš€ Intelligent Project Dependency Management")
 
112
 
113
+ # Inisialisasi session state
114
+ if 'tasks' not in st.session_state:
115
+ st.session_state.tasks = pd.DataFrame(columns=[
116
+ 'Task Name', 'Start Date', 'Duration', 'Complexity',
117
+ 'Predecessors', 'Successors', 'Predicted Duration', 'Risk Score'
118
+ ])
119
+
120
+ # Sidebar untuk input tugas
121
+ with st.sidebar:
122
+ st.header("πŸ”§ Input Tugas Proyek")
123
+ with st.form("task_form"):
124
+ task_name = st.text_input("Nama Tugas")
125
+ start_date = st.date_input("Tanggal Mulai")
126
+ duration = st.number_input("Durasi Awal (Hari)", min_value=1, value=5)
127
+ complexity = st.selectbox("Kompleksitas Tugas", ['Low', 'Medium', 'High'])
 
128
 
129
+ # Pilih predecessors dan successors
130
+ existing_tasks = list(st.session_state.tasks['Task Name'])
131
+ predecessors = st.multiselect("Predecessor Tugas", existing_tasks)
132
+ successors = st.multiselect("Successor Tugas", existing_tasks)
 
 
 
 
 
133
 
134
+ submit = st.form_submit_button("Tambah Tugas")
135
+
136
+ if submit and task_name:
137
+ # Buat tugas baru
138
+ new_task = pd.DataFrame([{
139
+ 'Task Name': task_name,
140
+ 'Start Date': start_date,
141
+ 'Duration': duration,
142
+ 'Complexity': complexity,
143
+ 'Predecessors': str(predecessors) if predecessors else None,
144
+ 'Successors': str(successors) if successors else None,
145
+ 'Predicted Duration': None,
146
+ 'Risk Score': None
147
+ }])
148
+
149
+ # Tambahkan ke dataframe
150
+ st.session_state.tasks = pd.concat([
151
+ st.session_state.tasks,
152
+ new_task
153
+ ], ignore_index=True)
154
+
155
+ # Tambahkan dependency
156
+ try:
157
+ self.dependency_manager.add_task_dependency(
158
+ st.session_state.tasks,
159
+ task_name,
160
+ predecessors=predecessors,
161
+ successors=successors
162
+ )
163
+ except ValueError as e:
164
+ st.error(str(e))
165
 
166
  # Tampilkan daftar tugas
167
+ if not st.session_state.tasks.empty:
168
+ st.header("πŸ“‹ Daftar Tugas Proyek")
169
  st.dataframe(st.session_state.tasks)
170
 
171
+ # Tombol optimasi proyek
172
+ if st.button("πŸ” Optimasi Proyek dengan AI"):
173
  try:
174
+ # Optimasi timeline
175
+ optimized_tasks, critical_path = self.dependency_manager.optimize_project_timeline(
176
  st.session_state.tasks
177
  )
178
 
179
  # Tampilkan hasil optimasi
180
+ st.subheader("🎯 Hasil Optimasi Proyek")
181
  st.dataframe(optimized_tasks)
182
 
183
+ # Tampilkan jalur kritis
184
+ st.subheader("πŸ”— Jalur Kritis Proyek")
185
+ st.write("Urutan Tugas Kritis:", critical_path)
186
+
187
+ # Visualisasi Graph Dependency
188
+ st.subheader("🌐 Visualisasi Hubungan Tugas")
189
+ dependency_graph = self.dependency_manager.dependency_graph
190
+
191
+ # Konversi graph ke edge list
192
+ edges_list = list(dependency_graph.edges())
193
+ edges_df = pd.DataFrame(edges_list, columns=['Source', 'Target'])
194
+
195
+ # Visualisasi graph dengan Plotly
196
+ fig = go.Figure(data=[go.Sankey(
197
+ node=dict(
198
+ pad=15,
199
+ thickness=20,
200
+ line=dict(color='black', width=0.5),
201
+ label=list(set(edges_df['Source']) | set(edges_df['Target'])),
202
+ color='blue'
203
+ ),
204
+ link=dict(
205
+ source=[list(edges_df['Source']).index(x) for x in edges_df['Source']],
206
+ target=[list(edges_df['Target']).index(x) for x in edges_df['Target']],
207
+ value=[1]*len(edges_df)
208
+ )
209
+ )])
210
+
211
+ fig.update_layout(title_text="Diagram Dependency Proyek", font_size=10)
212
  st.plotly_chart(fig)
213
 
214
+ # Analisis Risiko
215
+ st.subheader("⚠️ Analisis Risiko Proyek")
216
+ risk_analysis = optimized_tasks[['Task Name', 'Risk Score']]
217
+ st.dataframe(risk_analysis)
218
+
219
+ # Bar chart risiko
220
+ risk_fig = px.bar(
221
+ risk_analysis,
222
+ x='Task Name',
223
+ y='Risk Score',
224
+ title='Skor Risiko per Tugas'
225
+ )
226
+ st.plotly_chart(risk_fig)
227
 
228
  except Exception as e:
229
  st.error(f"Gagal mengoptimasi: {e}")
230
  else:
231
+ st.info("Tambahkan tugas untuk memulai analisis")
232
 
233
  def main():
234
+ dashboard = AIProjectDashboard()
235
+ dashboard.run()
236
 
237
  if __name__ == "__main__":
238
  main()