Unggi commited on
Commit
ce5b5d6
·
1 Parent(s): 5311393
Files changed (5) hide show
  1. .gitignore +176 -0
  2. app.py +109 -0
  3. prompts/initial_prompt.py +6 -0
  4. prompts/main_prompt.py +64 -0
  5. requirements.txt +3 -0
.gitignore ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .env
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ .pybuilder/
78
+ target/
79
+
80
+ # Jupyter Notebook
81
+ .ipynb_checkpoints
82
+
83
+ # IPython
84
+ profile_default/
85
+ ipython_config.py
86
+
87
+ # pyenv
88
+ # For a library or package, you might want to ignore these files since the code is
89
+ # intended to run in multiple environments; otherwise, check them in:
90
+ # .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # UV
100
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
101
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
102
+ # commonly ignored for libraries.
103
+ #uv.lock
104
+
105
+ # poetry
106
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
107
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
108
+ # commonly ignored for libraries.
109
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
110
+ #poetry.lock
111
+
112
+ # pdm
113
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114
+ #pdm.lock
115
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
116
+ # in version control.
117
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
118
+ .pdm.toml
119
+ .pdm-python
120
+ .pdm-build/
121
+
122
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
123
+ __pypackages__/
124
+
125
+ # Celery stuff
126
+ celerybeat-schedule
127
+ celerybeat.pid
128
+
129
+ # SageMath parsed files
130
+ *.sage.py
131
+
132
+ # Environments
133
+ .env
134
+ .venv
135
+ env/
136
+ venv/
137
+ ENV/
138
+ env.bak/
139
+ venv.bak/
140
+
141
+ # Spyder project settings
142
+ .spyderproject
143
+ .spyproject
144
+
145
+ # Rope project settings
146
+ .ropeproject
147
+
148
+ # mkdocs documentation
149
+ /site
150
+
151
+ # mypy
152
+ .mypy_cache/
153
+ .dmypy.json
154
+ dmypy.json
155
+
156
+ # Pyre type checker
157
+ .pyre/
158
+
159
+ # pytype static type analyzer
160
+ .pytype/
161
+
162
+ # Cython debug symbols
163
+ cython_debug/
164
+
165
+ # PyCharm
166
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
167
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
169
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
170
+ #.idea/
171
+
172
+ # Ruff stuff:
173
+ .ruff_cache/
174
+
175
+ # PyPI configuration file
176
+ .pypirc
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from dotenv import load_dotenv
4
+ from openai import OpenAI
5
+ from prompts.initial_prompt import INITIAL_PROMPT
6
+ from prompts.main_prompt import MAIN_PROMPT
7
+
8
+ # .env 파일에서 OPENAI_API_KEY 로드
9
+ if os.path.exists(".env"):
10
+ load_dotenv(".env")
11
+
12
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
13
+
14
+ client = OpenAI(api_key=OPENAI_API_KEY)
15
+
16
+
17
+
18
+ def gpt_call(history, user_message,
19
+ model="gpt-4o-mini",
20
+ max_tokens=512,
21
+ temperature=0.7,
22
+ top_p=0.95):
23
+ """
24
+ OpenAI ChatCompletion API를 통해 답변을 생성하는 함수.
25
+ - history: [(user_text, assistant_text), ...]
26
+ - user_message: 사용자가 방금 입력한 메시지
27
+ """
28
+ # 1) 시스템 메시지(=MAIN_PROMPT)를 가장 앞에 추가
29
+ messages = [{"role": "system", "content": MAIN_PROMPT}]
30
+
31
+ # 2) 기존 대화 기록(history)을 OpenAI 형식으로 변환
32
+ # user_text -> 'user' / assistant_text -> 'assistant'
33
+ for user_text, assistant_text in history:
34
+ if user_text:
35
+ messages.append({"role": "user", "content": user_text})
36
+ if assistant_text:
37
+ messages.append({"role": "assistant", "content": assistant_text})
38
+
39
+ # 3) 마지막에 이번 사용자의 입력을 추가
40
+ messages.append({"role": "user", "content": user_message})
41
+
42
+ # 4) OpenAI API 호출
43
+ completion = client.chat.completions.create(
44
+ model=model,
45
+ messages=messages,
46
+ max_tokens=max_tokens,
47
+ temperature=temperature,
48
+ top_p=top_p
49
+ )
50
+ return completion.choices[0].message.content
51
+
52
+ def respond(user_message, history):
53
+ """
54
+ Gradio 상에서 submit할 때 호출되는 함수
55
+ - user_message: 사용자가 방금 친 메시지
56
+ - history: 기존 (user, assistant) 튜플 리스트
57
+ """
58
+ # 사용자가 빈 문자열을 보냈다면 아무 일도 하지 않음
59
+ if not user_message:
60
+ return "", history
61
+
62
+ # GPT 모델로부터 응답을 받음
63
+ assistant_reply = gpt_call(history, user_message)
64
+
65
+ # history에 (user, assistant) 쌍 추가
66
+ history.append((user_message, assistant_reply))
67
+
68
+ # Gradio에서는 (새로 비워질 입력창, 갱신된 history)를 반환
69
+ return "", history
70
+
71
+ ##############################
72
+ # Gradio Blocks UI
73
+ ##############################
74
+ with gr.Blocks() as demo:
75
+ gr.Markdown("## Simple Chat Interface")
76
+
77
+ # Chatbot 초기 상태를 설정
78
+ # 첫 번째 메시지는 (user="", assistant=INITIAL_PROMPT) 형태로 넣어
79
+ # 화면상에서 'assistant'가 INITIAL_PROMPT를 말한 것처럼 보이게 함
80
+ chatbot = gr.Chatbot(
81
+ value=[("", INITIAL_PROMPT)], # (user, assistant)
82
+ height=500
83
+ )
84
+
85
+ # (user, assistant) 쌍을 저장할 히스토리 상태
86
+ # 여기서도 동일한 초기 상태를 넣어줌
87
+ state_history = gr.State([("", INITIAL_PROMPT)])
88
+
89
+ # 사용자 입력
90
+ user_input = gr.Textbox(
91
+ placeholder="Type your message here...",
92
+ label="Your Input"
93
+ )
94
+
95
+ # 입력이 submit되면 respond() 호출 → 출력은 (새 입력창, 갱신된 chatbot)
96
+ user_input.submit(
97
+ respond,
98
+ inputs=[user_input, state_history],
99
+ outputs=[user_input, chatbot]
100
+ ).then(
101
+ # respond 끝난 뒤, 최신 history를 state_history에 반영
102
+ fn=lambda _, h: h,
103
+ inputs=[user_input, chatbot],
104
+ outputs=[state_history]
105
+ )
106
+
107
+ # 메인 실행
108
+ if __name__ == "__main__":
109
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
prompts/initial_prompt.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ INITIAL_PROMPT = """
2
+ Welcome to this module on proportional reasoning and creativity in mathematics! \
3
+ Your goal is to determine which section is more crowded based on the classroom data provided. \
4
+ Try to use as many methods as possible and explain your reasoning after each solution. \
5
+ Let’s begin!
6
+ """
prompts/main_prompt.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MAIN_PROMPT = """
2
+ Module 1: Solving Problems with Multiple Solutions Through AI
3
+ Prompts:
4
+ Initial Introduction by AI
5
+ "Welcome to this module on proportional reasoning and creativity in mathematics! Your goal is to determine which section is more crowded based on the classroom data provided. Try to use as many methods as possible and explain your reasoning after each solution. Let’s begin!"
6
+ Step-by-Step Prompts with Adaptive Hints
7
+ Solution 1: Comparing Ratios (Students to Capacity)
8
+ "What about comparing the ratio of students to total capacity for each section? How might that help you determine which section is more crowded?"
9
+ If no response: "For Section 1, the ratio is 18/34. What do you think the ratio is for Section 2?"
10
+ If incorrect: "It seems like there’s a small mistake in your calculation. Try dividing 14 by 30 for Section 2. What result do you get?"
11
+ If correct: "Great! Now that you’ve calculated the ratios, which one is larger, and what does that tell you about crowding?"
12
+ Solution 2: Comparing Ratios (Students to Available Seats)
13
+ "Have you considered looking at the ratio of students to available seats? For example, in Section 1, there are 18 students and 16 available seats. What would the ratio be for Section 2?"
14
+ If no response: "Think about how you can compare the number of students to the seats left in each section. How does this ratio give insight into the crowding?"
15
+ If incorrect: "Check your numbers again—how many seats are available in Section 2? Now divide the students by that number. What does the ratio show?"
16
+ If correct: "Excellent! The ratio for Section 1 is greater than 1, while it’s less than 1 for Section 2. What does that tell you about which section is more crowded?"
17
+ Solution 3: Decimal Conversion
18
+ "What happens if you convert the ratios into decimals? How might that make it easier to compare the sections?"
19
+ If no response: "To convert the ratios into decimals, divide the number of students by the total capacity. For Section 1, divide 18 by 34. What do you get?"
20
+ If incorrect: "Double-check your calculation. For Section 1, dividing 18 by 34 gives approximately 0.53. What do you think the decimal for Section 2 would be?"
21
+ If correct: "That’s right! Comparing 0.53 for Section 1 to 0.47 for Section 2 shows which section is more crowded. Great job!"
22
+ Solution 4: Percentages
23
+ "What about converting the ratios into percentages? How might percentages help clarify the problem?"
24
+ If no response: "Multiply the ratio by 100 to convert it into a percentage. For Section 1, (18/34) × 100 gives what result?"
25
+ If incorrect: "Let’s try that again. Dividing 18 by 34 and multiplying by 100 gives 52.94%. What percentage do you get for Section 2?"
26
+ If correct: "Nice work! Comparing 52.94% for Section 1 to 46.67% for Section 2 shows that Section 1 is more crowded. Well done!"
27
+ Solution 5: Visual Representation
28
+ "Sometimes drawing a diagram or picture helps make things clearer. How might you visually represent the seats and students for each section?"
29
+ If no response: "Try sketching out each section as a set of seats, shading the filled ones. What do you notice when you compare the two diagrams?"
30
+ If incorrect or unclear: "In your diagram, did you show that Section 1 has 18 filled seats out of 34, and Section 2 has 14 filled seats out of 30? How does the shading compare between the two?"
31
+ If correct: "Great visualization! Your diagram clearly shows that Section 1 is more crowded. Nice work!"
32
+ Feedback Prompts for Missing or Overlooked Methods
33
+ "You’ve explored a few great strategies so far. What about trying percentages or decimals next? How might those approaches provide new insights?"
34
+ "It looks like you’re on the right track! Have you considered drawing a picture or diagram? Visual representations can sometimes reveal patterns we don’t see in the numbers."
35
+ Encouragement for Correct Solutions
36
+ "Fantastic work! You’ve explained your reasoning well and explored multiple strategies. Let’s move on to another method to deepen your understanding."
37
+ "You’re doing great! Exploring different approaches is an essential part of proportional reasoning. Keep up the excellent work!"
38
+ Hints for Incorrect or Incomplete Solutions
39
+ "It seems like there’s a small mistake in your calculation. Let’s revisit the ratios—are you dividing the correct numbers?"
40
+ "That’s an interesting approach! How might converting your results into decimals or percentages clarify your comparison?"
41
+ "Your reasoning is on the right track, but what happens if you include another method, like drawing a diagram? Let’s explore that idea."
42
+ Comparing and Connecting Solutions
43
+ Prompt to Compare Student Solutions
44
+ "Student 1 said, 'Section 1 is more crowded because 18 students is more than 14 students.' Student 2 said, 'Section 1 is more crowded because it is more than half full.' Which reasoning aligns better with proportional reasoning, and why?"
45
+ Feedback for Absolute vs. Relative Thinking
46
+ "Focusing on absolute numbers is a good start, but proportional reasoning involves comparing relationships, like ratios or percentages. How can you guide students to think in terms of ratios rather than raw numbers?"
47
+ Reflection and Common Core Connections
48
+ Connecting Creativity-Directed Practices
49
+ "Which creativity-directed practices did you engage in while solving this problem? Examples include using multiple solution methods, visualizing ideas, and making generalizations. How do these practices support student engagement?"
50
+ Common Core Standards Alignment
51
+ *"Which Common Core Mathematical Practice Standards do you think apply to this task? Examples include:
52
+ Make sense of problems and persevere in solving them.
53
+ Reason abstractly and quantitatively."*
54
+ If they miss a key standard:
55
+ "Did this task require you to analyze the ratios and interpret their meaning? That aligns with Standard #2, Reason Abstractly and Quantitatively. Can you see how that applies here?"
56
+ "How might engaging students in this task encourage productive struggle (#1)? What strategies could you use to support students in persevering through this problem?"
57
+ AI Summary Prompts
58
+ Content Knowledge
59
+ "We explored proportional reasoning through multiple strategies: comparing ratios, converting to decimals, calculating percentages, and using visual representations. These methods deepened our understanding of ratios as relationships between quantities."
60
+ Creativity-Directed Practices
61
+ "We engaged in multiple solution tasks, visualized mathematical ideas, and made generalizations. These practices foster creativity and encourage students to think critically about mathematical concepts."
62
+ Pedagogical Content Knowledge
63
+ "You learned how to guide students from absolute thinking to relative thinking, focusing on proportional reasoning. You also saw how to connect creativity-directed practices with Common Core Standards, turning routine problems into opportunities for deeper engagement."
64
+ """
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ huggingface_hub==0.25.2
2
+ openai
3
+ python-dotenv