GitHub Copilot Labsを使ってみた

# GitHub Copilot Labsとは？
VSCodeの拡張機能として、***GitHub Copilot Labs*** をインストールすれば、コードの解説をしてくれたり、リファクタリングしてくれたり、バグを修正してくれたりと便利な機能がたくさんあります。

以前に筆者が書いた以下のようなChatGTPの拡張機能のようなものです。

https://qiita.com/tak001/items/c3000b3ce9b6e72b2ae5

公式ページより抜粋

https://githubnext.com/projects/copilot-labs

> GitHub Copilotの実験的なアプリケーションのためのVS Code拡張機能。
> 
> GitHub Copilotは、開発者向けの画期的なAIペアプログラマですが、私たちはコーディングの未来を探求し始めたばかりです。テクニカルプレビューの期間中、Copilotチームは提案の質を向上させ、安全機能を追加しました。しかし、Copilotがコード提案以外にも提供できる潜在的な助けを見るのは難しいことではありません。
> 
> 本日、GitHub Copilot LabsというVS Codeの拡張機能を発表します。この拡張機能は、GitHub Copilot 拡張機能とは別のもので、GitHub Copilot に依存しています。Copilotが一般提供に向けて前進している間、Labsは開発者の体験を向上させる機械学習の実験的なアプリケーションのための実験場となる予定です。
> 
> Copilot Nightlyをお使いの方でしょうか？その拡張機能にバンドルされていた以前のバージョンのLabsを使用していたかもしれません。私たちは、Copilot Nightlyのこれらの機能をすべてこの独立した拡張機能に移植しています。
> 
> Copilot Labsは実験的なものであるため、時折、不具合が発生する可能性があります。初期の機能を共有することで、何が有効で何が有効でないかを学び、フィードバックを取り入れたいと考えています。Labsの実験がGitHub Copilotの恒久的な機能になることもあればならないこともありますが、皆さんの協力があれば、将来の取り組みに反映させることができます。

# 利用手順
- ***前提としてGitHub Copilot を利用している必要があります***
  - 概要や利用手順については[こちら](https://note.com/npaka/n/ne208e3482bab)が参考になります
- VSCodeに「GitHub Copilot」がインストールされていない場合、インストールしてください。
- [GitHub Copilot Labs を VSCodeからインストールします](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-labs)

- EXTENSIONS から「gitHub copilot labs」と検索する
- 該当の拡張機能を install する
![Screenshot 2023-03-21 at 2.07.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/bfa73ade-202c-830a-9e80-35bd1ea4f7c1.png)

- VSCodeの拡張機能が install できたら、右下のアカウントアイコンから「Grant access to GitHub for GitHub Copilot Labs...」をクリックする

![Screenshot 2023-03-21 at 2.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/1d3e99d8-ecc6-c1f1-6293-6d1d0dda1541.png)

- 確認されるので「Allow」をクリックする
![Screenshot 2023-03-21 at 2.07.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/52c9c359-6f77-fa39-2724-248cbe80ccba.png)

- Sign up をクリック
![Screenshot 2023-03-21 at 2.08.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/13f4fa37-6cdd-78d4-965e-8b44d7e768ed.png)

- [公式ページ](https://githubnext.com/projects/copilot-labs)に飛ぶので「Sign up for Copilot Labs」をクリック
![Screenshot 2023-03-21 at 2.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/074a1fdb-48a9-8198-d0d8-fcb06999e54b.png)

- GitHubアカウントの連携を求められるので「Authorize Next Waitlist」をクリックする
![Screenshot 2023-03-21 at 2.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/7412aa66-3675-3ee5-270c-ee2b5ce0dcf0.png)

- 完了すると以下のようなページに遷移するので、そのまま閉じます
![Screenshot 2023-03-21 at 2.09.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/1efbe431-4b96-83e9-dc6b-4316515ce4d6.png)


![Screenshot 2023-03-21 at 2.09.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/9cd9550b-4040-81fc-9858-e8c77df70024.png)

# インストール後
インストールが完了すると、サイドバーに GitHub Copilot のアイコンが表示されます。
![Screenshot 2023-03-21 at 22.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/2b96bec4-32ca-0d52-bd2c-98b83f18a836.png)

上から
- **EXPLAIN** -> コードの解説
- **LANGUAGE TRANSLATION** -> 言語の変換(例：JavaScriptのコードをPythonへ変換)
- **BRUNSHES** -> アイコンをクリックすることで各種機能が使用できる
- **TEST GENERATION** -> テストコードの作成

# 使用方法
- まずは該当のコードを範囲選択します
  - 以下のコードは例によってわざとバグを仕込んだコードにしています

## コードの解説
- EXPLAIN から Explain code を選択して、「Ask Copilot」をクリック

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3339393631302f37663462373431612d366432662d383163632d663934642d3463653032656534663062642e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/cb54f031-b556-f541-d13d-0396361e5b96.png)

- 以下のように解説してくれます

![Screenshot 2023-03-21 at 23.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/6694487a-95e0-2823-dd60-f9251910efbf.png)

```text:原文
RESULT
/* Here is the explanation for the code above:
1. for(let i = 1; i < 100; i++) { 
2.   if(i % 3 === 0) {
3.     console.log("Fizz")
4.   } else if(i % 5 === 0) {
5.     console.log("Buzz")
6.   } else if (i % 15) {
7.     console.log("FizzBuzz")
8.   } else {
9.     console.log(i)
10.  }
11. }

1. This line is the for loop. It is saying that i should start at 1 and go up to 100. It is also saying that i should increase by 1 each time it loops.
2. This line is the if statement. It is saying that if the remainder of i divided by 3 is equal to 0, then do the code on line 3.
3. This line is the console.log() method. It is saying to print "Fizz" to the console.
4. This line is the else if statement. It is saying that if the remainder of i divided by 5 is equal to 0, then do the code on line 5.
5. This line is the console.log() method. It is saying to print "Buzz" to the console.
6. This line is the else if statement. It is saying that if the remainder of i divided by 15 is equal to 0, then do the code on line 7.
7. This line is the console.log() method. It is saying to print "FizzBuzz" to the console.
8. This line is the else statement. It is saying that if the if and else if statement are false, then do the code on line 9.
9. This line is the console.log() method. It is saying to print i to the console.
10. This line is the closing bracket for the for loop.
11. This line is the closing bracket for the program. */
```

```text:翻訳
リザルト
/* 以下、上記のコードについて説明します。
1. for(let i = 1; i < 100; i++) {. 
2. if(i % 3 === 0) {.
3. console.log("Fizz")を実行します。
4.   } else if(i % 5 === 0) {。
5. console.log("バズ")
6.   } else if (i % 15) {
7. console.log("FizzBuzz")を実行します。
8.   } else {
9. console.log(i)
10.  }
11. }

1. この行は、forループです。この行は、「1から始めて100まで上げる」といっています。また、ループするたびに1ずつ増えていくことも言っています。
2. この行はif文です。iを3で割った余りが0になったら、3行目のコードを実行する、と言っているのです。
3. この行は、console.log()メソッドです。コンソールに "Fizz "と表示することを意味しています。
4. この行は、else if文です。iを5で割った余りが0になるなら、5行目のコードを実行せよと言っています。
5. この行は、console.log()メソッドです。コンソールに "Buzz "と表示することを意味しています。
6. この行は、else if文です。iを15で割った余りが0になるなら、7行目のコードを実行せよと言っています。
7. この行は、console.log()メソッドです。コンソールに "FizzBuzz "と表示することを意味しています。
8. この行はelse文です。if文とelse文がfalseなら、9行目のコードを実行せよということです。
9. この行は、console.log()メソッドです。コンソールにiを表示することを意味しています。
10. この行は、forループの閉じ括弧です。
11. この行は、プログラムの閉じ括弧です。*/
```

## 他のプログラミング言語に翻訳
- LANGUAGE TRANSLATION の「Translate code into」から、変換したい言語を選択して「Ask Copilot」をクリックします

![Screenshot 2023-03-21 at 23.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/94977867-0d71-db01-9815-31eb833140f5.png)

- 以下のように変換してくれます(微妙にバグったままです)
```py
for i in range(1, 100):
  if i % 3 == 0:
    print("Fizz")
  elif i % 5 == 0:
    print("Buzz")
  elif i % 15 == 0:
    print("FizzBuzz")
  else:
    print(i)
```

## 型の追加
- BRUNSHES から `ADD TYPES` をクリックする

```typescript:変更前
for(let i = 1; i < 100; i++) {
  if(i % 3 === 0) {
    console.log("Fizz")
  } else if(i % 5 === 0) {
    console.log("Buzz")
  } else if (i % 15) {
    console.log("FizzBuzz")
  } else {
    console.log(i)
  }
}
```

```typescript:変更後
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

命名などの細かい箇所は人の手で修正する必要がありますが、
微妙なバグも直してくれつつメソッド化もしてくれました。

## コメントでコードの概要を追加
- BRUNSHES から `READABLE` をクリックする

```typescript:変更後
// This function will return the correct string for any number given to it.
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

// This loop will run 99 times, starting at 1 and ending at 99.
for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

## バグを修正
- BRUNSHES から `FIX BUG` をクリックする

```typescript:変更前
// This function will return the correct string for any number given to it.
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

// This loop will run 99 times, starting at 1 and ending at 99.
for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

```typescript:変更後
// This function will return the correct string for any number given to it.
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

// This loop will run 100 times, starting at 1 and ending at 100.
for(let i = 1; i <= 100; i++) {
  console.log(fizzBuzz(i))
}
```

1〜99までのループを1〜100までにしてくれました。

## デバック用のコードを追加
- DEBUG をクリックすると、デバック用のコードを追加してくれます。
  - console.log()を追加してくれます

```typescript:変更後
// This function will return the correct string for any number given to it.
function fizzBuzz (n: number): string {
  console.log("Checking if " + n + " is divisible by 15")
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

// This loop will run 99 times, starting at 1 and ending at 99.
for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

## デバック用のコードを削除
- `CLEAN` をクリックすると、デバック用のコードを削除してくれます。

```typescript:変更後
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

## コメントを追加
- `LIST STEPS` をクリックすると、コメントを追加してくれます。

```typescript:変更前
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

```typescript:変更後
// Print the numbers from 1 to 100, replacing every multiple of 3 with "Fizz", every multiple of 5 with "Buzz", and every multiple of both with "FizzBuzz".
// This is a classic beginner programming challenge.
// The code has been written for you, but you should add comments to describe each step.
// If you're not sure what a step does, try running it and seeing how it affects the output.

// Define a function called "fizzBuzz" that takes a single number as an argument.
function fizzBuzz (n: number): string {
  // If the number is divisible by 15, return "FizzBuzz".
  if(n % 15 === 0) {
    return "FizzBuzz"
  // Otherwise, if the number is divisible by 3, return "Fizz".
  } else if(n % 3 === 0) {
    return "Fizz"
  // Otherwise, if the number is divisible by 5, return "Buzz".
  } else if(n % 5 === 0) {
    return "Buzz"
  // Otherwise, return the number as a string.
  } else {
    return n.toString()
  }
}

// Loop from 1 to 100.
for(let i = 1; i < 100; i++) {
  // Print the result of calling "fizzBuzz" with each number.
  console.log(fizzBuzz(i))
}
```

## コードの責務を細分化
- `CHUNK` をクリックすると責務を細分化してくれます。

```typescript:変更前
function fizzBuzz (n: number): string {
  if(n % 15 === 0) {
    return "FizzBuzz"
  } else if(n % 3 === 0) {
    return "Fizz"
  } else if(n % 5 === 0) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

```typescript:変更後
function isDivisibleBy(divisor: number, n: number): boolean {
  return n % divisor === 0
}

function fizzBuzz(n: number): string {
  if(isDivisibleBy(15, n)) {
    return "FizzBuzz"
  } else if(isDivisibleBy(3, n)) {
    return "Fizz"
  } else if(isDivisibleBy(5, n)) {
    return "Buzz"
  } else {
    return n.toString()
  }
}

for(let i = 1; i < 100; i++) {
  console.log(fizzBuzz(i))
}
```

## コードの堅牢化
- `MAKE ROBUST` をクリックするとコードを安全にしてくれます。
  - 申し訳ございません、これは例として良いコードが思い浮かびませんでした。。

# 関連記事
https://qiita.com/tak001/items/c3000b3ce9b6e72b2ae5

https://qiita.com/tak001/items/c6bca65d67843c24478f

# 参考文献
https://githubnext.com/projects/copilot-labs

https://flaming.codes/ja/posts/github-copilot-labs-experimental-extension-to-enhance-github-copilot

https://0115765.com/archives/7493