GitHub Copilot asking multiple questions
Tags: tutorial, ai, codenewbie
Published: 2024-06-15 00:12:43

Usually when using GitHub Copilot in Microsoft Visual Studio Code a developer asks a question, gets an acceptable answer, and continues. But there are times when the response is close and needs some changes. In these cases do not accept the answer, instead ask a secondary question.

Example, a developer wants a Customer class with the following properties, FirstName, LastName and BirthDate.

Ask Copilot using <kbd>CTRL</kbd> + <kbd>I</kbd>

_create a customer class with Id, FirstName, LastName and Birthdate properties_

Copilot responds with 

```csharp
public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime Birthdate { get; set; }
}
```

The developer does not need a full date time, without accepting the first answer, clears the question and enters followed by press <kbd>ENTER</kbd>.

_Change BirthDate to a DateOnly_

Copilot response with

```csharp
public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateOnly Birthdate { get; set; }
}
```

Now how about asking Copilot to generate a method to return a list of Customer using Bogus NuGet package (which is not yet installed).

Without accepting anything, clear the last question and enter the following and presses <kbd>ENTER</kbd>.

_Create a class named MockedData with a method to return 10 customers using Bogus_

Copilot produces

```csharp
public class MockedData
{
    public static List<Customer> GetCustomers()
    {
        List<Customer> customers = new List<Customer>();

        for (int i = 1; i <= 10; i++)
        {
            var faker = new Faker();
            Customer customer = new Customer
            {
                Id = i,
                FirstName = faker.Person.FirstName,
                LastName = faker.Person.LastName,
                Birthdate = faker.Date.Past(30)
            };

            customers.Add(customer);
        }

        return customers;
    }
}
```

The developer does not **i** for use in the **for** statement, without accepting the answer enter the following and press <kbd>ENTER</kbd>.

```csharp
public class MockedData
{
    public static List<Customer> GetCustomers()
    {
        List<Customer> customers = new List<Customer>();

        for (int index = 1; index <= 10; index++)
        {
            var faker = new Faker();
            Customer customer = new Customer
            {
                Id = index,
                FirstName = faker.Person.FirstName,
                LastName = faker.Person.LastName,
                Birthdate = faker.Date.Past(30)
            };

            customers.Add(customer);
        }

        return customers;
    }
}
```

Now accept the answer followed by adding NuGet package Bogus and there is an error on faker.Date.Past(30) as this does not apply to DateOnly.

After reading Bogus documentation the developer changes the errored code to 

```csharp
Birthdate = faker.Date.BetweenDateOnly(new DateOnly(1945,1,1), new DateOnly(2000,1,1))
```

Full code with the developer making changes to the BirthDate faking.

```csharp
public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateOnly Birthdate { get; set; }
}

public class MockedData
{
    public static List<Customer> GetCustomers()
    {
        List<Customer> customers = new List<Customer>();

        for (int index = 1; index <= 10; index++)
        {
            var faker = new Faker();
            Customer customer = new Customer
            {
                Id = index,
                FirstName = faker.Person.FirstName,
                LastName = faker.Person.LastName,
                Birthdate = faker.Date.BetweenDateOnly(new DateOnly(1945,1,1), new DateOnly(2000,1,1))
            };

            customers.Add(customer);
        }

        return customers;
    }
}
```

Next steps, move the Customer class to its own file and the same for the MockData class.

## What about a better solution?

First off, any developer AI which includes Copilot may provide a working piece of code but does not mean its optimal. In the example above the developer could keeping refining their question or use it. But in the case of Bogus the code below follows code samples in Bogus documentation. 

```csharp
public class MockedData
{
    public static List<Customer> GetCustomers(int count)
    {
        var identifier = 1;
        Randomizer.Seed = new Random(338);

        var faker = new Faker<Customer>()
            .CustomInstantiator(f => new Customer { Id = identifier++ })
            .RuleFor(u => u.FirstName, f => f.Name.FirstName())
            .RuleFor(c => c.LastName, f => f.Name.LastName())
            .RuleFor(c => c.Birthdate, f => 
                f.Date.BetweenDateOnly(new DateOnly(1950, 1, 1), new DateOnly(2010, 1, 1)));

        return faker.Generate(count);
    }
}
```

Bonus from reading Bogus documentation is that **Randomizer.Seed** creates consistent data each time the project runs.

## Summary

Being able to continually ask Copilot questions without accepting a recommendation until satisfied can save time rather than asking Copilot to fix the code.

Like any developer tool, Copilot may provide great answers or what appear to be great answers but perhaps only to the novice developers.

Like any developer tool, Copilot may provide great answers or what appear to be great answers but perhaps only to the novice developers. And as in the example above with the BirthDate code to mockup a customer, a developer may need to think for themselves and complete code by hand.