Cycle-Navigator / app.py
openfree's picture
Update app.py
cd5d77c verified
raw
history blame
4.36 kB
# cycles_chat_app.py
import os, math, numpy as np, matplotlib.pyplot as plt, gradio as gr
import openai
### 0.โ€†OpenAI ํ‚ค ์„ค์ • ---------------------------------------------------------
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = input("๐Ÿ”‘ Enter your OpenAI API key: ").strip()
openai.api_key = os.environ["OPENAI_API_KEY"]
### 1.โ€†์ฃผ๊ธฐ ์ฐจํŠธ ํ•จ์ˆ˜ ----------------------------------------------------------
CYCLES = {
"ํ…Œํฌ ์‚ฌ์ดํด (50 ๋…„)": 50,
"์žฌ๋ฌด ์‚ฌ์ดํด (80 ๋…„)": 80,
"ํŒจ๊ถŒ ์‚ฌ์ดํด (250 ๋…„)": 250,
}
CENTER = 2025 # ๊ธฐ์ค€์ 
def make_cycle_points(period, start, end):
n_min = math.floor((start - CENTER) / period)
n_max = math.ceil((end - CENTER) / period)
return [CENTER + n * period for n in range(n_min, n_max + 1)]
def plot_cycles(range_start, range_end):
plt.figure(figsize=(10, 4))
y_positions = np.arange(len(CYCLES))
align_years = None
for i, (name, period) in enumerate(CYCLES.items()):
years = make_cycle_points(period, range_start, range_end)
plt.scatter(years, [y_positions[i]] * len(years), label=name, s=60)
for y in years:
plt.text(y, y_positions[i] + 0.1, str(y), ha="center", fontsize=7)
align_years = set(years) if align_years is None else align_years & set(years)
if align_years:
for y in sorted(align_years):
plt.axvline(y, color="black", linestyle="--")
plt.text(y, y_positions[-1] + 0.35, f"๊ณต๋™ ์ •๋ ฌ โ†’ {y}",
ha="center", va="bottom", fontsize=9, fontweight="bold")
plt.yticks(y_positions, list(CYCLES.keys()))
plt.ylim(-0.5, len(CYCLES) - 0.2)
plt.grid(axis="x", alpha=0.3)
plt.xlabel("Year")
plt.title("์ฃผ๊ธฐ๋ณ„ ๋ฐœ์ƒ ์—ฐ๋„์™€ ๊ณต๋™ ์ •๋ ฌ ์ง€์ ")
plt.tight_layout()
return plt.gcf()
### 2.โ€†GPT ์ฑ„ํŒ… ํ•จ์ˆ˜ -----------------------------------------------------------
SYSTEM_PROMPT = (
"๋‹น์‹ ์€ ์นœ์ ˆํ•˜๊ณ  ๋ถ„์„์ ์ธ ์–ด์‹œ์Šคํ„ดํŠธ์ž…๋‹ˆ๋‹ค. "
"์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์— ํ•œ๊ตญ์–ด๋กœ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ๋‹ต๋ณ€ํ•˜์„ธ์š”."
)
def chat_with_gpt(history, user_message):
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
for u, a in history:
messages.append({"role": "user", "content": u})
messages.append({"role": "assistant", "content": a})
messages.append({"role": "user", "content": user_message})
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
max_tokens=600,
temperature=0.7,
)
assistant_reply = response.choices[0].message.content.strip()
return assistant_reply
### 3.โ€†Gradio ์ธํ„ฐํŽ˜์ด์Šค -------------------------------------------------------
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("## ๐Ÿ“Š 3-Cycle Timeline & ๐Ÿ’ฌ GPT Chat")
with gr.Tabs():
## Tab 1โ€Šโ€”โ€ŠChart
with gr.TabItem("๐Ÿ—“๏ธ ์ฃผ๊ธฐ ์ฐจํŠธ"):
start_year = gr.Number(label="๋ฒ”์œ„ ์‹œ์ž‘(Year)", value=1500)
end_year = gr.Number(label="๋ฒ”์œ„ ๋(Year)", value=2500)
plot_out = gr.Plot()
def update_chart(s, e):
return plot_cycles(int(s), int(e))
start_year.change(update_chart, [start_year, end_year], plot_out)
end_year.change(update_chart, [start_year, end_year], plot_out)
plot_out.render() # ์ดˆ๊ธฐ ํ‘œ์‹œ
## Tab 2โ€Šโ€”โ€ŠGPT Chat
with gr.TabItem("๐Ÿ’ฌ GPT ์ฑ„ํŒ…"):
chatbot = gr.Chatbot(label="GPT Assistant")
user_in = gr.Textbox(placeholder="๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”...", lines=3)
send_btn = gr.Button("Send", variant="primary")
def respond(chat_history, user_msg):
assistant_msg = chat_with_gpt(chat_history, user_msg)
chat_history.append((user_msg, assistant_msg))
return chat_history, gr.Textbox(value="", interactive=True)
send_btn.click(
respond,
inputs=[chatbot, user_in],
outputs=[chatbot, user_in],
)
user_in.submit(
respond,
inputs=[chatbot, user_in],
outputs=[chatbot, user_in],
)
if __name__ == "__main__":
demo.launch()