Spaces:
Running
Running
| # 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() | |