ankban commited on
Commit
7abf484
Β·
verified Β·
1 Parent(s): 48ddd4e

Update written_module.py

Browse files
Files changed (1) hide show
  1. written_module.py +89 -62
written_module.py CHANGED
@@ -2,9 +2,11 @@ import gradio as gr
2
  import uuid
3
  import os
4
  import matplotlib.pyplot as plt
 
5
  from openai import OpenAI
6
  from app_utils import (
7
  LANG_CODES, save_to_db, fetch_user_sessions,
 
8
  parse_scores_from_feedback, generate_progress_summary,
9
  build_score_comparison_data, render_score_chart,
10
  build_trend_data, render_trend_chart
@@ -12,119 +14,144 @@ from app_utils import (
12
 
13
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
14
 
15
- def generate_written_feedback(text, language, goal="general improvement", focus_areas=None, previous_text=None):
16
- focus_str = ", ".join(focus_areas) if focus_areas else "Clarity, Structure, Grammar, Style, Tone, Creativity"
17
- history_section = f"\n\nCompare this to their previous writing:\n{previous_text}" if previous_text else ""
18
 
19
  prompt = f"""
20
- You are a writing coach helping a student improve their writing for the following goal: **{goal}**.
21
 
22
- First, return a JSON object with scores (0–10) for each of these:
23
  {focus_str}
24
 
25
- Then write:
26
- - A brief explanation per score
27
- - A summary of strengths and improvements
28
- - One motivational line
29
 
30
- Current text:
31
- {text}
 
 
 
 
32
  {history_section}
33
- """
 
34
  response = client.chat.completions.create(
35
  model="gpt-4",
36
  messages=[
37
- {"role": "system", "content": f"You are a helpful writing tutor responding in {language}."},
38
  {"role": "user", "content": prompt}
39
  ],
40
  temperature=0.7
41
  )
42
  return response.choices[0].message.content
43
 
44
- def improve_written_text(text, language):
45
- prompt = f"""Improve this writing by refining structure, grammar, and clarity β€” without changing its meaning.
 
46
 
47
- Text:
48
- {text}
49
  """
50
  response = client.chat.completions.create(
51
  model="gpt-4",
52
  messages=[
53
- {"role": "system", "content": f"Reply in {language}. Provide only the improved version."},
54
  {"role": "user", "content": prompt}
55
  ]
56
  )
57
  return response.choices[0].message.content
58
 
59
- def written_dashboard(nickname):
60
- with gr.Column() as written_panel:
 
 
 
 
 
 
 
61
  gr.Markdown("""
62
  <div id="header" style="text-align: center;">
63
- <img src="file/images/chatter_owl.png" width="120">
64
- <h2>✍️ Written Communication with <strong>Chatter the Owl</strong></h2>
65
- <p>Paste or upload your writing. Select your goal and focus, and receive detailed feedback, improvement, and progress tracking.</p>
66
  </div>
67
  """)
68
 
69
  with gr.Row():
70
  language_dropdown = gr.Dropdown(label="🌍 Language", choices=list(LANG_CODES.keys()), value="English")
71
- goal_dropdown = gr.Dropdown(label="🎯 Writing Goal", choices=["Essay for school", "Job application", "Blog post", "Creative writing", "General improvement"], value="General improvement")
72
- focus_checkboxes = gr.CheckboxGroup(label="🧠 Focus Areas", choices=["Clarity", "Organization", "Grammar", "Vocabulary", "Tone", "Creativity"], value=["Clarity", "Organization", "Grammar", "Vocabulary", "Tone", "Creativity"])
73
 
74
  with gr.Row():
75
- input_text = gr.Textbox(label="πŸ“ Your Writing", lines=8, elem_id="input_text", elem_classes=["text_area"])
76
- submit_button = gr.Button("πŸš€ Submit", variant="primary")
77
 
78
- file_input = gr.File(label="πŸ“„ Upload Text File", file_types=[".txt", ".md"])
 
 
79
 
80
- feedback_box = gr.Textbox(label="πŸ’‘ Feedback", interactive=False, elem_id="feedback_box")
81
- improved_box = gr.Textbox(label="🎯 Improved Version", interactive=False, elem_id="improved_box")
 
 
 
82
  history_table = gr.Dataframe(headers=["πŸ•’ Timestamp", "🌐 Language", "πŸ“„ Transcript", "πŸ’¬ Feedback"])
83
  score_chart = gr.Plot(label="πŸ“Š Score Comparison")
84
  trend_chart = gr.Plot(label="πŸ“ˆ Tone Progress")
85
  milestone_box = gr.Markdown(visible=False)
86
- score_chart = gr.Plot(label="πŸ“Š Score Comparison")
87
- trend_chart = gr.Plot(label="πŸ“ˆ Clarity Progress")
88
- milestone_box = gr.Markdown(visible=False)
89
 
90
- def extract_text(file):
91
- if file is None:
92
- return ""
93
- with open(file.name, 'r', encoding='utf-8') as f:
94
- return f.read()
95
 
96
- file_input.change(fn=extract_text, inputs=file_input, outputs=input_text)
 
97
 
98
- def tutor_written(text, language, goal, focus_areas):
99
- if not text.strip():
100
- return "", "", [], None, None, gr.update(visible=False)
 
 
101
 
102
- sessions = fetch_user_sessions(nickname)
103
- previous_text = sessions[-1].transcript if sessions else None
104
- previous_feedback = sessions[-1].feedback if sessions else None
 
 
 
 
 
 
 
105
 
106
- feedback = generate_written_feedback(text, language, goal, focus_areas, previous_text)
107
- improved = improve_written_text(text, language)
 
108
 
109
- save_to_db(nickname, text, feedback, language)
110
  sessions = fetch_user_sessions(nickname)
111
  session_table = [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions]
112
 
113
- score_plot = render_score_chart(build_score_comparison_data(feedback, previous_feedback)) if previous_feedback else None
114
- dates, clarity_scores = build_trend_data(sessions, "Clarity")
115
- trend_plot = render_trend_chart(dates, clarity_scores, "Clarity") if clarity_scores else None
116
 
117
- milestone_msg = ""
118
- if len(sessions) in [3, 5, 10]:
119
- milestone_msg = f"πŸŽ‰ You’ve completed **{len(sessions)} writing sessions**!"
120
- feedback += f"\n\n{milestone_msg}"
121
 
122
- return feedback, improved, session_table, score_plot, trend_plot, gr.update(visible=bool(milestone_msg), value=milestone_msg)
123
-
124
- submit_button.click(
125
- fn=tutor_written,
126
- inputs=[input_text, language_dropdown, goal_dropdown, focus_checkboxes],
127
- outputs=[feedback_box, improved_box, history_table, score_chart, trend_chart, milestone_box]
128
  )
129
 
130
- return written_panel
 
 
 
 
 
 
 
 
 
2
  import uuid
3
  import os
4
  import matplotlib.pyplot as plt
5
+ from gtts import gTTS
6
  from openai import OpenAI
7
  from app_utils import (
8
  LANG_CODES, save_to_db, fetch_user_sessions,
9
+ convert_to_wav, transcribe_audio,
10
  parse_scores_from_feedback, generate_progress_summary,
11
  build_score_comparison_data, render_score_chart,
12
  build_trend_data, render_trend_chart
 
14
 
15
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
16
 
17
+ def generate_feedback(transcript, language, goal="general improvement", focus_areas=None, previous_transcript=None):
18
+ focus_str = ", ".join(focus_areas) if focus_areas else "Clarity, Structure, Fluency, Content Relevance, and Tone"
19
+ history_section = f"\n\nFor reference, their previous transcript was:\n{previous_transcript}" if previous_transcript else ""
20
 
21
  prompt = f"""
22
+ You are a supportive communication coach helping a learner whose goal is: **{goal}**.
23
 
24
+ Evaluate the user's current speech based on the following areas:
25
  {focus_str}
26
 
27
+ Give a score out of 10 and a short explanation for each area.
 
 
 
28
 
29
+ Then provide:
30
+ - A summary of strengths and improvement areas.
31
+ - One motivational line to end with.
32
+
33
+ Transcript:
34
+ {transcript}
35
  {history_section}
36
+ """.strip()
37
+
38
  response = client.chat.completions.create(
39
  model="gpt-4",
40
  messages=[
41
+ {"role": "system", "content": f"You are a warm and constructive communication coach responding in {language}."},
42
  {"role": "user", "content": prompt}
43
  ],
44
  temperature=0.7
45
  )
46
  return response.choices[0].message.content
47
 
48
+ def generate_example_response(transcript, language):
49
+ prompt = f"""Rewrite this speech to make it more polished, fluent, and confident.
50
+ Keep the meaning and tone the same, but improve clarity and structure.
51
 
52
+ Transcript:
53
+ {transcript}
54
  """
55
  response = client.chat.completions.create(
56
  model="gpt-4",
57
  messages=[
58
+ {"role": "system", "content": f"Reply in {language}. Provide only the improved version of the speech."},
59
  {"role": "user", "content": prompt}
60
  ]
61
  )
62
  return response.choices[0].message.content
63
 
64
+ def render_empty_chart(title):
65
+ fig, ax = plt.subplots()
66
+ ax.set_title(title)
67
+ ax.text(0.5, 0.5, "No data yet", ha='center', va='center', fontsize=12)
68
+ ax.axis('off')
69
+ return fig
70
+
71
+ def spoken_dashboard(nickname_input):
72
+ with gr.Column() as spoken_panel:
73
  gr.Markdown("""
74
  <div id="header" style="text-align: center;">
75
+ <img src="images/chatternest_logo.png" width="100">
76
+ <h2>πŸ¦‰ Meet <strong>Chatter the Owl</strong></h2>
77
+ <p>Speak and improve your communication with personalized feedback and progress tracking.</p>
78
  </div>
79
  """)
80
 
81
  with gr.Row():
82
  language_dropdown = gr.Dropdown(label="🌍 Language", choices=list(LANG_CODES.keys()), value="English")
83
+ goal_dropdown = gr.Dropdown(label="🎯 Goal", choices=["Interview preparation", "Public speaking", "Class presentation", "General improvement"], value="General improvement")
84
+ focus_checkboxes = gr.CheckboxGroup(label="🧠 Focus Areas", choices=["Clarity", "Structure", "Fluency", "Tone", "Content Relevance"], value=["Clarity", "Structure", "Fluency", "Tone", "Content Relevance"])
85
 
86
  with gr.Row():
87
+ audio_input = gr.Audio(type="filepath", label="πŸŽ™ Speak or Upload Audio")
88
+ audio_output = gr.Audio(label="πŸ”Š Chatter's Response", type="filepath")
89
 
90
+ transcript_box = gr.Textbox(label="πŸ“– Transcript", interactive=False)
91
+ feedback_box = gr.Textbox(label="πŸ’‘ Feedback", interactive=False)
92
+ hidden_transcript = gr.Textbox(visible=False)
93
 
94
+ with gr.Row():
95
+ try_again = gr.Button("πŸ” Try Again")
96
+ show_example = gr.Button("🎯 Show Me an Example")
97
+
98
+ example_box = gr.Textbox(label="πŸ—£ Suggested Improvement", visible=True)
99
  history_table = gr.Dataframe(headers=["πŸ•’ Timestamp", "🌐 Language", "πŸ“„ Transcript", "πŸ’¬ Feedback"])
100
  score_chart = gr.Plot(label="πŸ“Š Score Comparison")
101
  trend_chart = gr.Plot(label="πŸ“ˆ Tone Progress")
102
  milestone_box = gr.Markdown(visible=False)
 
 
 
103
 
104
+ def tutor_feedback(audio_file, language, goal, focus_areas, nickname):
105
+ if not audio_file:
106
+ return "", "No audio received.", None, "", [], render_empty_chart("πŸ“Š Score Comparison"), render_empty_chart("πŸ“ˆ Tone Progress"), gr.update(visible=False)
 
 
107
 
108
+ if hasattr(nickname, "value"):
109
+ nickname = nickname.value # Handle gr.Textbox or gr.State
110
 
111
+ wav_path = convert_to_wav(audio_file)
112
+ transcript = transcribe_audio(wav_path)
113
+ previous_sessions = fetch_user_sessions(nickname)
114
+ previous_transcript = previous_sessions[-1].transcript if previous_sessions else None
115
+ previous_feedback = previous_sessions[-1].feedback if previous_sessions else None
116
 
117
+ feedback_text = generate_feedback(transcript, language, goal, focus_areas, previous_transcript)
118
+
119
+ if previous_feedback:
120
+ feedback_text += generate_progress_summary(feedback_text, previous_feedback)
121
+
122
+ milestone = ""
123
+ session_count = len(previous_sessions) + 1
124
+ if session_count in [3, 5, 10]:
125
+ milestone = f"πŸŽ‰ Congrats on completing **{session_count} sessions**!"
126
+ feedback_text += f"\n\n{milestone}"
127
 
128
+ tts = gTTS(feedback_text, lang=LANG_CODES.get(language, "en"))
129
+ mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
130
+ tts.save(mp3_path)
131
 
132
+ save_to_db(nickname, transcript, feedback_text, language)
133
  sessions = fetch_user_sessions(nickname)
134
  session_table = [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions]
135
 
136
+ score_plot = render_score_chart(build_score_comparison_data(feedback_text, previous_feedback)) if previous_feedback else render_empty_chart("πŸ“Š Score Comparison")
137
+ dates, tone_scores = build_trend_data(sessions, "Tone")
138
+ trend_plot = render_trend_chart(dates, tone_scores, "Tone") if tone_scores else render_empty_chart("πŸ“ˆ Tone Progress")
139
 
140
+ return transcript, feedback_text, mp3_path, transcript, session_table, score_plot, trend_plot, gr.update(visible=bool(milestone), value=milestone)
 
 
 
141
 
142
+ audio_input.change(
143
+ fn=tutor_feedback,
144
+ inputs=[audio_input, language_dropdown, goal_dropdown, focus_checkboxes, nickname_input],
145
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, history_table, score_chart, trend_chart, milestone_box],
146
+ show_progress="minimal"
 
147
  )
148
 
149
+ try_again.click(fn=lambda: ("", "", None, "", "", render_empty_chart("πŸ“Š Score Comparison"), render_empty_chart("πŸ“ˆ Tone Progress"), gr.update(visible=False)),
150
+ inputs=None,
151
+ outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box, score_chart, trend_chart, milestone_box])
152
+
153
+ show_example.click(fn=generate_example_response,
154
+ inputs=[hidden_transcript, language_dropdown],
155
+ outputs=example_box)
156
+
157
+ return spoken_panel