Skip to content

Prompts for Programmers

Prompt Engineering - Effective Prompts for Programmers

Section titled “Prompt Engineering - Effective Prompts for Programmers”

In this chapter, we will explore how programmers can leverage the power of Large Language Models (LLMs) like ChatGPT through effective prompt engineering. LLMs, with their natural language processing and code generation capabilities, can be an invaluable assistant for programmers to enhance productivity, tackle coding challenges, understand new concepts, and generate various code-related artifacts.

Programmers can prompt LLMs to generate code snippets, functions, classes, or even entire application scaffolds in various programming languages.

Example:

User: Write a Python function that takes a list of integers and returns a new list containing only the even numbers.
LLM:
```python
def get_even_numbers(numbers):
"""Takes a list of integers and returns a new list with only even numbers."""
even_numbers = []
for num in numbers:
if num % 2 == 0:
even_numbers.append(num)
return even_numbers
# Example usage:
# my_list = [1, 2, 3, 4, 5, 6]
# print(get_even_numbers(my_list)) # Output: [2, 4, 6]
### 2. Code Explanation and Understanding
LLMs can explain complex code snippets, algorithms, or programming concepts in natural language, aiding in learning and comprehension.
Example:
```css
User: Explain this JavaScript code to me like I'm a beginner:
`const sum = (a, b) => a + b;`
LLM: Certainly! Let's break down that JavaScript code:
* `const`: This keyword is used to declare a variable whose value will not be reassigned. Think of it as creating a container with a fixed label.
* `sum`: This is the name we're giving to our variable (our container). In this case, the variable will hold a function.
* `=`: This is the assignment operator. It means we're putting something into the `sum` container.
* `(a, b) => a + b;`: This is an arrow function, which is a concise way to write functions in JavaScript.
* `(a, b)`: These are the parameters of the function. When you use (or 'call') this function, you'll provide two values, which will be known as `a` and `b` inside the function.
* `=>`: This arrow separates the parameters from what the function does.
* `a + b`: This is the body of the function. It simply adds the value of `a` and the value of `b` together.
* Since it's a concise arrow function with no curly braces `{}`, the result of `a + b` is automatically returned by the function.
So, in simple terms, this code creates a function named `sum` that takes two numbers (`a` and `b`) as input and gives you back their sum.

3. Debugging and Troubleshooting Assistance

Section titled “3. Debugging and Troubleshooting Assistance”

Programmers can describe an error or paste problematic code and ask the LLM for potential causes, debugging tips, or solutions.

Example:

User: I'm getting a `TypeError: 'NoneType' object is not iterable` in my Python code. What could cause this?
This is the relevant part of my code:
```python
def get_user_data(user_id):
# Simulating a database call that might return None
if user_id == 0:
return None
return ["data1", "data2"]
user_info = get_user_data(0)
for item in user_info:
print(item)

LLM: The TypeError: 'NoneType' object is not iterable occurs because your get_user_data function is returning None when user_id is 0. Then, in the line for item in user_info:, you’re trying to loop (iterate) over user_info, which holds the value None.

None is a special value in Python representing the absence of a value, and it’s not something you can loop through like a list or string.

To fix this, you should check if user_info is None before trying to iterate over it:

def get_user_data(user_id):
if user_id == 0:
return None
return ["data1", "data2"]
user_info = get_user_data(0)
if user_info is not None:
for item in user_info:
print(item)
else:
print("No user data found.")

This way, you only attempt the loop if user_info actually contains data (a list in this case).

### 4. Code Refactoring and Optimization
LLMs can suggest improvements to existing code, making it more efficient, readable, or compliant with best practices.
Example:
```python
User: Can you help refactor this Python code to be more idiomatic or efficient?
```python
my_string = "hello world"
upper_case_string = ""
for char in my_string:
upper_case_string += char.upper()

LLM: Yes, that code can be made more Pythonic and efficient. Here are a couple of ways:

  1. Using str.upper() method directly: The simplest way is to call the .upper() method on the entire string:

    my_string = "hello world"
    upper_case_string = my_string.upper()
    # print(upper_case_string) # Output: HELLO WORLD
  2. Using a list comprehension and str.join() (more verbose for this case, but good for complex transformations): This is overkill for simple uppercasing but demonstrates a common pattern for more complex character-by-character transformations:

    my_string = "hello world"
    upper_case_string = "".join([char.upper() for char in my_string])
    # print(upper_case_string) # Output: HELLO WORLD

For just converting a string to uppercase, the first method (my_string.upper()) is the most direct and idiomatic Python approach.

### 5. Generating Documentation and Comments
Provide code and ask the LLM to generate docstrings, comments, or even README file sections.
### 6. Translating Code Between Languages
LLMs can assist in translating code from one programming language to another, though careful review is always needed.
### 7. Writing Unit Tests
Provide a function or class and ask the LLM to generate unit test cases for it using a specific testing framework.
### Best Practices for Programmers Using LLM Prompts
- Be Specific and Provide Context: Clearly state the programming language, libraries/frameworks involved, and the desired outcome. For code generation, describe the function's purpose, inputs, and outputs.
- Provide Code Snippets: When asking about existing code, include the relevant snippets.
- Iterate and Refine: If the first response isn't perfect, refine your prompt or ask follow-up questions.
- Specify Constraints: If you have constraints (e.g., 'use Python 3.8 features', 'avoid using external libraries'), mention them.
- Verify and Test: Always critically review and thoroughly test any code generated by an LLM before using it in production. LLMs can make mistakes.
- Break Down Complex Problems: For large tasks, break them into smaller, manageable pieces and prompt for each part.
### Example Application: Python Implementation (Using LLM for a Coding Question)
This Python script demonstrates how to use the OpenAI API to ask an LLM a programming-related question, such as how to implement an algorithm.
```python
import openai
import os
# Recommended: Set your API key via an environment variable.
# openai.api_key = os.getenv("OPENAI_API_KEY")
# For this tutorial, using a placeholder. Replace with your actual key.
openai.api_key = 'YOUR_API_KEY'
def get_coding_assistance(question, language="Python"):
prompt_content = (
f"I have a programming question regarding {language}.\n"
f"Question: {question}\n"
f"Please provide a clear explanation and a code example if applicable."
)
messages = [
{"role": "system", "content": "You are an expert programming assistant, skilled in explaining concepts and providing accurate code examples."},
{"role": "user", "content": prompt_content}
]
try:
response = openai.chat.completions.create(
model="gpt-3.5-turbo", # Or a newer model like gpt-4o-mini
messages=messages,
max_tokens=800, # Allow for detailed explanations and code
temperature=0.5, # Balance creativity and factualness
n=1,
stop=None
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"An error occurred: {e}"
# Example Usage:
programming_question = "How can I implement a binary search algorithm in Python? Write the code for it and explain how it works."
assistance = get_coding_assistance(programming_question, language="Python")
print("LLM Assistance:")
print(assistance)

The script would print the LLM’s response, which would typically include an explanation of binary search and a Python code implementation:

LLM Assistance:
Certainly! Binary search is an efficient algorithm for finding an item from a **sorted** list of items. It works by repeatedly dividing in half the portion of the list that could contain the item, until you've narrowed down the possible locations to just one.
Here's how it works conceptually:
1. Compare the target value to the middle element of the sorted list.
2. If the target value matches the middle element, its position is found.
3. If the target value is less than the middle element, then it can only lie in the lower half of the list. So, repeat the process for the lower half.
4. If the target value is greater than the middle element, then it can only lie in the upper half of the list. So, repeat the process for the upper half.
5. Continue this process until the element is found or the sublist becomes empty (meaning the element is not in the list).
Here's a Python implementation of binary search:
```python
def binary_search(sorted_list, target):
"""
Performs a binary search on a sorted list to find the target element.
Returns the index of the target if found, otherwise -1.
"""
low = 0
high = len(sorted_list) - 1
while low <= high:
mid = (low + high) // 2 # Find the middle index
if sorted_list[mid] == target:
return mid # Target found at index mid
elif sorted_list[mid] < target:
low = mid + 1 # Target is in the right half
else:
high = mid - 1 # Target is in the left half
return -1 # Target not found in the list
# Example Usage:
my_sorted_list = [2, 5, 7, 8, 11, 12, 15, 18]
target_element = 12
index = binary_search(my_sorted_list, target_element)
if index != -1:
print(f"Element {target_element} found at index {index}")
else:
print(f"Element {target_element} not found in the list.")
# Another example
target_element_not_present = 10
index_not_present = binary_search(my_sorted_list, target_element_not_present)
if index_not_present != -1:
print(f"Element {target_element_not_present} found at index {index_not_present}")
else:
print(f"Element {target_element_not_present} not found in the list.")

Key things to remember about binary search:

  • It must be used on a sorted list. If the list isn’t sorted, binary search won’t work correctly.
  • It’s very efficient, with a time complexity of O(log n), making it suitable for large datasets.
### Conclusion
In this chapter, we explored how programmers can effectively use LLMs like ChatGPT through strategic prompt engineering. From generating code and explanations to assisting with debugging, refactoring, and documentation, LLMs can significantly augment a programmer's capabilities.
By following best practices—being specific, providing context, iterating, and always verifying LLM-generated output—programmers can harness these AI tools to improve their workflow, learn faster, and boost their overall productivity.