GitHub Copilot 作為 AI 程式碼輔助工具,已成為開發者提升效率的利器。除了基本的程式碼生成外,Copilot 還具備許多進階功能,能進一步最佳化開發流程。本文將探討如何透過 Copilot 的進階技巧,例如利用註解或 Copilot Chat 進行程式碼生成、使用 Copilot 命令自動建立專案或筆記本、應用除錯技巧提升程式碼穩定性,以及運用 Copilot 進行程式碼審查和最佳化,以開發更簡潔、高效且易於維護的程式碼。

提升 GitHub Copilot 的使用效率

簡介

到目前為止,你已經學會瞭如何使用 GitHub Copilot 和 ChatGPT 的基礎知識。這些基礎知識足以讓你學會如何撰寫提示(prompt)並接受它們。同時,也足以讓你開始建立機器學習、資料科學和網頁開發的解決方案。在網頁開發的案例中,你還發現 Copilot 在處理現有程式碼函式庫時是一個高效的工具。在本章中,我們希望將你的 AI 工具知識提升到下一個層次,因為還有更多的功能可以利用。

有很多方法可以提高效率;在後面的章節中,你將看到 Copilot 中的一些功能,讓你可以搭建檔案,並且你將更多地瞭解你的工作空間,甚至是 Visual Studio Code 作為編輯器的一些節省時間的功能。本章將介紹一些最重要的功能。

在本章中,我們將:

  • 學習如何使用 Copilot 生成程式碼
  • 使用 Copilot 命令自動執行任務,例如生成新專案
  • 應用技術來除錯和排查程式碼
  • 使用 Copilot 審查和最佳化程式碼

程式碼生成和自動化

Copilot 的核心是一個程式碼生成器。它可以為你生成文字,無論是檔案還是原始碼。

有兩種主要的方法可以使用 Copilot 生成程式碼:

  • 透過在活躍的編輯器中使用註解作為提示
  • 使用 Copilot Chat,這允許你輸入提示

Copilot 的活躍編輯器

當你在活躍的編輯器中時,Copilot 可以生成程式碼。要生成程式碼,你需要寫一個註解作為提示。不同的程式語言有不同的註解方式。例如,在 JavaScript 和 C# 中,你使用 //,而在 HTML 中,你會輸入 <!--

讓我們來看一個例子: // 建立一個名為 add 的函式,接受兩個引數

function add(num1, num2) {
    throw new Error('Function not implemented.');
}

在這個例子中,你沒有得到任何建議。你有幾個選擇:

  • 按下 Return 鍵以取得更多建議
  • 開始輸入你想要生成的程式碼的一部分,Copilot 將根據你的輸入建議程式碼

Copilot Chat

Copilot Chat 是一種透過聊天介面與 Copilot 互動的方式。要啟用 Copilot Chat,請點選 Visual Studio Code(或 VS Code)左下角的圖示,這將開啟一個聊天視窗。

讓我們嘗試根據相同的提示生成一些程式碼。讓我們在聊天視窗的輸入文字欄位中輸入提示: 建立一個名為 add 的函式,接受兩個引數

輸出結果分為兩部分:文字指令和程式碼建議。首先是文字指令:

function add(a, b) {
    return a + b;
}

它甚至向你展示瞭如何使用該函式的例子:

const result = add(2, 3);
console.log(result); // 輸出:5

Copilot 命令

如果你在聊天視窗中開始輸入 /,你將看到一個命令列表,你可以使用這些命令與 Copilot 互動。

建立一個筆記本

使用這個命令,你可以建立一個新的筆記本。筆記本是一個可以儲存程式碼片段和文字的地方。要建立一個筆記本,請輸入 /newNotebook,並提供筆記本的名稱,例如 products

你的筆記本在高層次上包含以下內容:

  • import:包含處理資料集所需的所有匯入函式庫
import pandas as pd # 匯入 Pandas 函式庫
import numpy as np # 匯入 NumPy 函式庫
import matplotlib.pyplot as plt # 匯入 Matplotlib 函式庫用於資料視覺化
import seaborn as sns # 匯入 Seaborn 函式庫用於資料視覺化

內容解密:

這段程式碼的作用是匯入常用的資料科學函式庫,包括 Pandas、NumPy、Matplotlib 和 Seaborn。這些函式庫分別用於資料處理、數值運算和資料視覺化。

  • 載入資料:包含從 CSV 檔案載入資料的程式碼
# 從 CSV 檔案載入產品資料到 Pandas DataFrame
product_data = pd.read_csv('product_data.csv')
# 從 JSON 檔案載入產品資料到 Pandas DataFrame
# product_data = pd.read_json('product_data.json')
# 顯示 DataFrame 的前 5 行
print(product_data.head())

內容解密:

這段程式碼的作用是從 CSV 檔案中載入資料到 Pandas DataFrame 中,並顯示前 5 行資料。這裡假設有一個名為 product_data.csv 的檔案,你需要根據實際情況調整檔名。

  • 探索產品資料:包含檢查資料的操作
# 使用 Pandas 函式探索產品資料
# 顯示 DataFrame 的最後 5 行
print(product_data.tail())
# 顯示 DataFrame 的摘要資訊
print(product_data.info())
# 顯示 DataFrame 的統計摘要
print(product_data.describe())

內容解密:

這段程式碼的作用是探索載入的資料,包括顯示最後 5 行、摘要資訊和統計摘要,以瞭解資料的基本情況。

  • 篩選產品資料:包含篩選資料的操作
# 使用布林索引根據特定條件篩選產品資料
filtered_data = product_data[(product_data['category'] == 'electronics') & (product_data['price'] < 100)]
# 顯示篩選後的資料
print(filtered_data)

內容解密:

這段程式碼的作用是根據特定條件篩選資料,例如篩選出類別為 ’electronics’ 且價格小於 100 的產品,並顯示篩選後的結果。

  • 排序資料:包含排序操作
# 使用 sort_values() 函式根據一或多個列對產品資料進行排序
# 按價格升序排序
product_data.sort_values(by='price', ascending=True, inplace=True)
# 按類別升序排序,然後按價格降序排序
product_data.sort_values(by=['category', 'price'], ascending=[True, False], inplace=True)

內容解密:

這段程式碼的作用是對產品資料進行排序,可以根據單一列(如價格)或多列(如類別和價格)進行排序,並可以選擇升序或降序排列。

提升 GitHub Copilot 的使用效率

資料處理與分析

GitHub Copilot 不僅能幫助開發者撰寫程式碼,還能在資料處理和分析方面提供便利。以產品資料的處理為例,我們可以使用 pandas 函式庫來讀取、排序和聚合資料。

資料排序

import pandas as pd

# 假設 product_data 是我們的 DataFrame
# 按照價格對產品資料進行排序
product_data = product_data.sort_values(by='price')

# 顯示排序後的資料
print(product_data)

內容解密:

  1. 匯入 pandas 函式庫:使用 import pandas as pd 匯入 pandas 並簡化其名稱為 pd,以便於後續使用。
  2. sort_values 方法:利用 sort_values 方法對 DataFrame 進行排序,引數 by='price' 指定按照 price 列進行排序。
  3. print 陳述式:輸出排序後的 DataFrame,以便檢查結果。

資料聚合

# 按照類別分組並計算每個類別的總價格
category_total_price = product_data.groupby('category')['price'].sum()
print(category_total_price)

# 計算每個類別的平均價格
category_avg_price = product_data.groupby('category')['price'].mean()
print(category_avg_price)

# 統計每個類別的產品數量
category_product_count = product_data.groupby('category')['product_id'].count()
print(category_product_count)

內容解密:

  1. groupby 方法:利用 groupby 方法對資料進行分組,這裡是根據 category 列進行分組。
  2. summeancount 方法:對分組後的資料進行聚合運算,分別計算總和、平均值和計數。
  3. 輸出結果:列印預出每個類別的總價格、平均價格和產品數量,以便進一步分析。

建立新專案

使用 GitHub Copilot 建立新專案可以節省時間。在聊天視窗中輸入 /new 命令,並提供專案描述,例如 “React”,Copilot 將自動建立一個包含 React 專案範本的新專案。

專案結構範例:

my-react-app
├── public
│ ├── index.html
│ └── favicon.ico
├── src
│ ├── App.js
│ ├── index.js
│ ├── components
│ │ ├── Customer.js
│ │ ├── Product.js
│ │ ├── CustomerList.js
│ │ └── ProductList.js
│ ├── data
│ │ ├── customers.json
│ │ └── products.json
│ └── styles
│ ├── App.css
│ ├── Customer.css
│ ├── Product.css
│ ├── CustomerList.css
│ └── ProductList.css
├── package.json
└── README.md

內容解密:

  1. public 資料夾:包含 index.html,它是應用程式的入口點。
  2. src 資料夾:包含應用程式的所有原始碼,並進一步分為 componentsdatastyles 等子資料夾,以保持程式碼的組織性。
  3. 其他檔案:如 package.jsonREADME.md,這些檔案對於專案的設定和說明非常重要。

除錯與故障排除

GitHub Copilot 可以幫助改程式式碼的除錯和故障排除能力。以下是一個 Flask API 的範例,展示如何增強除錯功能。

原始程式碼:

from flask import Flask, jsonify, request
import sqlite3

app = Flask(__name__)
conn = sqlite3.connect('products.db')
c = conn.cursor()

# 建立 products 資料表(如果不存在)
c.execute('''CREATE TABLE IF NOT EXISTS products
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
price REAL)''')
conn.commit()

@app.route('/products', methods=['GET'])
def get_products():
    # 從資料函式庫檢索所有產品
    c.execute('SELECT * FROM products')
    products = c.fetchall()
    response = [{'id': p[0], 'name': p[1], 'price': p[2]} for p in products]
    return jsonify(response)

@app.route('/products', methods=['POST'])
def add_product():
    data = request.get_json()
    name = data['name']
    price = data['price']
    c.execute('INSERT INTO products (name, price) VALUES (?, ?)', (name, price))
    conn.commit()
    return jsonify({'message': 'Product added successfully'})

if __name__ == '__main__':
    app.run(debug=True)

改進後的程式碼(加入除錯功能):

from flask import Flask, jsonify, request
import sqlite3

app = Flask(__name__)
conn = sqlite3.connect('products.db')
c = conn.cursor()

# 建立 products 資料表(如果不存在)
c.execute('''CREATE TABLE IF NOT EXISTS products
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
price REAL)''')
conn.commit()

@app.route('/products', methods=['GET'])
def get_products():
    try:
        c.execute('SELECT * FROM products')
        products = c.fetchall()
        response = [{'id': p[0], 'name': p[1], 'price': p[2]} for p in products]
        return jsonify(response)
    except Exception as e:
        app.logger.error(str(e))
        return jsonify({'error': 'An error occurred while retrieving products'})

@app.route('/products', methods=['POST'])
def add_product():
    try:
        data = request.get_json()
        name = data['name']
        price = data['price']
        c.execute('INSERT INTO products (name, price) VALUES (?, ?)', (name, price))
        conn.commit()
        return jsonify({'message': 'Product added successfully'})
    except Exception as e:
        app.logger.error(str(e))
        return jsonify({'error': 'An error occurred while adding the product'})

if __name__ == '__main__':
    app.run(debug=True)

內容解密:

  1. try/except 區塊:在 get_productsadd_product 函式中加入 try/except 區塊,以捕捉並處理可能發生的異常。
  2. 錯誤記錄:使用 app.logger.error 記錄錯誤訊息,以便於除錯。
  3. debug=True:在 app.run() 中設定 debug=True,以啟用除錯模式,提供更詳細的錯誤資訊。

使用 GitHub Copilot 進行程式碼審查與最佳化

接下來,我們將探討如何利用 GitHub Copilot 來協助程式碼審查和最佳化。Copilot 可以根據上下文提供改進建議,幫助開發者寫出更高效、更穩健的程式碼。

提升 GitHub Copilot 的效率:程式碼審查與最佳化技術

在開發過程中,我們經常需要處理程式碼的最佳化問題。GitHub Copilot 是一個強大的工具,可以幫助我們審查和最佳化程式碼。本文將探討如何利用 Copilot 來提升程式碼的效率和可維護性。

使用 Copilot 最佳化程式碼

首先,我們有一個可用的程式碼,但它並未經過最佳化。例如,將程式碼分成不同的檔案是一個良好的實踐。讓我們看看 Copilot 能為我們提供什麼樣的建議。

提示:最佳化選定的程式碼

Copilot 的回應包括文字和程式碼建議:

  • 使用上下文管理器(context manager)來處理資料函式庫連線和遊標(cursor),確保連線在程式碼執行完成後正確關閉,即使發生異常也是如此。
  • 使用列表推導式(list comprehension)將產品轉換為 JSON 回應,這比使用 for 迴圈更簡潔,也可能更快。
  • 使用 Response 物件的 json 引數傳回 JSON 回應,這比使用 jsonify 函式更簡潔。
  • 使用 request.json 屬性從請求主體中檢索產品資料,這是一種更簡潔、更 Pythonic 的做法。

最佳化後的程式碼

from flask import Flask, Response, request
import sqlite3

app = Flask(__name__)

# 如果產品表不存在,則建立它
with sqlite3.connect('products.db') as conn:
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS products
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  name TEXT,
                  price REAL)''')
    conn.commit()

@app.route('/products', methods=['GET'])
def get_products():
    try:
        # 從資料函式庫中檢索所有產品
        with sqlite3.connect('products.db') as conn:
            conn.row_factory = sqlite3.Row
            c = conn.cursor()
            c.execute('SELECT * FROM products')
            products = c.fetchall()
            # 將產品轉換為 JSON 回應
            response = [{'id': product['id'], 'name': product['name'], 'price': product['price']} for product in products]
            return Response(response=str(response).replace("'", '"'), status=200, mimetype='application/json')
    except Exception as e:
        # 記錄錯誤並傳回錯誤訊息
        app.logger.error(str(e))
        return Response(response=str({'error': 'An error occurred while retrieving products'}).replace("'", '"'), status=500, mimetype='application/json')

@app.route('/products', methods=['POST'])
def add_product():
    try:
        # 從請求主體中檢索產品資料
        data = request.json
        name = data['name']
        price = data['price']
        # 將產品插入資料函式庫
        with sqlite3.connect('products.db') as conn:
            c = conn.cursor()
            c.execute('INSERT INTO products (name, price) VALUES (?, ?)', (name, price))
            conn.commit()
        # 傳回成功訊息
        return Response(response=str({'message': 'Product added successfully'}).replace("'", '"'), status=201, mimetype='application/json')
    except Exception as e:
        # 記錄錯誤並傳回錯誤訊息
        app.logger.error(str(e))
        return Response(response=str({'error': 'An error occurred while adding the product'}).replace("'", '"'), status=500, mimetype='application/json')

if __name__ == '__main__':
    app.run(debug=True)

程式碼解析

最大的變化是使用了上下文管理器來處理資料函式庫連線和遊標,確保連線在程式碼執行完成後正確關閉,即使發生異常也是如此。

將程式碼分成不同的檔案

雖然 Copilot 最佳化了程式碼,但我們仍然希望將程式碼分成不同的檔案,以提高可維護性。讓我們看看 Copilot 如何幫助我們實作這一點。

提示:按責任將程式碼分成不同的檔案

Copilot 的回應包括以下檔案:

  • app.py:應用程式的主檔案,負責啟動應用程式和註冊藍圖(blueprint)。
  • database.py:負責處理資料函式庫連線。
  • products.py:負責處理產品 API。

分離後的程式碼

app.py

from flask import Flask
from products import products_bp

app = Flask(__name__)
app.register_blueprint(products_bp)

if __name__ == '__main__':
    app.run(debug=True)

database.py

import sqlite3

def get_db():
    db = sqlite3.connect('products.db')
    db.row_factory = sqlite3.Row
    return db

products.py

from flask import Blueprint, jsonify, request
from database import get_db

products_bp = Blueprint('products', __name__)

@products_bp.route('/products', methods=['GET'])
def get_products():
    try:
        # 從資料函式庫中檢索所有產品
        db = get_db()
        products = db.execute('SELECT * FROM products').fetchall()
        # 將產品轉換為 JSON 回應
        response = [{'id': product['id'], 'name': product['name'], 'price': product['price']} for product in products]
        return jsonify(response)
    except Exception as e:
        # 記錄錯誤並傳回錯誤訊息
        app.logger.error(str(e))
        return jsonify({'error': 'An error occurred while retrieving products'}), 500

@products_bp.route('/products', methods=['POST'])
def add_product():
    try:
        # 從請求主體中檢索產品資料
        data = request.json.get('data', {})
        name = data.get('name', '')
        price = data.get('price', 0)
        # 將產品插入資料函式庫
        db = get_db()
        db.execute('INSERT INTO products (name, price) VALUES (?, ?)', (name, price))
        db.commit()
        # 傳回成功訊息
        return jsonify({'message': 'Product added successfully'}), 201
    except Exception as e:
        # 記錄錯誤並傳回錯誤訊息
        app.logger.error(str(e))
        return jsonify({'error': 'An error occurred while adding the product'}), 500

程式碼解析

現在,我們的程式碼已經按照責任分成不同的檔案。app.py 負責啟動應用程式和註冊藍圖,database.py 負責處理資料函式庫連線,products.py 負責處理產品 API。

進一步地,我們可以改進 database.py,使其使用上下文管理器:

import sqlite3

def get_db():
    with sqlite3.connect('products.db') as db:
        db.row_factory = sqlite3.Row
        return db

def init_db():
    with sqlite3.connect('products.db') as db:
        db.execute('''CREATE TABLE IF NOT EXISTS products
                      (id INTEGER PRIMARY KEY AUTOINCREMENT,
                       name TEXT,
                       price REAL)''')
        db.commit()

工作空間(Workspace)

工作空間是指在一個目錄中開啟的所有檔案。我們希望 AI 助手在提供建議時考慮所有這些檔案。假設我們有以下 web 專案:

src/
app.py
utils.py

在這個專案中,我們可以利用 Copilot 對多個檔案進行審查和最佳化,從而提高整個專案的可維護性和效率。