{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ur8xi4C7S06n"
      },
      "outputs": [],
      "source": [
        "# Copyright 2024 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JAPoU8Sm5E6e"
      },
      "source": [
        "# Intro to Generating and Executing Python Code with Gemini 2.0\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fcode-execution%2Fintro_code_execution.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/code-execution/intro_code_execution.ipynb\">\n",
        "      <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/code-execution/intro_code_execution.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "84f0f73a0f76"
      },
      "source": [
        "| | |\n",
        "|-|-|\n",
        "| Author(s) |  [Kristopher Overholt](https://github.com/koverholt/) |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tvgnzT1CKxrO"
      },
      "source": [
        "## Overview\n",
        "\n",
        "This notebook introduces the code execution capabilities of the [Gemini 2.0 Flash model](https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2), a new multimodal generative AI model from Google [DeepMind](https://deepmind.google/). Gemini 2.0 Flash offers improvements in speed, quality, and advanced reasoning capabilities including enhanced understanding, coding, and instruction following.\n",
        "\n",
        "## Code Execution\n",
        "\n",
        "A key feature of this model is [code execution](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/code-execution), which is the ability to generate and execute Python code directly within the API. If you want the API to generate and run Python code and return the results, you can use code execution as demonstrated in this notebook.\n",
        "\n",
        "This code execution capability enables the model to generate code, execute and observe the results, correct the code if needed, and learn iteratively from the results until it produces a final output. This is particularly useful for applications that involve code-based reasoning such as solving mathematical equations or processing text.\n",
        "\n",
        "## Objectives\n",
        "\n",
        "In this tutorial, you will learn how to generate and execute code using the Gemini API in Vertex AI and the Google Gen AI SDK for Python with the Gemini 2.0 Flash model.\n",
        "\n",
        "You will complete the following tasks:\n",
        "\n",
        "- Generating and running sample Python code from text prompts\n",
        "- Exploring data using code execution in multi-turn chats\n",
        "- Using code execution in streaming sessions"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "61RBz8LLbxCR"
      },
      "source": [
        "## Getting started"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "No17Cw5hgx12"
      },
      "source": [
        "### Install Google Gen AI SDK for Python\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "tFy3H3aPgx12"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade --quiet google-genai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dmWOrTJ3gx13"
      },
      "source": [
        "### Authenticate your notebook environment (Colab only)\n",
        "\n",
        "If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "NyKGtVQjgx13"
      },
      "outputs": [],
      "source": [
        "import sys\n",
        "\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    auth.authenticate_user()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0fggiCx13zxX"
      },
      "source": [
        "### Import libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "JbrnA9yv3zMC"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "\n",
        "from IPython.display import Markdown, display\n",
        "from google import genai\n",
        "from google.genai.types import GenerateContentConfig, Tool, ToolCodeExecution"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vXiC1rOE3gSZ"
      },
      "source": [
        "### Connect to a generative AI API service\n",
        "\n",
        "Google Gen AI APIs and models including Gemini are available in the following two API services:\n",
        "\n",
        "- [Google AI for Developers](https://ai.google.dev/gemini-api/docs): Experiment, prototype, and deploy small projects.\n",
        "- [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs): Build enterprise-ready projects on Google Cloud.\n",
        "The Google Gen AI SDK provides a unified interface to these two API services.\n",
        "\n",
        "This notebook shows how to use the Google Gen AI SDK with the Gemini API in Vertex AI."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DF4l8DTdWgPY"
      },
      "source": [
        "### Set Google Cloud project information and create client\n",
        "\n",
        "To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
        "\n",
        "Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "Nqwi-5ufWp_B"
      },
      "outputs": [],
      "source": [
        "PROJECT_ID = \"[your-project-id]\"  # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
        "if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
        "    PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
        "\n",
        "LOCATION = os.environ.get(\"GOOGLE_CLOUD_REGION\", \"us-central1\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "3Ab5NQwr4B8j"
      },
      "outputs": [],
      "source": [
        "client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "x1vpnyk-q-fz"
      },
      "source": [
        "## Working with code execution in Gemini 2.0\n",
        "\n",
        "### Load the Gemini model\n",
        "\n",
        "The following code loads the Gemini 2.0 Flash model. You can learn about all Gemini models on Vertex AI by visiting the [documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models):"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "L8gLWcOFqqF2"
      },
      "outputs": [],
      "source": [
        "MODEL_ID = \"gemini-2.0-flash-001\"  # @param {type: \"string\"}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "q-jdBwXlM67j"
      },
      "source": [
        "### Define the code execution tool\n",
        "\n",
        "The following code initializes the code execution tool by passing `code_execution` in a `Tool` definition.\n",
        "\n",
        "Later we'll register this tool with the model that it can use to generate and run Python code:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "BFxIcGkxbq3_"
      },
      "outputs": [],
      "source": [
        "code_execution_tool = Tool(code_execution=ToolCodeExecution())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mZgn5tm-NCfH"
      },
      "source": [
        "### Generate and execute code\n",
        "\n",
        "The following code sends a prompt to the Gemini model, asking it to generate and execute Python code to calculate the sum of the first 50 prime numbers. The code execution tool is passed in so the model can generate and run the code:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "b52qMx0IGA0K"
      },
      "outputs": [],
      "source": [
        "PROMPT = \"\"\"What is the sum of the first 50 prime numbers?\n",
        "Generate and run code for the calculation.\"\"\"\n",
        "\n",
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=PROMPT,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=[code_execution_tool],\n",
        "        temperature=0,\n",
        "    ),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l-mfiMNasgqH"
      },
      "source": [
        "### View the generated code\n",
        "\n",
        "The following code iterates through the response and displays any generated Python code by checking for `part.executable_code` in the response parts:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "J5mcXw6ZraLS"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "\n",
              "```py\n",
              "\n",
              "def is_prime(n):\n",
              "    if n <= 1:\n",
              "        return False\n",
              "    if n <= 3:\n",
              "        return True\n",
              "    if n % 2 == 0 or n % 3 == 0:\n",
              "        return False\n",
              "    i = 5\n",
              "    while i * i <= n:\n",
              "        if n % i == 0 or n % (i + 2) == 0:\n",
              "            return False\n",
              "        i += 6\n",
              "    return True\n",
              "\n",
              "primes = []\n",
              "num = 2\n",
              "while len(primes) < 50:\n",
              "    if is_prime(num):\n",
              "        primes.append(num)\n",
              "    num += 1\n",
              "\n",
              "sum_of_primes = sum(primes)\n",
              "print(f'{sum_of_primes=}')\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "for part in response.candidates[0].content.parts:\n",
        "    if part.executable_code:\n",
        "        display(\n",
        "            Markdown(\n",
        "                f\"\"\"\n",
        "```py\n",
        "{part.executable_code.code}\n",
        "```\n",
        "\"\"\"\n",
        "            )\n",
        "        )"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ppumif-94xTF"
      },
      "source": [
        "### View the code execution results\n",
        "\n",
        "The following code iterates through the response and displays the execution result and outcome by checking for `part.code_execution_result` in the response parts:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "J891OBjc4xn9"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "`sum_of_primes=5117\n",
              "`"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Outcome: Outcome.OUTCOME_OK\n"
          ]
        }
      ],
      "source": [
        "for part in response.candidates[0].content.parts:\n",
        "    if part.code_execution_result:\n",
        "        display(Markdown(f\"`{part.code_execution_result.output}`\"))\n",
        "        print(\"\\nOutcome:\", part.code_execution_result.outcome)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5u_XuZlMnH9S"
      },
      "source": [
        "Great! Now you have the answer (`5117`) as well as the generated (and verified via execution!) Python code.\n",
        "\n",
        "At this point in your application, you would save the output code, result, or outcome and display it to the end-user or use it downstream in your application."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8uJ-Fk1I_AH8"
      },
      "source": [
        "### Code execution in a chat session\n",
        "\n",
        "This section shows how to use code execution in an interactive chat with history using the Gemini API.\n",
        "\n",
        "You can use `client.chats.create` to create a chat session and passes in the code execution tool, enabling the model to generate and run code:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "puL91bq7tirC"
      },
      "outputs": [],
      "source": [
        "chat = client.chats.create(\n",
        "    model=MODEL_ID,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=[code_execution_tool],\n",
        "        temperature=0,\n",
        "    ),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Bmu4bSApoECT"
      },
      "source": [
        "You'll start the chat by asking the model to generate sample time series data with noise and then output a sample of 10 data points:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "8iyq5sKCtstH"
      },
      "outputs": [],
      "source": [
        "PROMPT = \"\"\"Create sample time series data of temperature vs. time in a test furnace.\n",
        "Add noise to the data. Output a sample of 10 data points from the time series data.\"\"\"\n",
        "\n",
        "response = chat.send_message(PROMPT)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vVhCKKBioJga"
      },
      "source": [
        "Now you can iterate through the response to display any generated Python code and execution results by checking for `part.executable_code` and `part.code_execution_result` in the response parts:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "8pjwEGzft29N"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "\n",
              "```py\n",
              "\n",
              "import numpy as np\n",
              "import pandas as pd\n",
              "\n",
              "# Define time range (in hours)\n",
              "time = np.arange(0, 10)\n",
              "\n",
              "# Define base temperature profile (in Celsius)\n",
              "temperature = np.zeros(len(time))\n",
              "for i in range(len(time)):\n",
              "    if time[i] <= 5:\n",
              "        temperature[i] = 20 + 60 * time[i] / 5  # Linear heating from 20 to 80\n",
              "    elif time[i] <= 8:\n",
              "        temperature[i] = 80  # Constant temperature\n",
              "    else:\n",
              "        temperature[i] = 80 - 60 * (time[i] - 8) / 2  # Linear cooling from 80 to 20\n",
              "\n",
              "# Add noise (normal distribution with mean 0 and standard deviation 5)\n",
              "noise = np.random.normal(0, 5, len(time))\n",
              "temperature_noisy = temperature + noise\n",
              "\n",
              "# Create a Pandas DataFrame for better presentation\n",
              "data = pd.DataFrame({'Time (hours)': time, 'Temperature (Celsius)': temperature_noisy})\n",
              "\n",
              "# Output a sample of 10 data points\n",
              "print(data.sample(10))\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "`   Time (hours)  Temperature (Celsius)\n",
              "1             1              37.702092\n",
              "6             6              83.020622\n",
              "3             3              51.496619\n",
              "7             7              77.481004\n",
              "4             4              65.402154\n",
              "8             8              79.815473\n",
              "0             0              19.077681\n",
              "2             2              48.861174\n",
              "9             9              50.633805\n",
              "5             5              79.577297\n",
              "`"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Outcome: Outcome.OUTCOME_OK\n"
          ]
        }
      ],
      "source": [
        "for part in response.candidates[0].content.parts:\n",
        "    if part.executable_code:\n",
        "        display(\n",
        "            Markdown(\n",
        "                f\"\"\"\n",
        "```py\n",
        "{part.executable_code.code}\n",
        "```\n",
        "\"\"\"\n",
        "            )\n",
        "        )\n",
        "    if part.code_execution_result:\n",
        "        display(Markdown(f\"`{part.code_execution_result.output}`\"))\n",
        "        print(\"\\nOutcome:\", part.code_execution_result.outcome)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4AHoGmDBQuxn"
      },
      "source": [
        "Now you can ask the model to add a smoothed data series to the time series data:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "alR_tq3pss7j"
      },
      "outputs": [],
      "source": [
        "PROMPT = \"Now add a data series that smooths the sample data.\"\n",
        "\n",
        "response = chat.send_message(PROMPT)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MnSlnA5FQ9UH"
      },
      "source": [
        "And then display the generated Python code and execution results:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "uMXRpE0NtRYC"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "\n",
              "```py\n",
              "\n",
              "import numpy as np\n",
              "import pandas as pd\n",
              "\n",
              "# Define time range (in hours)\n",
              "time = np.arange(0, 10)\n",
              "\n",
              "# Define base temperature profile (in Celsius)\n",
              "temperature = np.zeros(len(time))\n",
              "for i in range(len(time)):\n",
              "    if time[i] <= 5:\n",
              "        temperature[i] = 20 + 60 * time[i] / 5  # Linear heating from 20 to 80\n",
              "    elif time[i] <= 8:\n",
              "        temperature[i] = 80  # Constant temperature\n",
              "    else:\n",
              "        temperature[i] = 80 - 60 * (time[i] - 8) / 2  # Linear cooling from 80 to 20\n",
              "\n",
              "# Add noise (normal distribution with mean 0 and standard deviation 5)\n",
              "noise = np.random.normal(0, 5, len(time))\n",
              "temperature_noisy = temperature + noise\n",
              "\n",
              "# Calculate moving average (window size = 3)\n",
              "window_size = 3\n",
              "temperature_smoothed = pd.Series(temperature_noisy).rolling(window=window_size, min_periods=1).mean()\n",
              "\n",
              "# Create a Pandas DataFrame for better presentation\n",
              "data = pd.DataFrame({'Time (hours)': time, 'Temperature (Celsius)': temperature_noisy, 'Temperature Smoothed (Celsius)': temperature_smoothed})\n",
              "\n",
              "# Output a sample of 10 data points\n",
              "print(data.sample(10))\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "`   Time (hours)  Temperature (Celsius)  Temperature Smoothed (Celsius)\n",
              "3             3              65.025977                       46.017601\n",
              "4             4              75.764042                       61.266254\n",
              "5             5              79.255920                       73.348646\n",
              "0             0              24.042592                       24.042592\n",
              "8             8              78.937537                       78.673018\n",
              "1             1              30.018085                       27.030339\n",
              "6             6              73.438907                       76.152957\n",
              "7             7              83.642608                       78.779145\n",
              "2             2              43.008742                       32.356473\n",
              "9             9              50.521038                       71.033728\n",
              "`"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Outcome: Outcome.OUTCOME_OK\n"
          ]
        }
      ],
      "source": [
        "for part in response.candidates[0].content.parts:\n",
        "    if part.executable_code:\n",
        "        display(\n",
        "            Markdown(\n",
        "                f\"\"\"\n",
        "```py\n",
        "{part.executable_code.code}\n",
        "```\n",
        "\"\"\"\n",
        "            )\n",
        "        )\n",
        "    if part.code_execution_result:\n",
        "        display(Markdown(f\"`{part.code_execution_result.output}`\"))\n",
        "        print(\"\\nOutcome:\", part.code_execution_result.outcome)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "I4VacTEyQ4lD"
      },
      "source": [
        "Finally, you can ask the model to generate descriptive statistics for the time series data:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "dmhPzmP8tywL"
      },
      "outputs": [],
      "source": [
        "PROMPT = \"Now generate and output descriptive statistics on the time series data.\"\n",
        "\n",
        "response = chat.send_message(PROMPT)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "I1t_zA5jRHsB"
      },
      "source": [
        "And then display the generated Python code and execution results:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "hIsMH3fPuKr5"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "\n",
              "```py\n",
              "\n",
              "import numpy as np\n",
              "import pandas as pd\n",
              "\n",
              "# Define time range (in hours)\n",
              "time = np.arange(0, 10)\n",
              "\n",
              "# Define base temperature profile (in Celsius)\n",
              "temperature = np.zeros(len(time))\n",
              "for i in range(len(time)):\n",
              "    if time[i] <= 5:\n",
              "        temperature[i] = 20 + 60 * time[i] / 5  # Linear heating from 20 to 80\n",
              "    elif time[i] <= 8:\n",
              "        temperature[i] = 80  # Constant temperature\n",
              "    else:\n",
              "        temperature[i] = 80 - 60 * (time[i] - 8) / 2  # Linear cooling from 80 to 20\n",
              "\n",
              "# Add noise (normal distribution with mean 0 and standard deviation 5)\n",
              "noise = np.random.normal(0, 5, len(time))\n",
              "temperature_noisy = temperature + noise\n",
              "\n",
              "# Calculate moving average (window size = 3)\n",
              "window_size = 3\n",
              "temperature_smoothed = pd.Series(temperature_noisy).rolling(window=window_size, min_periods=1).mean()\n",
              "\n",
              "# Create a Pandas DataFrame for better presentation\n",
              "data = pd.DataFrame({'Time (hours)': time, 'Temperature (Celsius)': temperature_noisy, 'Temperature Smoothed (Celsius)': temperature_smoothed})\n",
              "\n",
              "# Generate descriptive statistics\n",
              "descriptive_stats = data[['Temperature (Celsius)', 'Temperature Smoothed (Celsius)']].describe()\n",
              "\n",
              "# Output the descriptive statistics\n",
              "print(descriptive_stats)\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "`       Temperature (Celsius)  Temperature Smoothed (Celsius)\n",
              "count              10.000000                       10.000000\n",
              "mean               57.870155                       54.802199\n",
              "std                22.862738                       22.889574\n",
              "min                21.859841                       21.859841\n",
              "25%                38.573183                       33.414096\n",
              "50%                62.191952                       59.542733\n",
              "75%                76.884221                       76.168228\n",
              "max                84.971472                       80.844518\n",
              "`"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Outcome: Outcome.OUTCOME_OK\n"
          ]
        }
      ],
      "source": [
        "for part in response.candidates[0].content.parts:\n",
        "    if part.executable_code:\n",
        "        display(\n",
        "            Markdown(\n",
        "                f\"\"\"\n",
        "```py\n",
        "{part.executable_code.code}\n",
        "```\n",
        "\"\"\"\n",
        "            )\n",
        "        )\n",
        "    if part.code_execution_result:\n",
        "        display(Markdown(f\"`{part.code_execution_result.output}`\"))\n",
        "        print(\"\\nOutcome:\", part.code_execution_result.outcome)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TBbNyWtDRZto"
      },
      "source": [
        "This chat example demonstrates how you can use the Gemini API with code execution as a powerful tool for exploratory data analysis and more. Go forth and adapt this approach to your own projects and use cases!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Bl6KG5Ufu5XQ"
      },
      "source": [
        "### Code execution in a streaming session\n",
        "\n",
        "You can also use the code execution functionality with streaming output from the Gemini API.\n",
        "\n",
        "The following code demonstrates how the Gemini API can generate and execute code while streaming the results:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "gTNMMLkNu5JH"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "Okay"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              ", I can do that. Here's the process:\n",
              "\n",
              "1.  Generate"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              " a list of 20 random names. I'll use common English names for this"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              ".\n",
              "2.  Create a new list containing only the names from the first list that include the letter 'a' (case-insensitive).\n",
              "3."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "  Output the number of names in the new list.\n",
              "4.  Output the new list itself.\n",
              "\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Code stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "\n",
              "```py\n",
              "\n",
              "import random\n",
              "\n",
              "names = ['Alice', 'Bob', 'Charlie', 'David', 'Emily', 'Frank', 'Grace', 'Henry', 'Isabella', 'Jack', 'Kate', 'Liam', 'Mia', 'Noah', 'Olivia', 'Peter', 'Quinn', 'Ryan', 'Sophia', 'Thomas']\n",
              "\n",
              "names_with_a = [name for name in names if 'a' in name.lower()]\n",
              "\n",
              "count = len(names_with_a)\n",
              "\n",
              "print(f'{count=}')\n",
              "print(f'{names_with_a=}')\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Code result"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "\n",
              "```\n",
              "count=15\n",
              "names_with_a=['Alice', 'Charlie', 'David', 'Frank', 'Grace', 'Isabella', 'Jack', 'Kate', 'Liam', 'Mia', 'Noah', 'Olivia', 'Ryan', 'Sophia', 'Thomas']\n",
              "\n",
              "```\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "Here"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "'s the output:\n",
              "\n",
              "*   **Number of names containing 'a':** "
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "15\n",
              "*   **List of names containing 'a':** \\['Alice', '"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "Charlie', 'David', 'Frank', 'Grace', 'Isabella', 'Jack', 'Kate', 'Liam', 'Mia', 'Noah', 'Olivia"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "#### Natural language stream"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "', 'Ryan', 'Sophia', 'Thomas']"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": [
              "---"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "PROMPT = \"\"\"Generate a list of 20 random names, then create a new list with just\n",
        "the names containing the letter 'a', then output the number of names that\n",
        "contain 'a' and finally show me that new list.\"\"\"\n",
        "\n",
        "for chunk in client.models.generate_content_stream(\n",
        "    model=MODEL_ID,\n",
        "    contents=PROMPT,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=[code_execution_tool],\n",
        "        temperature=0,\n",
        "    ),\n",
        "):\n",
        "    if chunk.candidates and chunk.candidates[0].content:\n",
        "        if chunk.candidates[0].content.parts is not None:\n",
        "            for part in chunk.candidates[0].content.parts:\n",
        "                if part.text:\n",
        "                    display(Markdown(\"#### Natural language stream\"))\n",
        "                    display(Markdown(part.text))\n",
        "                    display(Markdown(\"---\"))\n",
        "                if part.executable_code:\n",
        "                    display(Markdown(\"#### Code stream\"))\n",
        "                    display(\n",
        "                        Markdown(\n",
        "                            f\"\"\"\n",
        "    ```py\n",
        "    {part.executable_code.code}\n",
        "    ```\n",
        "    \"\"\"\n",
        "                        )\n",
        "                    )\n",
        "                    display(Markdown(\"---\"))\n",
        "                if part.code_execution_result:\n",
        "                    display(Markdown(\"#### Code result\"))\n",
        "                    display(\n",
        "                        Markdown(\n",
        "                            f\"\"\"\n",
        "    ```\n",
        "    {part.code_execution_result.output}\n",
        "    ```\n",
        "    \"\"\"\n",
        "                        )\n",
        "                    )\n",
        "                    display(Markdown(\"---\"))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2a4e033321ad"
      },
      "source": [
        "This streaming example demonstrated how the Gemini API can generate, execute code, and provide results within a streaming session.\n",
        "\n",
        "## Summary\n",
        "\n",
        "Refer to the [documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/code-execution) for more details about code execution, and in particular, the [recommendations](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/code-execution#code-execution-vs-function-calling) regarding differences between code execution and [function calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling).\n",
        "\n",
        "### Next steps\n",
        "\n",
        "- See the [Google Gen AI SDK reference docs](https://googleapis.github.io/python-genai/)\n",
        "- Explore other notebooks in the [Google Cloud Generative AI GitHub repository](https://github.com/GoogleCloudPlatform/generative-ai)\n",
        "- Explore AI models in [Model Garden](https://cloud.google.com/vertex-ai/generative-ai/docs/model-garden/explore-models)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "YZNpgtKJDdPZ"
      ],
      "name": "intro_code_execution.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
