{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# 🚀 Day 1: Guided Lab - Your First LLM Interactions with Gemini\n",
        "\n",
        "Welcome to your first hands-on session with Large Language Models!\n",
        "\n",
        "## Learning Objectives\n",
        "By the end of this lab, you will be able to:\n",
        "- ✅ Set up and use the Gemini API in Google Colab\n",
        "- ✅ Make API calls and understand the response structure\n",
        "- ✅ Experiment with parameters like temperature and max tokens\n",
        "- ✅ Build multi-turn conversations\n",
        "- ✅ Create a simple business application\n",
        "\n",
        "## Time: 90 minutes\n",
        "\n",
        "---\n",
        "\n",
        "## 🎯 Ground Rules for Working with LLMs\n",
        "\n",
        "Keep these principles in mind throughout the course:\n",
        "\n",
        "1. **If unsure, say so** - LLMs should acknowledge uncertainty, not make things up\n",
        "2. **Output format matters** - Always specify the format you need (especially JSON)\n",
        "3. **Don't invent facts** - LLMs should only use information provided in the input\n",
        "4. **Verify important outputs** - Always spot-check critical results\n",
        "\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Part 1: Setup (15 minutes)\n",
        "\n",
        "### 1.1 Install the Gemini SDK\n",
        "\n",
        "Run the cell below to install the Google GenAI package.\n",
        "\n",
        "> ⚠️ You may see a dependency warning about `google-auth` - this is safe to ignore."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "!pip -q install -U google-genai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.2 Load Your API Key\n",
        "\n",
        "Make sure you've added your `GEMINI_API_KEY` to Colab Secrets (🔑 icon in the left sidebar).\n",
        "\n",
        "The secret name must be exactly: `GEMINI_API_KEY`"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "import json\n",
        "import time\n",
        "from datetime import datetime, timezone\n",
        "from google import genai\n",
        "from google.genai import types\n",
        "\n",
        "# --- Load API key ---\n",
        "# Option A (recommended): Colab Secrets\n",
        "try:\n",
        "    from google.colab import userdata\n",
        "    os.environ[\"GEMINI_API_KEY\"] = userdata.get(\"GEMINI_API_KEY\")\n",
        "except Exception:\n",
        "    pass\n",
        "\n",
        "# Option B (fallback): hidden paste\n",
        "if not os.environ.get(\"GEMINI_API_KEY\"):\n",
        "    import getpass\n",
        "    os.environ[\"GEMINI_API_KEY\"] = getpass.getpass(\"Paste your GEMINI_API_KEY (input hidden): \")\n",
        "\n",
        "# Verify\n",
        "if os.environ.get(\"GEMINI_API_KEY\"):\n",
        "    print(\"✅ API key loaded successfully!\")\n",
        "else:\n",
        "    print(\"❌ API key not found. Check your Colab Secrets.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.3 Initialize Client and Helper Functions\n",
        "\n",
        "We'll set up:\n",
        "1. The Gemini client\n",
        "2. A **prompt log** to track all our API calls (useful for learning!)\n",
        "3. Helper functions we'll use throughout the course"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Initialize the client\n",
        "client = genai.Client()\n",
        "\n",
        "# Model configuration\n",
        "MODEL_ID = \"gemini-2.0-flash-lite\"  # Fast and free-tier friendly\n",
        "\n",
        "# --- Prompt Logging ---\n",
        "# This helps you track what you tried and what worked\n",
        "PROMPT_LOG = []\n",
        "\n",
        "def _now():\n",
        "    \"\"\"Get current timestamp.\"\"\"\n",
        "    return datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z')\n",
        "\n",
        "def generate(prompt, temperature=0.7, max_tokens=500, log=True):\n",
        "    \"\"\"\n",
        "    Generate text using Gemini with customizable parameters.\n",
        "    Automatically logs all calls for later review.\n",
        "\n",
        "    Args:\n",
        "        prompt (str): The input prompt\n",
        "        temperature (float): Creativity level (0.0 to 2.0)\n",
        "        max_tokens (int): Maximum output length\n",
        "        log (bool): Whether to log this call\n",
        "\n",
        "    Returns:\n",
        "        str: The generated text\n",
        "    \"\"\"\n",
        "    t0 = time.time()\n",
        "\n",
        "    response = client.models.generate_content(\n",
        "        model=MODEL_ID,\n",
        "        contents=prompt,\n",
        "        config=types.GenerateContentConfig(\n",
        "            temperature=temperature,\n",
        "            max_output_tokens=max_tokens\n",
        "        )\n",
        "    )\n",
        "\n",
        "    text = response.text or \"\"\n",
        "    latency = time.time() - t0\n",
        "\n",
        "    # Log the call\n",
        "    if log:\n",
        "        PROMPT_LOG.append({\n",
        "            \"ts\": _now(),\n",
        "            \"model\": MODEL_ID,\n",
        "            \"temperature\": temperature,\n",
        "            \"max_tokens\": max_tokens,\n",
        "            \"prompt\": prompt,\n",
        "            \"output\": text,\n",
        "            \"latency_s\": round(latency, 3)\n",
        "        })\n",
        "\n",
        "    return text\n",
        "\n",
        "def try_parse_json(text):\n",
        "    \"\"\"\n",
        "    Attempt to parse JSON from LLM output.\n",
        "    Returns (success: bool, parsed_data: dict/list or None)\n",
        "    \"\"\"\n",
        "    # Try direct parse\n",
        "    try:\n",
        "        return True, json.loads(text)\n",
        "    except json.JSONDecodeError:\n",
        "        pass\n",
        "\n",
        "    # Try to extract JSON from markdown code blocks\n",
        "    import re\n",
        "    json_match = re.search(r'```(?:json)?\\s*([\\s\\S]*?)```', text)\n",
        "    if json_match:\n",
        "        try:\n",
        "            return True, json.loads(json_match.group(1))\n",
        "        except json.JSONDecodeError:\n",
        "            pass\n",
        "\n",
        "    # Try to find JSON object/array in text\n",
        "    json_match = re.search(r'[\\[\\{][\\s\\S]*[\\]\\}]', text)\n",
        "    if json_match:\n",
        "        try:\n",
        "            return True, json.loads(json_match.group())\n",
        "        except json.JSONDecodeError:\n",
        "            pass\n",
        "\n",
        "    return False, None\n",
        "\n",
        "def show_log(n=3):\n",
        "    \"\"\"Display the last n entries from the prompt log.\"\"\"\n",
        "    for row in PROMPT_LOG[-n:]:\n",
        "        print(\"=\" * 70)\n",
        "        print(f\"Time: {row['ts']} | Temp: {row['temperature']} | Latency: {row['latency_s']}s\")\n",
        "        print(\"--- PROMPT (first 500 chars) ---\")\n",
        "        print(row[\"prompt\"][:500])\n",
        "        print(\"--- OUTPUT (first 500 chars) ---\")\n",
        "        print(row[\"output\"][:500])\n",
        "\n",
        "print(f\"✅ Client initialized! Using model: {MODEL_ID}\")\n",
        "print(f\"📝 Prompt logging enabled. Use show_log() to review your calls.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.4 Test Your Connection\n",
        "\n",
        "Let's make sure everything works with a simple test."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Simple test call\n",
        "response = generate(\n",
        "    \"Say 'Hello, I am ready to learn!' in a friendly way.\",\n",
        "    temperature=0.7\n",
        ")\n",
        "\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "🎉 **If you see a friendly greeting above, you're all set!**\n",
        "\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Part 2: Basic Text Generation (15 minutes)\n",
        "\n",
        "### 2.1 Your First Business Prompt\n",
        "\n",
        "Let's generate a product description - a common business use case."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Simple product description\n",
        "prompt = \"Write a product description for wireless noise-canceling headphones in 2-3 sentences.\"\n",
        "\n",
        "response = generate(prompt)\n",
        "\n",
        "print(\"Generated Description:\")\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.2 Run It Multiple Times\n",
        "\n",
        "Run the cell below multiple times. Notice how the output varies each time!\n",
        "\n",
        "This is because LLMs are **probabilistic** - they don't always give the same answer."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Run this cell 3-4 times and observe the different outputs\n",
        "response = generate(\n",
        "    \"Suggest a creative name for a new coffee shop.\",\n",
        "    temperature=0.9  # Higher temperature = more variety\n",
        ")\n",
        "\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.3 Understanding the Response Object\n",
        "\n",
        "Let's look at more details from the API response, including token usage."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Make a call and examine the full response\n",
        "full_response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=\"What are three benefits of cloud computing for small businesses?\"\n",
        ")\n",
        "\n",
        "# The main text output\n",
        "print(\"=== Response Text ===\")\n",
        "print(full_response.text)\n",
        "\n",
        "# Usage statistics (tokens used)\n",
        "print(\"\\n=== Usage Statistics ===\")\n",
        "print(f\"Input tokens: {full_response.usage_metadata.prompt_token_count}\")\n",
        "print(f\"Output tokens: {full_response.usage_metadata.candidates_token_count}\")\n",
        "print(f\"Total tokens: {full_response.usage_metadata.total_token_count}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "💡 **Why tokens matter:**\n",
        "- API pricing is based on tokens\n",
        "- There are limits on input and output tokens\n",
        "- 1 token ≈ 4 characters or ¾ of a word in English\n",
        "\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Part 3: Exploring Parameters (15 minutes)\n",
        "\n",
        "### 3.1 Temperature: Controlling Creativity\n",
        "\n",
        "**Temperature** controls how \"creative\" or \"random\" the output is:\n",
        "- `temperature=0.0` → Deterministic, consistent outputs\n",
        "- `temperature=1.0` → More creative, varied outputs\n",
        "- `temperature=2.0` → Very random (often too chaotic)\n",
        "\n",
        "Let's see this in action!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "prompt = \"Suggest a name for a new smartphone app that helps people track their fitness goals.\"\n",
        "\n",
        "print(\"=\" * 50)\n",
        "print(\"TEMPERATURE = 0.0 (Deterministic)\")\n",
        "print(\"Running 3 times - outputs should be very similar:\")\n",
        "print(\"=\" * 50)\n",
        "\n",
        "for i in range(3):\n",
        "    response = generate(prompt, temperature=0.0)\n",
        "    print(f\"Run {i+1}: {response.strip()[:300]}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "print(\"=\" * 50)\n",
        "print(\"TEMPERATURE = 1.0 (Creative)\")\n",
        "print(\"Running 3 times - outputs should be different:\")\n",
        "print(\"=\" * 50)\n",
        "\n",
        "for i in range(3):\n",
        "    response = generate(prompt, temperature=1.0)\n",
        "    print(f\"Run {i+1}: {response.strip()[:300]}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 💭 Discussion Question\n",
        "\n",
        "**When would you use low temperature vs high temperature in a business context?**\n",
        "\n",
        "- Low temperature (0.0-0.3): _______________________\n",
        "- High temperature (0.7-1.0): _______________________"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.2 Max Output Tokens: Controlling Length\n",
        "\n",
        "You can limit how long the response should be."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "prompt = \"Explain the concept of machine learning to a business executive.\"\n",
        "\n",
        "# Short response (max 50 tokens)\n",
        "print(\"=== SHORT (max 50 tokens) ===\")\n",
        "response_short = generate(prompt, max_tokens=50)\n",
        "print(response_short)\n",
        "\n",
        "# Check actual length from log\n",
        "print(f\"\\n(Check the log for actual token count)\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Longer response (max 200 tokens)\n",
        "print(\"=== LONGER (max 200 tokens) ===\")\n",
        "response_long = generate(prompt, max_tokens=200)\n",
        "print(response_long)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.3 Review Your Prompt Log\n",
        "\n",
        "Let's see what we've tried so far!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# See how many calls we've made\n",
        "print(f\"Total API calls so far: {len(PROMPT_LOG)}\")\n",
        "\n",
        "# Show the last 3 calls\n",
        "show_log(3)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Part 4: Multi-turn Conversations (15 minutes)\n",
        "\n",
        "LLMs can maintain context across multiple exchanges, just like a real conversation.\n",
        "\n",
        "### 4.1 Starting a Chat Session"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create a chat session\n",
        "chat = client.chats.create(model=MODEL_ID)\n",
        "\n",
        "# First message\n",
        "response1 = chat.send_message(\"Hi! I'm looking for a laptop for video editing. What should I consider?\")\n",
        "print(\"User: Hi! I'm looking for a laptop for video editing. What should I consider?\")\n",
        "print(f\"\\nAssistant: {response1.text}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Follow-up message - the model remembers the context!\n",
        "response2 = chat.send_message(\"My budget is around $1500. Any specific recommendations?\")\n",
        "print(\"User: My budget is around $1500. Any specific recommendations?\")\n",
        "print(f\"\\nAssistant: {response2.text}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Another follow-up\n",
        "response3 = chat.send_message(\"What about battery life? I travel a lot.\")\n",
        "print(\"User: What about battery life? I travel a lot.\")\n",
        "print(f\"\\nAssistant: {response3.text}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 4.2 View Chat History\n",
        "\n",
        "You can access the full conversation history."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# View the conversation history\n",
        "print(\"=== Full Chat History ===\")\n",
        "for i, message in enumerate(chat._curated_history):\n",
        "    role = \"👤 User\" if message.role == \"user\" else \"🤖 Assistant\"\n",
        "    text = message.parts[0].text if message.parts else \"\"\n",
        "    preview = text[:150] + \"...\" if len(text) > 150 else text\n",
        "    print(f\"\\n{role}: {preview}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 💭 Discussion Question\n",
        "\n",
        "**How might multi-turn conversations be useful in a business application?**\n",
        "\n",
        "Think of 2-3 examples: _______________________\n",
        "\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Part 5: Business Application - Email Response Generator (15 minutes)\n",
        "\n",
        "Let's build something practical: a customer service email response generator.\n",
        "\n",
        "### 5.1 Basic Email Response"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def generate_email_response(customer_email, company_name=\"TechCorp\", tone=\"professional\"):\n",
        "    \"\"\"\n",
        "    Generate a customer service response to an email.\n",
        "\n",
        "    Args:\n",
        "        customer_email (str): The customer's email content\n",
        "        company_name (str): Your company name\n",
        "        tone (str): Response tone (professional, friendly, formal)\n",
        "\n",
        "    Returns:\n",
        "        str: Generated email response\n",
        "    \"\"\"\n",
        "    prompt = f\"\"\"You are a customer service representative for {company_name}.\n",
        "Write a {tone} response to this customer email.\n",
        "\n",
        "Customer Email:\n",
        "---\n",
        "{customer_email}\n",
        "---\n",
        "\n",
        "Requirements:\n",
        "- Acknowledge their concern empathetically\n",
        "- Provide a clear solution or next steps\n",
        "- Keep the response under 150 words\n",
        "- End with a positive note\n",
        "- Do not invent facts not present in the email\n",
        "\n",
        "Response:\"\"\"\n",
        "\n",
        "    return generate(prompt, temperature=0.3)  # Low temperature for consistency\n",
        "\n",
        "\n",
        "# Test with a sample email\n",
        "sample_email = \"\"\"\n",
        "Hi,\n",
        "\n",
        "I ordered a laptop last week (Order #12345) and it arrived today with a cracked screen.\n",
        "This is really frustrating as I needed it for an important presentation tomorrow.\n",
        "\n",
        "What can you do about this?\n",
        "\n",
        "Thanks,\n",
        "John\n",
        "\"\"\"\n",
        "\n",
        "response = generate_email_response(sample_email)\n",
        "print(\"Generated Response:\")\n",
        "print(response)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 5.2 Try Different Tones"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Same email, different tones\n",
        "print(\"=== PROFESSIONAL TONE ===\")\n",
        "print(generate_email_response(sample_email, tone=\"professional\"))\n",
        "\n",
        "print(\"\\n\" + \"=\"*50 + \"\\n\")\n",
        "\n",
        "print(\"=== FRIENDLY TONE ===\")\n",
        "print(generate_email_response(sample_email, tone=\"friendly and warm\"))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 5.3 Meeting Summary Generator\n",
        "\n",
        "Another common business use case: summarizing meeting notes."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def summarize_meeting(transcript):\n",
        "    \"\"\"\n",
        "    Summarize a meeting transcript into key points and action items.\n",
        "    \"\"\"\n",
        "    prompt = f\"\"\"Summarize the following meeting transcript.\n",
        "\n",
        "Provide:\n",
        "1. A 2-3 sentence summary\n",
        "2. Key decisions made (bullet points)\n",
        "3. Action items with owners (if mentioned)\n",
        "\n",
        "Rules:\n",
        "- Only include information from the transcript\n",
        "- If owner/deadline not mentioned, write \"Not specified\"\n",
        "- Be concise\n",
        "\n",
        "Meeting Transcript:\n",
        "---\n",
        "{transcript}\n",
        "---\n",
        "\n",
        "Summary:\"\"\"\n",
        "\n",
        "    return generate(prompt, temperature=0.2)\n",
        "\n",
        "\n",
        "# Sample meeting transcript\n",
        "meeting_transcript = \"\"\"\n",
        "Sarah: Okay everyone, let's discuss the Q2 marketing budget.\n",
        "\n",
        "Mike: I think we should increase social media spending by 20%. Our Instagram campaigns\n",
        "have been performing really well.\n",
        "\n",
        "Sarah: Good point. What about the trade show in March?\n",
        "\n",
        "Lisa: The trade show costs about $15,000. I think it's worth it for the leads we get.\n",
        "Last year we got 50 qualified leads from it.\n",
        "\n",
        "Mike: Agreed. Let's keep the trade show budget.\n",
        "\n",
        "Sarah: Alright, so we'll increase social media by 20% and maintain trade show spending.\n",
        "Mike, can you prepare a detailed social media plan by Friday?\n",
        "\n",
        "Mike: Sure, I'll have it ready.\n",
        "\n",
        "Sarah: Lisa, please confirm our trade show registration.\n",
        "\n",
        "Lisa: Will do, I'll handle it this week.\n",
        "\n",
        "Sarah: Great, let's reconvene next Tuesday to finalize everything.\n",
        "\"\"\"\n",
        "\n",
        "summary = summarize_meeting(meeting_transcript)\n",
        "print(\"Meeting Summary:\")\n",
        "print(summary)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 5.4 Testing JSON Output (Preview of Day 2)\n",
        "\n",
        "Sometimes you need structured data, not just text. Let's try getting JSON output."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Request JSON output\n",
        "json_prompt = \"\"\"Extract action items from this meeting note. Return JSON ONLY.\n",
        "\n",
        "Meeting note: \"Mike will prepare social media plan by Friday. Lisa will confirm trade show registration this week.\"\n",
        "\n",
        "Schema:\n",
        "[\n",
        "  {\"owner\": \"name\", \"task\": \"description\", \"deadline\": \"when\"}\n",
        "]\n",
        "\n",
        "JSON:\"\"\"\n",
        "\n",
        "response = generate(json_prompt, temperature=0.0)\n",
        "print(\"Raw output:\")\n",
        "print(response)\n",
        "\n",
        "# Try to parse it\n",
        "success, parsed = try_parse_json(response)\n",
        "print(f\"\\nValid JSON? {success}\")\n",
        "if success:\n",
        "    print(\"Parsed data:\")\n",
        "    for item in parsed:\n",
        "        print(f\"  - {item}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Part 6: Wrap-up (15 minutes)\n",
        "\n",
        "### 6.1 Export Your Prompt Log\n",
        "\n",
        "Save a record of everything you tried today!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import pandas as pd\n",
        "\n",
        "# Convert log to DataFrame\n",
        "df = pd.DataFrame(PROMPT_LOG)\n",
        "\n",
        "# Save to CSV\n",
        "df.to_csv(\"day1_guided_lab_prompt_log.csv\", index=False)\n",
        "print(f\"✅ Saved {len(df)} prompts to: day1_guided_lab_prompt_log.csv\")\n",
        "\n",
        "# Show summary\n",
        "print(f\"\\n📊 Session Summary:\")\n",
        "print(f\"   Total API calls: {len(df)}\")\n",
        "print(f\"   Average latency: {df['latency_s'].mean():.2f}s\")\n",
        "print(f\"   Temperature range: {df['temperature'].min()} - {df['temperature'].max()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 6.2 Key Takeaways\n",
        "\n",
        "**What we learned today:**\n",
        "\n",
        "1. **API Basics**: You can interact with LLMs through simple API calls\n",
        "2. **Parameters Matter**: Temperature and max tokens control output behavior\n",
        "3. **Conversations**: LLMs can maintain context across multiple turns\n",
        "4. **Business Value**: Even simple prompts can automate useful tasks\n",
        "5. **Logging Helps**: Tracking your prompts helps you learn what works\n",
        "\n",
        "### 6.3 Reflection Questions\n",
        "\n",
        "Before moving to the independent lab, discuss with a partner:\n",
        "\n",
        "1. What surprised you most about working with LLMs?\n",
        "2. What limitations did you notice?\n",
        "3. What business process in your experience could benefit from this technology?\n",
        "\n",
        "---\n",
        "\n",
        "## 🎯 Ready for the Independent Lab!\n",
        "\n",
        "In the next session, you'll work independently (or with a partner) to:\n",
        "- Build a content generation suite\n",
        "- Create text transformation tools\n",
        "- Develop an interactive Q&A system\n",
        "\n",
        "**Save this notebook** - you'll reuse the helper functions!"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
