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})