testrro commited on
Commit
d3afeb1
·
verified ·
1 Parent(s): aa4b888

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -600
app.py DELETED
@@ -1,600 +0,0 @@
1
- import gradio as gr
2
- import numpy as np
3
- import pandas as pd
4
- from datetime import datetime
5
- import random
6
- from collections import defaultdict
7
- import math
8
- import os
9
- import traceback
10
- import json
11
- from fastapi import FastAPI, Request
12
- from gradio.routes import App
13
-
14
- # ==================== কনফিগারেশন ====================
15
- CONFIG = {
16
- "HISTORY_LIMIT": 1000,
17
- "PINK_THRESHOLD": 3.0,
18
- "BIG_PINK_THRESHOLD": 5.0,
19
- "MAX_PREDICTION": 10000.0, # সর্বোচ্চ প্রেডিকশন সীমা (খুব বড় করা হয়েছে)
20
- }
21
-
22
- # ==================== ডেটা লোড ও টাইম-ভিত্তিক পরিসংখ্যান ====================
23
- TIME_STATS = None
24
-
25
- def load_time_statistics():
26
- global TIME_STATS
27
- try:
28
- # ডেটা ফাইলের পাথ
29
- data_path = 'data/aviator_Rounds_history_scrp.xlsx'
30
- if os.path.exists(data_path):
31
- df = pd.read_excel(data_path, sheet_name='scraping rounds crash')
32
- df = df[['ROUNDS', 'TIME ROUND']].dropna()
33
- df['multiplier'] = pd.to_numeric(df['ROUNDS'], errors='coerce')
34
- df = df.dropna()
35
- df['hour'] = pd.to_datetime(df['TIME ROUND'], format='%H:%M').dt.hour
36
-
37
- stats = df.groupby('hour')['multiplier'].agg(['mean', 'std', 'count']).to_dict('index')
38
- for h in range(24):
39
- if h not in stats:
40
- stats[h] = {'mean': 1.8, 'std': 1.0, 'count': 0}
41
- TIME_STATS = stats
42
- print(f"✅ সময় পরিসংখ্যান লোড হয়েছে। মোট রেকর্ড: {len(df)}")
43
- else:
44
- print("⚠️ এক্সেল ফাইল পাওয়া যায়নি। ডিফল্ট পরিসংখ্যান ব্যবহার করা হবে।")
45
- TIME_STATS = {h: {'mean': 1.8, 'std': 1.0, 'count': 100} for h in range(24)}
46
- except Exception as e:
47
- print(f"ডেটা লোড করতে সমস্যা: {e}")
48
- TIME_STATS = {h: {'mean': 1.8, 'std': 1.0, 'count': 100} for h in range(24)}
49
-
50
- load_time_statistics()
51
-
52
- # ==================== স্ট্যাটিস্টিক্যাল মডেল V1-V5 ====================
53
-
54
- class StatisticalModelV1:
55
- """V1: বেসিক স্ট্যাটিস্টিক্যাল + আউটলায়ার রিমুভাল"""
56
- def predict(self, history):
57
- recent = history[:15]
58
- if len(recent) < 3:
59
- return {'prediction': 1.5, 'confidence': 0.3}
60
-
61
- # আউটলায়ার রিমুভাল (IQR)
62
- q1, q3 = np.percentile(recent, [25, 75])
63
- iqr = q3 - q1
64
- filtered = [x for x in recent if (q1 - 1.5*iqr) <= x <= (q3 + 1.5*iqr)]
65
- if len(filtered) < 3:
66
- filtered = recent
67
-
68
- # ওয়েটেড ট্রেন্ড
69
- x = np.arange(len(filtered))
70
- weights = np.linspace(1.5, 0.5, len(filtered))
71
- weights /= weights.sum()
72
-
73
- weighted_mean_x = np.average(x, weights=weights)
74
- weighted_mean_y = np.average(filtered, weights=weights)
75
-
76
- numerator = np.sum(weights * (x - weighted_mean_x) * (filtered - weighted_mean_y))
77
- denominator = np.sum(weights * (x - weighted_mean_x)**2)
78
- trend = numerator / denominator if denominator != 0 else 0
79
-
80
- prediction = np.median(filtered) + trend * 1.5
81
-
82
- # কনফিডেন্স
83
- cv = np.std(filtered) / (np.mean(filtered) + 0.1)
84
- confidence = min(0.85, 0.5 + len(filtered)/len(recent)*0.3 - cv*0.2)
85
-
86
- return {'prediction': float(prediction), 'confidence': float(confidence)}
87
-
88
- class StatisticalModelV2:
89
- """V2: মাল্টি-টাইমফ্রেম"""
90
- def predict(self, history):
91
- timeframes = {'short': history[:5], 'medium': history[:10], 'long': history[:20]}
92
- preds, confs = [], []
93
-
94
- for name, data in timeframes.items():
95
- if len(data) < 3:
96
- continue
97
-
98
- ma_3 = np.mean(data[:3]) if len(data)>=3 else np.mean(data)
99
- ma_5 = np.mean(data[:5]) if len(data)>=5 else ma_3
100
-
101
- ema = data[0]
102
- alpha = 0.3
103
- for v in data[1:]:
104
- ema = alpha*v + (1-alpha)*ema
105
-
106
- x = np.arange(len(data))
107
- trend = np.polyfit(x, data, 1)[0]
108
-
109
- base = np.mean([ma_3, ma_5, ema])
110
- preds.append(base + trend * len(data) / 10)
111
- confs.append(min(0.9, 0.5 + len(data)/40))
112
-
113
- if not preds:
114
- return {'prediction': 1.5, 'confidence': 0.3}
115
-
116
- weights = {'short':0.5, 'medium':0.3, 'long':0.2}
117
- final_pred = 0
118
- total_weight = 0
119
-
120
- for i, name in enumerate(timeframes.keys()):
121
- if i < len(preds):
122
- w = weights.get(name, 0.2) * confs[i]
123
- final_pred += preds[i] * w
124
- total_weight += w
125
-
126
- final_pred /= total_weight if total_weight else 1
127
- confidence = np.mean(confs) * 0.9
128
-
129
- return {'prediction': float(final_pred), 'confidence': float(confidence)}
130
-
131
- class StatisticalModelV3:
132
- """V3: সাইকেল ডিটেকশন"""
133
- def detect_cycles(self, history):
134
- if len(history) < 10:
135
- return None
136
-
137
- cycles = []
138
- for period in range(3, 7):
139
- corrs = []
140
- for i in range(len(history) - period*2):
141
- seg1 = history[i:i+period]
142
- seg2 = history[i+period:i+period*2]
143
- if len(seg1) == len(seg2):
144
- corr = np.corrcoef(seg1, seg2)[0,1]
145
- if not np.isnan(corr):
146
- corrs.append(abs(corr))
147
- if corrs and np.mean(corrs) > 0.6:
148
- cycles.append({'period': period, 'strength': float(np.mean(corrs))})
149
-
150
- return cycles if cycles else None
151
-
152
- def predict(self, history):
153
- recent = history[:20]
154
- cycles = self.detect_cycles(recent)
155
- cycle_pred = None
156
-
157
- if cycles:
158
- best = max(cycles, key=lambda x: x['strength'])
159
- period = best['period']
160
- if len(recent) > period:
161
- next_val = recent[period:period+1]
162
- if next_val:
163
- cycle_pred = next_val[0] * (1 + best['strength'] * 0.1)
164
-
165
- base_pred = np.median(recent)
166
- if cycle_pred:
167
- base_pred = (base_pred + cycle_pred) / 2
168
-
169
- # ক্যাপ সরিয়ে দেওয়া হয়েছে - এখন যেকোনো মান হতে পারে
170
- prediction = max(1.05, base_pred)
171
-
172
- confidence = min(0.9, 0.5 + len(recent)/40 + (0.15 if cycles else 0))
173
-
174
- return {'prediction': float(prediction), 'confidence': float(confidence)}
175
-
176
- class StatisticalModelV4:
177
- """V4: এডাপটিভ লার্নিং"""
178
- def __init__(self):
179
- self.performance = []
180
- self.bias = 0
181
- self.volatility_regime = 'normal'
182
-
183
- def detect_volatility(self, history):
184
- if len(history) < 10:
185
- return 'normal'
186
- recent_vol = np.std(history[:5])
187
- long_vol = np.std(history[:20]) if len(history)>=20 else recent_vol
188
-
189
- if recent_vol > long_vol * 1.5:
190
- return 'high'
191
- elif recent_vol < long_vol * 0.5:
192
- return 'low'
193
- else:
194
- return 'normal'
195
-
196
- def predict(self, history):
197
- recent = history[:15]
198
- self.volatility_regime = self.detect_volatility(history)
199
-
200
- mean_val, median_val = np.mean(recent), np.median(recent)
201
-
202
- x = np.arange(len(recent))
203
- weights = np.exp(-0.2 * x)
204
- weights /= weights.sum()
205
-
206
- weighted_mean_x = np.average(x, weights=weights)
207
- weighted_mean_y = np.average(recent, weights=weights)
208
-
209
- numerator = np.sum(weights * (x - weighted_mean_x) * (recent - weighted_mean_y))
210
- denominator = np.sum(weights * (x - weighted_mean_x)**2)
211
- trend = numerator / denominator if denominator != 0 else 0
212
-
213
- preds = {'mean': mean_val, 'median': median_val, 'trend': median_val + trend * len(recent) * 0.5}
214
- w = {'mean': 0.3, 'median': 0.4, 'trend': 0.3}
215
-
216
- if self.volatility_regime == 'high':
217
- w['median'] *= 1.5
218
- elif self.volatility_regime == 'low':
219
- w['trend'] *= 1.3
220
-
221
- total = sum(w.values())
222
- for k in w:
223
- w[k] /= total
224
-
225
- prediction = sum(preds[k] * w[k] for k in preds) + self.bias
226
-
227
- confidence = 0.5 + len(recent)/30
228
- if self.volatility_regime == 'high':
229
- confidence *= 0.8
230
- elif self.volatility_regime == 'low':
231
- confidence *= 1.2
232
-
233
- if self.performance:
234
- recent_perf = np.mean(self.performance[-10:]) if len(self.performance)>=10 else np.mean(self.performance)
235
- confidence *= (1 + recent_perf * 0.1)
236
-
237
- confidence = min(0.9, confidence)
238
-
239
- # ক্যাপ সরিয়ে দেওয়া হয়েছে - এখন যেকোনো মান হতে পারে
240
- return {'prediction': float(max(1.05, prediction)), 'confidence': float(confidence)}
241
-
242
- def update(self, actual, predicted):
243
- error = abs(actual - predicted) / actual
244
- acc = max(0, 1 - error)
245
- self.performance.append(acc)
246
- if len(self.performance) > 100:
247
- self.performance = self.performance[-100:]
248
- self.bias += (actual - predicted) * 0.01
249
-
250
- class StatisticalModelV5:
251
- """V5: র‍্যান্ডম ফরেস্ট সিমুলেশন"""
252
- def __init__(self):
253
- self.n_estimators = 10
254
-
255
- def predict(self, history):
256
- if len(history) < 10:
257
- return {'prediction': 1.5, 'confidence': 0.5}
258
-
259
- recent = history[:10]
260
- trees = []
261
-
262
- for _ in range(self.n_estimators):
263
- idx = np.random.choice(len(recent), size=len(recent), replace=True)
264
- sample = [recent[i] for i in idx]
265
- if np.random.random() > 0.5:
266
- trees.append(np.mean(sample))
267
- else:
268
- trees.append(np.median(sample))
269
-
270
- pred = float(np.mean(trees))
271
- return {'prediction': pred, 'confidence': 0.7}
272
-
273
- # ==================== V6 মডেল (টাইম-ভিত্তিক) ====================
274
-
275
- class StatisticalModelV6:
276
- """V6: টাইম-অফ-ডে অ্যাডজাস্টমেন্ট"""
277
- def __init__(self, time_stats):
278
- self.time_stats = time_stats
279
-
280
- def predict(self, history, current_hour=None):
281
- if current_hour is None:
282
- current_hour = datetime.now().hour
283
-
284
- stats = self.time_stats.get(current_hour, {'mean': 1.8, 'std': 1.0})
285
- base_pred = np.median(history[:5]) if len(history)>=5 else 1.5
286
-
287
- alpha = 0.3
288
- prediction = base_pred * (1 - alpha) + stats['mean'] * alpha
289
- confidence = min(0.85, 0.5 + stats.get('count', 100) / 500)
290
-
291
- return {'prediction': float(prediction), 'confidence': float(confidence), 'hour': current_hour}
292
-
293
- # ==================== এনসেম্বল প্রেডিক্টর ====================
294
-
295
- class EnsemblePredictorV6:
296
- def __init__(self, time_stats):
297
- self.models = {
298
- 'v1': StatisticalModelV1(),
299
- 'v2': StatisticalModelV2(),
300
- 'v3': StatisticalModelV3(),
301
- 'v4': StatisticalModelV4(),
302
- 'v5': StatisticalModelV5(),
303
- 'v6': StatisticalModelV6(time_stats)
304
- }
305
- self.ensemble_weights = {'v1':0.2, 'v2':0.2, 'v3':0.15, 'v4':0.15, 'v5':0.15, 'v6':0.15}
306
- self.performance = defaultdict(list)
307
-
308
- def predict(self, history):
309
- if len(history) < 5:
310
- return self._default_prediction(f"মাত্র {len(history)}টি রাউন্ড, ৫টি প্রয়োজন")
311
-
312
- current_hour = datetime.now().hour
313
- preds = {}
314
- confs = {}
315
-
316
- for name, model in self.models.items():
317
- try:
318
- if name == 'v6':
319
- res = model.predict(history, current_hour)
320
- else:
321
- res = model.predict(history)
322
- preds[name] = res['prediction']
323
- confs[name] = res.get('confidence', 0.5)
324
- except Exception as e:
325
- print(f"মডেল {name} এ সমস্যা: {e}")
326
- preds[name] = 1.5
327
- confs[name] = 0.3
328
-
329
- # ওয়েট আপডেট
330
- for name in self.ensemble_weights:
331
- if name in self.performance and self.performance[name]:
332
- recent_acc = np.mean(self.performance[name][-20:]) if len(self.performance[name])>=20 else np.mean(self.performance[name])
333
- self.ensemble_weights[name] = 0.1 + recent_acc * 0.8
334
-
335
- total = sum(self.ensemble_weights.values())
336
- for name in self.ensemble_weights:
337
- self.ensemble_weights[name] /= total
338
-
339
- final_pred = 0
340
- total_weight = 0
341
- for name, pred in preds.items():
342
- weight = self.ensemble_weights.get(name, 0.2) * confs[name]
343
- final_pred += pred * weight
344
- total_weight += weight
345
-
346
- final_pred /= total_weight if total_weight else 1
347
-
348
- # মার্কেট স্টেট
349
- recent = history[:10]
350
- vol = np.std(recent) / (np.mean(recent)+0.1)
351
- if vol > 0.5:
352
- state = "অস্থির 🌪️"
353
- elif vol < 0.2:
354
- state = "স্থিতিশীল ✨"
355
- else:
356
- state = "সাধারণ ➡️"
357
-
358
- confidence = np.mean(list(confs.values())) * 0.9
359
- if vol < 0.2:
360
- confidence *= 1.1
361
- elif vol > 0.5:
362
- confidence *= 0.9
363
- confidence = min(0.95, confidence)
364
-
365
- # প্রেডিকশন ইন্টারভ্যাল
366
- all_preds = list(preds.values())
367
- std = np.std(all_preds) if len(all_preds)>1 else 0.2
368
- spread = std * (2 - confidence)
369
- spread = max(0.1, min(1.5, spread))
370
- interval = (max(1.01, final_pred - spread/2), final_pred + spread/2)
371
-
372
- # ডিসিশন
373
- if final_pred > 3.0:
374
- decision = "বড় 🚀"
375
- elif final_pred > 1.8:
376
- decision = "মাঝারি 💪"
377
- else:
378
- decision = "ছোট 🎯"
379
-
380
- hour_stats = TIME_STATS.get(current_hour, {'mean':1.8, 'count':0})
381
- time_info = f"বর্তমান ঘণ্টা: {current_hour}:00 – ঐতিহাসিক গড়: {hour_stats['mean']:.2f}x (ডাটা: {hour_stats['count']}টি)"
382
-
383
- summary = (
384
- f"🎯 **প্রেডিকশন ইন্টারভ্যাল**: {interval[0]:.2f}x – {interval[1]:.2f}x\n"
385
- f"📊 **এক্সপেক্টেড মাল্টিপ্লায়ার**: {final_pred:.2f}x\n"
386
- f"📈 **কনফিডেন্স**: {confidence*100:.1f}%\n"
387
- f"⚡ **মার্কেট স্টেট**: {state}\n"
388
- f"🎲 **ডিসিশন**: {decision}\n"
389
- f"⏰ **টাইম ফিচার**: {time_info}\n"
390
- f"📌 **ডাটা পয়েন্ট**: {len(history)}টি রাউন্ড"
391
- )
392
-
393
- return {
394
- 'summary': summary,
395
- 'prediction': final_pred,
396
- 'interval': interval,
397
- 'confidence': confidence,
398
- 'decision': decision,
399
- 'analysis': state,
400
- 'hour': current_hour
401
- }
402
-
403
- def _default_prediction(self, msg):
404
- return {
405
- 'summary': f"⚠️ {msg}\n\n📊 ডিফল্ট প্রেডিকশন: 1.50x (কনফিডেন্স 30%)",
406
- 'prediction': 1.5,
407
- 'interval': (1.3, 1.7),
408
- 'confidence': 0.3,
409
- 'decision': 'ছোট 🎯',
410
- 'analysis': 'অপ্রতুল ডাটা'
411
- }
412
-
413
- # ==================== অ্যাপ্লিকেশন ক্লাস ====================
414
-
415
- class AviatorPredictorApp:
416
- def __init__(self):
417
- self.history = []
418
- self.model = EnsemblePredictorV6(TIME_STATS)
419
-
420
- def add_round(self, multiplier):
421
- try:
422
- # ইনপুট ভ্যালিডেশন
423
- if multiplier is None:
424
- return self.get_all_outputs(error="মাল্টিপ্লায়ার দেওয়া হয়নি")
425
-
426
- # সংখ্যায় রূপান্তর
427
- val = float(multiplier)
428
-
429
- if val <= 0:
430
- return self.get_all_outputs(error="ইনভ্যালিড মাল্টিপ্লায়ার (১.০ এর বেশি দিন)")
431
-
432
- # ইতিহাসে যোগ করুন
433
- self.history.insert(0, val)
434
- if len(self.history) > CONFIG["HISTORY_LIMIT"]:
435
- self.history = self.history[:CONFIG["HISTORY_LIMIT"]]
436
-
437
- return self.get_all_outputs()
438
-
439
- except ValueError:
440
- return self.get_all_outputs(error=f"ইনভ্যালিড সংখ্যা: {multiplier}")
441
- except Exception as e:
442
- traceback.print_exc() # Hugging Face লগে প্রিন্ট হবে
443
- return self.get_all_outputs(error=f"⚠️ ত্রুটি: {str(e)}")
444
-
445
- def reset(self):
446
- self.history = []
447
- for _ in range(20):
448
- self.history.append(round(random.uniform(1.0, 3.5), 2))
449
- self.history.sort(reverse=True)
450
- return self.get_all_outputs()
451
-
452
- def get_all_outputs(self, error=None):
453
- if error:
454
- table = [[i+1, "?.??x"] for i in range(min(20, len(self.history)))] or [[1, "1.00x"]]
455
- return [table, f"⚠️ {error}"]
456
-
457
- try:
458
- pred_result = self.model.predict(self.history)
459
- table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
460
- return [table, pred_result['summary']]
461
- except Exception as e:
462
- traceback.print_exc()
463
- table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
464
- return [table, f"⚠️ প্রেডিকশনে সমস্যা: {str(e)}"]
465
-
466
- # ==================== অ্যাপ ইনিশিয়ালাইজ ====================
467
-
468
- predictor_app = AviatorPredictorApp()
469
- predictor_app.reset()
470
-
471
- # ==================== গ্র্যাডিও ইন্টারফেস ====================
472
-
473
- with gr.Blocks(title="AVOLD V6 Predictor") as demo:
474
- gr.HTML("""
475
- <div style="text-align: center; margin-bottom: 20px;">
476
- <h1 style="color: #00d4ff; font-size: 48px; margin: 0;">✈️ AVOLD V6</h1>
477
- <p style="color: #888; font-size: 14px;">সময়-ভিত্তিক এভিয়েটর প্রেডিক্টর – ৬টি মডেলের এনসেম্বল</p>
478
- </div>
479
- """)
480
-
481
- with gr.Row():
482
- inp = gr.Number(label="নতুন মাল্টিপ্লায়ার", value=1.0, step=0.1, minimum=1.0, maximum=None)
483
- add_btn = gr.Button("➕ যোগ করুন", variant="primary")
484
-
485
- prediction_box = gr.Textbox(label="🧠 প্রেডিকশন রিপোর্ট", lines=10, interactive=False)
486
- rounds_table = gr.Dataframe(label="📜 শেষ ৫০ রাউন���ড", headers=["রাউন্ড", "মাল্টিপ্লায়ার"], row_count=10)
487
- reset_btn = gr.Button("🔄 রিসেট ডাটা", variant="secondary")
488
-
489
- add_btn.click(
490
- fn=predictor_app.add_round,
491
- inputs=inp,
492
- outputs=[rounds_table, prediction_box]
493
- )
494
-
495
- reset_btn.click(
496
- fn=predictor_app.reset,
497
- outputs=[rounds_table, prediction_box]
498
- )
499
-
500
- demo.load(
501
- fn=predictor_app.get_all_outputs,
502
- outputs=[rounds_table, prediction_box]
503
- )
504
-
505
- # ==================== কাস্টম CSS (launch() এ দেওয়া হবে) ====================
506
-
507
- CUSTOM_CSS = """
508
- .gradio-container {
509
- background: #0a0a0f !important;
510
- color: #ffffff !important;
511
- font-family: 'Inter', sans-serif !important;
512
- }
513
- footer {visibility: hidden}
514
- h1 {
515
- color: #00d4ff !important;
516
- text-align: center;
517
- margin-bottom: 20px;
518
- text-shadow: 0 0 10px #00d4ff;
519
- }
520
- .gr-box {
521
- border: 1px solid #333 !important;
522
- background: rgba(255,255,255,0.05) !important;
523
- }
524
- .gr-button-primary {
525
- background: linear-gradient(135deg, #00d4ff, #0088ff) !important;
526
- border: none !important;
527
- }
528
- .gr-button-secondary {
529
- background: rgba(255,255,255,0.1) !important;
530
- border: 1px solid #00d4ff !important;
531
- margin-top: 20px !important;
532
- }
533
- .gr-dataframe {
534
- background: rgba(255,255,255,0.05) !important;
535
- }
536
- """
537
-
538
- # ==================== API এন্ডপয়েন্ট (ShareX-এর জন্য) ====================
539
-
540
- # FastAPI অ্যাপ তৈরি
541
- app = demo.app # demo.gr_app নয়, demo.app ব্যবহার করতে হবে
542
-
543
- @app.post("/api/add_crash")
544
- async def add_crash_api(request: Request):
545
- """
546
- ShareX থেকে JSON ডাটা গ্রহণ করে ইতিহাসে যোগ করে
547
- """
548
- try:
549
- data = await request.json()
550
- crash_value = data.get("crash_value")
551
-
552
- if crash_value is None:
553
- # বিকল্প হিসেবে "value" বা "multiplier" চেক করা
554
- crash_value = data.get("value") or data.get("multiplier")
555
-
556
- if crash_value is None:
557
- return {"status": "error", "message": "crash_value, value, অথবা multiplier প্রদান করুন"}
558
-
559
- # OCR থেকে আনা টেক্সট ক্লিন করা (যেমন "2.45x" থেকে "2.45")
560
- if isinstance(crash_value, str):
561
- # শুধু সংখ্যা ও ডট রাখা
562
- import re
563
- crash_value = re.sub(r'[^\d.]', '', crash_value)
564
-
565
- # সংখ্যায় রূপান্তর
566
- val = float(crash_value)
567
-
568
- if val <= 1.0:
569
- return {"status": "error", "message": f"মাল্টিপ্লায়ার ১.০ এর বেশি হতে হবে (পাওয়া গেছে: {val})"}
570
-
571
- # ইতিহাসে যোগ করা
572
- result = predictor_app.add_round(val)
573
-
574
- # API রেসপন্স
575
- return {
576
- "status": "success",
577
- "message": f"ক্র্যাশ ভ্যালু {val:.2f}x যোগ করা হয়েছে",
578
- "total_rounds": len(predictor_app.history)
579
- }
580
-
581
- except ValueError as e:
582
- return {"status": "error", "message": f"ইনভ্যালিড সংখ্যা: {crash_value}"}
583
- except Exception as e:
584
- traceback.print_exc()
585
- return {"status": "error", "message": f"সার্ভার ত্রুটি: {str(e)}"}
586
-
587
- @app.get("/api/status")
588
- async def api_status():
589
- """
590
- API স্ট্যাটাস চেক করার জন্য
591
- """
592
- return {
593
- "status": "active",
594
- "total_rounds": len(predictor_app.history),
595
- "last_10_rounds": [f"{x:.2f}" for x in predictor_app.history[:10]]
596
- }
597
-
598
- if __name__ == "__main__":
599
- # CSS এবং theme এখন launch() এ দেওয়া হয়েছে
600
- demo.launch(server_name="0.0.0.0", server_port=7860, css=CUSTOM_CSS, theme='dark')