This notebook demonstrates how to use prompting to perform basic code generation using the Gemini API’s JS SDK. Two use cases are explored: error handling and code generation.
The Gemini API can be a great tool to save you time during the development process. Tasks such as code generation, debugging, or optimization can be done with the assistance of the Gemini model.
You can create your API key using Google AI Studio with a single click.
Remember to treat your API key like a password. Don’t accidentally save it in a notebook or source file you later commit to GitHub. In this notebook we will be storing the API key in a .env file. You can also set it as an environment variable or use a secret manager.
Another option is to set the API key as an environment variable. You can do this in your terminal with the following command:
$ export GEMINI_API_KEY="<YOUR_API_KEY>"
Load the API key
To load the API key from the .env file, we will use the dotenv package. This package loads environment variables from a .env file into process.env.
$ npm install dotenv
Then, we can load the API key in our code:
const dotenv =require("dotenv") astypeofimport("dotenv");dotenv.config({ path:"../../.env",});const GEMINI_API_KEY =process.env.GEMINI_API_KEY??"";if (!GEMINI_API_KEY) {thrownewError("GEMINI_API_KEY is not set in the environment variables");}console.log("GEMINI_API_KEY is set in the environment variables");
GEMINI_API_KEY is set in the environment variables
Note
In our particular case the .env is is two directories up from the notebook, hence we need to use ../../ to go up two directories. If the .env file is in the same directory as the notebook, you can omit it altogether.
With the new SDK, now you only need to initialize a client with you API key (or OAuth if using Vertex AI). The model is now set in each call.
const google =require("@google/genai") astypeofimport("@google/genai");const ai =new google.GoogleGenAI({ apiKey: GEMINI_API_KEY });
Select a model
Now select the model you want to use in this guide, either by selecting one in the list or writing it down. Keep in mind that some models, like the 2.5 ones are thinking models and thus take slightly more time to respond (cf. thinking notebook for more details and in particular learn how to switch the thiking off).
For code generation, you should prioritize accuracy over creativity. A temperature of 0 ensures that the generated content is deterministic, producing the most sensible output every time.
const ERROR_HANDLING_SYSTEM_PROMPT =` Your task is to explain exactly why this error occurred and how to fix it.`;const errorPrompt = (message:string) =>` You've encountered the following error message: Error: ${message}`;
const error_message =` 1 my_list = [1,2,3] ----> 2 print(my_list[3]) IndexError: list index out of range`;const error_response =await ai.models.generateContent({ model: MODEL_ID, contents:errorPrompt(error_message), config: { temperature:0, systemInstruction: ERROR_HANDLING_SYSTEM_PROMPT, },});tslab.display.markdown(error_response.text??"");
This error, IndexError: list index out of range, is one of the most common errors when working with lists (or other sequence types like strings and tuples) in Python.
Let’s break down exactly why it occurred and how to fix it.
Understanding the Error: IndexError: list index out of range
What is an Index? In Python, elements in a list are stored in a specific order. Each element has a numerical position, called an “index,” which allows you to access it directly.
Zero-Based Indexing: The most crucial concept here is that Python (like many other programming languages) uses zero-based indexing. This means:
The first element is at index 0.
The second element is at index 1.
The third element is at index 2.
And so on…
Analyzing Your Code: You have the list: my_list = [1, 2, 3]
Let’s map the elements to their indices:
1 is at my_list[0]
2 is at my_list[1]
3 is at my_list[2]
Your code then tries to access print(my_list[3]).
The Problem: Since the list my_list only has three elements, its valid indices are 0, 1, and 2. There is no element at index 3. When you try to access an index that doesn’t exist within the list’s boundaries, Python raises an IndexError because the index is “out of range.”
How to Fix It
The fix depends on what you were trying to achieve:
Scenario 1: You wanted to access the last element
If you intended to get the last element (3 in this case), you have a couple of common ways:
Option A: Using len() (Length of the list) The length of my_list is 3. Since indexing is zero-based, the last element’s index is always len(list) - 1.
my_list = [1, 2, 3]# The length of my_list is 3.# The last valid index is 3 - 1 = 2.print(my_list[len(my_list) -1])# Output: 3
Option B: Using Negative Indexing (Recommended for last element) Python allows you to use negative indices to count from the end of the list: * -1 refers to the last element. * -2 refers to the second-to-last element. * And so on…
my_list = [1, 2, 3]print(my_list[-1])# Output: 3
Scenario 2: You wanted to access a specific existing element
If you simply made a mistake in the index number and wanted to access, say, the first, second, or third element:
my_list = [1, 2, 3]# To access the first element (which is 1):print(my_list[0])# Output: 1# To access the second element (which is 2):print(my_list[1])# Output: 2# To access the third element (which is 3):print(my_list[2])# Output: 3
Scenario 3: You’re iterating or accessing elements dynamically
If you’re working with lists whose size might change, or you’re looping, it’s good practice to check if an index is valid before trying to access it:
my_list = [1, 2, 3]index_to_access =3# This would cause the errorif index_to_access <len(my_list):print(my_list[index_to_access])else:print(f"Error: Index {index_to_access} is out of range for a list of size {len(my_list)}")# Output: Error: Index 3 is out of range for a list of size 3
Best Practices to Avoid This Error
Always Remember Zero-Based Indexing: This is fundamental.
Use len() for Bounds Checking: When you need to know the size or iterate up to the last element, len(my_list) is your friend.
Prefer Negative Indexing for End Elements:my_list[-1] is much cleaner than my_list[len(my_list) - 1].
Iterate Safely:
If you just need the items: for item in my_list:
If you need items and their indices: for index, item in enumerate(my_list): These methods automatically handle the bounds for you.
Error Handling (Advanced): For robust applications, you can use try-except blocks to gracefully handle IndexError if you anticipate it might occur due to external input or unpredictable data.
my_list = [1, 2, 3]user_input_index =5# Imagine this came from user inputtry:print(my_list[user_input_index])exceptIndexError:print(f"Sorry, the index {user_input_index} is not valid for this list. Valid indices are 0 to {len(my_list) -1}.")# Output: Sorry, the index 5 is not valid for this list. Valid indices are 0 to 2.
Code generation
const CODE_GENERATION_SYSTEM_PROMPT =` You are a coding assistant. Your task is to generate a code snippet that accomplishes a specific goal. The code snippet must be concise, efficient, and well-commented for clarity. Consider any constraints or requirements provided for the task. If the task does not specify a programming language, default to Python.`;
const code_response =await ai.models.generateContent({ model: MODEL_ID, contents:` Create a countdown timer that ticks down every second and prints "Time is up!" after 20 seconds Language: JavaScript `, config: { temperature:0, systemInstruction: CODE_GENERATION_SYSTEM_PROMPT, },});tslab.display.markdown(code_response.text??"");
/** * Creates a countdown timer that ticks down every second. * Prints the remaining time and "Time is up!" when it reaches zero. */functionstartCountdown() {let seconds =20;// Initial countdown time in seconds// Display initial time immediatelyconsole.log(`Time remaining: ${seconds} seconds`);// Set up an interval to run every 1000 milliseconds (1 second)const timerInterval =setInterval(() => { seconds--;// Decrement the timeif (seconds >0) {// If time is still remaining, print itconsole.log(`Time remaining: ${seconds} seconds`); } else {// If time is up, print the final message and clear the intervalconsole.log("Time is up!");clearInterval(timerInterval);// Stop the timer } },1000);// 1000 milliseconds = 1 second}// Start the countdown when the script runsstartCountdown();
const matchFound =/```javascript\n([\s\S]*?)```/.exec(code_response.text??"");if (matchFound) {const code = matchFound[1];// eslint-disable-next-line no-evaleval(code);} else {console.error("No JavaScript code found in the response");}
Time remaining: 20 seconds
Time remaining: 19 seconds
Time remaining: 18 seconds
Time remaining: 17 seconds
Time remaining: 16 seconds
Time remaining: 15 seconds
Time remaining: 14 seconds
Time remaining: 13 seconds
Time remaining: 12 seconds
Time remaining: 11 seconds
Time remaining: 10 seconds
Time remaining: 9 seconds
Time remaining: 8 seconds
Time remaining: 7 seconds
Time remaining: 6 seconds
Time remaining: 5 seconds
Time remaining: 4 seconds
Time remaining: 3 seconds
Time remaining: 2 seconds
Time remaining: 1 seconds
Time is up!
Next steps
Be sure to explore other examples of prompting in the repository. Try writing prompts around your own code as well using the examples in this notebook.