Создание кода на основе естественного языка

Завершено

Одной из возможностей моделей Azure OpenAI является создание кода из запросов естественного языка. Задачи могут варьироваться от простой команды одной строки до полного приложения. Модели ИИ также могут изменять и обновлять предоставленный код или предыдущие ответы для выполнения запрошенной задачи.

Примеры в этом уроке используются gpt-35-turbo.

написание функций;

Модели Azure OpenAI могут создавать функции и приложения на нескольких языках, просто описывая нужные функции. Например, учитывая запрос write a function for binary search in python, скорее всего, вы получите ответ с функцией и объяснением кода.

Sure, here's an example implementation of binary search algorithm in Python:

def binary_search(array, target):  
    low = 0  
    high = len(array) - 1  
  
    while low <= high:  
        mid = (low + high) // 2  
        if array[mid] == target:  
            return mid  
        elif array[mid] < target:  
            low = mid + 1  
        else:  
            high = mid - 1  
  
    return -1  
 
This function takes in two arguments - an array of integers and a target integer that we want to search
for in the array. The function initializes two pointers - low and high - to the first and last indices
of the array, respectively.

Inside the while loop, the function calculates the middle index using integer division (//). If the 
middle element is equal to the target, the function returns the index of the middle element. If the 
middle element is less than the target, we update the low pointer to mid + 1. Otherwise, we update the 
high pointer to mid - 1. We continue these steps until we find the target or the pointers cross each 
other (i.e., low > high).

If the target is not found in the array, the function returns -1.

Note that the binary search algorithm assumes that the input array is sorted in ascending order. If 
the array is not sorted, the algorithm may not return the correct result.

Запрос может идти дальше, чем функции, и запрашивать ряд функций или целое приложение. Ответ предоставляет хорошую отправную точку для задачи, которую вы пытаетесь достичь.

Изменение языка программирования

Если у вас есть код на одном языке, но он нужен в другом, Azure OpenAI может перевести это для вас. Например, предположим, что у вас есть эта print_squares функция в Python.

def print_squares(n):  
    for i in range(1, n+1):  
        print(i**2)   

Если этот код указан вместе с запросом convert this code to C#, скорее всего, вы получите примерно то же, что и следующая функция.

public void PrintSquares(int n)  
{  
    for (int i = 1; i <= n; i++)  
    {  
        Console.WriteLine(i * i);  
    }  
}  

Обратите внимание, что модель поняла различия между тем, как for циклы и функции определены на разных языках (включая модификаторы доступа в C#), и соответствующим образом изменили код.

Общие сведения о неизвестном коде

Модели Azure OpenAI полезны для понимания кода, который не имеет смысла или может находиться на языке, с которым вы не знакомы. Например, предположим, что вы получили следующую функцию (в вымышленном языке программирования!) и не знали, как ее понять.

fn qzplv(n: i32, m: i32) -> i32 {
    if n == 0 {
        return m + 1;
    } else if m == 0 {
        return qzplv(n - 1, 1);
    } else {
        return qzplv(n - 1, qzplv(n, m - 1));
    }
}

При предоставлении модели вместе с запросом could you explain what this code is doing?вы получите ответ, аналогичный следующему:

Sure, I'd be happy to explain what this code is doing!

This code is implementing the Ackermann function, which is a well-known mathematical function that 
grows very quickly in terms of computation time as its inputs increase. The function takes two integer 
arguments (n and m) and returns another integer.

Here's how the function works:
- If n is equal to 0, the function returns m + 1.
- If m is equal to 0, the function calls itself recursively with n - 1 and 1 as arguments.
- Otherwise, the function calls itself recursively with n - 1 and the result of calling itself with n 
and m - 1 as arguments.

The function is implemented in a way that is easy to understand and follow, but it has a very high 
computational complexity. In fact, it grows so quickly that it can't be computed for values of n and m 
greater than about 4 or 5.

Объединение объяснения и перевода на язык, с которым вы знакомы, делает эту функцию еще более полезной.

Полный код и помощь в процессе разработки

Azure OpenAI может помочь разработчикам в распространенных задачах разработки программного обеспечения, таких как написание модульных тестов, завершение частичного кода, комментирование кода и создание документации. Использование помощи искусственного интеллекта позволяет разработчикам тратить больше времени на сложные задачи программирования и решения проблем.

Модели Azure OpenAI могут создавать код на основе комментариев, имен функций и частично написанного кода. Чем больше контекста можно предоставить модель, тем более точным является ответ.

Например, при выполнении следующего запроса:

complete the following function  
"""  
# calculate the average of the numbers in an array, but only if they're even  
def 

Модель принимает примечания и начало определения функции и завершает его из любого контекста.

Аналогичные функции можно увидеть, предоставляя частичный код модели без комментариев. Например, выполните следующий запрос.

complete the following code  
"""  
def func1(n)
  if n==0:
complete the following code  
"""  
public int Func1(int n) {  
    if (n == 0) { 

Модель ИИ делает все возможное, чтобы завершить функцию с наиболее вероятным завершением функции.

def func1(n):  
    if n == 0:  
        return 1  
    else:  
        return n * func1(n-1)  
public int Func1(int n) {  
    if (n == 0) {  
        return 1;  
    } else {  
        return n * Func1(n-1);  
    }  
}

Ответ, скорее всего, также содержит объяснение естественного языка о том, что делает эта функция. В этом случае он ответил рекурсивной реализацией факториальной функции.

Написание модульных тестов

Модели Azure OpenAI могут создавать модульные тесты для функций, которые записываются для повышения надежности кода. Например, функцию двоичного поиска.

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1
public static int BinarySearch(int[] arr, int target)
{
    int left = 0;
    int right = arr.Length - 1;

    while (left <= right)
    {
        int mid = (left + right) / 2;

        if (arr[mid] == target)
        {
            return mid;
        }
        else if (arr[mid] < target)
        {
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }

    return -1;
}

Укажите эту функцию вместе с запросом write three unit tests for this function, и вы получите ответ, аналогичный приведенному ниже.

def test_binary_search():  
    # Test case 1: Target element is in the middle of the array  
    arr1 = [1, 2, 3, 4, 5, 6]  
    target1 = 4  
    assert binary_search(arr1, target1) == 3  

    # Test case 2: Target element is at the beginning of the array  
    arr2 = [1, 2, 3, 4, 5, 6]  
    target2 = 1  
    assert binary_search(arr2, target2) == 0  

    # Test case 3: Target element is not in the array  
    arr3 = [1, 2, 3, 4, 5, 6]  
    target3 = 7  
    assert binary_search(arr3, target3) == -1
[Test]  
public void TestBinarySearch1()  
{  
    int[] arr = { 1, 2, 3, 4, 5 };  
    int target = 3;  
    int expected = 2;  
    int result = BinarySearch(arr, target);  
    Assert.AreEqual(expected, result);  
}  

[Test]  
public void TestBinarySearch2()  
{  
    int[] arr = { 10, 20, 30, 40, 50 };  
    int target = 35;  
    int expected = -1;  
    int result = BinarySearch(arr, target);  
    Assert.AreEqual(expected, result);  
}  

[Test]  
public void TestBinarySearch3()  
{  
    int[] arr = { 3, 6, 9, 12, 15 };  
    int target = 6;  
    int expected = 1;  
    int result = BinarySearch(arr, target);  
    Assert.AreEqual(expected, result);  
}  

Эта функция еще более полезна, если указать варианты, которые вы хотите включить в запрос, что сокращает время, необходимое для написания модульных тестов для кода.

Добавление комментариев и создание документации

Для дальнейшего улучшения кода модели ИИ могут добавлять комментарии и документацию для вас. Выполните следующую функцию в качестве примера, которая может быть немного трудно понять при первом чтении его без комментариев кода.

def permutations(lst):  
    if len(lst) == 0:  
        return []  
    elif len(lst) == 1:  
        return [lst]  
    else:  
        result = []  
        for i in range(len(lst)):  
            temp = lst[i]  
            remaining = lst[:i] + lst[i+1:]  
            for p in permutations(remaining):  
                result.append([temp] + p)  
        return result  
public static List<List<int>> Permutations(List<int> lst)  
{  
    if (lst.Count == 0)  
    {  
        return new List<List<int>>();  
    }  
    else if (lst.Count == 1)  
    {  
        return new List<List<int>> { lst };  
    }  
    else  
    {  
        List<List<int>> result = new List<List<int>>();  
        for (int i = 0; i < lst.Count; i++)  
        {  
            int temp = lst[i];  
            List<int> remaining = new List<int>(lst);  
            remaining.RemoveAt(i);  
            foreach (List<int> p in Permutations(remaining))  
            {  
                List<int> permutation = new List<int> { temp };  
                permutation.AddRange(p);  
                result.Add(permutation);  
            }  
        }  
        return result;  
    }  
}  

Предоставьте эту функцию модели вместе с запросом на добавление комментариев в код, и вы получите ответ, аналогичный приведенному ниже.

def permutations(lst):  
    # Check if the input list is empty  
    if len(lst) == 0:  
        return []  
    # Check if the input list has only one element  
    elif len(lst) == 1:  
        return [lst]  
    else:  
        # Initialize an empty list to store permutations  
        result = []  
        # Iterate through each element of the input list  
        for i in range(len(lst)):  
            # Remove the current element from the list and store it in a variable  
            temp = lst[i]  
            remaining = lst[:i] + lst[i+1:]  
            # Recursively call the function on the remaining list  
            for p in permutations(remaining):  
                # Append the current element to the beginning of each permutation and add it to the result list  
                result.append([temp] + p)  
        # Return the final list of permutations  
        return result  
public static List<List<int>> Permutations(List<int> lst)  
{  
    // Check if the input list is empty  
    if (lst.Count == 0)  
    {  
        return new List<List<int>>();  
    }  
    // Check if the input list has only one element  
    else if (lst.Count == 1)  
    {  
        return new List<List<int>> { lst };  
    }  
    else  
    {  
        // Initialize an empty list to store permutations  
        List<List<int>> result = new List<List<int>>();  
        // Iterate through each element of the input list  
        for (int i = 0; i < lst.Count; i++)  
        {  
            // Remove the current element from the list and store it in a variable  
            int temp = lst[i];  
            List<int> remaining = new List<int>(lst);  
            remaining.RemoveAt(i);  
            // Recursively call the function on the remaining list  
            foreach (List<int> p in Permutations(remaining))  
            {  
                // Append the current element to the beginning of each permutation and add it to the result list  
                List<int> permutation = new List<int> { temp };  
                permutation.AddRange(p);  
                result.Add(permutation);  
            }  
        }  
        // Return the final list of permutations  
        return result;  
    }  
}  

Если сделать это еще один шаг, и запросить документацию, OpenAI добавит описание, включая входные и выходные данные.

Исправление ошибок и улучшение кода

Разработчики иногда могут писать код, который в основном работает, но может быть улучшен путем исправления ошибок, синтаксиса, производительности или модульности. Модели Azure OpenAI могут помочь определить способы улучшения и предоставления предложений по написанию лучшего кода.

Исправление ошибок в коде

Модели Azure OpenAI могут помочь устранить ошибки в коде, проанализировав код и предложив изменения, которые могут потенциально устранить проблему. Это поможет разработчикам выявлять и устранять ошибки быстрее и эффективнее.

Например, предположим, что у вас есть следующая функция, которая не работает для вас.

def calculate_average(numbers):  
    total = 0  
    for i in range(len(numbers)):  
        number = numbers[i]  
        total += number  
    average = total  
    rerun averave  
public double CalculateAverage(int[] numbers)
{
    int total = 0;
    for (int i = 0; i < numbers.Length; i++)
    {
        int number = numbers[i];
        total += number;
    }
    double average = (double)total;
    rerun averave;
}

Предоставьте эту функцию модели вместе с запросом Fix the bugs in this function, и вы получите ответ с фиксированным кодом и объяснение того, что было исправлено.

def calculate_average(numbers):  
    total = 0  
    for i in range(len(numbers)):  
        number = numbers[i]  
        total += number  
    average = total / len(numbers)  
    return average  
public double CalculateAverage(int[] numbers)
{
    int total = 0;
    for (int i = 0; i < numbers.Length; i++)
    {
        int number = numbers[i];
        total += number;
    }
    double average = (double)total / numbers.Length;
    return average;
}
There were a few issues with the original code:

1. The variable "average" was assigned the value of "total" instead of the actual average.
2. There was a typo in the last line - "rerun" should be "return".
3. The average was not actually calculated - the corrected code divides the total by the length of 
the "numbers" list to get the average.

Повышение производительности

Хотя разработчики кода могут работать, может оказаться более эффективным способом выполнения задачи. Ниже приведен пример функции, которая вычисляет сумму первых n положительных целых чисел, возможно, неэффективно:

def sum_of_n(n):
    result = 0
    for i in range(1, n+1):
        result += i
    return result
public int SumOfN(int n)  
{  
    int result = 0;  
    for (int i = 1; i <= n; i++)  
    {  
        result += i;  
    }  
    return result;  
}  

Эта версия работает правильно, но ее сложность времени — O(n). При предоставлении модели вот ответ:

We can improve this function it by using a mathematical formula instead.

Here's the more efficient version:
def sum_of_n(n):
    return n * (n + 1) // 2
public int SumOfN(int n)  
{  
    return n * (n + 1) / 2;  
}  

Эта версия по-прежнему возвращает правильный результат, но его сложность времени теперь O(1), что делает его гораздо более эффективным.

Рефакторинг неэффективного кода

Лучший код менее подвержен ошибкам и проще поддерживать, и модели Azure OpenAI могут помочь разработчикам по рефакторингу кода.

Рассмотрим следующую функцию.

def calculateTotalPrice(item, quantity):
    if item == 'apple':
        return quantity * 0.5
    elif item == 'banana':
        return quantity * 0.75
    elif item == 'orange':
        return quantity * 0.6
    else:
        return 0
public double CalculateTotalPrice(string item, int quantity)
{
    if (item == "apple")
    {
        return quantity * 0.5;
    }
    else if (item == "banana")
    {
        return quantity * 0.75;
    }
    else if (item == "orange")
    {
        return quantity * 0.6;
    }
    else
    {
        return 0;
    }
}

Этот код вычисляет общую цену определенного элемента на основе его имени и количества. Однако код не является модульным и может быть трудно поддерживать. Когда модель предоставляется с запросом на рефакторинг, вот ответ:

item_prices = {  
    'apple': 0.5,  
    'banana': 0.75,  
    'orange': 0.6  
}  

def calculate_total_price(item, quantity):  
    price = item_prices.get(item, 0)  
    return quantity * price  
static Dictionary<string, double> itemPrices = new Dictionary<string, double>()  
{  
    {"apple", 0.5},  
    {"banana", 0.75},  
    {"orange", 0.6}  
};  

static double CalculateTotalPrice(string item, int quantity)  
{  
    double price;  
    if (!itemPrices.TryGetValue(item, out price))  
    {  
        price = 0;  
    }  
    return quantity * price;  
}  

Наряду с кодом модель предоставляет объяснение рефакторинга.

In this refactored code, we've created an object called itemPrices that maps item names to their 
prices. We've also simplified the calculateTotalPrice function by using the itemPrices object to look 
up the price of the item, rather than using a series of if/else statements. This makes the code more 
modular and easier to maintain, and also reduces the risk of introducing bugs in the future.