Working with Artificial Intelligence Series: Co-Coding with AI
In the current era of remarkable technological advancement, a standout development has been the emergence of generative artificial intelligence (generative AI). This specific subset of AI generates new content to answer almost any request. All it needs from its user is a few words of text.
Each instalment in the Working with Artificial Intelligence Series delves into a specific use case, illustrating how generative AI can be effectively used in various scenarios. We investigate the most suitable tools for each task, reveal the most effective prompts, and share insider tricks to speed up the journey from input to ideal output.
Remember that when using AI tools, especially generative ones like ChatGPT, it is vital to adhere to best practices. We recommend reviewing and following the Government of Canada's Guide on the use of Generative AI to ensure responsible and ethical use of these technologies.
This article explores the role of generative AI in programming and will cover:
- enhancing programming efficiency with generative AI
- using generative AI as a collaborative tool for programming tasks
- ensuring the ethical and responsible use of generative AI
Your new AI-powered collaborator
Software development prioritizes efficiency, innovation, and secure and reliable code. It is therefore constantly evolving. Over the past few months, generative AI has become a transformative force in this space. Among its offerings are large language models (LLMs), which are trained to understand programming languages and assist in generating code. These AI tools excel in offering suggestions, finding and fixing bugs, and providing insights for code optimization.
However, LLMs are not stand-alone solutions. They do not have the capacity to independently handle all aspects of software development. Instead, they should be viewed as supports or co-developers, working closely with human developers. While developers bring critical thinking, creativity, and nuanced understanding to the table, generative AI tools bring speed, vast data processing capabilities, and pattern recognition.
Although this article focuses on OpenAI's ChatGPT, most of the techniques and approaches can still be applied to other LLM-based tools.
How did ChatGPT learn how to code?
Unlike a human developer, who understands and writes code based on their knowledge and experience, ChatGPT generates code by leveraging patterns it has learned from a vast dataset of programming-related text during its training. Saying a "vast dataset" may not paint a clear enough picture. Let's say, based on current estimates, that ChatGPT's training dataset includes approximately 11.5 million books, and there are 500 pages per book. Not only is this dataset massive, but it includes a variety of texts, like code samples, programming tutorials, and technical discussions.
However, ChatGPT has varying degrees of accuracy and effectiveness. It cannot create genuine new code or incorporate concepts that it has not been trained on.
Drafting and iterating code
Starting a new programming project can be daunting. LLMs like ChatGPT can help developers overcome this initial hurdle. They can create code templates based on information provided in a prompt. Developers can then refine, make changes, and eventually fill in the template with content.
LLM-based tools use a mechanism known as "attention" to determine which part of the user's prompt deserves special attention. If the prompt is overly complex, the AI may focus on the wrong information. Start with a simple, clear, and specific prompt and then gradually add in more complexity.
The following example asks ChatGPT to complete a programming task with a simple prompt.
Prompt
Please write a Python function that calculates the factorial of a given number. Evaluate the created function with all integers between (and including) -1 and 5.
This prompt is simple and precise. The first sentence specifies the desired programming language and what the function should accomplish. The second sentence then asks ChatGPT to test the accuracy of the generated code.
ChatGPT response
Here's a Python function that calculates the factorial of a given number.
# Define the factorial function
def factorial(n):
if n < 0:
# Factorial is not defined for negative integers
return "Undefined for negative integers"
elif n == 0:
return 1
else:
result = 1
for i in range(1, n + 1):
result *= i
return result
# Test the function with integers from -1 to 5 and print each result on a separate line
factorial_values = {n: factorial(n) for n in range(-1, 6)}
for n, fact_value in factorial_values.items():
print(f"factorial({n}): {fact_value}")
This function checks if the input number n is negative, and if so, it returns a message indicating that the factorial is not defined for negative numbers. If n is 0, it returns 1 (since 0! is 1). For positive numbers, it calculates the factorial by multiplying all the integers from 1 up to n.
The results of evaluating this function for all integers between -1 and 5 were as follows:
- factorial(-1): Undefined for negative integers
- factorial(0): 1
- factorial(1): 1
- factorial(2): 2
- factorial(3): 6
- factorial(4): 24
- factorial(5): 120
ChatGPT provided a working Python function and evaluated the function against the requested values. Now the function could easily be integrated into a larger program, or the AI could be asked to further develop the function to achieve a desired outcome.
Python is just one of several dozen languages that ChatGPT can generate code in, including most mainstream ones like Java, JavaScript, C, C++, C#, Rust, Swift, HTML/CSS, TypeScript, SQL, R, Ruby, and Kotlin. ChatGPT even supports legacy code, as it is well-versed in COBOL, Fortran and IBM 360 assembly language and can easily convert from one language to another. To illustrate, let's convert the above Python code into JavaScript:
Prompt
# Define the factorial function
def factorial(n):
if n < 0:
# Factorial is not defined for negative integers
return "Undefined for negative integers"
elif n == 0:
return 1
else:
result = 1
for i in range(1, n + 1):
result *= i
return result
Convert the above code into JavaScript
ChatGPT response
function factorial(n) {
if (n < 0) {
return "Undefined for negative integers";
} else if (n === 0) {
return 1;
} else {
let result = 1;
for (let i = 1; i <= n; i++) {
result *= i;
}
return result;
}
}
ChatGPT can also generate code and commands for more complex technologies, such as Microsoft PowerShell, HashiCorp Terraform, and Cisco IOS. It can even generate pseudocode, which proposes a sequence of instructions not in a machine-readable language. Developers can then express the pseudocode in their preferred scripting language.
Debugging code
Debugging code is a tedious and time-consuming process, especially when searching for logical errors. While syntax errors can be easily identified by compilers or integrated development environments, logical errors often go unnoticed. They cause unexpected behaviour or incorrect results in code that can take hours or even days to locate. The complexity and subtlety of these errors can lead to significant frustration and delays in development. Debugging code written by someone else adds another layer of complexity.
ChatGPT can review code, suggest potential logical errors, and explain what it should do to fix them. It not only identifies problematic areas developers might have overlooked, but also helps narrow down the number of possible errors.
Let's look at an example using C. The following function should return the sum of two numbers. However, a logical error was made. The code is calculating the sum of the same number (n1 + n1 instead of n1 + n2). An error like this can go unnoticed in a program that contains tens of thousands of lines of similar code.
To challenge ChatGPT even more, this example suggests that the sum should equal 50, when it should be 30. Let's see if it catches this error too.
Prompt
#include
int main() {
int n1 = 10;
int n2 = 20;
int total = n1 + n1;
printf("Total: %d", total);
return 0;
}
When I test my code, I expect the result of 50, but I am not getting that answer. Could you tell me what the problem might be?
ChatGPT response
The issue in your code is that you are adding n1 to itself instead of adding n1 and n2. The line int total = n1 + n1; should be changed to int total = n1 + n2;. With this correction, the code will correctly calculate the sum of n1 (which is 10) and n2 (which is 20), resulting in the expected total of 30.
Here's the corrected version of your code:
int main() {
int n1 = 10;
int n2 = 20;
int total = n1 + n2;
printf("Total: %d", total);
return 0;
}
After making this change, the output will be "Total: 30". If you expect the result to be 50, you need to adjust the values of n1 and/or n2 accordingly. For instance, setting n1 to 30 and keeping n2 as 20 would give you a total of 50.
ChatGPT correctly identified the logical error. It even suggested adjustments to the code to return the "expected" result of 50.
Sometimes, we also inherit complex code from developers who did not leave comments explaining what they did and why. The code in this next example is very difficult to read. It features a C function called Fast InvSqrt() or "fast inverse square root."
Prompt
float InvSqrt (float x){
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
Please explain what the above code does, providing an example of its potential usage.
ChatGPT response
The code you've provided is an implementation of the "Fast Inverse Square Root" algorithm. This algorithm is famous for its use in the video game industry, notably in the game "Quake III Arena." It's designed to calculate the inverse square root of a number much faster than traditional methods, albeit with slightly less precision. Here's a breakdown of how the code works:
- float xhalf = 0.5f*x;: This line computes half the value of the input x.
- int i = *(int*)&x;: This line is a bit tricky. It's using a technique known as "type punning" to treat the bits of the float x as an integer. It essentially reinterprets the binary representation of the floating-point number x as an integer.
- i = 0x5f3759df - (i >> 1);: This line is the core of the algorithm. The magic number 0x5f3759df is a carefully chosen constant that helps to approximate the inverse square root. The right shift operation i >> 1 is equivalent to dividing i by 2.
- x = *(float*)&i;: This line converts the integer i back to a float, again using type punning.
- x = x*(1.5f - xhalf*x*x);: Finally, this line refines the estimate using a form of Newton's method, a common technique for improving the accuracy of an initial guess.
Example Usage:
The algorithm is often used in graphics programming and game development, where calculating the inverse square root is common, such as in normalizing vectors or computing lighting and shading.
ChatGPT broke down this complex code structure into manageable chunks. It is now easier for both novice and experienced developers to understand and, if required, troubleshoot.
Remember, if you want to use ChatGPT (or other LLM-based tools) to explain code, ensure the code is not proprietary or confidential.
Checking code for flaws and vulnerabilities
Because developers are focused on creating functional code and meeting deadlines, they may inadvertently neglect potential flaws and vulnerabilities. Their code then becomes more susceptible to security breaches. This can have significant implications for environments where digital security is paramount.
ChatGPT can help fill this crucial gap. It can scan and analyze code, then highlight potential security flaws that a developer might miss.
Authentication is a common task for most websites. The following example asks ChatGPT to scan some Hypertext Preprocessor (PHP) authentication code for potential vulnerabilities.
Prompt
Review the following code for processing user input from a web form and identify any security vulnerabilities.
<?php
$name_nom = $_POST['name_nom'];
$pass_passe = $_POST['pass_passe'];
echo "Login/connexion : $name_nom";
// ... code to authenticate user - code pour authentifier l'utilisateur ...
?>
ChatGPT response
The provided PHP code snippet, which processes user input from a web form, has a significant security vulnerability related to how it handles and outputs user-provided data. Here's a breakdown of the issue:
Cross-Site Scripting (XSS) Vulnerability: The code directly outputs the user-provided $name_nom variable without any form of sanitization or encoding. This poses a risk of Cross-Site Scripting (XSS) attacks, where an attacker can inject malicious scripts into the web page. These scripts can be executed in the browsers of other users who view the page, leading to potential theft of cookies, session tokens, or other sensitive information, as well as the defacement of the web page or redirection to malicious sites.
To mitigate this vulnerability, you should encode any user-provided data before outputting it to the web page. In PHP, functions like htmlspecialchars() can be used to encode special characters into HTML entities. This prevents any potentially harmful code from being executed in the browser. Here's how you can modify the code to address this issue:
<?php
$name_nom = $_POST['name_nom'];
$pass_passe = $_POST['pass_passe'];
$safe_name_nom = htmlspecialchars($name_nom, ENT_QUOTES, 'UTF-8');
echo "Login/connexion : $safe_name_nom";
?>
This revised code converts special characters (like <, >, ", ', and &) to HTML entities, which prevents any embedded scripts from being executed in the browser.
Additional Considerations:
SQL Injection: If you are using this input data in database queries, there's a risk of SQL Injection. Always use prepared statements with parameterized queries to prevent this.
Data Validation: It's good practice to validate user input to ensure it meets your expectations (e.g., format, length).
Password Handling: If $pass_passe is a password, ensure it is securely handled. It should never be outputted or logged, and it should be stored in a hashed format using a strong hashing algorithm (like bcrypt) in the database.
Remember, handling user input securely is critical for web application security. Always assume that input could be malicious and treat it accordingly.
ChatGPT located the primary vulnerability in the code and identified it as cross-site scripting (XSS). Not only did it offer a practical solution to mitigate this issue, but it also highlighted some other potential security vulnerabilities.
Picture-perfect prompts
ChatGPT has introduced a new feature that allows users to add an image to their prompt. This can be used to communicate a lot of information without requiring too much text. In ChatGPT, an image can be attached using the paperclip ( ) symbol.
Prompt
Create the HTML5 and CSS3 code needed to produce the exact website layout indicated in the image, complete with correct content, proportions and colours.
ChatGPT response, not including the code
Creating the exact HTML and CSS to match the provided layout involves several steps. Below is a basic structure using HTML5 and CSS3 to recreate the layout as closely as possible. Since I don't have access to measure the exact proportions, I'll use a flexible design with percentage-based widths and a fixed footer height. Please adjust the colours, widths, heights, and other properties as necessary to fit your specific requirements.
This HTML structure will:
- Have Section 1 on the left with a height that extends to match the height of Section 2.
- Make Section 2 take up about 20% of the viewport height (20vh).
- Have Section 3 fill the remaining space to the right of Section 1 and below Section 2.
- Place Section 4 at the bottom, spanning the full width of the viewport.
In this example, ChatGPT has provided the HTML and CSS code required to successfully replicate the image, as shown.
This feature allows for a more intuitive and visual form of communication. It is especially useful in instances where the code produces a visual output, like user interface design or data visualization. It significantly reduces misunderstandings and clarifies the desired outcome. ChatGPT can more accurately understand the request and provide targeted coding advice or solutions.
Note: Not all LLM-based tools have this feature yet.
A comprehensive approach
The collaboration between human developers and LLM-based generative AI tools marks a significant advancement in software development. These tools can draft code, identify potential security vulnerabilities, and solve complex programming challenges.
Generative AI tools like ChatGPT can now be used at every stage of the software development lifecycle. For example, in the project planning phase, AI can make recommendations on how to structure software. In the design phase, it can create code templates. During implementation, it can help refine code. During testing, it can identify and fix bugs.
However, it is important to remember that AI has its limitations. We should consistently review and validate AI-generated outputs and exercise caution when dealing with sensitive information. We should also refer to and align with the "FASTER" principles recommended in the Treasury Board of Canada Secretariat's Guide on the use of Generative AI.
Resources