How AI helps the daily work of the development team

The article is aimed at the reader who still doubts whether he should try chatbots at work. If you are familiar with the technology and have tried it in your daily activities, you are unlikely to find it useful.

I’ll tell you a little about the real use of GPT in our company.

Introduction

A lot has been said about generative models: various sources predicted the extinction of every second intellectual profession. There were always people who said that “programmers are not needed, the username from city made a website/script/drawing.txt using ChatGPT, fired all the programmers and sitting alone sad looking for new ones Now his business runs itself, and he only collects money.”

Thanks to the furor that ChatGPT created, the “AY AY” sticker appeared on every second iron. At the same time, there were plenty of neural networks themselves in various architectures in the technologies that we are used to using without explicitly emphasizing that “artificial intelligence works there.”

Taken together, all this only caused me irritation, but it is stupid to deny the usefulness of a chatbot – even in its current form, we use it within the company, and it helps my colleagues and me solve routine work tasks. Today I'll talk a little about some successful practical applications.

Generation of UML diagrams

Prototyping is often one of the designer's tasks. This tool is useful not only for himself, but also for the person who will implement this decision. Prototyping makes it much easier for the final developer to understand the final concept, and understanding is the key to successful collaboration.

During the design process, the easiest way for a former developer to sketch out future models is to use a programming language, such as C# or Typescript. This is convenient, since your favorite ORMs often use a code first approach, and it is very easy to express the necessary connections in code in a form that is natural for the developer. And based on these connections, you can throw on a DSL and work out the subject area in a little more detail.

But in addition to the developer and architect, a system analyst is necessarily involved in developing a solution. And no matter how strong our analyst is, he does not speak the programming language and it will be difficult for him to understand such a scheme, but the analyst will easily understand ERD. Of course, you don’t want to describe this ERD manually, but rather generate it from existing code.

There are several products on the market that I can use to solve this problem, but they are paid (which is expected) and/or require connecting to a database that does not yet exist. The time and effort involved is not worth purchasing or using these products – it's faster to make this chart yourself and for free.

This is where GPT comes to the rescue and a simple request to generate an ERD diagram using PlantUML. And it copes with this task relatively well – after 2-3 times it produces a completely readable diagram, sufficient to illustrate the solution.

Here is an example of solving such a problem.

Suppose we have some entity Order, with which some objects of a certain type are associated. The example is intentionally small – it works the same on scale.

Hidden text

User:

Generate entity relationship diagram for PlantUML using following Typescript code

type UUID = String;

type RelatedEntityType = {
key: string;
}

type LinkedObject = {
entityType: RelatedEntityType;
key: string;
}

type Order = {
id: UUID;
linkedObjects: LinkedObject[];
}

GPT:

Sure! Here's the entity relationship diagram (ERD) for the TypeScript code you provided, using PlantUML syntax:

plantum
Copy
@startuml

!define ENTITY_RELATIONSHIP_DIAGRAM

package “Types” {
class UUID {
– value: String
}

class RelatedEntityType {
– key: String
}

class LinkedObject {
– entityType: RelatedEntityType
– key: String
}

class Order {
– id: UUID
– linkedObjects: LinkedObject[]
}
}

Order “1” — ““LinkedObject: containsLinkedObject”” — “1” RelatedEntityType : has

@enduml
This diagram represents the entities and their relationships as defined in the TypeScript code. The UUID, RelatedEntityType, and LinkedObject classes are defined in the Types package. The Order class has a one-to-many relationship with LinkedObject, denoted by the 1 — “” notation. The LinkedObject class has an association with RelatedEntityType with a one-to-one relationship, denoted by the “1” — “1” notation.

Please note that PlantUML allows for different diagram layouts and styling options, so you can customize the appearance of the diagram according to your preferences.

User:

Use PostgreSQL types for primitives

GPT

Certainly! Here's an updated version of the entity relationship diagram (ERD) incorporating PostgreSQL data types for the primitive types in your TypeScript code:

plantumlCopy@startuml

!define ENTITY_RELATIONSHIP_DIAGRAM

package “Types” { class UUID { – value: UUID NOT NULL } class RelatedEntityType { – key: VARCHAR(255) NOT NULL } class LinkedObject { – entityType: RelatedEntityType – key: VARCHAR(255) NOT NULL } class Order { – id : UUID NOT NULL – linkedObjects: LinkedObject[] }}

Order “1” — ““LinkedObject: contains
LinkedObject “*” — “1” RelatedEntityType : has

@enduml
In this updated diagram, I've replaced the UUID type with the UUID data type supported by PostgreSQL, which is represented as UUID NOT NULL. The RelatedEntityType and LinkedObject types now use the VARCHAR(255) NOT NULL data type to match the string type from TypeScript.

Feel free to adjust the data types according to your specific database requirements.

User:

Use Crow's Foot notation for relations

GPT:

Certainly! Here's an updated version of the entity relationship diagram (ERD) using the Crow's Foot notation for representing relationships:

plantum
Copy
@startuml

!define ENTITY_RELATIONSHIP_DIAGRAM

package “Types” {
entity “UUID” as uuid {
+ value : UUID [PK]
}

entity “RelatedEntityType” as relatedEntity {
+ key : String [PK]
}

entity “LinkedObject” as obj {
+ key : String [PK]
}

entity “Order” as order {
+ id : UUID [PK]
}

order –|{ obj : contains
obj }|– relatedEntity : has

@enduml
In this diagram, each entity is represented as a box, and the relationships are depicted using Crow's Foot notation. The primary key attributes are denoted with a “+” symbol, and the relationship between Order and LinkedObject is represented with the contains relationship using the “zero or more” (crow's foot) notation on the LinkedObject side. Similarly, the LinkedObject entity has a relationship with RelatedEntityType depicted by the has relationship using the “one or more” (crow's foot) notation on the RelatedEntityType side.

Please note that Crow's Foot notation represents cardinality and relationship types visually but doesn't explicitly depict the data types.

This is the diagram we will get as a result. The UUID description is, of course, superfluous, but this is nitpicking.

Generating code comments

Commenting code is a good and common practice. Comments allow you to quickly get the missing context about the purpose of a piece of code, method or class without compromising the readability of the source code itself, and developers are accustomed to leaving these comments (or they are forced they try to do it). But how often do you have to explain the purpose of each FILE?

One of the conditions for delivery of the project was the transfer of the source code to the customer. The team developed the project for several years – more than 3,000 source code files were written. And now, the development is completed and acceptance tests begin.

And what a surprise the team was when it became known about one interesting fact: according to the customer’s internal documents, each source code file must be accompanied by a commentary about what it is needed for.

Perhaps the requirement will seem absurd, perhaps it is already outdated both morally and organizationally, but it must be done. The task seems time-consuming and boring – to go into each file, look at it, make some summary. Boring, but doable. Who should be entrusted with such a task? Junior developer? But he didn't quit be upset after such a task? Distract the whole team for an hour?

And here we remember about the wonderful skill of our GPT – the ability to generalize! Isn't this what we need?

Let's try to check. Let's take a file with our code and ask it to tell us: what's going on here?

Hidden text

User:

Document the code and return the answer to MarkDown

GPT:

#### Файл myfile.ts

Данный файл является исходным кодом на языке TypeScript. В файле определен класс MyClass. Класс содержит методы для обработки CRUD-операций с состоянием операций по исправлению сбоев, например, добавление/редактирование/удаление операций, добавление/удаление материалов, установка текущей даты и т.д. Класс использует внешние зависимости и библиотеки для работы с потоками данных и другим функционалом.

As it turned out, GPT quite clearly determined what this file contains. Let's try it at scale – we modify the request a little, go through the code through our repository, ask GPT via the API to summarize each file and output it to a text file.

We quickly rechecked the assistant's work. Everything was coming together.

The problem is solved, the colleagues' nerves are saved!

Storming problems

Sometimes when dealing with a storm of problems, you don’t know where to start: your thoughts are confused, it’s unclear where the cause is and where the effect is. The problem is often rather psychological – to start correctly, not to lose your way.

Many often use a colleague for this: calling together and trying to solve a problem together is, of course, exciting, but this practice steals a lot of working time from others. Moreover, often a colleague in this process is more like duckling. But interactive.

If you don’t want to distract your colleague, then a chatbot can become such an interlocutor. It is especially useful when you do not have deep technical expertise in a certain area and you need not just a duckling, but a senior duckling who can give you a hint.

And sometimes it’s just embarrassing to ask questions. Probably the most popular is problems with git. Despite the extensive documentation and a huge number of examples, many people point blank ignore studying it and repeat the same mistakes over and over again or mindlessly execute scripts from stackoverflow.

The questioner (who is very ashamed of this part of the article) not only did not link the local repository with the remote one, but also did not commit.

Hidden text

User:
HEAD detached at origin/main what does it mean?

GPT:

The message “HEAD detached at origin/main” in the context of working with the Git version control system indicates that your current working copy of the repository is not at the top of any branch, but in a “detached HEAD” state. This happens when you go directly to a specific commit or tag rather than working within a branch. In this state, you can review the code, test changes on specific commits, but any new commits created in this state will not belong to any branch. If you then move to another branch without creating a new branch for those commits, you risk losing them since they won't be tied to any of the repository branches.
To “fix” this condition and return to working within the branch, you can do one of the following:

If you want to save your changes to a new branch:

git checkout -b новая-ветка

This will create a new branch starting from the current state and switch you to it.

If you want to revert to working on an existing branch and abandon the changes to the detached HEAD state:

git checkout имя-существующей-ветки

For example, to return to the main branch, use:

git checkout main

These commands will help you get back to working normally in Git, where you can continue making branch commits.

User:
warning: remote HEAD refers to nonexistent ref, unable to checkout and how is this?

GPT:
Error message
warning: remote HEAD refers to nonexistent ref, unable to checkout
indicates an issue with a remote repository in Git. It indicates that the HEAD link in the remote repository points to a branch that does not exist in this repository. This can happen for several reasons, for example:
Deleting a branch on a remote repository: If the branch pointed to by the remote repository's HEAD has been deleted, but the HEAD has not been updated to point to an existing branch.
Incorrect configuration of a remote repository: Configuring HEAD in a remote repository may be incorrect if, for example, the wrong branch is specified in the configuration files.

What to do?

To resolve this issue, you can take the following steps:
Check the current HEAD state on the remote repository. This can be done using the git remote show origin command (assuming origin is the name of your remote repository). This command will show you the current state of the branches on the remote repository and which branch HEAD is pointing to.

Fix the HEAD pointer on the remote repository. If you have access to the remote repository settings, make sure that HEAD points to an existing branch. How to do this depends on what service or software you use to host your repository. In some cases, this may require running git symbolic-ref HEAD refs/heads/name of existing branch on the server.

Update the links in the local repository. Once the issue on the remote repository has been fixed, run git remote update origin –prune (or just git fetch –prune) to update the branch information in your local repository. The –prune option will remove stale references to branches that no longer exist on the remote server.

If you do not have access to the remote repository settings (for example, if it is an external repository to which you have limited access), you may need to contact your hosting service administrator or support to have them fix the problem.

Sometimes reasoning requires expertise. It was necessary to transfer data from one table to another using migration. An important nuance was that the service supported work with two DBMSs: PostgreSQL and SQLite.

Correspondence with GPT 3.5 was quite tedious, and it was difficult to get it to produce the desired result. But GPT 4 coped with the task.

The solution is certainly not complete, but the main thing is that it gave impetus to thinking in the right direction without the need to call on senior colleagues.

Hidden text

User:

How to write a migration to take data from a table to another table in EF Core? The migration should run correctly on both PostgreSQL and SQLite.
When migrating, you need to generate a new id of type uuid for each record using only SQL.

GPT:

You can write a migration to move data from one table to another in Entity Framework Core using migrationBuilder.Sql(), which is used to execute raw SQL commands. If you need to perform this action on different types of databases – SQLite and PostgreSQL, you will need to take into account their specifics. One thing to keep in mind is that EF Core doesn't provide a universal way to generate UUID/GUID for different SQL dialects, but you can use raw SQL.

Here is an example migration that can be modified to suit your needs:

csharp
Copy
public partial class DataTransferMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
string idGenerationMethod;

switch(migrationBuilder.ActiveProvider)
{
case “Pomelo.EntityFrameworkCore.MySql”:
case “Microsoft.EntityFrameworkCore.SqlServer”:
idGenerationMethod = “NEWID()”;
break;
case “Npgsql.EntityFrameworkCore.PostgreSQL”:
idGenerationMethod = “uuid_generate_v4()”;
break;
default:
throw new NotSupportedException(“Unknown DB provider: ” + migrationBuilder.ActiveProvider);
}

migrationBuilder.Sql($@”
INSERT INTO NewTable (Id, Column1, Column2)
SELECT {idGenerationMethod}, oldTable.Column1, oldTable.Column2
FROM OldTable as oldTable
“);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
// You can add migration rollback logic here.
// Don't forget about the irreversibility of the operation of generating a new identifier.
}
}

Please replace 'NewTable' and 'OldTable', as well as 'Column1' and 'Column2', with the actual names of your target and source tables and the names of the columns you are moving. idGenerationMethod will be equal to the function your database uses to generate a new uuid or Guid.

Please note that SQLite does not support generating uuid directly in SQL, so if you intend to use SQLite you will have to use other methods. You may have to migrate the data from code rather than from SQL.

Epilogue

Neural networks in various manifestations are increasingly becoming something commonplace, and their implementation in products is becoming more common. We're no exception—we use computer vision and OCR to make it easier for users to enter paper documents into one of our products.

GPT, on the other hand, is a new tool, which means it has not yet been well studied in terms of use.
Therefore, it is too early to evaluate its effectiveness in full-fledged work: the fact that a chatbot could not solve the problem you need does not mean that it cannot do this with sufficient experience in using it. The same can be said about the ability to use search engines – not everyone knows that the search bar of the same Google has built-in search operators and even fewer use them in real life, although this significantly reduces search time.

Its use now, of course, has known disadvantages:

  1. A chatbot can give the wrong answer or even make it up – this is dangerous if you do not have expertise in the task and the result cannot be verified using tooling.

  2. GPT does not know about events and technologies that arose before a certain year—you can’t ask a chatbot about recent problems and technologies.

Despite this, we encourage the use of AI assistants in work – as the experiment with file descriptions showed, the tool can really increase productivity and allows you to apply moral and mental effort to more interesting tasks instead of routine.

And sometimes it just helps to smile.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *