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)
內容解密:
- 匯入 pandas 函式庫:使用
import pandas as pd匯入 pandas 並簡化其名稱為pd,以便於後續使用。 sort_values方法:利用sort_values方法對 DataFrame 進行排序,引數by='price'指定按照price列進行排序。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)
內容解密:
groupby方法:利用groupby方法對資料進行分組,這裡是根據category列進行分組。sum、mean和count方法:對分組後的資料進行聚合運算,分別計算總和、平均值和計數。- 輸出結果:列印預出每個類別的總價格、平均價格和產品數量,以便進一步分析。
建立新專案
使用 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
內容解密:
public資料夾:包含index.html,它是應用程式的入口點。src資料夾:包含應用程式的所有原始碼,並進一步分為components、data和styles等子資料夾,以保持程式碼的組織性。- 其他檔案:如
package.json和README.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)
內容解密:
try/except區塊:在get_products和add_product函式中加入try/except區塊,以捕捉並處理可能發生的異常。- 錯誤記錄:使用
app.logger.error記錄錯誤訊息,以便於除錯。 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 對多個檔案進行審查和最佳化,從而提高整個專案的可維護性和效率。