kronoloji / app.py
hbulduk's picture
Update app.py
ded56ec verified
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 dilini Türkçe olarak ayarlıyoruz.
wikipedia.set_lang("tr")
# Türk devletlerinin listesi (17 devlet) – burada dropdown için kullanıyoruz.
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"
]
# Wikipedia sayfa başlıkları için mapping – eğer Wikipedia sayfa başlıkları farklı ise düzenleyin.
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"
}
# Stopword listesi (basit, gerekirse genişletilebilir)
stopwords = set(["ve", "ile", "bir", "bu", "de", "da", "için", "olarak",
"ne", "var", "yok", "ise", "gibi", "ama", "ancak", "çok", "en", "kadar"])
# T5 soru üretimi için model ve tokenizer hazırlıyoruz.
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:
# Eğer metnin dili Türkçe değilse çeviriyoruz (genellikle Wikipedia Türkçe ayarlı olduğu için gerekmez).
translated = GoogleTranslator(source='auto', target='tr').translate(summary)
return translated
except Exception:
return summary
# Örneğin bazı devletler için hazır soru setleri (predefined)
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']
# Bazı durumlarda tek tırnak yerine çift tırnak kullanılması gerekebilir.
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:
# Hata durumunda dummy sorular üretelim.
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):
# Eğer hazır soru seti varsa (örneğin Uygur Devleti ve Osmanlı İmparatorluğu için),
# onu döndür; aksi halde, özet üzerinden otomatik soru üretimi yap.
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):
# Öğrenciler için özetin uzun olmaması adına kısa özet üretebiliriz.
# Burada Wikipedia'nın summary fonksiyonunu 5 cümle ile çağırıyoruz.
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):
# Hem detaylı hem de öğrenci için uygun kısa özet: burada get_state_summary_for_display kullanıyoruz.
return get_state_summary_for_display(state)
def get_state_summary_wrapper(state):
# Eğer çeviri gerekiyorsa ekleyebilirsiniz; fakat Wikipedia Türkçe ayarlı olduğu için çoğunlukla gerekmez.
return get_state_summary_final(state)
# Global öğrenci verilerini saklamak için değişken.
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()