akhaliq HF Staff commited on
Commit
b6e792e
·
verified ·
1 Parent(s): d926f1e

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +362 -0
  2. requirements.txt +10 -0
app.py ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from typing import List, Dict, Tuple
3
+ import time
4
+
5
+ class TodoApp:
6
+ def __init__(self):
7
+ self.todos = []
8
+
9
+ def add_todo(self, todo_text: str, current_todos: List[Dict]) -> Tuple[List[Dict], str]:
10
+ """Add a new todo item to the list."""
11
+ if not todo_text.strip():
12
+ raise gr.Warning("Please enter a todo item!")
13
+
14
+ new_todo = {
15
+ "id": len(current_todos) + 1,
16
+ "text": todo_text.strip(),
17
+ "completed": False,
18
+ "created_at": time.strftime("%Y-%m-%d %H:%M")
19
+ }
20
+
21
+ updated_todos = current_todos + [new_todo]
22
+ return updated_todos, ""
23
+
24
+ def toggle_todo(self, todo_indices: List[int], current_todos: List[Dict]) -> List[Dict]:
25
+ """Toggle the completion status of selected todos."""
26
+ if not todo_indices:
27
+ return current_todos
28
+
29
+ updated_todos = current_todos.copy()
30
+ for idx in todo_indices:
31
+ if 0 <= idx < len(updated_todos):
32
+ updated_todos[idx]["completed"] = not updated_todos[idx]["completed"]
33
+
34
+ return updated_todos
35
+
36
+ def delete_todos(self, todo_indices: List[int], current_todos: List[Dict]) -> List[Dict]:
37
+ """Delete selected todos from the list."""
38
+ if not todo_indices:
39
+ return current_todos
40
+
41
+ # Sort indices in reverse to avoid index shifting issues
42
+ todo_indices_sorted = sorted(todo_indices, reverse=True)
43
+ updated_todos = current_todos.copy()
44
+
45
+ for idx in todo_indices_sorted:
46
+ if 0 <= idx < len(updated_todos):
47
+ del updated_todos[idx]
48
+
49
+ # Reassign IDs
50
+ for i, todo in enumerate(updated_todos):
51
+ todo["id"] = i + 1
52
+
53
+ return updated_todos
54
+
55
+ def clear_all(self) -> List[Dict]:
56
+ """Clear all todos from the list."""
57
+ return []
58
+
59
+ def get_todo_display(self, todos: List[Dict]) -> List[str]:
60
+ """Format todos for display in CheckboxGroup."""
61
+ display_list = []
62
+ for todo in todos:
63
+ status = "✅" if todo["completed"] else "⭕"
64
+ display_text = f"{status} {todo['text']} (Created: {todo['created_at']})"
65
+ display_list.append(display_text)
66
+ return display_list
67
+
68
+ # Initialize the TodoApp
69
+ todo_manager = TodoApp()
70
+
71
+ def create_todo_app():
72
+ """Create and configure the Gradio Todo App interface."""
73
+
74
+ with gr.Blocks(
75
+ title="Todo App",
76
+ theme=gr.themes.Soft(),
77
+ css="""
78
+ .todo-container {
79
+ border: 2px solid #e5e7eb;
80
+ border-radius: 8px;
81
+ padding: 16px;
82
+ margin: 8px 0;
83
+ background: #f9fafb;
84
+ }
85
+ .header-text {
86
+ text-align: center;
87
+ margin-bottom: 20px;
88
+ }
89
+ """
90
+ ) as demo:
91
+
92
+ # Header with attribution
93
+ gr.HTML("""
94
+ <div class="header-text">
95
+ <h1>📝 Todo App</h1>
96
+ <p>Manage your tasks efficiently with this simple todo application!</p>
97
+ <p style="font-size: 0.9em; color: #666;">
98
+ Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
99
+ </p>
100
+ </div>
101
+ """)
102
+
103
+ # State to manage the todo list
104
+ todo_state = gr.State(value=[])
105
+
106
+ with gr.Row():
107
+ with gr.Column(scale=3):
108
+ # Input section
109
+ with gr.Group():
110
+ gr.Markdown("### Add New Todo")
111
+ todo_input = gr.Textbox(
112
+ placeholder="Enter your todo item here...",
113
+ label="Todo Item",
114
+ lines=1,
115
+ max_lines=1,
116
+ autofocus=True,
117
+ show_label=False
118
+ )
119
+
120
+ with gr.Row():
121
+ add_btn = gr.Button(
122
+ "➕ Add Todo",
123
+ variant="primary",
124
+ size="sm"
125
+ )
126
+ clear_input_btn = gr.Button(
127
+ "🗑️ Clear Input",
128
+ variant="secondary",
129
+ size="sm"
130
+ )
131
+
132
+ with gr.Column(scale=2):
133
+ # Statistics
134
+ with gr.Group():
135
+ gr.Markdown("### Statistics")
136
+ total_count = gr.Number(
137
+ label="Total Todos",
138
+ value=0,
139
+ interactive=False
140
+ )
141
+ completed_count = gr.Number(
142
+ label="Completed",
143
+ value=0,
144
+ interactive=False
145
+ )
146
+ pending_count = gr.Number(
147
+ label="Pending",
148
+ value=0,
149
+ interactive=False
150
+ )
151
+
152
+ # Todo list display and actions
153
+ with gr.Group():
154
+ gr.Markdown("### Todo List")
155
+ todo_display = gr.CheckboxGroup(
156
+ choices=[],
157
+ label="Select todos to toggle or delete",
158
+ info="Check items to mark as complete/incomplete or delete them",
159
+ interactive=True
160
+ )
161
+
162
+ with gr.Row():
163
+ toggle_btn = gr.Button(
164
+ "🔄 Toggle Selected",
165
+ variant="secondary",
166
+ size="sm"
167
+ )
168
+ delete_btn = gr.Button(
169
+ "🗑️ Delete Selected",
170
+ variant="stop",
171
+ size="sm"
172
+ )
173
+ clear_all_btn = gr.Button(
174
+ "🧹 Clear All",
175
+ variant="stop",
176
+ size="sm"
177
+ )
178
+
179
+ # Hidden component to trigger updates
180
+ update_trigger = gr.Number(visible=False)
181
+
182
+ # Functions
183
+
184
+ def add_todo_handler(todo_text, current_todos):
185
+ """Handle adding a new todo."""
186
+ updated_todos, cleared_input = todo_manager.add_todo(todo_text, current_todos)
187
+ display_choices = todo_manager.get_todo_display(updated_todos)
188
+
189
+ # Calculate statistics
190
+ total = len(updated_todos)
191
+ completed = sum(1 for todo in updated_todos if todo["completed"])
192
+ pending = total - completed
193
+
194
+ return (
195
+ updated_todos,
196
+ display_choices,
197
+ cleared_input,
198
+ total,
199
+ completed,
200
+ pending,
201
+ time.time() # Trigger update
202
+ )
203
+
204
+ def toggle_todo_handler(selected_indices, current_todos):
205
+ """Handle toggling todo completion status."""
206
+ if not selected_indices:
207
+ return current_todos, todo_manager.get_todo_display(current_todos)
208
+
209
+ updated_todos = todo_manager.toggle_todo(selected_indices, current_todos)
210
+ display_choices = todo_manager.get_todo_display(updated_todos)
211
+
212
+ # Calculate statistics
213
+ total = len(updated_todos)
214
+ completed = sum(1 for todo in updated_todos if todo["completed"])
215
+ pending = total - completed
216
+
217
+ return (
218
+ updated_todos,
219
+ display_choices,
220
+ total,
221
+ completed,
222
+ pending,
223
+ time.time() # Trigger update
224
+ )
225
+
226
+ def delete_todo_handler(selected_indices, current_todos):
227
+ """Handle deleting selected todos."""
228
+ if not selected_indices:
229
+ return current_todos, todo_manager.get_todo_display(current_todos)
230
+
231
+ updated_todos = todo_manager.delete_todos(selected_indices, current_todos)
232
+ display_choices = todo_manager.get_todo_display(updated_todos)
233
+
234
+ # Calculate statistics
235
+ total = len(updated_todos)
236
+ completed = sum(1 for todo in updated_todos if todo["completed"])
237
+ pending = total - completed
238
+
239
+ return (
240
+ updated_todos,
241
+ display_choices,
242
+ total,
243
+ completed,
244
+ pending,
245
+ time.time() # Trigger update
246
+ )
247
+
248
+ def clear_all_handler():
249
+ """Handle clearing all todos."""
250
+ updated_todos = todo_manager.clear_all()
251
+ display_choices = todo_manager.get_todo_display(updated_todos)
252
+
253
+ return (
254
+ updated_todos,
255
+ display_choices,
256
+ 0,
257
+ 0,
258
+ 0,
259
+ time.time() # Trigger update
260
+ )
261
+
262
+ def clear_input_handler():
263
+ """Clear the input textbox."""
264
+ return ""
265
+
266
+ def update_display(current_todos):
267
+ """Update the display when todos change."""
268
+ display_choices = todo_manager.get_todo_display(current_todos)
269
+
270
+ # Calculate statistics
271
+ total = len(current_todos)
272
+ completed = sum(1 for todo in current_todos if todo["completed"])
273
+ pending = total - completed
274
+
275
+ return display_choices, total, completed, pending
276
+
277
+ # Event handlers
278
+ add_btn.click(
279
+ fn=add_todo_handler,
280
+ inputs=[todo_input, todo_state],
281
+ outputs=[todo_state, todo_display, todo_input, total_count, completed_count, pending_count, update_trigger]
282
+ )
283
+
284
+ todo_input.submit(
285
+ fn=add_todo_handler,
286
+ inputs=[todo_input, todo_state],
287
+ outputs=[todo_state, todo_display, todo_input, total_count, completed_count, pending_count, update_trigger]
288
+ )
289
+
290
+ clear_input_btn.click(
291
+ fn=clear_input_handler,
292
+ outputs=[todo_input]
293
+ )
294
+
295
+ toggle_btn.click(
296
+ fn=toggle_todo_handler,
297
+ inputs=[todo_display, todo_state],
298
+ outputs=[todo_state, todo_display, total_count, completed_count, pending_count, update_trigger]
299
+ )
300
+
301
+ delete_btn.click(
302
+ fn=delete_todo_handler,
303
+ inputs=[todo_display, todo_state],
304
+ outputs=[todo_state, todo_display, total_count, completed_count, pending_count, update_trigger]
305
+ )
306
+
307
+ clear_all_btn.click(
308
+ fn=clear_all_handler,
309
+ outputs=[todo_state, todo_display, total_count, completed_count, pending_count, update_trigger]
310
+ )
311
+
312
+ # Update display when state changes
313
+ update_trigger.change(
314
+ fn=update_display,
315
+ inputs=[todo_state],
316
+ outputs=[todo_display, total_count, completed_count, pending_count]
317
+ )
318
+
319
+ # Examples
320
+ gr.Examples(
321
+ examples=[
322
+ ["Buy groceries"],
323
+ ["Finish project report"],
324
+ ["Call mom"],
325
+ ["Schedule dentist appointment"],
326
+ ["Learn Gradio"]
327
+ ],
328
+ inputs=[todo_input],
329
+ examples_per_page=3,
330
+ label="Example todos (click to use)"
331
+ )
332
+
333
+ # Instructions
334
+ with gr.Accordion("📖 How to Use", open=False):
335
+ gr.Markdown("""
336
+ ### Instructions:
337
+
338
+ 1. **Add Todo**: Type your task in the input box and press Enter or click "Add Todo"
339
+ 2. **Mark Complete**: Check the box next to a todo and click "Toggle Selected"
340
+ 3. **Delete Todos**: Select todos and click "Delete Selected"
341
+ 4. **Clear All**: Click "Clear All" to remove all todos at once
342
+ 5. **Statistics**: View real-time counts of total, completed, and pending todos
343
+
344
+ ### Tips:
345
+ - ✅ indicates completed tasks
346
+ - ⭕ indicates pending tasks
347
+ - Each todo shows its creation time
348
+ - Select multiple todos to perform bulk actions
349
+ """)
350
+
351
+ return demo
352
+
353
+ # Create and launch the app
354
+ if __name__ == "__main__":
355
+ demo = create_todo_app()
356
+ demo.launch(
357
+ share=False,
358
+ show_error=True,
359
+ show_tips=True,
360
+ height=600,
361
+ width="100%"
362
+ )
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ requests
3
+ Pillow
4
+ numpy
5
+ pandas
6
+ matplotlib
7
+ plotly
8
+ fastapi
9
+ uvicorn
10
+ pydantic