An experienced developer kicks the tires on GitHub Copilot for generating code with AI. See what he thinks and how it might work for you.
GitHub Copilot revolutionizes coding as your AI pair programmer, helping you craft code faster and more effectively. It intuitively understands the context from your comments and code, swiftly suggesting individual lines and complete routines.
This innovative tool springs from a collaborative effort between GitHub, OpenAI and Microsoft, powered by a cutting-edge generative AI model. Copilot analyzes not just your current file but also linked files as you code, offering smart autocomplete suggestions in your text editor.
Image from a custom prompt in Leonardo.ai
This tool isn’t just about speed—it’s transforming the programming landscape by making coding more efficient and accessible. GitHub’s research highlights Copilot’s significant role in boosting developer productivity and satisfaction. It’s breaking down barriers to software development for newcomers and smoothing out the challenges of writing basic code.
The impact of generative AI on the economy will be monumental. Developers and businesses are already embracing AI-powered coding tools like GitHub Copilot, marking a new era in software development.
GitHub Copilot is a vital tool that can assist us, as developers, with writing code more quickly and efficiently. It can revolutionize the programming world by making coding more approachable and lowering the entrance barrier for new developers.
In this article, I’ll demonstrate how GitHub Copilot can help produce code using GitHub Copilot and explain how I got the desired result. (This post was written in December 2023.)
I’ve been actively using GitHub Copilot for four months, experiencing its capabilities firsthand. Let’s say you’re already familiar with the paid version of ChatGPT-4 or Bing Chat, which incorporates ChatGPT-4 connected to the web. You’ll notice that GitHub Copilot’s code generation capabilities are similar to these tools. Interestingly, when one tool struggles to generate code, others often face the same challenge.
GitHub Copilot seamlessly integrates with both Visual Studio 2022 and Visual Studio Code. A notable development was introducing a new feature for Visual Studio 2022 Preview, launched in December 2022. This enhancement significantly enriches the Visual Studio IDE experience by adding commit descriptions.
I have 30 years of experience designing thousands of components and an AI framework model based on database structure with self-awareness of relations of fields and tables created with mixed artificial intelligence. With it, one of the results was a chat with the database where the end user can ask anything about the stored data and get a reply that is 90% accurate.
This is my experience with AI, so when ChatGPT was launched, I saw the potential for artificial assistance, like GitHub Copilot.
This introduction I did was to bring you to my point of view and say:
If you have the necessary background, know the names of the components and technologies, and understand how to envision a machine “thinking” with the commands it receives, you will become an excellent prompt engineer.
It depends on you. How long will you practice the prompts to find the best solution for your solutions, projects and problems? I spent four hours testing prompts for writing this post, asking for GitHub Copilot to deliver code that satisfies my requirements.
The requirement was to generate a model with EF Core commands to create a form to read these fields using Kendo UI and the code for the Controller to send an email. For validations, the date of birth should be greater than 01/01/1900 to DateTime.Now, and return a date greater than DateTime.Now+1, validating email with regex.
From my experience, I observed that what is new in design, languages and patterns is not generated very well. But as of the last update of ChatGTP-4, which is currently April 2023, if the technology is older, the result is better than the new ones.
Let’s start with what does not work exceptionally well with GitHub Copilot:
Here are some of the things GitHub Copilot does well with Telerik UI frameworks:
I started creating a prompt for the model. Let’s see this prompt below:
Please generate a C# code with these requirements: Create a model Admission in namespace TelerikAspNetCoreApp1.Model, add display properties for the fields: Id as key and GUID type autogenerate, Name as unique max 100 chars, Date Birthday, Email, Subject max 255, Description max 4096, Return Date.
Please add EF Core validations for Date Birthday greater than 01/01/1900 to DateTime.Now, and return date greater than DateTime.Now+1, validate email with regex.
Structure of the prompt:
Below is the result for the model (the project is available on my GitHub):
1. using System.ComponentModel.DataAnnotations;
2. using System.ComponentModel.DataAnnotations.Schema;
3.
4. public class Admission
5. {
6. [Key]
7. [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
8. public Guid Id { get; set; }
9.
10. [Required]
11. [StringLength(100)]
12. [Index(IsUnique = true)]
13. public string Name { get; set; }
14.
15. [Required]
16. [DataType(DataType.Date)]
17. [Display(Name = "Date Birthday")]
18. [CustomValidation(typeof(Admission), "ValidateDateOfBirth")]
19. public DateTime DateBirthday { get; set; }
20.
21. [Required]
22. [DataType(DataType.EmailAddress)]
23. [RegularExpression(@"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$", ErrorMessage = "Invalid Email Format")]
24. public string Email { get; set; }
25.
26. [StringLength(255)]
27. public string Subject { get; set; }
28.
29. [StringLength(4096)]
30. public string Description { get; set; }
31.
32. [Required]
33. [DataType(DataType.Date)]
34. [Display(Name = "Return Date")]
35. [CustomValidation(typeof(Admission), "ValidateReturnDate")]
36. public DateTime ReturnDate { get; set; }
37.
38. public static ValidationResult ValidateDateOfBirth(DateTime dateOfBirth, ValidationContext context)
39. {
40. if (dateOfBirth < new DateTime(1900, 1, 1) || dateOfBirth > DateTime.Now)
41. {
42. return new ValidationResult("Date Birthday must be greater than 01/01/1900 and less than current date.");
43. }
44.
45. return ValidationResult.Success;
46. }
47.
48. public static ValidationResult ValidateReturnDate(DateTime returnDate, ValidationContext context)
49. {
50. if (returnDate <= DateTime.Now.AddDays(1))
51. {
52. return new ValidationResult("Return Date must be greater than current date plus one day.");
53. }
54.
55. return ValidationResult.Success;
56. }
57. }
58.
There was only one mistake: The code was generated without the namespace. But I solved this by just adding the namespace:
1. <![endif]>namespace TelerikAspNetCoreApp1.Model;
Some things I learned:
I started creating a prompt for the form. Let’s see this prompt below:
Please using Kendo UI for jQuery with Html Helper style for ASP.NET Core MVC project create a Kendo UI form to post in Admission Home Controller. Using the model Admission, please build all fields using Kendo UI, and labels for each field, and with respective validation. For posting the form generate Admission that must get all data from the model and send to an email from consts pEmailFrom to pEmailTo defining a fake value for the consts.”
Structure of the prompt:
Below is the result for the model (the project is available on my GitHub):
1. @model TelerikAspNetCoreApp1.Model.Admission
2. @{
3. ViewData["Title"] = "Admission";
4. }
5.
6. @using (Html.BeginForm(“Admission”, “Home”, FormMethod.Post))
7. {
8. @Html.AntiForgeryToken()
9.
10. <div class="form-horizontal">
11. <h4>Admission</h4>
12. <hr />
13. @Html.ValidationSummary(true, "", new { @class = "text-danger" })
14.
15. <div class="form-group">
16. @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
17. <div class="col-md-10">
18. @(Html.Kendo().TextBoxFor(model => model.Name)
19. .HtmlAttributes(new { @class = "k-textbox" }))
20. @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
21. </div>
22. </div>
23.
24. <div class="form-group">
25. @Html.LabelFor(model => model.DateBirthday, htmlAttributes: new { @class = "control-label col-md-2" })
26. <div class="col-md-10">
27. @(Html.Kendo().DatePickerFor(model => model.DateBirthday)
28. .HtmlAttributes(new { @class = "k-datepicker" }))
29. @Html.ValidationMessageFor(model => model.DateBirthday, "", new { @class = "text-danger" })
30. </div>
31. </div>
32.
33. <div class="form-group">
34. @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
35. <div class="col-md-10">
36. @(Html.Kendo().TextBoxFor(model => model.Email)
37. .HtmlAttributes(new { @class = "k-textbox" }))
38. @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
39. </div>
40. </div>
41.
42. <div class="form-group">
43. @Html.LabelFor(model => model.Subject, htmlAttributes: new { @class = "control-label col-md-2" })
44. <div class="col-md-10">
45. @(Html.Kendo().TextBoxFor(model => model.Subject)
46. .HtmlAttributes(new { @class = "k-textbox" }))
47. @Html.ValidationMessageFor(model => model.Subject, "", new { @class = "text-danger" })
48. </div>
49. </div>
50.
51. <div class="form-group">
52. @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
53. <div class="col-md-10">
54. @(Html.Kendo().TextAreaFor(model => model.Description)
55. .HtmlAttributes(new { @class = "k-textarea" }))
56. @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
57. </div>
58. </div>
59.
60. <div class="form-group">
61. @Html.LabelFor(model => model.ReturnDate, htmlAttributes: new { @class = "control-label col-md-2" })
62. <div class="col-md-10">
63. @(Html.Kendo().DatePickerFor(model => model.ReturnDate)
64. .HtmlAttributes(new { @class = "k-datepicker" }))
65. @Html.ValidationMessageFor(model => model.ReturnDate, "", new { @class = "text-danger" })
66. </div>
67. </div>
68.
69. <div class="form-group">
70. <div class="col-md-offset-2 col-md-10">
71. <input type="submit" value="Create" class="btn btn-default" />
72. </div>
73. </div>
74. </div>
75. }
Code for Home Controller:
1. private const string pEmailFrom = "fake@example.com";
2. private const string pEmailTo = "destination@example.com";
3.
4. [HttpPost]
5. [ValidateAntiForgeryToken]
6. public ActionResult Admission(Admission admission)
7. {
8. if (ModelState.IsValid)
9. {
10. // Send email
11. var mail = new MailMessage(pEmailFrom, pEmailTo)
12. {
13. Subject = admission.Subject,
14. Body = $"Name: {admission.Name}\nDate Birthday: {admission.DateBirthday}\nEmail: {admission.Email}\nDescription: {admission.Description}\nReturn Date: {admission.ReturnDate}"
15. };
16.
17. var smtpServer = new SmtpClient("smtp.example.com");
18. smtpServer.Send(mail);
19.
20. return RedirectToAction("Index");
21. }
22.
23. return View();
24. }
Its first response was lazy, indicating the need to add the other fields. People say ChatGPT-4 is becoming lazy, and GitHub Copilot is too.
So, I did another prompt:
For all fields, please.
Below is the form running on the browser:
Here is the demonstration of the validations for the fields:
GitHub Copilot is in development, in my opinion, and has space for growing in quality. If you need to start something new or rewrite legacy projects, you have a good assistant. Maybe the GitHub Copilot is missing something from Kendo UI components but it generates a good percentage of the code.
For success with Telerik UI and GitHub Copilot, you need to spend some time testing and learning how to prompt, and the rule is no pain, no gain.
Maybe in the future someone will create a plugin for ChatGPT-4—could it be you? Or perhaps Microsoft will evolve GitHub Copilot for better integration.
Jefferson S. Motta is a senior software developer, IT consultant and system analyst from Brazil, developing in the .NET platform since 2011. Creator of www.Advocati.NET, since 1997, a CRM for Brazilian Law Firms. He enjoys being with family and petting his cats in his free time. You can follow him on LinkedIn and GitHub.