iT邦幫忙

2023 iThome 鐵人賽

DAY 5
1
自我挑戰組

用ChatGPT詠唱來完成工作與點亮前後端技能樹系列 第 5

【Day5】指南:讓ChatGPT成為程式碼的開發/運維好夥伴

  • 分享至 

  • xImage
  •  

目前這個系列已挑選ChatGPT、前端&React相關章節出版成書!
感謝大家的閱讀與支持!
《用 ChatGPT 詠唱來點亮 React & 前端技能樹》
歷經重新整理、校正、編排、與修改後,讓章節內容之間的銜接更平順,除了補充上更多的解說之外,甚至有部分章節為重新撰寫的內容,讓理解變得更輕鬆!
目前已在天瓏書局博客來金石堂等通路都買得到了! 也有電子書的選擇!
歡迎各位點擊連結選購,謝謝大家~
https://ithelp.ithome.com.tw/upload/images/20240419/20135750lQM12by6v1.jpg


接下來要講解幾個和語言和技術沒有太大關聯,只要需要與「程式碼」接觸
就能請chatGPT來協助的幾個方式

無論是開發還是要閱讀其他人的程式碼
或是想要學習新語言,都有讓chatGPT來協助自己的機會

以下是我很常使用的幾種情況

  • 提供程式碼範例
  • 解釋程式碼
  • 註解程式碼
  • 翻譯、改寫程式碼
  • 優化程式碼
  • 提供單元測試

這些用法也都會在後續的系列文章中大量出現

另外,在和程式碼有關的使用上,我會建議要清楚指示ChatGPT要提供完整的程式碼
上一篇有提到關於Custom instructions (客制化說明)
我在使用上,都會將「要提供完整程式碼」的指令放在Custom instructions 中

接下來我就一一的舉例示範,以及展示ChatGPT的回答狀況
以下內容會簡單涵蓋 js、php、jest等網頁前後端語言,但不熟悉的話也沒關係
因為這些語言的熟悉不是本篇的重點

提供程式碼範例

「請提供XXX的範例」
當我在學習一個新的語言、或是新的語法、不熟悉的語法時
可以直接對著ChatGPT下達的一個命令,請他提供示範
從示範中學習使用的方式,或是再從中去替換成自己的情況

假設,我今天要第一次來學習如何撰寫單元測試,但也沒有實際的情境或程式碼需要進行測試
因此直接提出一個很廣泛的 「請提供一段jest單元測試的範例」
以下是ChatGPT的回答
https://ithelp.ithome.com.tw/upload/images/20230915/20135750wR8xz7S7l9.png

這個用法我自己很常使用,逐步的跟著指示就能完成第一個新技術的hello world

途中有不明白的地方還能進一步地做詢問
https://ithelp.ithome.com.tw/upload/images/20230915/2013575052IFZ2W4ln.png
一邊思考一邊做詢問,是我認為很有效率的學習方法之一

解釋程式碼

當需要閱讀他人的程式碼時,若程式碼中有不清楚作用的內容
就可以請ChatGPT來進行解說

接下來,我拿上上一篇ChatGPT提供給我們的程式碼當作範例
我這邊特別把function名稱與註解給替換掉,避免他從名字或註解去進行判斷
https://ithelp.ithome.com.tw/upload/images/20230915/20135750VPsxKUmTrc.png

以下是他的回答

這段程式碼是一個 JavaScript 函式,命名為 f。讓我們來逐步解釋:

  1. function f(inputArray) {:這行定義了一個函式 f,接受一個叫做 inputArray 的參數。
  2. const charCodeA = 'A'.charCodeAt(0) - 1;:這行宣告了一個常數 charCodeA,其值為大寫字母 'A' 的 Unicode 編碼減去 1,這樣 charCodeA 的值就是 65 - 1 = 64。
  3. const charCodea = 'a'.charCodeAt(0) - 1;:這行宣告了另一個常數 charCodea,其值為小寫字母 'a' 的 Unicode 編碼減去 1,這樣 charCodea 的值就是 97 - 1 = 96。
  4. const resultArray = [];:這行宣告了一個空陣列 resultArray,用來存放符合特定條件的字串。
  5. for (let str of inputArray) {:這是一個迴圈,它會遍歷 inputArray 中的每一個元素,並將其暫時命名為 str
  6. let sum = 0;:這行宣告了一個變數 sum,並初始化為 0,用來累加字母的編碼值。
  7. for (let i = 0; i < str.length; i++) {:這是另一個迴圈,它會遍歷字串 str 中的每一個字符。
  8. let charCode = str.charCodeAt(i);:這行取得字串 str 中第 i 個字符的 Unicode 編碼,並將其儲存在變數 charCode 中。
  9. 接下來的 if-else if-else 條件式是在檢查 charCode 的範圍,並依照字母的大小寫分別處理:
    • 如果 charCode 在大寫字母範圍 (65 到 90 之間),則 sum 會加上 charCode 減去 charCodeA,這樣就能得到該字母在字母表中的位置。
    • 如果 charCode 在小寫字母範圍 (97 到 122 之間),則 sum 會加上 charCode 減去 charCodea,同樣得到該字母在字母表中的位置。
    • 如果 charCode 為空格 (32),則不進行任何操作。
  10. if (sum === 100) {:這行檢查變數 sum 是否等於 100。
  11. resultArray.push(str);:如果 sum 等於 100,則將目前的字串 str 加入到 resultArray 陣列中。
  12. }:結束內層迴圈。
  13. }:結束外層迴圈。
  14. return resultArray;:這行回傳最終的結果陣列 resultArray

總括來說,這段程式碼的功能是接受一個包含多個字串的陣列 inputArray,然後對於每個字串進行處理,計算字母在字母表中的位置總和,如果總和等於 100,則將該字串存入一個結果陣列中,最終返回這個結果陣列。

到這個程度我覺得可以了。回答正確

註解程式碼

這個和上面一個「解釋」的用法有一點類似,但也可以用在自己開發的程式碼需要撰寫註解

可以是因為懶得寫註解,然後請ChatGPT來協助撰寫

好的,以下是已為程式碼加上詳細註解:

// 定義一個名為 f 的函式,接受一個名為 inputArray 的陣列作為參數
function f(inputArray) {
    // 取得大寫字母 A 的 Unicode 編碼值並減去 1,存入 charCodeA 變數
    const charCodeA = 'A'.charCodeAt(0) - 1;
    // 取得小寫字母 a 的 Unicode 編碼值並減去 1,存入 charCodea 變數
    const charCodea = 'a'.charCodeAt(0) - 1;
    // 建立一個空陣列,用來儲存符合條件的字串
    const resultArray = [];
    // 開始迴圈,逐一處理 inputArray 中的字串
    for (let str of inputArray) {
        // 初始化一個變數 sum 用來累加字元的值
        let sum = 0;
        // 開始內部迴圈,逐一處理字串中的字元
        for (let i = 0; i < str.length; i++) {
            // 取得字元的 Unicode 編碼值
            let charCode = str.charCodeAt(i);
            // 檢查字元是否為大寫英文字母
            if (charCode >= 65 && charCode <= 90) {
                // 若是大寫字母,將其值轉換為 1 到 26 之間的數字,並加到 sum 上
                sum += charCode - charCodeA;
            } else if (charCode >= 97 && charCode <= 122) {
                // 檢查字元是否為小寫英文字母
                // 若是小寫字母,同樣將其值轉換為 1 到 26 之間的數字,並加到 sum 上
                sum += charCode - charCodea;
            } else if (charCode === 32) {
                // 檢查字元是否為空格,若是則不影響 sum 的值
                sum += 0;
            }
        }
        // 檢查 sum 是否等於 100,若是則將字串加入 resultArray 中
        if (sum === 100) {
            resultArray.push(str);
        }
    }
    // 回傳最終的結果陣列
    return resultArray;
}

這樣就為你的程式碼添加了詳細的註解,讓你更容易理解每一部分的功能和邏輯。如果你對任何部分有疑問,請隨時提問。

風格、格式可以根據喜好指定
由於我指定為詳細、清楚的註解,於是結果就會變成這樣

翻譯、改寫程式碼

當一段程式碼需要進行語言的轉換,例如公司內要翻新系統、翻新語言的時候
就可以請ChatGPT來提供改寫、轉換

向ChatGPT說明清楚要從什麼語言轉換到什麼語言、可以用哪些套件或是技術來進行
ChatGPT翻出來的東西基本上就是再順過一次就可以使用了

一樣拿上面的程式碼來進行舉例:
https://ithelp.ithome.com.tw/upload/images/20230915/20135750konsuUOCj6.png
以下是ChatGPT的回答

將您提供的 PHP 程式碼轉換成 JavaScript 如下所示:

function f(inputArray) {
    const charCodeA = 'A'.charCodeAt(0) - 1;
    const charCodea = 'a'.charCodeAt(0) - 1;
    const resultArray = [];
    inputArray.forEach(str => {
        let sum = 0;
        for (let i = 0; i < str.length; i++) {
            const charCode = str.charCodeAt(i);
            if (charCode >= 65 && charCode <= 90) {
                sum += charCode - charCodeA;
            } else if (charCode >= 97 && charCode <= 122) {
                sum += charCode - charCodea;
            } else if (charCode === 32) {
                sum += 0;
            }
        }
        if (sum === 100) {
            resultArray.push(str);
        }
    });
    return resultArray;
}

這段 JavaScript 程式碼與您提供的 PHP 程式碼功能相同,可以接受一個字串陣列 inputArray 作為輸入,並返回符合條件的字串陣列。請在您的前端專案中使用這個 JavaScript 函式。如果您需要任何進一步的協助,請隨時告訴我!

由於我自己在工作中,有需要進行 php+pdo 轉 nodeJS + nextJS + knex + swagger 的翻新
這時候逐一將function丟給ChatGPT
我原本可能要進行一整天的工作,就能在短時間內完成

我需要做的只有順一次流程,確認邏輯沒有漏寫
把時間放在實際測試功能,或處理單元測試等

優化程式碼

程式碼除了講究能夠執行與其結果的正確性之外,也講求可讀性、效能優化等等
ChatGPT可以協助我們進行程式碼的優化

以JS來說,他可能會推薦我們使用async await的語法,以及高階函數.map的使用
除了提供優化版本的程式碼外,ChatGPT還會向我們解釋他優化了哪個部分
可以從中去決定是不是要採用他的方式,以及學習優化的內容
下一次寫出來的程式,也許就能照著這樣的方式或風格來撰寫

另外,延續前一個「翻譯、改寫程式碼」的用法
由於不同語言間可能有不一樣的邏輯思維或是用法、習慣
在做翻譯改寫的時候,通常是功能上的直接做翻譯
但是結構或是效能優化等等,不一定會做得最好

因此我個人在使用上,也很常在請ChatGPT進行程式碼的翻譯改寫之後
再請他直接針對該程式碼進行優化
得到的程式碼就會接近「本來就是用這個語言」寫出來的風格與邏輯
也確保了程式碼的品質

繼續用上面的JS範例來進行
https://ithelp.ithome.com.tw/upload/images/20230915/20135750DcyVFRz8Fq.png

以下是ChatGPT的回答

你好!這是你提供的程式碼,我會協助你進行優化:

function f(inputArray) {
    const resultArray = [];
    for (let str of inputArray) {
        let sum = 0;
        for (let i = 0; i < str.length; i++) {
            let charCode = str.charCodeAt(i);
            if (charCode >= 65 && charCode <= 90) {
                sum += charCode - 64; // 直接減去 'A' 的 charCode
            } else if (charCode >= 97 && charCode <= 122) {
                sum += charCode - 96; // 直接減去 'a' 的 charCode
            } else if (charCode === 32) {
                sum += 0;
            }
        }
        if (sum === 100) {
            resultArray.push(str);
        }
    }
    return resultArray;
}

這個優化主要在以下幾點:

  1. 原本使用 const charCodeA = 'A'.charCodeAt(0) - 1;const charCodea = 'a'.charCodeAt(0) - 1; 來獲得字元 'A' 和 'a' 的 charCode,現在直接使用 charCode - 64charCode - 96 來計算字元對應的數值。
  2. if (charCode === 32) 的情況下,sum 會加上 0,這部分可以省略。

這樣的修改可以使程式碼更加簡潔和容易理解。如果你有任何疑問或需要進一步的解釋,請隨時告訴我。

提供單元測試

目前實測來說,ChatGPT可以提供簡易的單元測試

當需要測試的情境變得複雜的時候,效果不見得那麼好
但請ChatGPT提供單元測試,仍然可以減少去撰寫相關格式的時間

我們繼續用一樣的function來請ChatGPT提供單元測試看看

https://ithelp.ithome.com.tw/upload/images/20230915/20135750tE6eamyoAB.png

當然可以幫你撰寫 Jest 單元測試!以下是程式碼以及對應的單元測試:

// main.js

function f(inputArray) {
    const charCodeA = 'A'.charCodeAt(0) - 1;
    const charCodea = 'a'.charCodeAt(0) - 1;
    const resultArray = [];
    for (let str of inputArray) {
        let sum = 0;
        for (let i = 0; i < str.length; i++) {
            let charCode = str.charCodeAt(i);
            if (charCode >= 65 && charCode <= 90) {
                sum += charCode - charCodeA;
            } else if (charCode >= 97 && charCode <= 122) {
                sum += charCode - charCodea;
            } else if (charCode === 32) {
                sum += 0;
            }
        }
        if (sum === 100) {
            resultArray.push(str);
        }
    }
    return resultArray;
}

module.exports = f;

接著是 Jest 單元測試:

// main.test.js

const f = require('./main');

test('檢查函式是否正確運作', () => {
    const inputArray = ['abc', 'def', 'ghi'];
    const expectedOutput = ['def'];

    const result = f(inputArray);

    expect(result).toEqual(expectedOutput);
});

test('檢查空陣列時是否回傳空陣列', () => {
    const inputArray = [];
    const expectedOutput = [];

    const result = f(inputArray);

    expect(result).toEqual(expectedOutput);
});

test('檢查含有特殊字元的情況', () => {
    const inputArray = ['abc', 'de f', 'gh i'];
    const expectedOutput = ['de f', 'gh i'];

    const result = f(inputArray);

    expect(result).toEqual(expectedOutput);
});

這些測試涵蓋了幾個不同的情境,可以幫助你確保你的函式正確運作。如果你有任何其他問題或需要進一步協助,請隨時告訴我!

OK,從這個例子中我們也能明白,ChatGPT真的很不擅長運算

這個與運算相關的功能,他並不知道正確答案應該要是什麼
但是他提供了我們格式、範例
也提醒我們要去處理與測試「空陣列的時候」、「有特殊字元的情況」
只要自己去把輸入與預期答案給填上去,這個單元測試基本上就完成了

舒舒服服、輕輕鬆鬆

結論

我自己常用的六個與程式碼相關的用法:

  • 提供程式碼範例
  • 解釋程式碼
  • 註解程式碼
  • 翻譯、改寫程式碼
  • 優化程式碼
  • 提供單元測試

這六個用法在我工作上班時,很大幅度的提升了我的效率
我不需要把時間大量花在打字、設中斷點追code上
就能快速的將工作完成、理解程式碼,甚至是上手一個新語言

我是使用ChatGPT輕鬆上班的前端工程師一宵三筵,我們明天見~


上一篇
【Day4】量身打造:利用Custom instructions (自訂指令) 來打造工程師的專屬助手
下一篇
【Day6】ChatGPT請教教我:網頁基礎入門 - Html、JavaScript、CSS
系列文
用ChatGPT詠唱來完成工作與點亮前後端技能樹56
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言