File size: 15,582 Bytes
dfc7b05
 
 
 
 
c35e733
74f9434
6a21cb7
52d95e9
 
 
 
 
 
 
 
 
 
c35e733
 
 
 
 
0f55337
 
 
 
c35e733
 
 
93dc968
24fe75e
 
93dc968
 
73698fd
 
6a21cb7
 
 
315f401
6a21cb7
 
3b33a74
 
 
 
6a21cb7
3b33a74
3dcfedf
3b33a74
3dcfedf
3b33a74
3dcfedf
3b33a74
 
 
 
 
 
 
 
 
 
dfc7b05
3b33a74
dfc7b05
6a21cb7
3b33a74
dfc7b05
6a21cb7
3b33a74
 
 
 
 
 
 
6a21cb7
dbec99e
6a21cb7
 
 
 
 
3b33a74
3dcfedf
3b33a74
 
 
6a21cb7
3b33a74
6a21cb7
 
 
3b33a74
6a21cb7
b5fe944
 
 
 
 
 
 
 
 
 
 
 
 
24fe75e
 
3dcfedf
dfc7b05
bb344cb
ce191d4
bb344cb
ce191d4
 
 
 
bb344cb
8b665e6
c0fe300
8b665e6
 
ce191d4
 
 
04d1d35
 
 
bb344cb
 
 
 
dfc7b05
ce191d4
bb344cb
2802387
bb344cb
 
 
 
 
dfc7b05
f53c6ad
bb344cb
 
dfc7b05
bb344cb
04d1d35
bb344cb
 
dfc7b05
ce191d4
 
 
d03711d
 
 
 
bb344cb
 
9c00108
c35e733
 
 
c7d3893
193b98a
dfc7b05
04d1d35
 
 
 
 
ce191d4
f53c6ad
2839e91
ce191d4
c35e733
5a05329
d03711d
5a05329
f171562
 
5a05329
c35e733
d03711d
 
5a05329
 
f171562
b208eef
04d1d35
5a05329
2839e91
341f773
ce191d4
6a43a2f
 
0f55337
714e0f4
0f55337
c35e733
 
0f55337
dbec99e
0f55337
 
714e0f4
0f55337
c35e733
0f55337
dbec99e
c35e733
73698fd
c35e733
73698fd
 
ab701df
c35e733
27cd445
0f55337
451a347
2879807
ce191d4
ab701df
dbec99e
451a347
 
 
 
 
 
 
 
b73cdc1
c7d3893
73698fd
0f55337
 
edeec3c
714e0f4
ce191d4
edeec3c
714e0f4
 
 
c35e733
 
 
 
 
 
 
451a347
 
 
5b8e793
451a347
 
 
d8c9ca6
edeec3c
451a347
4acce00
0f55337
4acce00
7ef807c
4acce00
d8c9ca6
0f55337
eebb2c6
 
4acce00
7ef807c
 
 
 
 
 
 
 
0f55337
 
 
7ef807c
4acce00
 
 
 
 
 
 
17791b8
0f55337
4acce00
0f55337
17791b8
0f55337
 
 
 
4acce00
 
7ef807c
 
 
6a21cb7
ce191d4
0f55337
edeec3c
 
0f55337
edeec3c
0f55337
 
edeec3c
451a347
a37fc5a
451a347
6b63df3
 
4fcbf7d
6b63df3
4fcbf7d
a37fc5a
6b63df3
d8c9ca6
6b63df3
 
 
 
 
 
 
a37fc5a
4fcbf7d
a37fc5a
 
 
451a347
 
 
c35e733
0f55337
a37fc5a
6b63df3
c35e733
04d1d35
0ae450c
 
 
 
ccbc5a3
 
 
04d1d35
24fe75e
ce191d4
 
 
c35e733
 
ce191d4
 
 
 
c35e733
 
ce191d4
 
7ef807c
 
 
ccbc5a3
 
7ef807c
 
0ae450c
ccbc5a3
 
 
 
46a39f9
c35e733
4acce00
 
 
0ae450c
4acce00
 
0ae450c
4acce00
 
04d1d35
ce191d4
 
e76424c
4fd8705
f53c6ad
0f55337
 
 
 
f53c6ad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
import pandas as pd, numpy as np, gradio as gr
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from sklearn.metrics import accuracy_score
from concrete.ml.sklearn import XGBClassifier as ConcreteXGBClassifier
from concrete.ml.deployment import FHEModelDev, FHEModelClient, FHEModelServer
import os


# Örnek dosyalar
SAMPLE_DIR = "Sample Inputs (Excel)"
EXAMPLE_XLSX = [
    f"{SAMPLE_DIR}/ROYAL_2019.xlsx",
    f"{SAMPLE_DIR}/MARKA_2016.xlsx",
    f"{SAMPLE_DIR}/THYAO_2023.xlsx",
    f"{SAMPLE_DIR}/TTRAK_2024.xlsx"
]

# Global değişkenler
client = None
server = None
encrypted_input = None
encrypted_output = None
fhe_prediction_ready = False
simulate_prediction = []  


fhe_dir = "fhe_model_artifacts"
key_dir = "client_keys"


def safe_div(a: pd.Series, b: pd.Series) -> pd.Series:
    return (a / b.replace(0, np.nan)).fillna(0)

def compute_ratios(df: pd.DataFrame) -> pd.DataFrame:
    for col in [c for c in df.columns if c != "Periyot"]:
        df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0)

    ta = df["Dönen Varlıklar"] + df["Duran Varlıklar"]
    tl = df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"]
    df["Dönen Varlıklar / Aktif (%)"] = 100 * safe_div(df["Dönen Varlıklar"], df["Dönen Varlıklar"] + df["Duran Varlıklar"])

    df["Cari Oran"] = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
    df["Asit Test Oranı"] = safe_div(
        df["Dönen Varlıklar"] - df["Stoklar"] - df["Diğer Dönen Varlıklar"],
        df["Kısa Vadeli Yükümlülükler"]
    )
    df["Nakit Oranı"] = safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"])
    df["Aktif Karlılık (%)"] = safe_div(df["Dönem Net Kar/Zararı"] * 100, ta)
    df["Faaliyet Kar Marjı"] = safe_div(df["FAALİYET KARI (ZARARI)"] * 100, df["Satış Gelirleri"])
    df["Esas Faaliyet Kar Marjı"] = safe_div(df["Net Faaliyet Kar/Zararı"] * 100, df["Satış Gelirleri"])
    df["Brüt Kar Marjı (%)"] = safe_div(df["Ticari Faaliyetlerden Brüt Kar (Zarar)"] * 100, df["Satış Gelirleri"])
    df["FAVÖK Marjı (%)"] = safe_div(df["FAALİYET KARI (ZARARI)"] * 100, df["Satış Gelirleri"])
    df["Net Kar Marjı"] = safe_div(df["Dönem Net Kar/Zararı"] * 100, df["Satış Gelirleri"])
    df["Özsermaye Karlılığı (%)"] = safe_div(df["Dönem Net Kar/Zararı"] * 100, df["Özkaynaklar"])
    df["VAFÖK Marjı"] = safe_div(df["FAALİYET KARI (ZARARI)"] * 100, df["Satış Gelirleri"])
    df["ROCE Oranı"] = safe_div(df["FAALİYET KARI (ZARARI)"] * 100, ta)
    df["Finansman Gider / Net Satış"] = safe_div(df["Finansman Giderleri"], df["Satış Gelirleri"])
    df["Borç Kaynak Oranı"] = safe_div(tl * 100, df["Özkaynaklar"])
    df["Duran Varlıklar / Aktif "] = safe_div(df["Duran Varlıklar"] * 100, ta)
    df["Duran Varlıklar / Maddi Özkaynak"] = safe_div(df["Duran Varlıklar"], df["Özkaynaklar"] - df["Maddi Olmayan Duran Varlıklar"])
    df["Esas Faaliyet Karı / Kısa Vadeli Borç"] = safe_div(df["Net Faaliyet Kar/Zararı"], df["Kısa Vadeli Yükümlülükler"])
    df["FAVÖK / Kısa Vade Borç"] = safe_div(df["FAALİYET KARI (ZARARI)"], df["Kısa Vadeli Yükümlülükler"])
    df["Net Borç / FAVÖK"] = safe_div(tl, df["FAALİYET KARI (ZARARI)"])
    df["Kısa Vade Borç / Aktif"] = safe_div(df["Kısa Vadeli Yükümlülükler"], ta)
    df["Kısa Vade Borç / Dönen Varlık"] = safe_div(df["Kısa Vadeli Yükümlülükler"], df["Dönen Varlıklar"])
    df["Kısa Vade Borç / Özsermaye"] = safe_div(df["Kısa Vadeli Yükümlülükler"], df["Özkaynaklar"])
    df["Kısa Vade Borç / Toplam Borç"] = safe_div(df["Kısa Vadeli Yükümlülükler"], tl)
    df["Net Satışlar / Kısa Vade Borç"] = safe_div(df["Satış Gelirleri"], df["Kısa Vadeli Yükümlülükler"])
    df["Özsermaye / Aktif"] = safe_div(df["Özkaynaklar"], ta)
    df["Özsermaye / Maddi Duran Varlıklar"] = safe_div(df["Özkaynaklar"], df["Maddi Duran Varlıklar"])
    df["Toplam Borç / Özsermaye"] = safe_div(tl, df["Özkaynaklar"])
    df["Aktif Devir Hızı"] = safe_div(df["Satış Gelirleri"], ta)
    df["Alacak Devir Hızı"] = safe_div(df["Satış Gelirleri"], df["Ticari Alacaklar"])
    df["Dönen Varlıklar Devir Hızı"] = safe_div(df["Dönen Varlıklar"], df["Satış Gelirleri"])
    df["Ticari Borçlar Devir Hızı"] = -safe_div(df["Satışların Maliyeti (-)"], df["Ticari Borçlar"])
    df["Finansal Kaldıraç"] = safe_div(tl * 100, ta)
    df["Stok Devir Hızı"] = -safe_div(df["Satışların Maliyeti (-)"], df["Stoklar"])

    # Altman Z-Score
    X1 = safe_div(df["Dönen Varlıklar"] - df["Kısa Vadeli Yükümlülükler"], ta)
    X2 = safe_div(df["Geçmiş Yıllar Kar/Zararları"] + df["Dönem Net Kar/Zararı"], ta)
    X3 = safe_div(df["SÜRDÜRÜLEN FAALİYETLER VERGİ ÖNCESİ KARI (ZARARI)"], ta)
    X4 = safe_div(df["Özkaynaklar"], tl)
    X5 = safe_div(df["Satış Gelirleri"], ta)
    df["Altman Z-Skoru"] = 1.2 * X1 + 1.4 * X2 + 3.3 * X3 + 0.6 * X4 + X5

    # Springate
    S3 = safe_div(df["SÜRDÜRÜLEN FAALİYETLER VERGİ ÖNCESİ KARI (ZARARI)"], df["Kısa Vadeli Yükümlülükler"])
    df["Springate Skoru"] = 1.03 * X1 + 3.07 * X3 + 0.66 * S3 + 0.4 * X5

    # Zmijewski
    Z1 = safe_div(df["Dönem Net Kar/Zararı"], ta)
    Z2 = safe_div(tl, ta)
    Z3 = safe_div(df["Dönen Varlıklar"], df["Kısa Vadeli Yükümlülükler"])
    df["Zmijewski Skoru"] = -4.3 - 4.5 * Z1 + 5.7 * Z2 - 0.004 * Z3

    #L Model Score
    L1 = X1
    L2 = X2
    L3 = X3
    L4 = X4
    L5 = X5
    
    L6_num = safe_div(df["Nakit ve Nakit Benzerleri"], df["Kısa Vadeli Yükümlülükler"])
    L6 = safe_div(L6_num, df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"])
    L7 = safe_div(df["Kısa Vadeli Yükümlülükler"] + df["Uzun Vadeli Yükümlülükler"], df["Dönen Varlıklar"] + df["Duran Varlıklar"])
    df["L Model Skoru"] = -0.113*L1 + 0.238*L2 - 0.052* L3 - 0.051* L4 + 0.011* L5 + 0.729*L6 - 0.639*L7

    
    return df


# ------------------------ MODEL EĞİTİMİ ------------------------
df = pd.read_csv("refined_data.csv")
df["Görüs Tipi"] = df["Görüs Tipi"].apply(lambda x: "Olumlu" if "olumlu" in str(x).lower() else x)

DROP = ["Şirket Adı", "Şirketin Kodu", "Periyot", "Yıl", "Dönen Varlıklar", "Duran Varlıklar",
        "Toplam Varlıklar", "Kısa Vadeli Yükümlülükler", "Uzun Vadeli Yükümlülükler",
        "Toplam Yükümlülükler", "Toplam Özkaynaklar", "Ana Ortaklığa Ait Özkaynaklar",
        "Kontrol Gücü Olmayan Kaynaklar", "Toplam Kaynaklar"]

df = df.drop(columns=DROP) 
df = df.dropna(subset=["Görüs Tipi"])

X = df.drop(columns=["Görüs Tipi"]) 
y = df["Görüs Tipi"]

X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
scaler_full = MinMaxScaler().fit(X_tr)
Xtr_s = scaler_full.transform(X_tr)
Xte_s = scaler_full.transform(X_te)

encoder = LabelEncoder()
ytr_e = encoder.fit_transform(y_tr)
yte_e = encoder.transform(y_te)

# Grid Search
grid = GridSearchCV(
    ConcreteXGBClassifier(n_bits=8, random_state=42),
    {"n_estimators": [20, 30, 50], "max_depth": [3, 4, 5], "learning_rate": [0.1, 0.2]},
    cv=3, scoring="accuracy", verbose=0
)
grid.fit(Xtr_s, ytr_e)
best_params = grid.best_params_

# Özellik seçimi
full_plain = ConcreteXGBClassifier(n_bits=8, **best_params, random_state=42)
full_plain.fit(Xtr_s, ytr_e)

imp_df = pd.DataFrame({"col": X.columns, "imp": full_plain.feature_importances_})
imp_df = imp_df.sort_values("imp", ascending=False).reset_index(drop=True)
imp_df["cum"] = imp_df["imp"].cumsum()
COLS = imp_df.loc[imp_df["cum"] <= 0.95, "col"].tolist()

# Final model
scaler_sel = MinMaxScaler().fit(X_tr[COLS])
Xtr_sel = scaler_sel.transform(X_tr[COLS])

if os.path.exists(fhe_dir):
    shutil.rmtree(fhe_dir)
    
final_model = ConcreteXGBClassifier(n_bits=8, **best_params, random_state=42)
final_model.fit(Xtr_sel, ytr_e)
final_model.compile(Xtr_sel)

dev = FHEModelDev(path_dir=fhe_dir, model=final_model)
dev.save()



print("\n🔍 Seçilen Özellikler (%95 etkili):")
for i, col in enumerate(COLS, 1):
    print(f"{i:>2}. {col}")


# ------------------------ FONKSİYONLAR ------------------------
import shutil

def generate_keys():
    global client

    # Klasörleri temizle
    if os.path.exists(key_dir):
        shutil.rmtree(key_dir)
    os.makedirs(key_dir, exist_ok=True)

    client = FHEModelClient(path_dir=fhe_dir, key_dir=key_dir)
    
    # force yeni key yaratması için: eski key'leri sildik zaten
    serialized_eval_keys = client.get_serialized_evaluation_keys()

    return str(serialized_eval_keys[:120]) + "..."





def encrypt_excel(file):
    if file is None:
        raise gr.Error("Lütfen önce bir Excel dosyası yükleyin.")

    global encrypted_input, encrypted_output, fhe_prediction_ready, simulate_prediction

    if client is None:
        raise gr.Error("Lütfen önce 'Anahtar Oluştur'a tıklayın.")

    #  Yeni yükleme geldiğinde önceki tahminleri sıfırla
    encrypted_output = None
    fhe_prediction_ready = False
    simulate_prediction = []

    df = pd.read_excel(file.name, header=None).set_index(0).T.reset_index(drop=True)

    #  Temizlik işlemleri
    df.columns = df.columns.str.strip()
    df = df.loc[:, ~df.columns.duplicated()]
    df.rename(columns={"Desc": "Periyot"}, inplace=True)
    if "Periyot" in df.columns:
        df["Periyot"] = df["Periyot"].astype(str).str.replace(r"\s+", " ", regex=True).str.strip()

    enriched = compute_ratios(df)
    X_input = enriched[COLS].dropna().head(1)

    print(" Şifreleme öncesi shape:", X_input.shape)

    scaled = scaler_sel.transform(X_input)

    #  Her satırı ayrı ayrı şifrele
    encrypted_list = []
    for row in scaled:
        row = row.reshape(1, -1)
        encrypted = client.quantize_encrypt_serialize(row)
        encrypted_list.append(encrypted)

    encrypted_input = encrypted_list
    return f"{len(encrypted_input)} adet satır şifrelendi."







def run_fhe():
    global server, encrypted_output, fhe_prediction_ready
    if client is None:
        raise gr.Error("Lütfen önce 'Anahtar Oluştur'a tıklayın.")
        
    if encrypted_input is None:
        raise gr.Error("Veri şifrelenmemiş.")
    
    server = FHEModelServer(path_dir=fhe_dir)
    server.load()
    
    eval_keys = client.get_serialized_evaluation_keys()
    encrypted_result = []

    for enc in encrypted_input:
        result = server.run(enc, eval_keys)
        encrypted_result.append(result)

    encrypted_output = encrypted_result
    fhe_prediction_ready = True  
    return "Gerçek tahmin tamamlandı."




def run_simulate_direct(file):
    global simulate_prediction
    simulate_prediction = []  

    if file is None:
        raise gr.Error("Lütfen bir Excel dosyası yükleyin.")

    df = pd.read_excel(file.name, header=None).set_index(0).T.reset_index(drop=True)
    df.columns = df.columns.str.strip()
    df = df.loc[:, ~df.columns.duplicated()]
    df.rename(columns={"Desc": "Periyot"}, inplace=True)

    enriched = compute_ratios(df)
    X_input = enriched[COLS].dropna().head(1)

    if X_input.empty:
        raise gr.Error("Geçerli veri bulunamadı. Excel dosyasını kontrol edin.")

    scaled = scaler_sel.transform(X_input)
    y_pred = final_model.predict(scaled, fhe="simulate")
    label = encoder.inverse_transform([int(y_pred[0])])[0]

    simulate_prediction = [label]
    return "Simülasyon tahmini tamamlandı."




def show_simulate_result():
    if not simulate_prediction or not isinstance(simulate_prediction, list):
        raise gr.Error("Henüz simülasyon tahmini yapılmadı.")

    if not all(isinstance(label, str) for label in simulate_prediction):
        raise gr.Error("Geçerli bir tahmin sonucu bulunamadı.")

    return "\n".join(f"{i+1}. {label}" for i, label in enumerate(simulate_prediction))





def decrypt_result():
    global fhe_prediction_ready, encrypted_output

    if not fhe_prediction_ready:
        raise gr.Error("Henüz gerçek tahmin tamamlanmadı. Lütfen önce 'Gerçek Tahmini Başlat' butonuna basın.")

    if encrypted_output is None or len(encrypted_output) == 0:
        raise gr.Error("Şifreli tahmin sonucu bulunamadı.")

    predictions = []
    for i, enc in enumerate(encrypted_output):
        pred = client.deserialize_decrypt_dequantize(enc)
        raw = pred.flatten()

        print(f"\n🔍 [Tahmin {i+1}]")
        print(f"📈 Decrypted output (vektör?): {raw}")
        print(f"🎯 Sınıf listesi: {list(encoder.classes_)}")

        if len(raw) > 1:
            # Çok sınıflı olasılık çıktısı 
            label_idx = int(np.argmax(raw))
            print(f"🔢 argmax sonucu: {label_idx}")
        else:
            # Tek değer → doğrudan sınıf indexi olabilir
            label_idx = int(round(raw[0]))
            print(f"🔢 Yuvarlanmış değer: {raw[0]}{label_idx}")

        if label_idx >= len(encoder.classes_):
            label = f"⚠️ Geçersiz sınıf indexi: {label_idx}"
        else:
            label = encoder.inverse_transform([label_idx])[0]

        predictions.append(label)

    return "\n".join(f"{i+1}. {label}" for i, label in enumerate(predictions))




    

# -------------------- Gradio UI -------------------- #
def fhe_start_message():
    return "Tahmin başlatıldı, lütfen bekleyin..."

def sim_start_message():
    return "Simülasyon başlatıldı, lütfen bekleyin..."

# -------------------- Gradio UI -------------------- #
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
    gr.Markdown("# Denetçi Görüşü Tahmin Uygulaması (FHE)")

    gr.Markdown("## 1. Anahtar Oluştur")
    key_btn = gr.Button("🔑 Anahtar Oluştur")
    key_out = gr.Textbox(label="Evaluation Key")
    key_btn.click(generate_keys, outputs=key_out)

    gr.Markdown("## 2. Excel Yükle")
    file_in = gr.File(file_types=[".xlsx"], label="Excel Dosyası")
    encrypt_btn = gr.Button("🔐 Veriyi Şifrele")
    enc_out = gr.Textbox(label="Şifreli Veri")
    encrypt_btn.click(encrypt_excel, inputs=file_in, outputs=enc_out)

    gr.Markdown("## 3. Tahmini Gerçekleştir")
    with gr.Row():
        run_real_btn = gr.Button("🔐 Gerçek Tahmini Başlat (FHE)")
        run_sim_btn = gr.Button("🧪 Simülasyon Tahminini Başlat")

    status_real = gr.Textbox(label="Durum (Gerçek Tahmin)")
    status_sim = gr.Textbox(label="Durum (Simülasyon)")

    run_real_btn.click(fhe_start_message, outputs=status_real).then(run_fhe, outputs=status_real)
    run_sim_btn.click(sim_start_message, outputs=status_sim).then(run_simulate_direct, inputs=[file_in], outputs=status_sim)



    gr.Markdown("## 4. Sonucu Deşifre Et")
    with gr.Row():
        decrypt_btn = gr.Button("🔓 Gerçek Tahmini Göster (FHE)")
        decrypt_sim_btn = gr.Button("🧪 Simülasyon Sonucunu Göster")
    
    result_real = gr.Textbox(label="Gerçek Tahmin Sonucu")
    result_sim = gr.Textbox(label="Simülasyon Tahmin Sonucu")
    
    decrypt_btn.click(decrypt_result, outputs=result_real)
    decrypt_sim_btn.click(show_simulate_result, outputs=result_sim)

    gr.Markdown("## 📂 Örnek Dosyalar")
    gr.Examples(examples=EXAMPLE_XLSX, inputs=file_in, label="Örnek Excel Seç", cache_examples=False)

if __name__ == "__main__":
    print("✅ Gradio app is launching...")
    fhe_prediction_ready = False
    simulate_prediction = []
    encrypted_output = None
    
    demo.launch()