File size: 8,282 Bytes
f336bd7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import plotly.express as px
import pandas as pd
import gradio as gr
import openai

# 課程資料
course_dict = {
    "基礎必修": [
        {"科目": "統計學", "學分": 3, "課程": ["統計學", "初級統計", "教育統計", "體育統計學", "生物統計學", "數理統計", "機率與統計"]},
        {"科目": "資料庫系統", "學分": 3, "課程": ["資料庫系統", "資料庫管理系統", "資料庫"]},
        {"科目": "資料探勘", "學分": 3, "課程": ["資料探勘", "人工智慧", "資料結構", "教育資料科學概論", "大數據分析", "深度學習", "機器學習", "演算法", "資料視覺化"]}
    ],
    "核心選修": [
        {"科目": "研究方法", "學分": 3, "課程": ["研究方法", "教育研究法", "社會科學研究法", "科學教育研究法", "量化研究"]},
        {"科目": "高等統計學", "學分": 3, "課程": ["高等教育統計", "高等體育統計學"]},
        {"科目": "多變量分析", "學分": 3, "課程": ["多變量分析"]},
        {"科目": "程式設計", "學分": 3, "課程": ["程式設計", "基礎程式設計", "計算機程式設計", "網路程式設計", "物件導向程式設計", "視窗程式設計", "行動程式設計", "網頁程式設計", "遊戲程式設計", "資料科學程式設計", "視覺化程式設計語言"]},
        {"科目": "前端工程設計", "學分": 3, "課程": ["前端工程設計", "網頁設計與製作", "網頁設計", "網站建置與管理", "跨平台前端工程設計"]},
        {"科目": "使用者經驗設計", "學分": 3, "課程": ["使用者經驗設計", "設計方法", "視覺傳達設計", "電腦多媒體理論與實務", "混合實境科技", "人機介面設計與製作"]},
        {"科目": "專題研究", "學分": 2, "課程": ["智慧型科技專題", "資訊科技專題", "資料探勘專題研究", "人工智慧案例討論", "大數據分析案例討論"]}
    ]
}

# 將資料轉換為平坦的 DataFrame
def create_dataframe(course_dict):
    data = []
    for category, subjects in course_dict.items():
        for subject in subjects:
            for course in subject["課程"]:
                data.append({
                    "類別": category,
                    "科目": subject["科目"],
                    "課程": course
                })
    return pd.DataFrame(data)


df = create_dataframe(course_dict)

# 創建樹狀圖函數
def create_sunburst_chart(df):
    fig = px.sunburst(
        df,
        path=['類別', '科目', '課程'],
        title="課程結構互動圖",
        color='類別',
        color_discrete_sequence=px.colors.qualitative.Pastel
    )

    # 自訂 hovertemplate,不顯示學分
    fig.update_traces(
        hovertemplate="<b>%{label}</b><br><extra></extra>"
    )
    
    # 更新圖表佈局
    fig.update_layout(
        margin=dict(t=50, l=25, r=25, b=25)
    )
    return fig


# 生成初始樹狀圖
initial_fig = create_sunburst_chart(df)

# 課程推薦函數
def recommend_courses(learning_background, difficulty, preferred_course, question_type, possible_career_paths, api_key):
    openai.api_key = api_key

    try:
        # 使用 OpenAI API 生成建議,符合新版 API 介面
        completion = openai.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": "你是一位資深的教育顧問,負責為學生提供個性化的學習建議,請以純文字格式回答,不要包含 Markdown 語法。"},
                {
                    "role": "user",
                    "content": f"""請確保不要以Markdown語法回覆,
                               根據以下課程資料:{course_dict}
                               學習背景為{learning_background}
                               難度為{difficulty}
                               最感興趣的課程名稱為{preferred_course}
                               偏好教學方式為{question_type}
                               未來可能從事的職業或研究方向為{possible_career_paths}
                               請根據課程資料、學習背景、難度、最感興趣的課程、偏好教學方式、未來可能從事的職業或研究方向推薦所需修的科目,
                               請推薦至少9學分的基礎必修科目和至少8學分的核心選修科目,
                               並依照科目推薦對應的2-3個課程,
                               請確保至少9學分的基礎必修科目,
                               並確保至少8學分的核心選修科目與總科目學分不少於17學分,
                               並顯示目前所選科目的學分,
                               並顯示所選科目的學分的加總(包含詳細選擇課程學分的加總過程),
                               並依照推薦課程提供對應多個學習資源(如網站名稱,不要連結)建議。
                               請輸出推薦課程的學習路徑,範例:科目→科目→科目,
                               詳細分析此學習路徑原因,
                               請以純文字格式回答,不要包含 Markdown 語法。"""
                }
                
            ]
        )
        recommendation = completion.choices[0].message.content

        # 返回推薦結果,不更新圖表
        return recommendation

    except Exception as e:
        return f"錯誤發生:{str(e)}。請檢查 API Key 是否正確或稍後再試。"

# Gradio 表單設計
with gr.Blocks() as demo:
    gr.Markdown("# 個人化課程學習建議")

    with gr.Row():
        # 左側欄:課程結構與學分分佈樹狀圖
        with gr.Column(scale=1):
            sunburst_output = gr.Plot(value=initial_fig, label="課程結構互動圖")
        
        # 中間欄:課程推薦表單
        with gr.Column(scale=1):

            with gr.Row():
                # 學習背景(複選)
                learning_background = gr.CheckboxGroup(
                    choices=[
                        "無資訊技術背景",
                        "相關資訊課經驗",
                        "資訊本科生",
                        "軟體開發經驗",
                        "網頁設計經驗",
                        "數據分析經驗"
                    ],
                    label="學習背景"
                )
            with gr.Row():
                # 難度區
                difficulty = gr.Dropdown(["基礎", "進階", "專業"], label="偏好難度")
                # 偏好教學方式
                question_type = gr.Dropdown(
                    ["理論講解", "案例分析", "實作練習", "專題研究"],
                    label="偏好教學方式"
                )

            with gr.Row():
                # 課程
                preferred_course = gr.Dropdown(
                    ["程式設計", "統計", "資料庫", "專題研究", "人機介面設計與製作", "網頁設計"],
                    label="最感興趣的課程名稱"
                )
                # 未來可能從事的職業或研究方向
                possible_career_paths = gr.Dropdown(
                    ["資料科學家",
                     "機器學習工程師",
                     "前端設計師",
                     "後端軟體工程師"],
                    label="可能從事的職業或研究方向"
                )
            
            with gr.Row():
                # API Key 輸入
                api_key = gr.Textbox(label="生成金鑰(API Key)", type="password")
            
            # 提交按鈕
            submit = gr.Button("提交")
        
        # 右側欄:課程推薦輸出
        with gr.Column(scale=1):
            # 課程推薦輸出
            output = gr.Textbox(label="課程推薦", lines=24)

    # 將提交按鈕與輸出連接
    submit.click(
        recommend_courses,
        inputs=[learning_background, difficulty, preferred_course, question_type, possible_career_paths, api_key],
        outputs=output
    )

# 啟動 Gradio 的應用
demo.launch()