Таблицата не е отговор
В урок 23 програмата връща таблица. Директорът обаче не иска таблица — иска три изречения: кой клас е най-силен, кой изостава, с колко. А класният иска графика за родителската среща. Днес добавяме и двете към справката — и се научаваме да не вярваме на изреченията.
Разделението на труда е ясно от самото начало: числата се смятат в SQL и pandas, моделът само ги описва с думи. Езиковият модел пише добре и смята зле — видяхте го в урок 16.
Таблицата в промпта
Моделът приема текст, затова DataFrame се превръща в текст. Най-простото е CSV — to_csv(index=False); Markdown таблица (to_markdown) е по-четима за човек, но иска допълнителна библиотека. За 3–10 реда CSV е напълно достатъчен.
PROMPT = f"""Ето справка за средния успех по класове (CSV):
{df.to_csv(index=False)}
Напиши кратък анализ от 3–4 изречения на български:
- кой клас е с най-висок и кой с най-нисък успех и с колко се различават
- ползвай само числа от таблицата; не измисляй и не закръгляй по друг начин
- не говори за тенденции — таблицата няма данни във времето"""
otg = client.models.generate_content(
model="gemini-2.5-flash", contents=PROMPT,
config=types.GenerateContentConfig(temperature=0))
analiz = otg.text
print(analiz)- Ограничението в промпта — „само числа от таблицата“ — е първата защита срещу измислени стойности.
- Казваме какво да не прави: без тенденции, без причини. Иначе моделът услужливо добавя „поради по-добра мотивация“ — нещо, което в таблицата го няма.
- Искаме кратко. Дълъг анализ на малка таблица е сигурен знак за пълнеж.
Графика с matplotlib
matplotlib е стандартната библиотека за графики в Python и е предварително инсталирана в Colab. За справка по категории — стълбовидна диаграма; за стойности във времето — линейна.
import matplotlib.pyplot as plt
plt.figure(figsize=(5, 3))
plt.bar(df["klas"], df["sreden"], color="#3b82f6")
plt.ylim(2, 6) # скалата на оценките
plt.ylabel("среден успех")
plt.title("Среден успех по клас")
for i, v in enumerate(df["sreden"]):
plt.text(i, v + 0.05, f"{v:.2f}", ha="center") # числото над стълба
plt.tight_layout()
plt.savefig("uspeh_po_klas.png", dpi=150) # файл за доклада
plt.show()ylim(2, 6)— оста започва от 2, защото оценки под 2 няма; графика от 0 би сплескала разликите, а графика от 4 би ги преувеличила. Изборът на скала е също твърдение.- Числата над стълбовете идват от DataFrame — същите, които е видял моделът. Графика и текст не бива да си противоречат.
savefigпредиshow, иначе файлът е празен.
Къде моделът греши
Четири типични грешки
| Грешка | Пример | Защита |
|---|---|---|
| сбъркано число | „11Б е с 4,80“ при 4,50 в таблицата | проверка на всяко число срещу таблицата |
| измислена тенденция | „успехът се подобрява“ — при данни без време | изрична забрана в промпта; въпрос „откъде?“ |
| сметка наум | „разликата е над 1,5“ при 5,75 − 4,50 = 1,25 | разликите се смятат в pandas и се подават готови |
| причина от нищото | „заради по-опитни учители“ | таблицата няма такава колона — твърдението се трие |
Проверката на твърденията
Анализът се разбива на отделни твърдения и всяко се проверява срещу таблицата. Част от проверката може да е автоматична — числата:
import re
def chisla_v(tekst):
return {float(x.replace(",", ".")) for x in re.findall(r"\d+[.,]\d+", tekst)}
v_tablicata = set(df["sreden"].round(2)) | {round(df["sreden"].max() - df["sreden"].min(), 2)}
for ch in sorted(chisla_v(analiz)):
print(ch, "✓" if ch in v_tablicata else "✗ няма го в таблицата")Останалото — „най-висок“, „изостава“, „подобрява се“ — се проверява от човек, с таблица от три колони: твърдение, къде в данните, вярно или невярно. Точно това е задача 4 в практикума.
Какво трябва да запомниш
- Числата се смятат в SQL и pandas; моделът само ги описва с думи.
- Таблицата влиза в промпта като текст —
to_csv— с изрични ограничения: само числа от таблицата, без тенденции и причини. - Графика:
plt.barза категории,plt.plotза време; скалата на оста е също твърдение. - Число в анализа, което го няма в таблицата, значи грешен анализ.
- Всяко твърдение се проверява поотделно — числата автоматично, останалото от човек.