Skip to content

Commit 3b7002b

Browse files
committed
Fix: tprs prompt, pause between segments ...
1 parent d1a91e6 commit 3b7002b

File tree

2 files changed

+80
-26
lines changed

2 files changed

+80
-26
lines changed

lingoanki/diary.py

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ def openai_translate_sentence(self, sentence_dict):
769769
- The main key is "sentence".
770770
- Under "sentence" is another dictionnary with 3 keys:
771771
- the "primary_language_sentence" to translate.
772-
- the "study_language_sentences" is the translation you need to create
772+
- the "study_language_sentence" is the translation you need to create
773773
- the "tips" is some tips to explain the translation. The tips should be written in {self.config["languages"]["primary_language"]}.
774774
- **DO NOT invent extra words or modify the original meaning of the sentence.**
775775
- If the primary_language_sentence is not grammatically correct, or if there are minor issues, you could fix the grammar and ponctuation only.
@@ -1056,6 +1056,9 @@ def create_first_tprs_md_file(self):
10561056
for sentence_no, sentence_dict in diary_dict[diary_date][
10571057
"sentences"
10581058
].items():
1059+
self.logging.info(
1060+
f'Creating TPRS content for "{sentence_dict["study_language_sentence"]}"'
1061+
)
10591062
qa_dict = self.openai_tprs(sentence_dict["study_language_sentence"])
10601063
tprs_dict[diary_date][
10611064
sentence_dict["study_language_sentence"]
@@ -1175,11 +1178,14 @@ def create_tprs_audio(self, day_block, date):
11751178
# create a pause file
11761179
pause_filename = os.path.join(tempfile.gettempdir(), f"{hash('pause')}.wav")
11771180
paused_duration = self.config["tts"]["pause_between_sentences_duration"] # ms
1178-
pause_segment = AudioSegment.silent(duration=paused_duration)
1181+
pause_segment = AudioSegment.silent(
1182+
duration=paused_duration / self.config["tts"]["repeat_sentence_tprs"]
1183+
)
11791184
pause_segment.export(pause_filename, format="wav")
11801185

11811186
media_files = []
11821187
for sentence, tprs_qa in day_block.items():
1188+
self.logging.info(f"Generating audio for {sentence}")
11831189
audio_filename = os.path.join(
11841190
tempfile.gettempdir(), f"{hash(sentence)}.wav"
11851191
)
@@ -1197,6 +1203,7 @@ def create_tprs_audio(self, day_block, date):
11971203
self.logging.info(f"SENTENCE: {sentence}")
11981204
for question, answer in tprs_qa:
11991205
# create question file
1206+
media_files.append(pause_filename)
12001207
audio_filename = os.path.join(
12011208
tempfile.gettempdir(), f"{hash(question)}.wav"
12021209
)
@@ -1207,7 +1214,6 @@ def create_tprs_audio(self, day_block, date):
12071214
voice=self.config["tts"]["piper"]["voice"],
12081215
)
12091216
media_files.append(audio_filename)
1210-
media_files.append(pause_filename)
12111217

12121218
# create a silent file
12131219
audio_filename = os.path.join(
@@ -1216,7 +1222,7 @@ def create_tprs_audio(self, day_block, date):
12161222
silence_duration = (
12171223
self.config["tts"]["answer_silence_duration"]
12181224
/ self.config["tts"]["repeat_sentence_tprs"]
1219-
) # ms
1225+
) # ms duration divided by n as every file is repeated
12201226
silenced_segment = AudioSegment.silent(duration=silence_duration)
12211227
silenced_segment.export(audio_filename, format="wav")
12221228
media_files.append(audio_filename)
@@ -1243,9 +1249,13 @@ def create_tprs_audio(self, day_block, date):
12431249

12441250
combined = AudioSegment.empty()
12451251
for sentence in playlist_media:
1246-
combined += (
1247-
sentence * self.config["tts"]["repeat_sentence_tprs"]
1248-
) # repeat audio n times so that it's easier to remember
1252+
for _ in range(self.config["tts"]["repeat_sentence_tprs"]):
1253+
combined += sentence
1254+
combined += pause_segment # Insert pause between repetitions
1255+
1256+
# combined += (
1257+
# sentence * self.config["tts"]["repeat_sentence_tprs"]
1258+
# ) # repeat audio n times so that it's easier to remember
12491259

12501260
combined.export(
12511261
tprs_audio_lesson_filepath,
@@ -1279,27 +1289,34 @@ def convert_tts_tprs_entries(self):
12791289

12801290
def openai_tprs(self, study_language_sentence):
12811291
# Define the prompt
1292+
12821293
prompt = f"""
1283-
We are working on a TPRS (Teaching Proficiency through Reading and Storytelling) method to learn {self.config["languages"]["study_language"]}.
1284-
From the following {self.config["languages"]["study_language"]} sentence, generate a few questions and answers.
1294+
We are working on a TPRS (Teaching Proficiency through Reading and Storytelling) method to learn {
1295+
self.config["languages"]["study_language"]
1296+
}.
1297+
All output must be written in {self.config["languages"]["study_language"]}.
1298+
From the following {
1299+
self.config["languages"]["study_language"]
1300+
} input, generate a few questions and answers per sentence.
12851301
The output should be a JSON dictionary where:
12861302
- The main keys are numbers (starting from 1) as strings.
12871303
- Each value is another dictionary with two keys: "question" and "answer".
12881304
- **DO NOT invent extra words or modify the original meaning of the sentence.**
1289-
- If the sentence contains an unusual phrase, keep it as is.
1305+
- **Preserve unusual or idiomatic expressions exactly as they appear.**
12901306
- **Questions must be logically sound and relevant to the sentence.**
1291-
- **Avoid questions that are vague, redundant, or unnatural.**
1292-
- If a question doesn’t make sense with the given sentence, rephrase it or skip it.
1293-
- Ensure that the **answers are complete and natural responses**, not just one-word replies.
1294-
1295-
1296-
Example output format:
1297-
{{
1298-
"1": {{"question": "Hvor sitter katten?", "answer": "Katten sitter på bordet."}},
1299-
"2": {{"question": "Hva gjør katten?", "answer": "Den sitter."}}
1300-
}}
1301-
1302-
### Example:
1307+
- **Make sure the questions and answers sound natural, like a native speaker would actually say them.**
1308+
- Ensure that the **answers are complete, not just one-word replies.**
1309+
- **Avoid overly formal, awkward, or robotic phrases.**
1310+
- Each question should be directly answerable from the sentence, but not repetitive.
1311+
- don't use emojis as this will be converted for TTS
1312+
- The original sentence may include informal, emotional, or sexual language. Do not censor or sanitise it.
1313+
- Interpret the sentence like a native speaker would, even if the content is suggestive or mature.
1314+
- **Questions should explore various aspects of the sentence (who, what, when, how, why), without repeating the same information.**
1315+
- **Try to match the emotional tone or style of the sentence (e.g., casual, funny, dramatic).**
1316+
- **Avoid repeating the same phrasing or vocabulary in both the questions and answers. Use different angles, emotions, or contextual clues to make each question unique.**
1317+
- **You can explore the setting, emotional dynamics, or deeper meanings behind the actions in the sentence.**
1318+
1319+
### Example 1 – Neutral:
13031320
Input sentence: "Fredag var Johanne veldig syk. Vi ble hjemme og dro for å fiske med Emil og Mati. Jeg var den første som fanget noe – min første norske fisk."
13041321
13051322
Expected questions and answers:
@@ -1310,9 +1327,41 @@ def openai_tprs(self, study_language_sentence):
13101327
"4": {{"question": "Hva var spesielt med fisken jeg fanget?", "answer": "Det var min første norske fisk."}}
13111328
}}
13121329
1313-
### Now generate logical questions and answers for this {self.config["languages"]["study_language"]} sentence: "{study_language_sentence}"
1314-
"""
1330+
### Example 2 – Sad:
1331+
Input sentence: "Elle est partie sans dire au revoir. Je suis resté seul avec mon café froid."
13151332
1333+
Expected questions and answers:
1334+
{{
1335+
"1": {{"question": "Pourquoi est-ce que tu es resté seul ?", "answer": "Parce qu'elle est partie sans dire au revoir."}},
1336+
"2": {{"question": "Qu'est-ce qu'elle a oublié de faire en partant ?", "answer": "Elle n'a pas dit au revoir."}},
1337+
"3": {{"question": "Avec quoi es-tu resté après son départ ?", "answer": "Avec mon café froid... et ma solitude."}}
1338+
}}
1339+
1340+
### Example 3 – Funny:
1341+
Input sentence: "J'ai mis du sel au lieu du sucre dans mon café. Résultat : je me suis réveillé plus vite que prévu."
1342+
1343+
Expected questions and answers:
1344+
{{
1345+
"1": {{"question": "Qu'est-ce que tu as mis dans ton café par erreur ?", "answer": "Du sel au lieu du sucre."}},
1346+
"2": {{"question": "Comment as-tu réagi après avoir bu le café ?", "answer": "Je me suis réveillé plus vite que prévu !"}},
1347+
"3": {{"question": "Pourquoi ton café avait un goût bizarre ?", "answer": "Parce qu’il y avait du sel dedans, pas du sucre."}}
1348+
}}
1349+
1350+
1351+
### Example 4 - Cheeky (French):
1352+
Input sentence: "Hier soir, elle est rentrée avec un grand sourire... et sans pantalon."
1353+
1354+
Expected questions and answers:
1355+
{{"1": {{"question": "Pourquoi elle avait un grand sourire hier soir ?", "answer": "Parce qu'elle est rentrée sans pantalon."}},
1356+
"2": {{"question": "Comment est-elle rentrée hier soir ?", "answer": "Avec un grand sourire et sans pantalon."}},
1357+
"3": {{"question": "Qu'est-ce qu'il manquait à sa tenue ?", "answer": "Elle n'avait pas de pantalon."}},
1358+
"4": {{"question": "On peut deviner pourquoi elle souriait ?", "answer": "Probablement... mais ce n’est pas écrit dans la phrase."}}
1359+
}}
1360+
1361+
### Now generate logical questions and answers in {
1362+
self.config["languages"]["study_language"]
1363+
} for the following sentence: "{study_language_sentence}"
1364+
"""
13161365
# Make the API call
13171366

13181367
client = OpenAI(api_key=self.config["openai"]["key"])

lingoanki/webapp.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,13 @@ def view_markdown(filename):
638638
@app.route("/play_audio")
639639
@login_required
640640
def play_audio_page():
641-
mp3_files = [f for f in os.listdir(session["tprs_folder"]) if f.endswith(".mp3")]
642-
mp3_files = sorted(set(mp3_files), reverse=True)
641+
if not os.path.exists(session["tprs_folder"]):
642+
mp3_files = []
643+
else:
644+
mp3_files = [
645+
f for f in os.listdir(session["tprs_folder"]) if f.endswith(".mp3")
646+
]
647+
mp3_files = sorted(set(mp3_files), reverse=True)
643648

644649
return render_template("diary_tprs_play_audio.html", mp3_files=mp3_files)
645650

0 commit comments

Comments
 (0)