{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "colab": {
   "provenance": [],
   "name": "session_1_lab.ipynb"
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lab 1 — Your First AI API Call\n",
    "**Generative AI: Foundations and Applications · Session 1 · TCE Madurai**\n",
    "\n",
    "Before you start:\n",
    "1. **File → Save a copy in Drive** (do it now, or your work vanishes).\n",
    "2. Have your Gemini API key ready — from https://aistudio.google.com → *Get API key*.\n",
    "3. Run cells top to bottom with **Shift+Enter**.\n",
    "\n",
    "> Your key is a secret. This notebook asks for it with a hidden input box — never paste it into a code cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 1 — install the SDK (takes ~20 seconds)\n",
    "%pip install -q -U google-genai\n",
    "print(\"SDK installed ✓\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 2 — enter your API key (input stays hidden)\n",
    "from getpass import getpass\n",
    "from google import genai\n",
    "\n",
    "API_KEY = getpass(\"Paste your Gemini API key and press Enter: \")\n",
    "client = genai.Client(api_key=API_KEY)\n",
    "\n",
    "# One variable controls which model we use everywhere.\n",
    "# Free tier friendly. If a newer model is free when you read this, change this one line.\n",
    "# Current list: https://ai.google.dev/gemini-api/docs/models\n",
    "MODEL = \"gemini-flash-latest\"  # the free tier's current Flash (July 2026 → Gemini 3.5 Flash). 503 'high demand'? swap to \"gemini-flash-lite-latest\".\n",
    "print(\"Client ready ✓  using model:\", MODEL)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part B — Your first call\n",
    "\n",
    "Four lines. That's all it takes to talk to a frontier model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 3 — first API call\n",
    "response = client.models.generate_content(\n",
    "    model=MODEL,\n",
    "    contents=\"Introduce yourself in 2 sentences to a class of engineering students in Madurai.\"\n",
    ")\n",
    "print(response.text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ✓ Checkpoint 1\n",
    "If you see a response above — congratulations, you are officially calling one of the most capable AI models on Earth from your own code. Read it aloud to your partner.\n",
    "\n",
    "---\n",
    "## A helper function (with rate-limit protection)\n",
    "\n",
    "The free tier allows ~10 requests/minute. If the whole class hits the API at once you may see a `429` error — the helper below waits and retries automatically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 4 — helper with retry\n",
    "import time\n",
    "\n",
    "def ask(prompt, temperature=None, model=None):\n",
    "    \"\"\"Send a prompt to Gemini, retrying politely if we hit rate limits.\"\"\"\n",
    "    from google.genai import types\n",
    "    config = types.GenerateContentConfig(temperature=temperature) if temperature is not None else None\n",
    "    for attempt in range(4):\n",
    "        try:\n",
    "            r = client.models.generate_content(\n",
    "                model=model or MODEL, contents=prompt, config=config)\n",
    "            return r.text\n",
    "        except Exception as e:\n",
    "            if \"429\" in str(e) and attempt < 3:\n",
    "                wait = 20 * (attempt + 1)\n",
    "                print(f\"Rate limited — waiting {wait}s (attempt {attempt+1}/3)...\")\n",
    "                time.sleep(wait)\n",
    "            else:\n",
    "                raise\n",
    "print(\"Helper ready ✓\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part C — The five prompts\n",
    "\n",
    "Five core skills: explain, summarize, translate, extract, roleplay. Run the cell, read every output carefully."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 5 — five prompts\n",
    "prompts = {\n",
    "    \"1 · EXPLAIN\":   \"Explain how UPI works to a 10-year-old, in 5 sentences.\",\n",
    "    \"2 · SUMMARIZE\": \"Summarize the plot of Ponniyin Selvan in exactly 3 bullet points.\",\n",
    "    \"3 · TRANSLATE\": \"Translate to formal Tamil: 'The exam has been postponed to next Monday.'\",\n",
    "    \"4 · EXTRACT\":   \"Extract name, degree, year as JSON from: 'Hi, I'm Priya, third year BE CSE at TCE.'\",\n",
    "    \"5 · ROLEPLAY\":  \"You are a strict interviewer at a product company. Ask me one DSA question, then wait for my answer.\",\n",
    "}\n",
    "\n",
    "for label, p in prompts.items():\n",
    "    print(\"=\" * 70)\n",
    "    print(label, \"→\", p)\n",
    "    print(\"-\" * 70)\n",
    "    print(ask(p))\n",
    "    print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Your observations (edit this cell — double-click)\n",
    "\n",
    "One honest line per prompt: what was good, what was off?\n",
    "\n",
    "| # | Good | Off / surprising |\n",
    "|---|------|------------------|\n",
    "| 1 Explain | | |\n",
    "| 2 Summarize | | |\n",
    "| 3 Translate | *(ask a Tamil speaker: formal enough?)* | |\n",
    "| 4 Extract | *(valid JSON? extra text around it?)* | |\n",
    "| 5 Roleplay | | |\n",
    "\n",
    "### ✓ Checkpoint 2 — all five ran, five observations written.\n",
    "\n",
    "---\n",
    "## Part D — One prompt, three models\n",
    "\n",
    "Pick ONE prompt (from above, or your own). Run it here on Gemini, then paste the same text into:\n",
    "- **ChatGPT** → https://chatgpt.com\n",
    "- **One more**: Claude (https://claude.ai) / Copilot / Meta AI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cell 6 — your chosen prompt on Gemini\n",
    "my_prompt = \"Explain how UPI works to a 10-year-old, in 5 sentences.\"   # ← change me\n",
    "\n",
    "print(ask(my_prompt))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comparison table (edit this cell)\n",
    "\n",
    "| | Gemini (API) | ChatGPT | Third model: ______ |\n",
    "|---|---|---|---|\n",
    "| Length / format | | | |\n",
    "| Tone / personality | | | |\n",
    "| Accuracy issues? | | | |\n",
    "| Ship it to a user? | | | |\n",
    "\n",
    "**The one difference that surprised me most:** _______________\n",
    "\n",
    "### ✓ Checkpoint 3 — show the instructor your Gemini output + your surprise.\n",
    "\n",
    "---\n",
    "## Stretch goals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Stretch 1 — Temperature: robotic vs poetic\n",
    "p = \"Give a creative name for a new juice shop near TCE, one name only.\"\n",
    "\n",
    "print(\"--- temperature = 0.0 (three runs) ---\")\n",
    "for i in range(3):\n",
    "    print(f\"  run {i+1}:\", ask(p, temperature=0.0))\n",
    "\n",
    "print(\"--- temperature = 1.5 (three runs) ---\")\n",
    "for i in range(3):\n",
    "    print(f\"  run {i+1}:\", ask(p, temperature=1.5))\n",
    "\n",
    "# What do you notice? Which setting for a legal document? Which for a movie script?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Stretch 2 — Tamil stress test\n",
    "q_en = \"Who composed the music for the film 'Roja' and in which year was it released?\"\n",
    "q_ta = \"'ரோஜா' திரைப்படத்திற்கு இசையமைத்தவர் யார்? அது எந்த ஆண்டு வெளியானது?\"\n",
    "\n",
    "print(\"EN →\", ask(q_en))\n",
    "print()\n",
    "print(\"TA →\", ask(q_ta))\n",
    "\n",
    "# Same facts? Same quality? Same length?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Stretch 3 — Count tokens (remember the lecture demo?)\n",
    "en = \"The exam has been postponed to next Monday.\"\n",
    "ta = \"தேர்வு அடுத்த திங்கட்கிழமைக்கு ஒத்திவைக்கப்பட்டுள்ளது.\"\n",
    "\n",
    "for label, text in [(\"English\", en), (\"Tamil  \", ta)]:\n",
    "    n = client.models.count_tokens(model=MODEL, contents=text).total_tokens\n",
    "    print(f\"{label}: {n:3d} tokens ← {text}\")\n",
    "\n",
    "# Same meaning. Compare the counts — this is the tokenizer equity issue, measured by you."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### S4 · The 15-line language model (the lecture's counting demo)\n",
    "\n",
    "Remember *“those odds aren’t magic — you just count words”*? Here is that whole idea as runnable code. You **train** a next-word model by tallying, then **sample** sentences from it — the same three steps Gemini uses (read context → get a distribution → sample), except here step 2 is a table you can print, and “training” is pure counting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Stretch 4 — the whole idea in ~15 lines: a next-word model you can read.\n",
    "# Same three steps as Gemini (context -> distribution -> sample); \"trained\" by counting.\n",
    "import random\n",
    "from collections import defaultdict, Counter\n",
    "\n",
    "corpus = [\n",
    "    \"the build is failing again\",\n",
    "    \"the build is passing now\",\n",
    "    \"did you push the code\",\n",
    "    \"did you fix the bug\",\n",
    "    \"i think the code is fine\",\n",
    "]\n",
    "\n",
    "table = defaultdict(Counter)                 # \"training\" = tally which word follows which\n",
    "for msg in corpus:\n",
    "    words = [\"<start>\"] + msg.split() + [\"<end>\"]\n",
    "    for a, b in zip(words, words[1:]):\n",
    "        table[a][b] += 1\n",
    "\n",
    "def next_word(word):                         # read one row, roll weighted by the counts\n",
    "    choices = table[word]\n",
    "    return random.choices(list(choices), weights=list(choices.values()))[0]\n",
    "\n",
    "def generate():\n",
    "    word, out = \"<start>\", []\n",
    "    while (word := next_word(word)) != \"<end>\":\n",
    "        out.append(word)\n",
    "    return \" \".join(out)\n",
    "\n",
    "for _ in range(5):\n",
    "    print(generate())\n",
    "\n",
    "print(\"\\nThat's a language model. Gemini runs the same loop — but step 2 is a\")\n",
    "print(\"learned function over billions of parameters, not a table you can print.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part E — Build your test set (last 10 min)\n",
    "\n",
    "Sessions run back-to-back, so do this **now**:\n",
    "\n",
    "1. Pick a subject you know **cold** (DSA, cricket, cinema, your hometown — anything).\n",
    "2. Write **10 questions + correct answers** in a text file and keep it handy.\n",
    "3. That file becomes your test set in the very next session — the lie-detector lab.\n",
    "\n",
    "## Overnight (before Day 2 — 5 min)\n",
    "\n",
    "Day 2 = **chat with your own notes** (RAG). Put 2–3 real documents on your laptop or Drive: lecture notes, a textbook chapter PDF, anything you'd genuinely want to query.\n",
    "\n",
    "## Remember\n",
    "- Never share or commit your API key.\n",
    "- Free-tier data may be used by Google to improve products — don't paste anything private.\n",
    "- Rate limits: ~10 requests/min. The `ask()` helper handles the occasional 429.\n",
    "\n",
    "**You just did real AI engineering. Short break — then Session 2: catching AI lying, with numbers.**"
   ]
  }
 ]
}