openfree commited on
Commit
d403426
ยท
verified ยท
1 Parent(s): f6b850a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -60
app.py CHANGED
@@ -2,62 +2,80 @@
2
  import os, math, numpy as np, matplotlib.pyplot as plt, gradio as gr
3
  import openai
4
 
5
- ### 0.โ€†OpenAI ํ‚ค ์„ค์ • ---------------------------------------------------------
 
 
6
  if "OPENAI_API_KEY" not in os.environ:
7
  os.environ["OPENAI_API_KEY"] = input("๐Ÿ”‘ Enter your OpenAI API key: ").strip()
8
-
9
  openai.api_key = os.environ["OPENAI_API_KEY"]
10
 
11
- ### 1.โ€†์ฃผ๊ธฐ ์ฐจํŠธ ํ•จ์ˆ˜ ----------------------------------------------------------
 
 
12
  CYCLES = {
13
- "ํ…Œํฌ ์‚ฌ์ดํด (50 ๋…„)": 50,
14
- "์žฌ๋ฌด ์‚ฌ์ดํด (80 ๋…„)": 80,
15
- "ํŒจ๊ถŒ ์‚ฌ์ดํด (250 ๋…„)": 250,
16
  }
17
- CENTER = 2025 # ๊ธฐ์ค€์ 
18
 
19
  def make_cycle_points(period, start, end):
20
  n_min = math.floor((start - CENTER) / period)
21
  n_max = math.ceil((end - CENTER) / period)
22
  return [CENTER + n * period for n in range(n_min, n_max + 1)]
23
 
24
- def plot_cycles(range_start, range_end):
25
- plt.figure(figsize=(10, 4))
26
- y_positions = np.arange(len(CYCLES))
27
- align_years = None
28
 
29
- for i, (name, period) in enumerate(CYCLES.items()):
30
- years = make_cycle_points(period, range_start, range_end)
31
- plt.scatter(years, [y_positions[i]] * len(years), label=name, s=60)
32
  for y in years:
33
- plt.text(y, y_positions[i] + 0.1, str(y), ha="center", fontsize=7)
 
34
  align_years = set(years) if align_years is None else align_years & set(years)
35
 
36
  if align_years:
37
  for y in sorted(align_years):
38
- plt.axvline(y, color="black", linestyle="--")
39
- plt.text(y, y_positions[-1] + 0.35, f"๊ณต๋™ ์ •๋ ฌ โ†’ {y}",
40
- ha="center", va="bottom", fontsize=9, fontweight="bold")
41
-
42
- plt.yticks(y_positions, list(CYCLES.keys()))
43
- plt.ylim(-0.5, len(CYCLES) - 0.2)
44
- plt.grid(axis="x", alpha=0.3)
45
- plt.xlabel("Year")
46
- plt.title("์ฃผ๊ธฐ๋ณ„ ๋ฐœ์ƒ ์—ฐ๋„์™€ ๊ณต๋™ ์ •๋ ฌ ์ง€์ ")
47
- plt.tight_layout()
48
- return plt.gcf()
49
-
50
- ### 2.โ€†GPT ์ฑ„ํŒ… ํ•จ์ˆ˜ -----------------------------------------------------------
51
- SYSTEM_PROMPT = (
52
- "๋‹น์‹ ์€ ์นœ์ ˆํ•˜๊ณ  ๋ถ„์„์ ์ธ ์–ด์‹œ์Šคํ„ดํŠธ์ž…๋‹ˆ๋‹ค. "
53
- "์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์— ํ•œ๊ตญ์–ด๋กœ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ๋‹ต๋ณ€ํ•˜์„ธ์š”."
 
 
 
 
 
 
 
 
 
 
54
  )
55
 
56
- def chat_with_gpt(history, user_message):
57
- messages = [{"role": "system", "content": SYSTEM_PROMPT}]
 
 
 
58
  for u, a in history:
59
- messages.append({"role": "user", "content": u})
60
- messages.append({"role": "assistant", "content": a})
 
61
  messages.append({"role": "user", "content": user_message})
62
 
63
  response = openai.chat.completions.create(
@@ -66,52 +84,53 @@ def chat_with_gpt(history, user_message):
66
  max_tokens=600,
67
  temperature=0.7,
68
  )
69
- assistant_reply = response.choices[0].message.content.strip()
70
- return assistant_reply
71
 
72
- ### 3.โ€†Gradio ์ธํ„ฐํŽ˜์ด์Šค -------------------------------------------------------
 
 
73
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
74
- gr.Markdown("## ๐Ÿ“Š 3-Cycle Timeline & ๐Ÿ’ฌ GPT Chat")
 
 
75
 
76
  with gr.Tabs():
77
- ## Tab 1โ€Šโ€”โ€ŠChart
78
- # --- Tab 1โ€Šโ€”โ€ŠChart -------------------------------------------
79
- with gr.TabItem("๐Ÿ—“๏ธ ์ฃผ๊ธฐ ์ฐจํŠธ"):
80
- start_year = gr.Number(label="๋ฒ”์œ„ ์‹œ์ž‘(Year)", value=1500)
81
- end_year = gr.Number(label="๋ฒ”์œ„ ๋(Year)", value=2500)
82
 
83
- # ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ธฐ๋ณธ ์ฐจํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก value ์ง€์ •
84
- plot_out = gr.Plot(value=plot_cycles(1500, 2500))
85
 
86
  def update_chart(s, e):
87
- return plot_cycles(int(s), int(e))
88
-
89
- start_year.change(update_chart, [start_year, end_year], plot_out)
90
- end_year.change(update_chart, [start_year, end_year], plot_out)
91
- # โŒ plot_out.render() โ† ์‚ญ์ œ
92
-
93
-
94
 
 
 
 
 
95
 
96
- ## Tab 2โ€Šโ€”โ€ŠGPT Chat
97
- with gr.TabItem("๐Ÿ’ฌ GPT ์ฑ„ํŒ…"):
98
- chatbot = gr.Chatbot(label="GPT Assistant")
99
  user_in = gr.Textbox(placeholder="๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”...", lines=3)
100
  send_btn = gr.Button("Send", variant="primary")
101
 
102
- def respond(chat_history, user_msg):
103
- assistant_msg = chat_with_gpt(chat_history, user_msg)
104
  chat_history.append((user_msg, assistant_msg))
105
  return chat_history, gr.Textbox(value="", interactive=True)
106
 
107
  send_btn.click(
108
  respond,
109
- inputs=[chatbot, user_in],
110
  outputs=[chatbot, user_in],
111
  )
112
  user_in.submit(
113
  respond,
114
- inputs=[chatbot, user_in],
115
  outputs=[chatbot, user_in],
116
  )
117
 
 
2
  import os, math, numpy as np, matplotlib.pyplot as plt, gradio as gr
3
  import openai
4
 
5
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
6
+ # 0. OpenAI key
7
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
8
  if "OPENAI_API_KEY" not in os.environ:
9
  os.environ["OPENAI_API_KEY"] = input("๐Ÿ”‘ Enter your OpenAI API key: ").strip()
 
10
  openai.api_key = os.environ["OPENAI_API_KEY"]
11
 
12
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
13
+ # 1. Cycle-chart utilities
14
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
15
  CYCLES = {
16
+ "Tech Cycle (50 yr)": 50,
17
+ "Finance Cycle (80 yr)": 80,
18
+ "Hegemony Cycle (250 yr)": 250,
19
  }
20
+ CENTER = 2025 # reference year
21
 
22
  def make_cycle_points(period, start, end):
23
  n_min = math.floor((start - CENTER) / period)
24
  n_max = math.ceil((end - CENTER) / period)
25
  return [CENTER + n * period for n in range(n_min, n_max + 1)]
26
 
27
+ def build_chart_and_summary(start, end):
28
+ # --------- build figure (tower style) ----------
29
+ fig, ax = plt.subplots(figsize=(7, 5))
30
+ align_years, summaries = None, []
31
 
32
+ for idx, (name, period) in enumerate(CYCLES.items()):
33
+ years = make_cycle_points(period, start, end)
34
+ ax.scatter([idx] * len(years), years, s=60)
35
  for y in years:
36
+ ax.text(idx, y + 5, str(y), ha="center", va="bottom", fontsize=7)
37
+ summaries.append(f"{name.replace(' ', ' ')}: {years}")
38
  align_years = set(years) if align_years is None else align_years & set(years)
39
 
40
  if align_years:
41
  for y in sorted(align_years):
42
+ ax.axhline(y, color="black", linestyle="--", linewidth=1)
43
+ ax.text(-0.4, y + 8, f"Alignment โ†’ {y}", fontsize=9, fontweight="bold")
44
+
45
+ ax.set_xticks(range(len(CYCLES)), CYCLES.keys(), rotation=15)
46
+ ax.set_ylabel("Year")
47
+ ax.set_xlabel("Cycle")
48
+ ax.set_title("Cycle Events and Alignment")
49
+ ax.set_ylim(start - 10, end + 10)
50
+ ax.invert_yaxis() # older years at bottom, newer at top
51
+ ax.grid(axis="y", alpha=0.3)
52
+
53
+ # --------- build textual summary ----------
54
+ align_txt = ", ".join(map(str, sorted(align_years))) if align_years else "None"
55
+ summary = (
56
+ f"Range: {start}-{end}\n"
57
+ + "\n".join(summaries)
58
+ + f"\nAlignment years: {align_txt}"
59
+ )
60
+ return fig, summary
61
+
62
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
63
+ # 2. GPT chat
64
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
65
+ BASE_PROMPT = (
66
+ "You are a concise, accurate assistant who answers in Korean. "
67
+ "If the chart summary is provided, take it into account."
68
  )
69
 
70
+ def chat_with_gpt(history, user_message, chart_summary):
71
+ messages = [{"role": "system", "content": BASE_PROMPT}]
72
+ if chart_summary and chart_summary != "No chart yet.":
73
+ messages.append({"role": "system", "content": f"[Chart summary]\n{chart_summary}"})
74
+
75
  for u, a in history:
76
+ messages.extend([{"role": "user", "content": u},
77
+ {"role": "assistant", "content": a}])
78
+
79
  messages.append({"role": "user", "content": user_message})
80
 
81
  response = openai.chat.completions.create(
 
84
  max_tokens=600,
85
  temperature=0.7,
86
  )
87
+ return response.choices[0].message.content.strip()
 
88
 
89
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
90
+ # 3. Gradio UI
91
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
92
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
93
+ gr.Markdown("## ๐Ÿ“Š Three-Cycle Timeline & ๐Ÿ’ฌ GPT Chat")
94
+
95
+ chart_summary_state = gr.State(value="No chart yet.")
96
 
97
  with gr.Tabs():
98
+ # ---------- Tab 1: Chart ----------
99
+ with gr.TabItem("Timeline Chart"):
100
+ start_year = gr.Number(label="Start Year", value=1500)
101
+ end_year = gr.Number(label="End Year", value=2500)
 
102
 
103
+ fig0, summary0 = build_chart_and_summary(1500, 2500)
104
+ plot_out = gr.Plot(value=fig0)
105
 
106
  def update_chart(s, e):
107
+ fig, summ = build_chart_and_summary(int(s), int(e))
108
+ return fig, summ
 
 
 
 
 
109
 
110
+ start_year.change(update_chart, [start_year, end_year],
111
+ [plot_out, chart_summary_state])
112
+ end_year.change(update_chart, [start_year, end_year],
113
+ [plot_out, chart_summary_state])
114
 
115
+ # ---------- Tab 2: GPT Chat ----------
116
+ with gr.TabItem("GPT Chat"):
117
+ chatbot = gr.Chatbot(label="Assistant")
118
  user_in = gr.Textbox(placeholder="๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”...", lines=3)
119
  send_btn = gr.Button("Send", variant="primary")
120
 
121
+ def respond(chat_history, user_msg, chart_summary):
122
+ assistant_msg = chat_with_gpt(chat_history, user_msg, chart_summary)
123
  chat_history.append((user_msg, assistant_msg))
124
  return chat_history, gr.Textbox(value="", interactive=True)
125
 
126
  send_btn.click(
127
  respond,
128
+ inputs=[chatbot, user_in, chart_summary_state],
129
  outputs=[chatbot, user_in],
130
  )
131
  user_in.submit(
132
  respond,
133
+ inputs=[chatbot, user_in, chart_summary_state],
134
  outputs=[chatbot, user_in],
135
  )
136