|
import gradio as gr |
|
import matplotlib.pyplot as plt |
|
import wikipedia |
|
import random |
|
import re |
|
import json |
|
from deep_translator import GoogleTranslator |
|
from transformers import pipeline, T5Tokenizer |
|
|
|
|
|
wikipedia.set_lang("tr") |
|
|
|
|
|
turk_states_list = [ |
|
"Büyük Hun İmparatorluğu", |
|
"Batı Hun İmparatorluğu", |
|
"Hun İmparatorluğu", |
|
"Ak Hun İmparatorluğu", |
|
"Göktürkler", |
|
"Avarlar", |
|
"Hazar Kağanlığı", |
|
"Uygur Devleti", |
|
"Karahanlılar", |
|
"Gazneliler", |
|
"Büyük Selçuklu İmparatorluğu", |
|
"Harezmşahlar Devleti", |
|
"Altın Orda Devleti", |
|
"Timur İmparatorluğu", |
|
"Babürlüler", |
|
"Osmanlı İmparatorluğu", |
|
"Türkiye" |
|
] |
|
|
|
|
|
wiki_title_mapping = { |
|
"Büyük Hun İmparatorluğu": "Hiung-nu", |
|
"Batı Hun İmparatorluğu": "Batı Hiung-nu", |
|
"Hun İmparatorluğu": "Hun İmparatorluğu", |
|
"Ak Hun İmparatorluğu": "Ak Hun İmparatorluğu", |
|
"Göktürkler": "Göktürkler", |
|
"Avarlar": "Avarlar", |
|
"Hazar Kağanlığı": "Hazar Kağanlığı", |
|
"Uygur Devleti": "Uygur Devleti", |
|
"Karahanlılar": "Karahanlılar", |
|
"Gazneliler": "Gazneliler", |
|
"Büyük Selçuklu İmparatorluğu": "Büyük Selçuklu Devleti", |
|
"Harezmşahlar Devleti": "Harzemşahlar", |
|
"Altın Orda Devleti": "Altın Orda Devleti", |
|
"Timur İmparatorluğu": "Timur İmparatorluğu", |
|
"Babürlüler": "Babür İmparatorluğu", |
|
"Osmanlı İmparatorluğu": "Osmanlı İmparatorluğu", |
|
"Türkiye": "Türkiye Cumhuriyeti" |
|
} |
|
|
|
|
|
stopwords = set(["ve", "ile", "bir", "bu", "de", "da", "için", "olarak", |
|
"ne", "var", "yok", "ise", "gibi", "ama", "ancak", "çok", "en", "kadar"]) |
|
|
|
|
|
tokenizer = T5Tokenizer.from_pretrained("valhalla/t5-base-e2e-qg", use_fast=False) |
|
qg_pipeline = pipeline("text2text-generation", model="valhalla/t5-base-e2e-qg", tokenizer=tokenizer) |
|
|
|
def get_short_structured_summary(state): |
|
""" |
|
Wikipedia sayfasından, 5 cümlelik kısa özet çeker, |
|
cümleleri 'Giriş', 'Gelişim' ve 'Sonuç' başlıkları altında yapılandırır. |
|
""" |
|
wiki_title = wiki_title_mapping.get(state, state) |
|
try: |
|
raw_summary = wikipedia.summary(wiki_title, sentences=5) |
|
except Exception as e: |
|
search_results = wikipedia.search(wiki_title) |
|
if search_results: |
|
try: |
|
raw_summary = wikipedia.summary(search_results[0], sentences=5) |
|
except Exception as e: |
|
raw_summary = "Özet bulunamadı." |
|
else: |
|
raw_summary = "Özet bulunamadı." |
|
sentences = re.split(r'(?<=[.!?])\s+', raw_summary) |
|
if len(sentences) >= 3: |
|
giriş = sentences[0] |
|
gelişim = " ".join(sentences[1:-1]) |
|
sonuç = sentences[-1] |
|
md_summary = f"## Giriş\n{giriş}\n\n## Gelişim\n{gelişim}\n\n## Sonuç\n{sonuç}" |
|
return md_summary |
|
else: |
|
return f"## Özet\n{raw_summary}" |
|
|
|
def get_state_summary(state): |
|
summary = get_short_structured_summary(state) |
|
try: |
|
|
|
translated = GoogleTranslator(source='auto', target='tr').translate(summary) |
|
return translated |
|
except Exception: |
|
return summary |
|
|
|
|
|
predefined_questions = { |
|
"Uygur Devleti": [ |
|
{ "question": "Uygurlar, yerleşik hayata geçen ilk Türk devleti olarak bilinir. Aşağıdakilerden hangisi, Uygurların yerleşik hayata geçtiğini gösteren en önemli bulgudur?", |
|
"options": ["Tahıl saklama kabı", "Tohumluk buğday kabı", "Kâğıt kullanımı", "Para sistemi"], |
|
"correct": "A" }, |
|
{ "question": "Uygur Devleti'nin başkenti hangisidir?", |
|
"options": ["Karakurum", "Ordu-Balık", "Karaköy", "Balkh"], |
|
"correct": "B" }, |
|
{ "question": "Uygurların yerleşik hayata geçişinde hangi faktör belirleyici olmuştur?", |
|
"options": ["Tarımın gelişmesi", "Göçebe yaşam tarzının sürmesi", "Askeri güç", "Ticaretin artması"], |
|
"correct": "A" }, |
|
{ "question": "Uygur Devleti döneminde en önemli kültürel gelişmelerden biri hangisidir?", |
|
"options": ["Halk edebiyatı", "Büyük İslam medeniyeti", "Maniheizm", "Budizm"], |
|
"correct": "D" }, |
|
{ "question": "Uygurların ekonomik temellerinden biri aşağıdakilerden hangisidir?", |
|
"options": ["Hayvancılık", "Tarım ve ticaret", "Madencilik", "Balıkçılık"], |
|
"correct": "B" } |
|
], |
|
"Osmanlı İmparatorluğu": [ |
|
{ "question": "Osmanlı İmparatorluğu'nun kuruluşunda hangi olay belirleyici rol oynamıştır?", |
|
"options": ["Malazgirt Savaşı", "İstanbul'un fethi", "Beylikler döneminin sona ermesi", "Ermeni isyanı"], |
|
"correct": "C" }, |
|
{ "question": "Osmanlı İmparatorluğu'nda padişahın yetkisini simgeleyen unvan hangisidir?", |
|
"options": ["Sultan", "Bey", "Emir", "Hatun"], |
|
"correct": "A" }, |
|
{ "question": "İstanbul'un fethi hangi yılda gerçekleşmiştir?", |
|
"options": ["1453", "1492", "1520", "1571"], |
|
"correct": "A" }, |
|
{ "question": "Osmanlı İmparatorluğu'nda en önemli askeri birlik hangisidir?", |
|
"options": ["Yeniçeri Ocağı", "Süvari Birliği", "Topçu Ocağı", "Sipahi"], |
|
"correct": "A" }, |
|
{ "question": "Osmanlı'nın günümüze bıraktığı en önemli miraslardan biri aşağıdakilerden hangisidir?", |
|
"options": ["Sanat ve mimari", "Bilim ve teknoloji", "Ekonomi", "Hepsi"], |
|
"correct": "D" } |
|
] |
|
} |
|
|
|
def generate_standard_questions(summary, num_questions=10): |
|
""" |
|
Eğer hazır soru seti yoksa, T5 tabanlı soru üretim modeline sabit bir prompt vererek, |
|
klasik çoktan seçmeli 10 soru üretmeye çalışır. |
|
Çıktı JSON formatında olmalıdır. Eğer çıktı alınamazsa, dummy sorular döndürülür. |
|
""" |
|
prompt = ( |
|
f"Metin: {summary}\n" |
|
"Lütfen yukarıdaki metne dayanarak 10 adet klasik çoktan seçmeli soru oluşturun. " |
|
"Her soru 4 seçenek içermeli ve her sorunun doğru cevabı A, B, C veya D harf notasyonu ile belirtilmelidir. " |
|
"Cevabı ve seçenekleri sadece JSON formatında veriniz. Örnek çıktı: \n" |
|
'[{"question": "Soru metni", "options": ["Seçenek A", "Seçenek B", "Seçenek C", "Seçenek D"], "correct": "A"}, ...]' |
|
) |
|
try: |
|
output = qg_pipeline(prompt, max_length=1024, num_return_sequences=1)[0]['generated_text'] |
|
|
|
output = output.replace("'", "\"") |
|
questions = json.loads(output) |
|
if isinstance(questions, list) and len(questions) >= num_questions: |
|
return questions[:num_questions] |
|
else: |
|
raise ValueError("Yetersiz soru üretildi.") |
|
except Exception as e: |
|
|
|
dummy_questions = [] |
|
for i in range(num_questions): |
|
dummy_questions.append({ |
|
"question": f"{i+1}. soru: Özetin ilk 50 karakteri: {summary[:50]}...", |
|
"options": ["Örnek A", "Örnek B", "Örnek C", "Örnek D"], |
|
"correct": "A" |
|
}) |
|
return dummy_questions |
|
|
|
def get_questions_for_state(state): |
|
|
|
|
|
questions = get_predefined_questions(state) |
|
if len(questions) >= 10: |
|
return questions |
|
else: |
|
summary = get_state_summary(state) |
|
auto_questions = generate_standard_questions(summary, num_questions=10) |
|
return auto_questions |
|
|
|
def get_state_summary_for_display(state): |
|
|
|
|
|
wiki_title = wiki_title_mapping.get(state, state) |
|
try: |
|
raw_summary = wikipedia.summary(wiki_title, sentences=5) |
|
except Exception as e: |
|
raw_summary = "Kısa özet alınamadı." |
|
sentences = re.split(r'(?<=[.!?])\s+', raw_summary) |
|
if len(sentences) >= 3: |
|
giriş = sentences[0] |
|
gelişim = " ".join(sentences[1:-1]) |
|
sonuç = sentences[-1] |
|
md_summary = f"## Giriş\n{giriş}\n\n## Gelişim\n{gelişim}\n\n## Sonuç\n{sonuç}" |
|
return md_summary |
|
else: |
|
return f"## Özet\n{raw_summary}" |
|
|
|
def get_state_summary_final(state): |
|
|
|
return get_state_summary_for_display(state) |
|
|
|
def get_state_summary_wrapper(state): |
|
|
|
return get_state_summary_final(state) |
|
|
|
|
|
student_data = {} |
|
|
|
def load_history(name, state): |
|
student_data["name"] = name |
|
student_data["state"] = state |
|
summary = get_state_summary_wrapper(state) |
|
questions = get_questions_for_state(state) |
|
student_data["questions"] = questions |
|
md_updates = [] |
|
radio_updates = [] |
|
for q in questions: |
|
md_updates.append(gr.update(value=q["question"])) |
|
radio_updates.append(gr.update(choices=q["options"], value="")) |
|
return gr.update(value=summary, visible=True), *[comp for pair in zip(md_updates, radio_updates) for comp in pair] |
|
|
|
def generate_chart(wrong_indices): |
|
num_questions = len(student_data.get("questions", [])) |
|
results = [1 if (i+1 in wrong_indices) else 0 for i in range(num_questions)] |
|
fig, ax = plt.subplots() |
|
ax.bar(range(1, num_questions+1), results) |
|
ax.set_xlabel("Soru Numarası") |
|
ax.set_ylabel("Yanlış (1) / Doğru (0)") |
|
ax.set_title("Değerlendirme Sonuçları") |
|
return fig |
|
|
|
def submit_answers(*answers): |
|
questions = student_data.get("questions", []) |
|
score = 0 |
|
wrong_indices = [] |
|
for i, user_answer in enumerate(answers): |
|
if i < len(questions): |
|
try: |
|
idx = questions[i]["options"].index(user_answer) |
|
letter = ["A", "B", "C", "D"][idx] |
|
except ValueError: |
|
letter = "" |
|
if letter == questions[i]["correct"].strip().upper(): |
|
score += 1 |
|
else: |
|
wrong_indices.append(i+1) |
|
if score >= 9: |
|
medal = "Gold" |
|
elif score >= 7: |
|
medal = "Silver" |
|
else: |
|
medal = "Bronze" |
|
student_data["score"] = score |
|
student_data["medal"] = medal |
|
student_data["wrong"] = wrong_indices |
|
return f"Skorunuz: {score}/10", f"Madalya: {medal}", generate_chart(wrong_indices) |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# Türk Tarihi Öğrenme ve Değerlendirme Uygulaması") |
|
|
|
with gr.Tab("Giriş"): |
|
name_input = gr.Textbox(label="Öğrenci İsmi (Tek seferlik)", placeholder="İsminizi giriniz") |
|
state_choice = gr.Dropdown(choices=turk_states_list, label="Türk Tarihi Devletleri", value=turk_states_list[0]) |
|
start_btn = gr.Button("Başla") |
|
history_display = gr.Markdown(visible=False, label="Tarih Özeti") |
|
|
|
with gr.Tab("Değerlendirme"): |
|
with gr.Column(): |
|
gr.Markdown("### Değerlendirme Soruları") |
|
question_md = [] |
|
question_radio = [] |
|
for i in range(10): |
|
q_md = gr.Markdown(label=f"Soru {i+1} Metni") |
|
q_radio = gr.Radio(choices=["Seçenek A", "Seçenek B", "Seçenek C", "Seçenek D"], |
|
label=f"Soru {i+1} Cevap", value="") |
|
question_md.append(q_md) |
|
question_radio.append(q_radio) |
|
submit_btn = gr.Button("Cevapları Gönder") |
|
score_display = gr.Markdown(label="Sonuç") |
|
medal_display = gr.Markdown(label="Madalya") |
|
chart_display = gr.Plot(label="Yanlış Sorular Grafiği") |
|
|
|
start_btn.click( |
|
load_history, |
|
inputs=[name_input, state_choice], |
|
outputs=[history_display] + [comp for pair in zip(question_md, question_radio) for comp in pair] |
|
) |
|
|
|
submit_btn.click( |
|
submit_answers, |
|
inputs=question_radio, |
|
outputs=[score_display, medal_display, chart_display] |
|
) |
|
|
|
demo.launch() |