{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "65273922",
   "metadata": {},
   "source": [
    "# Tema 1 — Explorarea corpusului și primul prompt\n",
    "În acest notebook vei explora corpusul curățat de comentarii YouTube și vei testa un prim prompt exploratoriu.\n",
    "\n",
    "Vei testa 10 comentarii și vei reflecta asupra unor probleme precum ambiguitatea, țintele multiple, sarcasmul și confuzia dintre sentiment și poziționarea față de țintă."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7c722c5",
   "metadata": {},
   "source": [
    "## 1. Pregătire\n",
    "Încărcăm bibliotecile necesare și cheia API pentru Gemini.\n",
    "Modificați doar celula de configurare a studentului."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "33a58c26",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import os\n",
    "import json\n",
    "import random\n",
    "import pandas as pd\n",
    "from dotenv import load_dotenv\n",
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "256ffcd5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Root project: c:\\PROJECTS\\echochamber-app\n",
      "Gemini key found: True\n"
     ]
    }
   ],
   "source": [
    "ROOT = Path.cwd()\n",
    "while not (ROOT / \".env\").exists() and ROOT.parent != ROOT:\n",
    "    ROOT = ROOT.parent\n",
    "load_dotenv(ROOT / \".env\")\n",
    "\n",
    "GEMINI_API_KEY = os.getenv(\"GEMINI_API_KEY\")\n",
    "BASE_URL = \"https://generativelanguage.googleapis.com/v1beta/openai/\"\n",
    "print(\"Root project:\", ROOT)\n",
    "print(\"Gemini key found:\", GEMINI_API_KEY is not None)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b126cdf0",
   "metadata": {},
   "source": [
    "## 2. Configurare\n",
    "Modificați  această celulă.\n",
    "Schimbați `student_id` cu folderul vostru: `student_01`, `student_02`, etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0f38982e",
   "metadata": {},
   "outputs": [],
   "source": [
    "student_id = \"student_XX\"\n",
    "model = \"gemini-2.5-flash-lite\"\n",
    "temperature = 0.2\n",
    "corpus_file = ROOT / \"data\" / \"cleaned\" / \"corpus_youtube_large_clean.jsonl\"\n",
    "output_file = ROOT / \"outputs\" / f\"{student_id}_prompt_outputs.jsonl\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06e11287",
   "metadata": {},
   "source": [
    "## 3. Încărcăm corpusul curățat\n",
    "Corpusul este salvat în format JSONL.\n",
    "JSONL înseamnă: un comentariu pe fiecare linie."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "68d85550",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>source_platform</th>\n",
       "      <th>source_channel</th>\n",
       "      <th>text</th>\n",
       "      <th>text_raw</th>\n",
       "      <th>bubble_label</th>\n",
       "      <th>bubble_self_identified</th>\n",
       "      <th>topic</th>\n",
       "      <th>rhetoric_type</th>\n",
       "      <th>video_id</th>\n",
       "      <th>video_title</th>\n",
       "      <th>video_date</th>\n",
       "      <th>comment_date</th>\n",
       "      <th>likes</th>\n",
       "      <th>lang</th>\n",
       "      <th>collected_at</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>yt_5rHoTX3U_3Q_UgxaV5so7vyeXpyy8up4AaABAg</td>\n",
       "      <td>youtube</td>\n",
       "      <td>georgesimionoficial</td>\n",
       "      <td>Felicitării George Simion Președintele Românie...</td>\n",
       "      <td>Felicitării George Simion Președintele Românie...</td>\n",
       "      <td>None</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "      <td>5rHoTX3U_3Q</td>\n",
       "      <td>Turul României: realități de la firul ierbii</td>\n",
       "      <td>2025-09-30</td>\n",
       "      <td>2025-10-23</td>\n",
       "      <td>1</td>\n",
       "      <td>ro</td>\n",
       "      <td>2026-03-22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>yt_5rHoTX3U_3Q_UgwJYiRLMbLfl2AipVR4AaABAg</td>\n",
       "      <td>youtube</td>\n",
       "      <td>georgesimionoficial</td>\n",
       "      <td>Asa trebuie să fiți printre oameni nu sa se do...</td>\n",
       "      <td>Asa trebuie să fiți printre oameni nu sa se do...</td>\n",
       "      <td>None</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "      <td>5rHoTX3U_3Q</td>\n",
       "      <td>Turul României: realități de la firul ierbii</td>\n",
       "      <td>2025-09-30</td>\n",
       "      <td>2025-10-02</td>\n",
       "      <td>5</td>\n",
       "      <td>ro</td>\n",
       "      <td>2026-03-22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>yt_5rHoTX3U_3Q_UgzXqOk_SypZcQS-JcF4AaABAg</td>\n",
       "      <td>youtube</td>\n",
       "      <td>georgesimionoficial</td>\n",
       "      <td>Eu am votat cu George Simion din primul tur pt...</td>\n",
       "      <td>Eu am votat cu George Simion din primul tur pt...</td>\n",
       "      <td>None</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "      <td>5rHoTX3U_3Q</td>\n",
       "      <td>Turul României: realități de la firul ierbii</td>\n",
       "      <td>2025-09-30</td>\n",
       "      <td>2025-10-01</td>\n",
       "      <td>30</td>\n",
       "      <td>ro</td>\n",
       "      <td>2026-03-22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>yt_5rHoTX3U_3Q_UgzpKghDX0_l-Gc3P4V4AaABAg</td>\n",
       "      <td>youtube</td>\n",
       "      <td>georgesimionoficial</td>\n",
       "      <td>Si de trebuie deposite de combustibil degeaba ...</td>\n",
       "      <td>Si de trebuie deposite de combustibil degeaba ...</td>\n",
       "      <td>None</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "      <td>5rHoTX3U_3Q</td>\n",
       "      <td>Turul României: realități de la firul ierbii</td>\n",
       "      <td>2025-09-30</td>\n",
       "      <td>2025-10-16</td>\n",
       "      <td>3</td>\n",
       "      <td>ro</td>\n",
       "      <td>2026-03-22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>yt_5rHoTX3U_3Q_UgwqOTRSHNPj9cuGwNt4AaABAg</td>\n",
       "      <td>youtube</td>\n",
       "      <td>georgesimionoficial</td>\n",
       "      <td>Nu te descuraja că dobitoci și proști vor fi p...</td>\n",
       "      <td>Nu te descuraja că dobitoci&nbsp;&nbsp;și proști&nbsp;&nbsp;vor fi...</td>\n",
       "      <td>None</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "      <td>5rHoTX3U_3Q</td>\n",
       "      <td>Turul României: realități de la firul ierbii</td>\n",
       "      <td>2025-09-30</td>\n",
       "      <td>2025-10-01</td>\n",
       "      <td>9</td>\n",
       "      <td>ro</td>\n",
       "      <td>2026-03-22</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                          id source_platform  \\\n",
       "0  yt_5rHoTX3U_3Q_UgxaV5so7vyeXpyy8up4AaABAg         youtube   \n",
       "1  yt_5rHoTX3U_3Q_UgwJYiRLMbLfl2AipVR4AaABAg         youtube   \n",
       "2  yt_5rHoTX3U_3Q_UgzXqOk_SypZcQS-JcF4AaABAg         youtube   \n",
       "3  yt_5rHoTX3U_3Q_UgzpKghDX0_l-Gc3P4V4AaABAg         youtube   \n",
       "4  yt_5rHoTX3U_3Q_UgwqOTRSHNPj9cuGwNt4AaABAg         youtube   \n",
       "\n",
       "        source_channel                                               text  \\\n",
       "0  georgesimionoficial  Felicitării George Simion Președintele Românie...   \n",
       "1  georgesimionoficial  Asa trebuie să fiți printre oameni nu sa se do...   \n",
       "2  georgesimionoficial  Eu am votat cu George Simion din primul tur pt...   \n",
       "3  georgesimionoficial  Si de trebuie deposite de combustibil degeaba ...   \n",
       "4  georgesimionoficial  Nu te descuraja că dobitoci și proști vor fi p...   \n",
       "\n",
       "                                            text_raw bubble_label  \\\n",
       "0  Felicitării George Simion Președintele Românie...         None   \n",
       "1  Asa trebuie să fiți printre oameni nu sa se do...         None   \n",
       "2  Eu am votat cu George Simion din primul tur pt...         None   \n",
       "3  Si de trebuie deposite de combustibil degeaba ...         None   \n",
       "4  Nu te descuraja că dobitoci  și proști  vor fi...         None   \n",
       "\n",
       "   bubble_self_identified topic rhetoric_type     video_id  \\\n",
       "0                   False  None          None  5rHoTX3U_3Q   \n",
       "1                   False  None          None  5rHoTX3U_3Q   \n",
       "2                   False  None          None  5rHoTX3U_3Q   \n",
       "3                   False  None          None  5rHoTX3U_3Q   \n",
       "4                   False  None          None  5rHoTX3U_3Q   \n",
       "\n",
       "                                    video_title  video_date comment_date  \\\n",
       "0  Turul României: realități de la firul ierbii  2025-09-30   2025-10-23   \n",
       "1  Turul României: realități de la firul ierbii  2025-09-30   2025-10-02   \n",
       "2  Turul României: realități de la firul ierbii  2025-09-30   2025-10-01   \n",
       "3  Turul României: realități de la firul ierbii  2025-09-30   2025-10-16   \n",
       "4  Turul României: realități de la firul ierbii  2025-09-30   2025-10-01   \n",
       "\n",
       "   likes lang collected_at  \n",
       "0      1   ro   2026-03-22  \n",
       "1      5   ro   2026-03-22  \n",
       "2     30   ro   2026-03-22  \n",
       "3      3   ro   2026-03-22  \n",
       "4      9   ro   2026-03-22  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Citim fiecare linie din fișierul JSONL si o transformăm într-un dataframe pentru explorare\n",
    "records = []\n",
    "with corpus_file.open(\"r\", encoding=\"utf-8\") as f:\n",
    "    for line in f:\n",
    "        records.append(json.loads(line))\n",
    "# Transformăm lista într-un DataFrame pentru explorare mai ușoară\n",
    "df = pd.DataFrame(records)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "b0873848",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of comments: 30451\n",
      "Columns: ['id', 'source_platform', 'source_channel', 'text', 'text_raw', 'bubble_label', 'bubble_self_identified', 'topic', 'rhetoric_type', 'video_id', 'video_title', 'video_date', 'comment_date', 'likes', 'lang', 'collected_at']\n"
     ]
    }
   ],
   "source": [
    "print(\"Number of comments:\", len(df))\n",
    "print(\"Columns:\", list(df.columns))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c753660",
   "metadata": {},
   "source": [
    "## 4. Explorare rapidă a corpusului\n",
    "Ne uităm la canalele principale și la câteva exemple de comentarii.\n",
    "Această etapă ne ajută să înțelegem ce tip de date avem înainte să folosim modelul."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a9926c1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "source_channel\n",
       "RecorderRomania                   12177\n",
       "turcescu111                        5019\n",
       "georgesimionoficial                3669\n",
       "CălinGeorgescu-CanalulOficial      3460\n",
       "@CălinGeorgescu-CanalulOficial     2557\n",
       "TuDecizi-s3g                        647\n",
       "StareaNatiei                        623\n",
       "AltcevacuAdrianArtene               363\n",
       "roxindaniel                         305\n",
       "otvdirect                           304\n",
       "digi24hd56                          265\n",
       "euronewsro                          238\n",
       "DianaSosoacaOfficial                227\n",
       "AdevaruriSecrete                    180\n",
       "g4media479                          158\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# cele mai frecvente 15 canale sursă din dataset\n",
    "df[\"source_channel\"].... # completează pentru a vedea cele mai frecvente 15 canale sursă din dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ca63ccbf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source_channel</th>\n",
       "      <th>video_title</th>\n",
       "      <th>text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>23002</th>\n",
       "      <td>CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - Pacea de la București ( IPJ ...</td>\n",
       "      <td>Multă sănătate dl. Președinte Călin Georgescu....</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5815</th>\n",
       "      <td>@CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - De ce vorbim despre Eminescu...</td>\n",
       "      <td>Un discurs care trebuia sa vina de la Cotrocen...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11191</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Primarul Negoiță a construit șosele peste magi...</td>\n",
       "      <td>Autoritatile abilitate sa intervina!!! De acee...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11316</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Primarul Negoiță a construit șosele peste magi...</td>\n",
       "      <td>In acest moment mai putem spune doar Dumnezeu ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12505</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>DOCUMENTAR RECORDER. Singuri</td>\n",
       "      <td>E dureros.. e crunt.. simt vinovatie si recuno...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                       source_channel  \\\n",
       "23002   CălinGeorgescu-CanalulOficial   \n",
       "5815   @CălinGeorgescu-CanalulOficial   \n",
       "11191                 RecorderRomania   \n",
       "11316                 RecorderRomania   \n",
       "12505                 RecorderRomania   \n",
       "\n",
       "                                             video_title  \\\n",
       "23002  Călin Georgescu - Pacea de la București ( IPJ ...   \n",
       "5815   Călin Georgescu - De ce vorbim despre Eminescu...   \n",
       "11191  Primarul Negoiță a construit șosele peste magi...   \n",
       "11316  Primarul Negoiță a construit șosele peste magi...   \n",
       "12505                       DOCUMENTAR RECORDER. Singuri   \n",
       "\n",
       "                                                    text  \n",
       "23002  Multă sănătate dl. Președinte Călin Georgescu....  \n",
       "5815   Un discurs care trebuia sa vina de la Cotrocen...  \n",
       "11191  Autoritatile abilitate sa intervina!!! De acee...  \n",
       "11316  In acest moment mai putem spune doar Dumnezeu ...  \n",
       "12505  E dureros.. e crunt.. simt vinovatie si recuno...  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# aruncă o privire asupra unor comentarii random din dataset\n",
    "df[[\"source_channel\", \"video_title\", \"text\"]].sample(5, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5ca547a",
   "metadata": {},
   "source": [
    "## 5. Alegem 10 comentarii pentru testarea promptului\n",
    "Folosim 10 comentarii curate.\n",
    "Puteți păstra eșantionarea aleatorie sau puteți selecta manual comentarii mai interesante."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "f703fe75",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source_channel</th>\n",
       "      <th>text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>23002</th>\n",
       "      <td>CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Multă sănătate dl. Președinte Călin Georgescu....</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5815</th>\n",
       "      <td>@CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Un discurs care trebuia sa vina de la Cotrocen...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11191</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Autoritatile abilitate sa intervina!!! De acee...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11316</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>In acest moment mai putem spune doar Dumnezeu ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12505</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>E dureros.. e crunt.. simt vinovatie si recuno...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9644</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Cite dosare ați judecat și nu ați recuperat ni...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23843</th>\n",
       "      <td>turcescu111</td>\n",
       "      <td>Totul duce către: Noua Ordine Mondială, pentru...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11605</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Un hot corupt arogant si nesimtit, caruia nime...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15486</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>4:30 și încă 1% rămas pentru Crin Alcoolescu, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7767</th>\n",
       "      <td>RecorderRomania</td>\n",
       "      <td>Vă mai dau niște firme din Galați care au alți...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                       source_channel  \\\n",
       "23002   CălinGeorgescu-CanalulOficial   \n",
       "5815   @CălinGeorgescu-CanalulOficial   \n",
       "11191                 RecorderRomania   \n",
       "11316                 RecorderRomania   \n",
       "12505                 RecorderRomania   \n",
       "9644                  RecorderRomania   \n",
       "23843                     turcescu111   \n",
       "11605                 RecorderRomania   \n",
       "15486                 RecorderRomania   \n",
       "7767                  RecorderRomania   \n",
       "\n",
       "                                                    text  \n",
       "23002  Multă sănătate dl. Președinte Călin Georgescu....  \n",
       "5815   Un discurs care trebuia sa vina de la Cotrocen...  \n",
       "11191  Autoritatile abilitate sa intervina!!! De acee...  \n",
       "11316  In acest moment mai putem spune doar Dumnezeu ...  \n",
       "12505  E dureros.. e crunt.. simt vinovatie si recuno...  \n",
       "9644   Cite dosare ați judecat și nu ați recuperat ni...  \n",
       "23843  Totul duce către: Noua Ordine Mondială, pentru...  \n",
       "11605  Un hot corupt arogant si nesimtit, caruia nime...  \n",
       "15486  4:30 și încă 1% rămas pentru Crin Alcoolescu, ...  \n",
       "7767   Vă mai dau niște firme din Galați care au alți...  "
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sample_df = df.sample(10, random_state=42).copy()\n",
    "sample_df[[\"source_channel\", \"text\"]]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c79ba97",
   "metadata": {},
   "source": [
    "Optional , poti alege sa folosesti  alta metoda de esantionare sau sa filtrezi dupa anumite canale sursa sau alte criterii. Important e sa ai un set de date mic pe care sa testezi promptul inainte de a-l rula pe intregul dataset."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb85e84f",
   "metadata": {},
   "source": [
    "## 6. Primul prompt exploratoriu\n",
    "Completăm un prompt simplu pentru analizarea comentariilor politice.\n",
    "Promptul trebuie să ceară:\n",
    "- ținta comentariului;\n",
    "- poziționarea față de țintă;\n",
    "- tonul;\n",
    "- tema;\n",
    "- problema de interpretare;\n",
    "- o justificare scurtă.\n",
    "Important: tonul sau sentimentul general nu este același lucru cu poziționarea față de țintă."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "620e9782",
   "metadata": {},
   "outputs": [],
   "source": [
    "# IMPORTANT - SCHIMBA PROMTUL DE MAI JOS PENTRU A SE POTRIVI CU CERINȚELE TALE ȘI ASIGURĂ-TE CĂ RESPECTĂ STRUCTURA SOLICITATĂ\n",
    "# include în prompt instrucțiuni clare pentru fiecare dintre cele 7 elemente pe care vrei să le extragi și asigură-te că modelul înțelege că trebuie să returneze un JSON valid cu exact acele chei\n",
    "# inlocueste \"...\" cu instrucțiuni clare pentru fiecare element\n",
    "# Prompt de sistem: definește rolul modelului\n",
    "# poti pune si alte axe de analiza care te intereseaza\n",
    "\n",
    "\n",
    "SYSTEM_PROMPT = \"\"\"\n",
    "...\n",
    "\"\"\"\n",
    "\n",
    "USER_PROMPT_TEMPLATE = \"\"\"\n",
    "Citește următorul comentariu politic și identifică:\n",
    "1. target: ...\n",
    "2. stance:...\n",
    "3. sentiment: ...\n",
    "4. tone: ...\n",
    "5. topic: ...\n",
    "6. interpretation_problem: ...\n",
    "\n",
    "Important:\n",
    "\n",
    "... \n",
    "Returnează JSON valid cu exact aceste chei:\n",
    "target, stance, ...\n",
    "Comentariu:\n",
    "<<< {comment_text} >>>\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "516211a9",
   "metadata": {},
   "source": [
    "## 7. Conectarea la model\n",
    "Folosim Gemini prin endpoint compatibil cu OpenAI.\n",
    "Modelul și temperatura au fost setate mai sus."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "30240995",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "client = OpenAI(\n",
    "    api_key=\"pune aici variabila de mediu care conține cheia ta API pentru Gemini\",\n",
    "    base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "50e93e57",
   "metadata": {},
   "outputs": [],
   "source": [
    "def annotate_comment(comment_text):\n",
    "    prompt = USER_PROMPT_TEMPLATE.format(comment_text=comment_text)\n",
    "    response = client.chat.completions.create(\n",
    "        model=model,\n",
    "        temperature=temperature,\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
    "            {\"role\": \"user\", \"content\": prompt}\n",
    "        ]\n",
    "    )\n",
    "    return response.choices[0].message.content"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87319cca",
   "metadata": {},
   "source": [
    "## 8. Rulăm promptul pe 10 comentarii\n",
    "Trimitem fiecare comentariu selectat la model și salvăm răspunsurile."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7024391b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source_channel</th>\n",
       "      <th>video_title</th>\n",
       "      <th>comment_text</th>\n",
       "      <th>model_output</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - Pacea de la București ( IPJ ...</td>\n",
       "      <td>Multă sănătate dl. Președinte Călin Georgescu....</td>\n",
       "      <td>```json\\n{\\n&nbsp;&nbsp;\"target\": \"Călin Georgescu\",\\n&nbsp;&nbsp;...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>@CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - De ce vorbim despre Eminescu...</td>\n",
       "      <td>Un discurs care trebuia sa vina de la Cotrocen...</td>\n",
       "      <td>```json\\n{\\n&nbsp;&nbsp;\"target\": \"Cotroceni (implicit, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   source_channel  \\\n",
       "0   CălinGeorgescu-CanalulOficial   \n",
       "1  @CălinGeorgescu-CanalulOficial   \n",
       "\n",
       "                                         video_title  \\\n",
       "0  Călin Georgescu - Pacea de la București ( IPJ ...   \n",
       "1  Călin Georgescu - De ce vorbim despre Eminescu...   \n",
       "\n",
       "                                        comment_text  \\\n",
       "0  Multă sănătate dl. Președinte Călin Georgescu....   \n",
       "1  Un discurs care trebuia sa vina de la Cotrocen...   \n",
       "\n",
       "                                        model_output  \n",
       "0  ```json\\n{\\n  \"target\": \"Călin Georgescu\",\\n  ...  \n",
       "1  ```json\\n{\\n  \"target\": \"Cotroceni (implicit, ...  "
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_comments = 2  # schimbă aici: 3, 5 sau 10\n",
    "sample_for_prompt = \"pune aici dataframe-ul cu comentarii\".head(n_comments)\n",
    "\n",
    "outputs = []\n",
    "for _, row in sample_for_prompt.iterrows():\n",
    "    outputs.append({\n",
    "        \"source_channel\": row.get(\"source_channel\", \"\"),\n",
    "        \"video_title\": row.get(\"video_title\", \"\"),\n",
    "        \"comment_text\": row[\"text\"],\n",
    "        \"model_output\": annotate_comment(row[\"text\"])\n",
    "    })\n",
    "results_df = pd.DataFrame(outputs)\n",
    "results_df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b058561d",
   "metadata": {},
   "source": [
    "# 9. Verificam rezultatele"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "71cb828a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'```json\\n{\\n  \"target\": \"Călin Georgescu\",\\n  \"stance\": \"critică/ironică\",\\n  \"sentiment\": \"negativ\",\\n  \"tone\": \"sarcastic/batjocoritor\",\\n  \"topic\": \"politica internă/alegeri prezidențiale\",\\n  \"interpretation_problem\": \"Niciunul\"\\n}\\n```'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results_df.model_output[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "94aed8b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# funcție pentru a curăța și parsa output-ul modelului, care poate conține JSON în diferite formate (text simplu sau bloc ```json)\n",
    "\n",
    "def parse_model_output(text):\n",
    "    # Modelul poate întoarce JSON ca text simplu sau în bloc ```json\n",
    "    text = text.replace(\"```json\", \"\")\n",
    "    text = text.replace(\"```\", \"\")\n",
    "    text = text.strip()\n",
    "    \n",
    "    return json.loads(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "437bc54f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source_channel</th>\n",
       "      <th>video_title</th>\n",
       "      <th>comment_text</th>\n",
       "      <th>target</th>\n",
       "      <th>stance</th>\n",
       "      <th>sentiment</th>\n",
       "      <th>tone</th>\n",
       "      <th>topic</th>\n",
       "      <th>interpretation_problem</th>\n",
       "      <th>reason</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - Pacea de la București ( IPJ ...</td>\n",
       "      <td>Multă sănătate dl. Președinte Călin Georgescu....</td>\n",
       "      <td>Călin Georgescu</td>\n",
       "      <td>critică/ironică</td>\n",
       "      <td>negativ</td>\n",
       "      <td>sarcastic/batjocoritor</td>\n",
       "      <td>politica internă/alegeri prezidențiale</td>\n",
       "      <td>Niciunul</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>@CălinGeorgescu-CanalulOficial</td>\n",
       "      <td>Călin Georgescu - De ce vorbim despre Eminescu...</td>\n",
       "      <td>Un discurs care trebuia sa vina de la Cotrocen...</td>\n",
       "      <td>Cotroceni (implicit, Președinția României)</td>\n",
       "      <td>Pozitivă față de discursul lui Călin Georgescu...</td>\n",
       "      <td>Pozitiv</td>\n",
       "      <td>Apreciativ, laudativ</td>\n",
       "      <td>Discurs politic, leadership, Președinție</td>\n",
       "      <td>Nu există probleme de interpretare majore. Com...</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   source_channel  \\\n",
       "0   CălinGeorgescu-CanalulOficial   \n",
       "1  @CălinGeorgescu-CanalulOficial   \n",
       "\n",
       "                                         video_title  \\\n",
       "0  Călin Georgescu - Pacea de la București ( IPJ ...   \n",
       "1  Călin Georgescu - De ce vorbim despre Eminescu...   \n",
       "\n",
       "                                        comment_text  \\\n",
       "0  Multă sănătate dl. Președinte Călin Georgescu....   \n",
       "1  Un discurs care trebuia sa vina de la Cotrocen...   \n",
       "\n",
       "                                       target  \\\n",
       "0                             Călin Georgescu   \n",
       "1  Cotroceni (implicit, Președinția României)   \n",
       "\n",
       "                                              stance sentiment  \\\n",
       "0                                    critică/ironică   negativ   \n",
       "1  Pozitivă față de discursul lui Călin Georgescu...   Pozitiv   \n",
       "\n",
       "                     tone                                     topic  \\\n",
       "0  sarcastic/batjocoritor    politica internă/alegeri prezidențiale   \n",
       "1    Apreciativ, laudativ  Discurs politic, leadership, Președinție   \n",
       "\n",
       "                              interpretation_problem reason  \n",
       "0                                           Niciunul         \n",
       "1  Nu există probleme de interpretare majore. Com...         "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parsed_outputs = []\n",
    "\n",
    "for _, row in results_df.iterrows():\n",
    "    parsed = parse_model_output(row[\"model_output\"])\n",
    "    \n",
    "    parsed_outputs.append({\n",
    "        \"source_channel\": row[\"source_channel\"],\n",
    "        \"video_title\": row[\"video_title\"],\n",
    "        \"comment_text\": row[\"comment_text\"],\n",
    "        \"target\": parsed.get(\"target\", \"\"),\n",
    "        \"stance\": parsed.get(\"stance\", \"\"),\n",
    "        \"sentiment\": parsed.get(\"sentiment\", \"\"),\n",
    "        \"tone\": parsed.get(\"tone\", \"\"),\n",
    "        \"topic\": parsed.get(\"topic\", \"\"),\n",
    "        \"interpretation_problem\": parsed.get(\"interpretation_problem\", \"\"),\n",
    "        \"reason\": parsed.get(\"reason\", \"\")\n",
    "    })\n",
    "\n",
    "parsed_df = pd.DataFrame(parsed_outputs)\n",
    "parsed_df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e0bf546",
   "metadata": {},
   "source": [
    "# 10 Salvarea csv si inspectarea rezulatelor\n",
    "- salvati ca csv \n",
    "- deschideti csv si verificati rezultatele \n",
    "- raspundeti la urmatoarele intrebare: promptul separă corect sentimentul general de poziționarea față de target? "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c0684331",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "39a2f4a7",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python (.venv)",
   "language": "python",
   "name": "echochamber"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
