File size: 8,607 Bytes
8f33be7 e6b021f 8f33be7 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f 4635488 e6b021f | 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 | import streamlit as st
import requests
import json
import os
import graphviz
import time
from dotenv import load_dotenv
from prompts import SYSTEM_INSTRUCTIONS
st.set_page_config(page_title="StepWise: Algorithmic Thinking Mentor", layout="wide")
load_dotenv()
api_key = os.getenv("API_KEY")
def call_gemini(messages):
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent?key={api_key}"
headers = {'Content-Type': 'application/json'}
contents = []
for m in messages:
role = "model" if m["role"] == "assistant" else "user"
contents.append({"role": role, "parts": [{"text": m["content"]}]})
payload = {"contents": contents}
for attempt in range(3):
try:
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()['candidates'][0]['content']['parts'][0]['text']
elif response.status_code in [429, 503]:
time.sleep(5)
continue
else:
return f"🚨 API Hatası: {response.status_code}"
except:
time.sleep(2)
continue
return "🚨 Sunucu yoğun, lütfen tekrar dene."
if "messages" not in st.session_state: st.session_state.messages = []
if "flow_nodes" not in st.session_state: st.session_state.flow_nodes = []
if "flow_edges" not in st.session_state: st.session_state.flow_edges = []
if "mode" not in st.session_state: st.session_state.mode = "chat"
with st.sidebar:
st.title("🚀 StepWise Paneli")
st.divider()
if st.button("📚 Konu Tekrarı", use_container_width=True):
st.session_state.mode = "chat"
st.session_state.messages = [{"role": "user", "content": f"SİSTEM: {SYSTEM_INSTRUCTIONS}\n\nGÖREV: Merhaba! Lütfen öğrenciye konuyu en baştan anlatmaya başla."}]
with st.spinner("Öğretmen hazırlanıyor..."):
res = call_gemini(st.session_state.messages)
st.session_state.messages.append({"role": "assistant", "content": res})
st.rerun()
if st.button("📐 Akış Şeması İnşası", use_container_width=True):
st.session_state.mode = "flowchart"
st.session_state.flow_nodes, st.session_state.flow_edges = [], []
st.session_state.messages = [{"role": "user", "content": f"SİSTEM: {SYSTEM_INSTRUCTIONS}\n\nGÖREV: Akış Şeması modundayız. Lütfen öğrenciye içinde mutlaka bir KARAR yapısı olan orta zorlukta bir problem ver ve çizmesini iste."}]
with st.spinner("Senaryo oluşturuluyor..."):
res = call_gemini(st.session_state.messages)
st.session_state.messages.append({"role": "assistant", "content": res})
st.rerun()
if st.button("🎁 Girdi-Çıktı Kutusu", use_container_width=True):
st.session_state.mode = "blackbox"
st.session_state.messages = [{"role": "user", "content": f"SİSTEM: {SYSTEM_INSTRUCTIONS}\n\nGÖREV: Girdi-Çıktı oyun modundayız. Gizli bir kural belirle, kategoriyi söyle ve ilk Girdi: X, Çıktı: Y örneğini ver."}]
with st.spinner("Kutu hazırlanıyor..."):
res = call_gemini(st.session_state.messages)
st.session_state.messages.append({"role": "assistant", "content": res})
st.rerun()
if st.button("🔧 Algoritma Tamirhanesi", use_container_width=True):
st.session_state.mode = "repair"
st.session_state.messages = [{"role": "user", "content": f"SİSTEM: {SYSTEM_INSTRUCTIONS}\n\nGÖREV: Tamirhane modundayız. Lütfen adımları birbirine karışmış bozuk bir senaryo ver ve öğrenciden doğru sıralamayı (A-B-C gibi) iste."}]
with st.spinner("Arıza tespit ediliyor..."):
res = call_gemini(st.session_state.messages)
st.session_state.messages.append({"role": "assistant", "content": res})
st.rerun()
st.divider()
if st.button("🗑️ Her Şeyi Sıfırla", use_container_width=True):
st.session_state.messages, st.session_state.flow_nodes, st.session_state.flow_edges, st.session_state.mode = [], [], [], "chat"
st.rerun()
st.title("🤖 StepWise: Algoritmik Düşünme Mentoru")
if st.session_state.mode == "repair":
st.info("🔧 **Tamirhane Modu:** Aşağıdaki adımları mantıklı bir sıraya dizebilir misin? Tahminini aşağıya yaz!")
elif st.session_state.mode == "flowchart":
with st.container(border=True):
st.subheader("🛠️ Akış Şeması Tasarım Alanı")
c1, c2, c3 = st.columns([2, 3, 1])
with c1:
shape_type = st.selectbox("Şekil:", ["Elips (Başla/Bitir)", "Dikdörtgen (İşlem)", "Eşkenar Dörtgen (Karar)", "Paralelkenar (Bilgi Girişi)"])
with c2:
node_text = st.text_input("Metin:", key="node_input")
with c3:
st.write("")
if st.button("➕ Ekle", use_container_width=True):
if node_text:
st.session_state.flow_nodes.append({"id": str(len(st.session_state.flow_nodes)), "text": node_text, "type": shape_type})
st.rerun()
if st.session_state.flow_nodes:
bc1, bc2, bc3, bc4 = st.columns([2, 2, 2, 1])
with bc1:
source = st.selectbox("Kaynak:", options=st.session_state.flow_nodes, format_func=lambda x: f"{x['id']}: {x['text']}")
with bc2:
target = st.selectbox("Hedef:", options=st.session_state.flow_nodes, format_func=lambda x: f"{x['id']}: {x['text']}")
with bc3:
label = st.selectbox("Yol:", ["", "Evet", "Hayır"]) if "Eşkenar" in source["type"] else ""
with bc4:
st.write("")
if st.button("🔗 Bağla", use_container_width=True):
st.session_state.flow_edges.append({"from": source["id"], "to": target["id"], "label": label})
st.rerun()
dot = graphviz.Digraph()
for node in st.session_state.flow_nodes:
shape = "ellipse" if "Elips" in node["type"] else "box" if "Dikdörtgen" in node["type"] else "diamond" if "Eşkenar" in node["type"] else "parallelogram"
dot.node(node["id"], node["text"], shape=shape, color="blue", style="filled", fillcolor="white")
for edge in st.session_state.flow_edges:
dot.edge(edge["from"], edge["to"], label=edge["label"])
st.graphviz_chart(dot)
b1, b2 = st.columns(2)
if b1.button("🗑️ Şemayı Temizle"):
st.session_state.flow_nodes, st.session_state.flow_edges = [], []
st.rerun()
if b2.button("✅ Bitti ve Kontrol Et"):
node_map = {n['id']: n['text'] for n in st.session_state.flow_nodes}
schema_desc = " | ".join([f"{node_map[e['from']]} -> {node_map[e['to']]} ({e['label']})" for e in st.session_state.flow_edges])
st.session_state.messages.append({"role": "user", "content": f"SİSTEM: Öğrenci şemayı bitirdi. Yapı şu şekilde: {schema_desc}. Lütfen analiz et ve geri bildirim ver."})
with st.spinner("Kontrol ediliyor..."):
res = call_gemini(st.session_state.messages)
st.session_state.messages.append({"role": "assistant", "content": res})
st.rerun()
elif st.session_state.mode == "blackbox":
with st.container(border=True):
st.subheader("🎁 Sihirli Kara Kutu")
box_viz = graphviz.Digraph()
box_viz.attr(rankdir='LR')
box_viz.node("IN", "Girdi", shape="parallelogram", style="filled", fillcolor="#E1BEE7")
box_viz.node("BOX", "???", shape="box", style="filled", fillcolor="#212121", fontcolor="white")
box_viz.node("OUT", "Çıktı", shape="parallelogram", style="filled", fillcolor="#C8E6C9")
box_viz.edge("IN", "BOX"); box_viz.edge("BOX", "OUT")
st.graphviz_chart(box_viz)
st.divider()
for message in st.session_state.messages:
if not message["content"].startswith("SİSTEM"):
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("Mesajını yaz..."):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"): st.markdown(prompt)
with st.chat_message("assistant"):
res = call_gemini(st.session_state.messages)
st.markdown(res)
st.session_state.messages.append({"role": "assistant", "content": res}) |