🔍 搜尋結果:練習

🔍 搜尋結果:練習

後端 JS 訓練二:第6課 ── 回應 http post request

## 課程目標 - 使用 node 與 express 回應 http post request ## 課程內容 前面幾課我們學習了 http get 的寫法,這次來學 http post 的寫法 在「會更新主機資料狀態」的操作時,通常都會用 http post 例如,新增資料、更新資料、刪除資料,等等常見操作! 通常主機資料狀態會放在「資料庫軟體」例如 mysql 裡面,我們簡單起見,放在一個 json 檔案就好! --- 替這課建立 lesson6 資料夾,內容跟 lesson5 一樣即可 新增一個 new.ejs 檔案,放入以下內容 ``` <h1>新同學報到!</h1> <form method="post" action="/create"> name: <input type="text" name="name"> </form> ``` 然後在 index.js 加入這段程式碼 ``` const bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.get('/new', function(req, res){ res.render('new'); }); app.post('/create', (req, res) => { const fs = require('fs'); const name = req.body.name; const data = fs.readFileSync('./lesson6/users.json'); const users = JSON.parse(data); users.push({ name: name }); fs.writeFileSync('./lesson6/users.json', JSON.stringify(users)); res.send('<h1>新增成功!</h1>'); }) ``` 然後去終端機輸入 ``` node lesson6/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/new ``` 你會看到新增同學的頁面與表單! 輸入姓名之後,送出表單就可以新增同學的資料了! --- 開頭跟 bodyParser 有關的兩行,要引入並設定好,才能使用 req.body 的參數 為什麼要加這兩行?這跟 express 的 middleware 機制設計有關,這邊不深入說明 反正就是在需要使用某些功能的時候,express 不會預設通通提供給你,要請你去設定啟用之後,才會支援 --- 之前處理 http get 的 url 參數時,我們使用 req.query 來取得參數 這次處理 http post 的表單參數時,我們使用 req.body 來取得參數 express 會這樣設計,是因為在 http 協定中,這兩種參數本來就放在不同地方喔! 看不太懂沒關係,先照做就對了! --- 檔案處理、新增資料放進 json 檔案的段落,跟之前的課程一樣,忘記的話就回頭翻閱一下吧! ## 課後作業 這次要開發「新增文章」的功能 並且練習用 node 回應 http post request 請把 hw5 的內容複製到 hw6,然後增加 new.ejs 檔案 ``` /repo /hw6 /index.js /homepage.ejs /view.ejs /new.ejs /posts.json /public /style.css ``` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/new` 這個網址 這網址會把 new.ejs 的內容 render 出來,內容就放一個 form 表單 表單內可輸入 `標題` 以及 `文章內容`,點擊送出按鈕會以 http post 的形式發送到 `/create` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/create` 這個網址 將接收到的資料,存進 `posts.json` 裡面 完成以上任務,你就完成這次的課程目標了! --- 在上傳到 github 時,你會注意到因為 `posts.json` 有改變,所以會帶著新資料一起上傳,好像有點怪? 其實,實務上會把資料存在 mysql 這類專門資料庫軟體,不會這樣存在 json 檔案中 本課程為了簡化,所以直接存在 json 檔案,這不是實務正常做法~ 為了方便起見,每次新增文章 `posts.json` 都會改變,就都一起上傳,沒關係~

後端 JS 訓練二:第5課 ── 處理 url 參數

## 課程目標 - 使用 node 與 express 處理 url 參數 ## 課程內容 在瀏覽網站的時候,點擊不同頁面時,有時需要透過 url(網址)附帶一些參數 這課來學習如何用 node 處理 url 參數 替這課建立 lesson5 資料夾,內容跟 lesson4 一樣即可 在 index.js 加入這段程式碼 ``` app.get('/view', (req, res) => { const data = fs.readFileSync('./lesson5/users.json'); const users = JSON.parse(data); const index = req.query.index; const user = users[index]; res.send('<h1>' + user.name + '同學,你好!</h1>'); }); ``` 然後把 hello.ejs 的內容修改成 ``` <div> <% for(var i = 0; i < users.length; i++) { %> <p> <%= users[i].name %>同學,你好! <a href="/view?index=<%= i %>">單獨打招呼頁面</a> </p> <% } %> </div> ``` 然後去終端機輸入 ``` node lesson5/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到每段訊息旁邊,多了一個單獨連結,點下去,就會到單獨打招呼頁面! 操作看看吧!試試看「透過網址傳參數」的感覺! --- 在 http 協定中,網址中出現問號 `?` 代表後面的部份是參數,參數的值應該可以單獨被抓出來 前面說過 `(req, res)` ,很多人會寫 `(request, response)`,兩者意思一樣,就是在 express 中代表請求&回應的物件 這邊是我們第一次使用「請求」物件!我們在請求物件中,使用 `req.query.index` 找出名為 `index` 的參數 然後在首頁,透過迴圈,加上每個單獨頁面的連結,通通使用 `index` 作為參數傳遞 --- 實務上,開發後端應用時,只要是 http get request,有時會透過網址本身代表參數,例如 ``` /view/1 /view/2 /view/3 ``` 有時會透過 url parameter 傳遞參數,例如 ``` /view?id=1 /view?id=2 /view?id=3 ``` 這是一個主觀偏好問題,其實都可以!效果也差不多 這兩種寫法,在各種程式語言中,處理起來有點不一樣 本課就以 url parameter 作為示範,先照做即可,別擔心! ## 課後作業 這次要開發「閱讀單篇文章」的功能 並且練習 url 參數的傳遞&取得 請把 hw4 的內容複製到 hw5,然後增加 view.ejs 檔案 ``` /repo /hw5 /index.js /homepage.ejs /view.ejs /posts.json /public /style.css ``` 修改部落格首頁,替每篇文章加上 <a> 超連結,點擊之後會前往單篇文章的網址 舉例來說,第一篇文章的網址會是 ``` <a href="/view?index=0"> ``` 第二篇的網址會是 ``` <a href="/view?index=1"> ``` 第三篇的網址會是 ``` <a href="/view?index=2"> ``` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/view` 這種網址 然後根據從網址取得的索引參數,找出 posts.json 中對應的文章資料 接著把資料放進 view.ejs 模板中,回應顯示為網頁 請自行設計 view.ejs 的內容,簡單顯示一篇文章內容即可 請稍微加上一點樣式,弄得漂亮一點! 完成以上任務,你就完成這次的課程目標了!

後端 JS 訓練二:第4課 ── 提供靜態檔案

## 課程目標 - 使用 node 與 express 提供靜態檔案 ## 課程內容 目前為止的網頁,都是純 html,太陽春了! 這一課來學習,如何用 node 來提供 css 或圖片之類的「靜態檔案」! 替這課建立 lesson4 資料夾,內容跟 lesson3 同樣之外,再建立一個 public 資料夾,裡面新增 style.css 檔案 ``` /repo /lesson4 /index.js /hello.ejs /users.json /public /style.css ``` 在 index.js 裡面多加一行程式碼 ``` app.use(express.static('./lesson4/public')); ``` 在 style.css 裡面加入一些樣式 ``` p { color: green; } ``` 接著在 hello.ejs 加入樣式連結 ``` <link rel="stylesheet" href="/style.css"> ``` 然後去終端機輸入 ``` node lesson4/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到原本的打招呼訊息,文字變成了綠色! --- 後端程式設計,不論何種程式語言,在提供圖片、css 這種靜態檔案的時候,通常會開一個獨立的 public 資料夾來放檔案 所以本課使用的 `app.use(express.static('./lesson4/public'));` 程式碼 就只是設定一下,請 express 從某個資料夾提供靜態檔案,就這樣而已! ## 課後作業 這次要練習用 node 回應靜態檔案 請把 hw3 的內容複製到 hw4,然後增加 public 資料夾與 style.css 檔案 ``` /repo /hw4 /index.js /homepage.ejs /posts.json /public /style.css ``` 請在 style.css 中,稍微替你的日記首頁加一些樣式,弄得漂亮一點! 完成以上任務,你就完成這次的課程目標了!

後端 JS 訓練二:第3課 ── 使用 ejs 模板並讀取變數

## 課程目標 - 使用 ejs 模板並讀取變數 ## 課程內容 這一課來學習如何讀取變數之後,放進 ejs 模板呈現! 先來安裝之前用過的 readline-sync 套件 ``` npm install readline-sync ``` 替這課建立一個資料夾,然後建立 `index.js` `hello.ejs` `users.json` 這幾個檔案 此時資料夾會長類似這樣 ``` repo ├── package.json ├── package-lock.json ├── node_modules ├── lesson1 │   └── index.js ├── lesson2 │ ├── hello.ejs │   └── index.js └── lesson3 ├── users.json ├── hello.ejs    └── index.js ``` 在 users.json 放入以下內容 ``` [ { "name": "小明", }, { "name": "小華", }, { "name": "小王", } ] ``` 在 hello.ejs 放入以下內容 ``` <div> <% for(var i = 0; i < users.length; i++) { %> <p> <%= users[i].name %>同學,你好! </p> <% } %> </div> ``` 在 index.js 放入以下內容 ``` const express = require('express'); const app = express(); const engine = require('ejs-locals'); const fs = require('fs'); app.engine('ejs', engine); app.set('views', './lesson3'); app.set('view engine', 'ejs'); app.get('/', function(req, res){ const data = fs.readFileSync('./lesson3/users.json'); const users = JSON.parse(data); res.render('hello', { users: users }); }); app.listen(3000); ``` 然後去終端機輸入 ``` node lesson3/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到很多則訊息,分別跟多位同學打招呼! --- 這段程式不用我多加說明了吧!檔案讀取也是之前教過的內容! 這邊唯一多學的東西,就是 ejs 關於 for 迴圈的語法,反正就是 `<%` 跟 `%>` 之類的東西包起來而已 ejs 還有支援很多豐富的語法&功能,有興趣的話,自行研究一下吧! ## 課後作業 這次要練習匯入資料到 ejs 模板 請新建立 hw3 資料夾,採用以下結構 ``` /repo /hw3 /index.js /homepage.ejs /posts.json ``` 請修改 homepage.ejs 內容,將文章內容移出來,放在 posts.json 裡面 ``` [ { "title": "第一篇日記", "content": "今天天氣很好,夏天太陽很大,讓我心情很好" }, { "title": "第二篇日記", "content": "早起出門運動,回家沖個澡,整天心情很好" }, { "title": "第三篇日記", "content": "下大雨一整天,整天在家追劇,滿舒服的" } ] ``` 這樣 homepage.ejs 內就不會只是 html 了,你會練習到 ejs 獨有的模板語法! 完成以上任務,你就完成這次的課程目標了! --- 請更新你的 github 專案內容,此時應該變成這樣 ``` /repo /hw1 /index.js /hw2 /index.js /homepage.ejs /hw3 /index.js /homepage.ejs /posts.json ``` 依此類推,之後就這樣交作業!

後端 JS 訓練二:第2課 ── 使用 ejs 模板渲染出 html

## 課程目標 - 使用 ejs 模板渲染出 html ## 課程內容 上一課我們成功讓後端回應 html 給瀏覽器了,很棒 可是每次都讓 res.send 回應一大串 html,就太奇怪了 至少要讓 html 內容放在單獨一個檔案,才有寫網頁的感覺吧! 這課來學習如何做到這點吧! --- 來安裝一款新套件,請在終端機輸入 ``` npm install ejs-locals ``` 替這課建立一個資料夾,然後建立一個 index.js 檔案與一個 hello.ejs 檔案 此時資料夾會長類似這樣 ``` repo ├── package.json ├── package-lock.json ├── node_modules ├── lesson1 │   └── index.js └── lesson2 ├── hello.ejs    └── index.js ``` 在 hello.ejs 放入以下內容 ``` <h1>恭喜您,成功囉!</h1> <h2>您真的做得很棒!</h2> <p>繼續學習,不斷進步吧!</p> ``` 然後在 index.js 放入以下內容 ``` const express = require('express'); const app = express(); const engine = require('ejs-locals'); app.engine('ejs', engine); app.set('views', './lesson2'); app.set('view engine', 'ejs'); app.get('/', function(req, res){ res.render('hello') }); app.listen(3000); ``` 然後去終端機輸入 ``` node lesson2/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到一段打招呼訊息! --- ejs 是 javascript 社群常用的一款「模板引擎」套件 我們不是直接安裝 ejs 套件,而是安裝 ejs-locals 套件,這是一款把 ejs 整合進 express 的方便套件! 在載入 ejs-locals 之後,接著用 app.engine 告訴 express 我們要設定模板引擎 然後用 app.set 告訴 express 要去哪邊找到 `模板檔案` 最後,處理 http 請求的地方,把原本的 res.send 改成 res.render 並放進模板檔案名稱,就可以囉! 多看幾眼這段程式,這就是後端開發,用 node、express 來讀取一段 html,並且回應給瀏覽器的方式,不難吧! ## 課後作業 這次要練習使用 ejs 模板 請新建立 hw2 資料夾,採用以下結構 ``` /repo /hw2 /index.js /homepage.ejs ``` 並開發一個 app,打開首頁 `http://localhost:3000/` 會顯示 homepage.ejs 的內容作為部落格首頁,homepage.ejs 的內容先放這些 html 就好: ``` <h1>我的個人日記 APP</h1> <div> <h2>第一篇日記</h2> <div>今天天氣很好,夏天太陽很大,讓我心情很好</div> </div> <div> <h2>第二篇日記</h2> <div>早起出門運動,回家沖個澡,整天心情很好</div> </div> <div> <h2>第三篇日記</h2> <div>下大雨一整天,整天在家追劇,滿舒服的</div> </div> ``` 完成以上任務,你就完成這次的課程目標了! --- 請更新你的 github 專案內容,此時應該變成這樣 ``` /repo /hw1 /index.js /hw2 /index.js /homepage.ejs ``` 依此類推,之後就這樣交作業!

後端 JS 訓練二:第1課 ── 回應 http get request

## 課程目標 - 使用 node 與 express 回應 http get request ## 課程內容 在 node 中開發後端程式,通常會使用一款叫做 express 的套件 雖然不用 express 也能夠開發後端應用,但 express 提供很多現成好用功能 所以先來安裝 express 吧! ``` npm install express ``` 建立一個資料夾,放我們每課的練習內容,這一課就叫 lesson1 吧 然後建立一個 index.js 檔案 此時資料夾會長類似這樣 ``` repo ├── package.json ├── package-lock.json ├── node_modules └── lesson1    └── index.js ``` 在 index.js 檔案放入以下內容 ``` const express = require('express'); const app = express(); app.get('/', function(req, res){ res.send('<h1>恭喜您,成功囉!</h1>'); }); app.listen(3000); ``` 然後去終端機輸入 ``` node lesson1/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到一段大大的打招呼訊息! --- 讓我們逐行說明一下 前面兩句是載入 express 套件,然後建立主程式物件 `app.get()` 是註冊登記一個處理 `HTTP GET 請求` 第一個參數是 `要處理的網址` 第二個參數是放進一段「函式定義」代表要如何處理 函式定義通常會用 `(req, res)` 當參數,有人會寫 `(request, response)`,都可以,分別是代表 `請求` 與` 回應` 的物件 這段看不太懂沒關係,需要稍微研究一下「HTTP 協定」才會知道定義 反正就先用 `res.send` 來回應一段 html 就對了! 最後用 `app.listen(3000);` 來在 port 3000 跑這段後端程式 --- 在一台電腦上,多個程式之間彼此溝通,通常會在電腦上各自使用一個 port 號碼 在瀏覽器中,通常只會輸入網址,例如 `https://www.google.com.tw` 之類的 只輸入網址,代表使用 443 當作 port,舉例來說,你可以在網址輸入 `https://www.google.com.tw:443` 看看,結果一模一樣 一個 port 只能同時給一個程式使用,為了避免用到別的程式在用的 port,我們請 node 在這邊使用 3000 這個冷門的 port,方便我們測試 然後 `localhost` 不是真的網址,是請瀏覽器直接在本機電腦上尋找網站開啟的意思! 以上通通看不懂沒關係,需要對 `網際網路協定` 稍微研讀才比較懂,先照做即可! ## 課後作業 這次的系列作業,要練習開發一個「個人日記 APP」 首先來練習如何用 node 回應 http get request 請開發一個 app,打開首頁 `http://localhost:3000/` 會顯示 `<h1>我的個人日記 APP</h1>`,先做到這樣就好 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 請建立一個 repo 上傳到 github 這個 repo 的檔案結構應該會是這樣: ``` repo ├── package.json ├── package-lock.json ├── node_modules └── hw1    └── index.js ``` 接下來的每次作業,都新開一個小資料夾 然後把 github 專案連結,貼到留言區即可

Pair Programming:實務技巧與工具推薦

合作對於開發高質量程式碼至關重要。在本文中,我們將探討結對編程的概念,揭示其優點並推薦有用的工具。我們還將打破一些關於結對編程的常見誤解。 原文出處:https://dev.to/documatic/pair-programming-best-practices-and-tools-154j ## 什麼是結對編程? [結對編程](https://en.wikipedia.org/wiki/Pair_programming) 是一種讓兩個開發人員一起完成同一任務的技術。在這個過程中,一個人編寫程式碼(驅動程序),另一個人檢查每一行並提供反饋(導航器)。這種方法不同於傳統的單獨編程,並具有多種優點。 驅動程序的職責是專注於操作計算機和輸入程式碼的機制。導航員的責任是思考需要做什麼以及我們要去哪裡。兩人會不斷地溝通並頻繁地轉換角色,可能每隔幾分鐘。 ![結對編程](https://martinfowler.com/articles/on-pair-programming/driver_navigator.png) ## 結對編程的好處 ### 提高程式碼質量 當兩個軟體工程師一起工作時,他們可以快速發現彼此的錯誤,從而產生高質量的程式碼,從而顯著減少遺漏錯誤的機會。編程合作夥伴可以提供寶貴的見解、提出改進建議,並在做出承諾之前獲得有關其想法的反饋。 例如,在處理編碼問題時,一個軟體工程師可以專注於實現解決方案,而另一個軟體工程師則監視任何錯誤或語法錯誤。這樣,團隊就可以建立更清晰、更實用、更優化的程式碼。 ### 加強協作和溝通 結對編程還增強了兩個開發人員之間的協作。它幫助他們在相同的程式碼庫上工作並分享他們的知識和技能,從而更好地解決問題。它還解決了同事之間的溝通鴻溝,因為它促進了溝通,實現了快速、輕鬆的訊息共享。 例如,在開發新功能時,一名軟體工程師可以解釋他們的思維過程和想法,而另一名軟體工程師可以提供反饋並提出問題以澄清需要做什麼。這樣,團隊就可以共同尋找最佳解決方案並避免誤解。 ### 提高生產力 結對編程可以提高開發團隊的生產力。當兩個軟體工程師一起工作時,他們可以通過分擔責任更快地完成任務。一個可以解決問題,另一個可以搜尋潛在的錯誤。這樣,團隊就能比單獨工作更高效地解決問題、更有效地工作。這也取決於個人,一些軟體工程師在單獨工作時效率更高。 例如,在一個專案上的兩人合作中,一個人可能需要一兩個小時才能完成一項單獨開發人員需要三四個小時才能完成的任務。第二對可以專注於查找程式碼中的錯誤或其他問題。這意味著團隊可以用更少的時間和更少的精力完成任務,從而提高整體生產力。 ## 關於結對編程的誤解 在討論結對編程的最佳實踐之前,讓我們先澄清一些關於結對編程的誤解。 ### 誤區#1:結對編程很昂貴 這是關於結對編程的一個常見誤區。但實際上,這是對團隊生產力、程式碼質量和創新的投資。從長遠來看,通過及早發現錯誤可以節省時間並降低成本。所以,這不是真的。 ### 誤區#2:結對編程很慢 結對編程比其他編碼方法更快,因為它允許快速更正。當兩個開發人員協作時,他們可以避免許多錯誤和錯誤並加快問題解決速度。因此,除非開發人員只是為了好玩而不是高效地工作,否則這是不正確的。 ### 誤區#3:結對編程導致緊張 一些人認為結對編程會給開發人員帶來太大壓力,導致工作場所發生衝突。然而,這種情況只發生在該技術實施不佳的情況下。這取決於您與編程夥伴的關係如何。如果它很好,那麼這不適用於你。 ## 結對編程的最佳實踐 為了充分利用結對編程課程,請考慮遵循以下最佳實踐: ### 明確定義角色 明確界定駕駛員和領航員的角色。駕駛員編寫程式碼,而導航員檢查程式碼並提供反饋。經常切換角色以保持兩位開發人員的參與並避免一個人主導整個會話。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/govzbp92oczw6yx7259t.png) ### 有效溝通 結對編程期間,溝通至關重要。雙方開發人員都應該積極參與,表達自己的想法,並認真傾聽。分享想法、提出問題並公開討論程式碼。使用螢幕共享和程式碼審查平台等協作工具來促進溝通。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y46bjmfoivparjdb5lu2.png) ### 尊重和同理心 相互尊重和同理心對於成功的結對編程至關重要。重視彼此的意見、想法和專業知識。對建設性批評持開放態度,避免人身攻擊。建立一個鼓勵協作和學習的支持性和非評判性環境。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e34ughpeje20bxfbuekt.png) ### 休息一下 結對編程可能對智力要求很高。定期休息對於防止疲勞和保持工作效率非常重要。利用這些休息時間反思進展、討論挑戰併計劃下一步。請記住考慮彼此的精力水平並相應地安排休息時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/au3xmal7cftl1xtx5tub.png) ### 擁抱學習機會 結對編程是學習和技能發展的絕佳機會。與您的合作夥伴分享知識、技術和最佳實踐。對新想法和方法持開放態度。鼓勵參與的開發人員不斷學習和成長。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1myouifacd659tc2ox6.png) ### 練習主動程式碼審查 利用結對編程的力量來持續審查和驗證程式碼。討論潛在的改進、及早發現缺陷並解決設計缺陷。利用兩位開發人員的專業知識來確保程式碼具有最高質量。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chmhnulefghzk17ulmy9.png) ### 計劃並設定目標 在開始結對編程課程之前,討論並調整手頭任務的目的和目標。將工作分解為更小的、可管理的部分。設定明確的里程碑並確定任務的優先順序,以保持重點和進展。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hse6ayo7sggjfrico6y.png) ### 記錄和分享知識 在結對編程會議期間做筆記,以記錄重要的討論、決策和見解。建立可以與團隊共享的文件,有助於傳播知識並確保整個專案的一致性。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfqcuoqdpv2dq9bxigiz.png) ### 反思和改進 完成結對編程課程後,花時間反思這次經歷。討論哪些方面進展順利,哪些方面可以改進。根據反饋和經驗教訓不斷完善您的結對編程實踐。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dlrw737qbsij0i3fvb8.png) *通過遵循這些最佳實踐,您可以最大限度地發揮結對編程的優勢。協作和程式碼質量將得到改善,開發人員將有機會增長他們的技能和知識。* ## 結對編程工具 為了充分利用結對編程,開發人員可以依靠各種工具來簡化流程。以下是一些可用的最佳工具: ### 實時分享(VS Code) [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare) 是 VS Code 的擴展。它包含在最新版本的 VS Code 中。該工具使使用 VS Code 的開發人員能夠實時協作。 ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686383031679/a2336e60-fe72-477b-ada7-978c113961ef.png) ### Replit [Replit](https://replit.com/) 是一個在線工具,可讓您與其他開發人員協作,而無需下載或安裝任何額外的軟體。您所要做的就是打開網絡瀏覽器,然後就可以開始了。如果您只是需要與其他人一起實時編輯程式碼,那麼它是完美的。 Replit 的一大優點是它支持 50 多種編程語言,使其具有多功能性並適合廣泛的專案。 ![](https://replit.com/public/images/IDE2/hero-image.svg) ### CodeSandbox Live [CodeSandbox](https://codesandbox.io/blog/introducing-codesandbox-live-real-time-code-collaboration-in-the-browser) Live 是一項實時協作功能,使開發人員能夠在同一平台上工作實時專案。借助 CodeSandbox Live,多個開發人員可以同時處理同一個程式碼庫,從而更輕鬆地協作處理複雜的專案。 ![](https://codesandbox.io/_next/image?url=%2Fnew%2Fblog%2Fintroducing-codesandbox-live-real-time-code-collaboration-in-the-browser%2F0.gif&w=1920&q=75) ### Codeanywhere [Codeanywhere](https://codeanywhere.com/) 是一個基於雲的集成開發環境 (IDE),允許開發人員使用任何具有網路連接的設備從任何地方編碼、協作和管理他們的專案。它提供了一套全面的工具和功能來促進編碼和簡化開發工作流程。 ![](https://i.imgur.com/jIr0IqV.png) ### [CodeTogether](https://www.codetogether.com/) CodeTogether **允許您通過 Eclipse、IntelliJ 或 VS Code 主持和加入協作編碼會話**。來賓可以從安裝了 CodeTogether 的自己的 IDE 加入會話,即使它與主機的 IDE 不同。訪客還可以通過任何現代瀏覽器加入會話,無需進行任何設置。 ![](https://i.imgur.com/8KDJzAv.png) ## 結論 最後,結對編程對於軟體開發人員來說是一種非常有效的技術。它增強了協作、程式碼質量、團隊生產力和許多其他方面。遵循最佳實踐並使用適當的工具是成功結對編程的關鍵。

回答網友提問:26歲無經驗、高職畢,先去讀個二技 vs 直接補習轉職?

阿川收到網友提問如下: ``` 哈囉站長你好 我目前有在看蓬蓬的自學影片跟寫你分享的練習題 有件事想詢問一下我目前快26之前的工作經歷跟軟體一點關係都沒有 高職畢業 目前在自學一些程式語言的技能 如果未來要朝這個方向走建議我先去讀個二技相關科系補學歷嗎? 還是直接找線上課程或補習班轉職謝謝 原本的打算是想說上二技假日進修補個學歷順便幫自己打底 因為網路上看到蠻多分享是上完課後基礎理論不好 想順便詢問一下沒有學歷的話對未來的工作發展影響大嗎? 還是學歷只是初期比較看待後面看能力這樣子 ``` 寫一篇完整、公開回答跟大家分享,給類似狀況的人參考: # 不建議回學校補學歷 回學校補學歷真的太花時間了,動輒數年以上 何況入學之後還未必喜歡學校、未必喜歡寫程式 業界很多人也是「學歷普普且無經驗」自學4-9個月後,半路出家轉職成功 不論是金錢 or 時間成本來說,都應該先這樣試試看比較保險吧 # 很多人半路出家之後覺得自己底子不好 本科&非本科,基礎一定有差 但是現在網路資源、書本資源很多 寫網站不是什麼需要博士學位的「太空火箭科學」 工作上缺哪方面,就往哪方面慢慢自己補充,且戰且走也還夠用的 這行業根據職位狀況,難度可深可淺,一開始先負責較簡單的網頁工作也行 發現自己底子不好,趕快花業餘時間,大力自修一下呀 甚至先入行之後,週末再去學校進修,都比較保險吧 # 學歷對未來工作影響大嗎 學歷好看的話,當然在職場上有優勢 但如果態度不專業、工作多年還是沒什麼作品集,那也很難當工程師吧? 反過來說,學經歷不強的話 如果態度積極,作品集擺開在那邊,就算不是「超猛」的作品,也讓人知道這工程師有基本的「戰鬥力」呀 更不用說,如果積極貢獻社群、Github 專案有一堆星星,這種時候誰會管這工程師的學歷? 所以這題的答案是:學歷出色還是很吃香,但也還好啦!畢竟軟體工程這行,偏向「實力主義」,很難靠「關係」或者當「花瓶」或者「辦公室政治」就能混得出色 # 不建議直接跳進去補習班 另外我也不建議直接跑去需「全職上課」半年左右,學費十萬以上那種實體補習班 首先,班上同學程度不一,如果你稍微沒跟上進度,後面老師在講什麼就聽不懂,這樣花了大錢、時間,學習效果也不怎麼樣呀 我建議先大量找免費或便宜的教材,先吸收,多試幾份,真的卡關了,再開始挑補習班 先直接找一些作業跟專案寫寫看,從免費 -> 便宜的 -> 稍貴的,這樣一點一點花錢,風險比較小 更認識自身需求之後,再去比較市面上的各種補習班,最後再把這錢花下去,比較保險 事實上,也有很多人,最後根本沒去補習班,只靠著免費&便宜的一些資源,就直接順利轉職的呢! # 結論 這行學無止盡,就算台大畢業,工作十年經驗,還是一直在不斷自學寫程式的奇妙&精益求精 另外,我也有設計免費的 html&css 教材,還有便宜的 javascript 教材,內含「大量練習專案」,不論你最後選擇哪種學習方式,我都推薦搭配拿去學習、練習,稍有難度,但不少人全做完之後就順利面試上班了 以上,簡單分享個人看法

AI 咒語工程簡介:什麼是 AI 咒語工程?如何利用各種 AI 得到理想產出?

人工智能遍地開花,隨處可見一些新的人工智能工具。在 [ChatGPT](https://openai.com/blog/chatgpt)、[AutoGPT](https://autogpt.net/)、[Midjourney](https://www.midjourney.com/home/) 之間, [Dall-E](https://openai.com/dall-e-2) 和 [GitHub Copilot](https://github.com/features/copilot),您可以建置、編碼、獲取答案,以及創造美麗的藝術品……至少我們中的一些人可以。 為什麼有些人在使用生成式 AI 時比其他人獲得更好的結果?為什麼有些人製作的藝術品配得上盧浮宮,而另一些人卻得到了接近狗屁的東西? 這一切都取決於您使用的輸入。此輸入稱為“提示”。提示是您提出的問題,或者您用來建立內容的詞語。那些“製作”提示或對輸入有策略的人將其稱為“提示工程”。 原文出處:https://dev.to/github/prompt-engineering-for-ai-what-is-prompt-engineering-and-how-to-get-good-results-from-ai-engines-5ch6 ## 什麼是提示工程? 提示工程是指專門設計提示,以便從 AI 獲得更好的結果。 [OpenAI](https://openai.com/)、[Google](https://bard.google.com/) 等人工智能係統的建立者甚至聘請“快速工程師”來幫助訓練他們的模型。一些“創作者”甚至在 Etsy 等平台上出售他們的 Midjourney 提示。 簡而言之,人工智能系統就像資料:輸入垃圾,輸出垃圾。如果輸入錯誤,可能會得到錯誤的結果。提示工程在很大程度上受上下文影響。 ## 人工智能的背景 當涉及到我們得到的結果時,上下文是最大的問題之一。例如,如果我用谷歌搜尋“donut”(或“doughnut”:doughnut:),我可以獲得一整套結果;從甜甜圈食譜到甜甜圈圖片,或者在哪裡可以買到這種美味的甜點。這是因為我沒有給搜尋引擎任何其他上下文。當然,Google 會使用我之前的搜尋歷史記錄和我的位置等訊息來幫助確定結果,但僅此而已。 ![GitHub 甜甜圈](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp4pnnp89sr7u1nkqnli.jpg) _搜尋引擎中的術語“甜甜圈”可以指任何形狀、Slack 插件、應用程式,或者 GitHub Universe 2022 上提供的這些美味的 GitHub 甜甜圈_ 例如,如果我想找到一個關於在 Blender 中建立甜甜圈 3D 模型的教程,那麼如果我只輸入“甜甜圈”,搜尋結果可能不會顯示。我需要更具體。諸如“甜甜圈 Blender3D 教程”之類的東西會為我提供更準確的結果。 人工智能也是如此。您需要為 AI 提供足夠的上下文,以便根據您的需要獲得更好的結果。 ## 聊天應用的提示工程 許多人向我們展示了來自 ChatGPT 的一些瘋狂結果。雖然它們並不總是準確的,但 ChatGPT 確實擅長一件事:散文。寫出優美、結構合理、流暢的句子真是令人難以置信。結果很容易閱讀,聽起來真的很棒。但獲得準確的回應完全是另一回事。例如,人們厭倦了使用 ChatGPT 撰寫歷史文章,雖然文章可能讀起來不錯,但在歷史上可能並不准確。比如你讓ChatGPT“寫一篇關於中國的淪陷的2000字的文章”,它就會給你寫一篇關於中國的淪陷的2000字的文章。但它不一定是事實正確的。 ![ChatGPT 生物響應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jc4mphrlgsmfw3yobfo.png) _雖然某些內容可能讀起來不錯,但實際上可能不正確。提示:我沒有博士學位_ :wink: 這是因為 ChatGPT 從各種來源獲取訊息並將它們融合在一起。這些來源本身可能並不准確。 ChatGPT 也不知道您指的是中國的_哪個_秋天。因此它很容易錯誤地交叉引用日期。通過以對話方式向 ChatGPT 提供訊息,然後要求它寫一篇 2000 字的文章,您將獲得更好的結果。 那到底是什麼意思?有些人認為 ChatGPT 是一種單向的、對話式的、單一輸入的獲取訊息的方法。但事實並非如此。它被稱為“聊天”是有原因的。進行對話,完善您的問題,為您的回答提供背景訊息。 例如,如果我想要一段關於“NDC 會議”的旅行報告,我不會以“給我寫一段 NDC 旅行報告”來開始我的 ChatGPT。相反,我會首先弄清楚 ChatGPT 對 NDC 了解多少,並在此過程中提供上下文。您提供的輸入在很大程度上決定了輸出。這就是為什麼有些人能夠獲得非常好的結果,而其他人則不能。 ![ChatGPT 響應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eks1e166pqqu0jh9hpll.png) _沒有任何上下文,ChatGPT 不知道我指的是什麼 NDC_ 另一個例子:如果你要去參加工作面試,你想要一些提示,讓 ChatGPT“給我一些準備工作面試的提示”,會給你一些很好的回應,但它遠非具體。相反,諸如“我要去一家 AI 初創公司面試軟體開發人員的職位。你能給我一些準備面試的提示嗎?”將為您提供更加量身定制的個性化結果。這就好比你讓台上的專家給觀眾中的 1000 個人一個答案,他們可能會提供一些通用的東西,這樣每個人都有一個外賣訊息。但如果你一對一地問同一個人,他們可能會問你一些後續問題以了解你的情況,因此會提供更個性化、更具體的答案。 ## 藝術應用的提示工程 您可能已經看到一些人使用穩定的傳播應用程式創作的一些精美藝術品。然後是看起來“錯誤”的藝術品。其中很多都歸結為上下文。例如,如果我使用 [Night Café](https://nightcafe.studio/)(我最喜歡的生成器之一),然後輸入“dog”這個詞,這就是我得到的: ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61ibs1fd5j3ht37e4epn.jpg) _使用 Night Café 生成的圖像,以及提示符“dog”_ 有一些隨機的“狗”字寫成一個標誌,前景中有一隻看起來很奇怪的狗,而且它的顏色非常奇怪。現在,如果我想像成年德國牧羊犬在陽光明媚的日子裡在公園裡的照片般的圖像,那可能不是我要得到的。人工智能沒有那種背景。它無法讀懂我的想法(還沒有!)。當你想創作藝術品時,你需要描述你在腦海中想像的圖像。您提供的細節越多,輸出就越好。這就是它變得棘手的地方。許多穩定的擴散應用程式都有有限的字符數。因此,您需要對如何製作提示具有意義和戰略性。 與 ChatGPT 類似,您需要不斷地重新製作提示並完善它們。然而,基於聊天的 AI 的優勢在於,您可以繼續對話並不斷向 AI 提供更多訊息和不同的問題,以獲得良好的回應。雖然一些藝術生成器允許您“重新混合”您的輸出,但它仍然依賴於新的提示。因此,您一直在等待輸出,查看未加入的內容,然後發送經過調整的新提示。一些用戶在 Midjourney 上花費數小時,接收輸出並重新製作他們的提示以產生一些驚人的作品。這都是練習的問題。這就是為什麼一些創作者在 Etsy 上出售他們的提示! ![AI生成戰鬥兔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z0411o5c2fgbz7oikzwz.jpg) _我的朋友 Jean 使用 Midjourney 製作的藝術品_ 有一件事是肯定的,如果你想製作一些高質量的藝術品,不要指望花幾秒鐘寫一個提示,點擊“建立”按鈕然後看到莫內。沒有!相反,您需要投入時間(和金錢)來創作數百件藝術品,在每次迭代中重新處理您的提示以製作您的傑作。 ## 提示工程程式碼 我不會花大量時間談論如何為 [GitHub Copilot](https://github.com/features/copilot) 之類的東西製作好的提示。我的同事 [Rizel](https://twitter.com/blackgirlbytes/) 寫了一篇精彩的博文,深入探討了 GitHub Copilot 的提示工程: https://dev.to/github/a-beginners-guide-to-prompt-engineering-with-github-copilot-3ibp 我要說的是——類似於 ChatGPT——GitHub Copilot 依賴於上下文。存儲庫中還編寫了哪些其他程式碼?文件的擴展名(以及語言)是什麼? GitHub Copilot 還為您打造了什麼?您在程式碼中加入了哪些註釋?所有這些都將幫助 GitHub Copilot 為您合成更準確的程式碼。 可以這樣想:如果您寫了一條評論,說明您想要建立一個使用後端資料並解決特定問題的複雜函數,那麼您可能不會僅僅通過一條評論就得到很好的回應。就像你的程式碼——至少它應該是——被分解成許多函數,(希望)有很多有用的評論,當你分解東西時,GitHub Copilot 工作得更好。 而不是要求 GitHub Copilot: `//反轉句子`(使用 JavaScript) 想想如何從邏輯上分解問題。例如,如果有人給我一張紙,上面寫著一句話,讓我把它倒過來,我會怎麼做?像這樣寫評論會更有益。如果您這樣做,GitHub Copilot 將擁有更多的上下文並更好地理解您想要什麼。 與 ChatGPT 之類的東西相比,GitHub Copilot 的另一個區別是 GitHub Copilot 考慮了你擁有的_所有_上下文。我上面提到的所有事情: - 什麼是文件擴展名 - 專案中還有哪些其他文件 - 你是怎麼寫其他評論的 - 其他程式碼是如何建置的 - 您輸入的評論是什麼 - 您輸入的程式碼是什麼 ChatGPT 和其他聊天應用程式會更加重視您對聊天所做的最後評論; 也就是,您加入到對話中的最後一條訊息。但是,GitHub Copilot 始終會考慮上下文以生成更好的程式碼結果。 ## 更好的提示工程 歸根結底,從任何類型的生成式 AI 中獲得好的結果都在你身上——你提供輸入的人。正如我一開始所說:垃圾進,垃圾出。因此,在製作提示時請考慮以下重要提示: - 提供良好的**上下文**;提供有關您要實現的目標的示例和訊息 - 請明確點**;如果它是針對特定觀眾的,那麼就說 - **分解**問題 - **清楚**你如何提問。如果返回的內容聽起來不對,請澄清 - 根據您的提示**改寫**和**精煉** 最後,始終,始終驗證您從 AI 收到的訊息。對於藝術品生成器而言,這不太重要,但如果您查看程式碼和訊息,它就很重要。檢查您收到的程式碼是否按照您的預期工作。驗證提供給您的書面訊息的準確性。 請記住,無論發生什麼,您仍然是飛行員。您仍然是負責人,您對使用和共享哪些藝術作品、哪些程式碼片段以及哪些訊息有最終決定權。

分享職場小菜雞所遇到的狀況

感謝站長關懷~ 是的,這禮拜確實有遇到一些之前有稍微碰過卻不太熟悉的東西,也有之前沒有碰過的東西,是有些小崩潰...,但還是可以稍微跟大家分享與請教一下: 這裡有一些前期提要:公司目前的前端開發並不使用現在的主流前端框架,也沒有使用打包整合工具...(像是Webpack、Parcel這類的),JS使用JQuery,並且將JS檔案一個一個的引入網頁中。 ## 遇到的問題1 :CSS樣式問題 過去在自學的時候其開發方法是:在本機開發,然後在處理樣式與RWD時就是開啟Chrome 的 Dev Tools來做調整,但也有遇過在Chrome的Dev Tools中看起來將樣式都調整好了之後,部署到網路上之後換手機來查看頁面時卻發生了一些差異,這些差異可能包含滿版、間距等等,這部分我自己理解的差異可能會是有些手機會有瀏海的緣故以及Chrome與Safari之間的小差異.到新公司後發現在更多的裝置上,例如安卓手機,則存在的差異更多,包含顏色、日期時間選取器等等的樣式,因為型號真的太多了. ###到這裡可以跟大家分享的以及向各位請教的: 這裡我自己有想到幾個解決的方式,第一個是最懶的方法我最想用但是我有些不知道該如何整合給其他人使用的方法,例如透過Vue cli直接在npm下載PostCSS以及Autoprefixer這樣的工具來使用,一次解決主流瀏覽器的差異,但目前我不太曉得如何在公司的開發方法下,不透過整合工具來完成這個流程. 另一個我想到的方法是加入CSS Normalize來減少各個瀏覽器在不同樣式的預設值差異,過去我們可能都有寫過非常簡易CSS reset 例如: ```css= *{ padding: 0; margin:0; box-sizing:border-box; } ``` 但這樣如果把每一個樣式的預設值全部強制歸零,可能會導致有些樣式到後來要重新寫,或許Normalize可以只是單純地減少差異(也是因為網路上有人已經整理好了XD). ## 遇到的問題2 :API串接 過去我自己練習串接API的方式實在是相當簡易,我拿的是中央氣象局開放資料平台的API,所以之前很簡單的一行fetch就拿到資料了,毫無難度哈哈哈,但第一天公司需要我去切幾個版面並且串接運輸資料TDX的資料,恩...我一開始不知道要如何在JS中塞入登入資料並且拿回Token的方式.以及我要查詢的數值該如何發出. ###到這裡可以跟大家分享的以及向各位請教的: 這中間我摸索了fetch的一些選項設定,這應該也適用其他的非同步請求方法,例如ajax、axios(這兩個我還沒用過,後續應該會來摸索一下axios),包含請求方法(method),header與body中的內容設定等等. 至於API該如何塞入a頁面填入查詢參數並且跳轉到b頁面顯示查詢解果,在沒有前端框架全域狀態管理的支援下,這邊則是摸索了encodeURIComponent以及decodeURIComponent這樣的函式,將要查詢的參數在a頁面進行編碼並丟入到URL中,跳轉到b頁面後再進行解碼.並fetch我要的資料.最後是有成功的,只是覺得自己像薪水小偷哈哈哈,效率並不高. 這個方法感覺並不建議應用在需要輸入有個人資料的內容中,因為編碼的方式是雙向的,資料可以編碼也可以解碼,所以....像個資這類的內容就應該不建議塞在URL中用這種方式傳輸.至於要用什麼方法,這也是我想知道的. ## 遇到的問題3:不同裝置的問題 這個並非第一個樣式的問題,而是我目前覺得還沒有解的問題,就是我在網頁中需要獲取使用者的位置,因此用了navigator.geolocation 這個API,但神奇的是,在本機中都可以抓得到資料,打開Dev Tools檢查回傳的狀態碼與經緯度也都是沒有問題,但是在手機中雖然會顯示是否能夠取得使用者位置的提示,但按了同意後卻一直無法獲取資料,而且尷尬的是,我無法在手機中打開Dev Tools,所以我也不知道問題發生在哪....,過去有使用過navigator.geolocation 好像也沒有碰過這樣的問題 想跟各位請教的是,有什麼方式可以查看手機上的問題嗎? ## 遇到的問題4:不同的開發方式 這個是我自己很好奇的,雖然說我知道Vue是漸進式框架,但我卻不知道該如何漸進.我理解的漸進式是,有些頁面或元件可以自行選擇要不要使用Vue開發,還是這個漸進式的意思是可以自行選擇要使用多少Vue的套件工具呢(像是要不要使用Vue Router or Vuex). 會這樣問是因爲,假如現在有一份專案一共是十個頁面,我被分到了其中五頁,另外的同事則是負責另外五頁,誠如開頭所說,假如公司既定的開發方式並不使用框架與其他整合工具,我有可能使用框架進行開發並與之合作嗎?還是我這是一個很奇怪的問題,本來就應該要統一一個開發方式? --- 感謝看到這邊的各位,以上有些觀念上是我這位小菜雞自己摸索的,是可能不是正確的(例如有些函式、工具的用途或使用情境),因此歡迎大家指教與討論,這是我這禮拜可以跟大家分享的啦. 謝謝~~ --- PS:我自學八個月的時間有摸了原生JS、CSS、Vue.js、Tailwind、SCSS這樣的工具,本來我是很想要在第一份工作多了解與強化上述工具以及多人開發GitHub的部分,我了解這些終究只是工具且我自己也沒有到非常熟,只要可以完成專案目的即可,我的實力在哪裡我也知道,但以目前公司的開發模式來說,我需要考量沒有踏上趨勢的這個問題嗎?還是我多慮呢了?

給軟體工程師:50 個好用的 ChatGPT 咒語指令

下列 ChatGPT-4 咒語,對開發者很有幫助。附上原文與中文指令,供您參考。 原文出處:https://dev.to/hackertab_org/50-chat-gpt-prompts-every-software-developer-should-know-tested-9al ### **程式碼生成** - Generate a boilerplate `[language]` code for a `[class/module/component]` named [name] with the following functionality: `[functionality description].` - 為名為 [name] 的 `[class/module/component]` 生成樣板 `[language]` 程式碼,具有以下功能:`[functionality description]。 - Create a [language] function to perform `[operation]` on `[data structure]` with the following inputs: [input variables] and expected output: `[output description]`. - 建立一個 [語言] 函數以使用以下輸入對 `[資料結構]` 執行 `[操作]`:[輸入變數] 和預期輸出:`[輸出描述]`。 - Generate a `[language]` class for a `[domain]` application that includes methods for `[methods list]` and properties `[properties list]`. - 為包含“[方法列表]”的方法和屬性“[屬性列表]”的“[域]”應用程式生成一個“[語言]”類。 - Based on the [design pattern], create a code snippet in [language] that demonstrates its implementation for a [use case]. - 基於[設計模式],用[語言]建立一個程式碼片段,演示其對[用例]的實現。 **例子:** ``` Generate a boilerplate Python code for a shopping cart module named "ShoppingCart" with the following functionality: - A constructor that initializes an empty list to store cart items. - A method called "add_item" that takes in an item object and adds it to the cart. - A method called "remove_item" that takes in an item object and removes it from the cart if it exists. - A method called "get_items" that returns the list of items in the cart. - A method called "get_total" that calculates and returns the total price of all items in the cart. ``` ### **程式碼完成** - In `[language]`, complete the following code snippet that initializes a [data structure] with `[values]`: `[code snippet]`. - 在“[語言]”中,完成以下使用“[值]”初始化[資料結構]的程式碼片段:“[程式碼片段]”。 - Finish the `[language]` function that calculates [desired output] given the following input parameters: `[function signature]`. - 在給定以下輸入參數的情況下完成計算[期望輸出]的[語言]函數:[函數簽名]。 - Complete the `[language]` code to make an API call to `[API endpoint]` with [parameters] and process the response: `[code snippet]`. - 完成“[語言]”程式碼以使用[參數]對“[API 端點]”進行 API 呼叫並處理響應:“[程式碼片段]”。 **Example** : Finish the Python function that calculates the average of a list of numbers given the following input parameters: **示例**:完成計算給定以下輸入參數的數字列表的平均值的 Python 函數: ``` def calculate_average(num_list) ``` ### **錯誤檢測** - Identify any potential bugs in the following [language] code snippet: `[code snippet]`. - 確定以下 [語言] 程式碼片段中的任何潛在錯誤:`[程式碼片段]`。 - Analyze the given [language] code and suggest improvements to prevent [error type]: `[code snippet]`. - 分析給定的[語言]程式碼並提出改進建議以防止[錯誤類型]:`[程式碼片段]`。 - Find any memory leaks in the following [language] code and suggest fixes: `[code snippet]`. - 在以下 [語言] 程式碼中查找任何內存洩漏並提出修復建議:`[程式碼片段]`。 **Example** : Identify any potential bugs in the following Python code snippet: **示例**:辨識以下 Python 程式碼片段中的任何潛在錯誤: ``` def calculate_sum(num_list): sum = 0 for i in range(len(num_list)): sum += num_list[i] return sum ``` ### **程式碼審查** - Review the following `[language]` code for best practices and suggest improvements: `[code snippet]`. - 查看以下“[語言]”程式碼以獲得最佳實踐並提出改進建議:“[程式碼片段]”。 - Analyze the given `[language]` code for adherence to `[coding style guidelines]`: `[code snippet]`. - 分析給定的“[語言]”程式碼是否符合“[編碼風格指南]”:“[程式碼片段]”。 - Check the following [language] code for proper error handling and suggest enhancements: `[code snippet]`. - 檢查以下 [語言] 程式碼以正確處理錯誤並提出改進建議:`[程式碼片段]`。 - Evaluate the modularity and maintainability of the given `[language]` code: `[code snippet]`. - 評估給定“[語言]”程式碼的模塊化和可維護性:“[程式碼片段]”。 **Example** : Review the following Python code for best practices and suggest improvements: **示例**:查看以下 Python 程式碼以獲得最佳實踐並提出改進建議: ``` def multiply_list(lst): result = 1 for num in lst: result *= num return result ``` ### **API 文件生成** - Generate API documentation for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成 API 文件:“[程式碼片段]”。 - Create a concise API reference for the given `[language]` class: `[code snippet]`. - 為給定的“[語言]”類建立簡明的 API 參考:“[程式碼片段]”。 - Generate usage examples for the following `[language]` API: `[code snippet]`. - 為以下“[語言]”API 生成用法示例:“[程式碼片段]”。 **Example** : Generate API documentation for the following JavaScript code: **示例**:為以下 JavaScript 程式碼生成 API 文件: ``` /** * Returns the sum of two numbers. * @param {number} a - The first number to add. * @param {number} b - The second number to add. * @returns {number} The sum of a and b. */ function sum(a, b) { return a + b; } ``` ### **查詢優化** - Optimize the following SQL query for better performance: `[SQL query]`. - 優化以下 SQL 查詢以獲得更好的性能:`[SQL 查詢]`。 - Analyze the given SQL query for any potential bottlenecks: `[SQL query]`. - 分析給定的 SQL 查詢是否存在任何潛在瓶頸:`[SQL 查詢]`。 - Suggest indexing strategies for the following SQL query: `[SQL query]`. - 為以下 SQL 查詢建議索引策略:`[SQL 查詢]`。 - Optimize the following NoSQL query for better performance and resource usage: `[NoSQL query]`. - 優化以下 NoSQL 查詢以獲得更好的性能和資源使用:`[NoSQL 查詢]`。 **Example** : Optimize the following SQL query for better performance: **示例**:優化以下 SQL 查詢以獲得更好的性能: ``` SELECT * FROM orders WHERE order_date BETWEEN '2022-01-01' AND '2022-12-31' ORDER BY order_date DESC LIMIT 100; ``` ### **用戶界面設計** - Generate a UI mockup for a `[web/mobile]` application that focuses on [`user goal or task]`. - 為專注於 [`用戶目標或任務]` 的`[web/mobile]` 應用程式生成 UI 模型。 - Suggest improvements to the existing user interface of `[app or website]` to enhance `[usability, accessibility, or aesthetics]`. - 建議改進“[應用程式或網站]”的現有用戶界面,以增強“[可用性、可存取性或美學]”。 - Design a responsive user interface for a `[web/mobile]` app that adapts to different screen sizes and orientations. - 為適應不同螢幕尺寸和方向的“[web/mobile]”應用程式設計響應式用戶界面。 **Example** : Generate a UI mockup for a mobile application that focuses on managing personal finances. **示例**:為專注於管理個人財務的移動應用程式生成 UI 模型。 ### **自動化測試** - Generate test cases for the following [language] function based on the input parameters and expected output: `[function signature]`. - 根據輸入參數和預期輸出為以下 [語言] 函數生成測試用例:`[函數簽名]`。 - Create a test script for the given [language] code that covers [unit/integration/system] testing: `[code snippet]`. - 為涵蓋[單元/集成/系統]測試的給定[語言]程式碼建立測試腳本:`[程式碼片段]`。 - Generate test data for the following [language] function that tests various edge cases: `[function signature]`. - 為以下測試各種邊緣情況的[語言]函數生成測試資料:`[函數簽名]`。 - Design a testing strategy for a [web/mobile] app that includes [unit, integration, system, and/or performance] testing. - 為 [網絡/移動] 應用程式設計測試策略,包括 [單元、集成、系統和/或性能] 測試。 **Example:** Generate test cases for the following Python function based on the input parameters and expected output: **示例:** 根據輸入參數和預期輸出為以下 Python 函數生成測試用例: ``` def divide(a: float, b: float) -> float: if b == 0: raise ZeroDivisionError('division by zero') return a / b ``` ### **程式碼重構** - Suggest refactoring improvements for the following [language] code to enhance readability and maintainability: `[code snippet]`. - 建議對以下 [語言] 程式碼進行重構改進,以增強可讀性和可維護性:`[程式碼片段]`。 - Identify opportunities to apply [design pattern] in the given [language] code: `[code snippet]`. - 確定在給定的[語言]程式碼中應用[設計模式]的機會:`[程式碼片段]`。 - Optimize the following [language] code for better performance: `[code snippet]`. - 優化以下 [語言] 程式碼以獲得更好的性能:`[程式碼片段]`。 **Example** : Optimize the following Python code for better performance: **示例**:優化以下 Python 程式碼以獲得更好的性能: ``` def find_max(numbers): max_num = numbers[0] for num in numbers: if num > max_num: max_num = num return max_num ``` ### **設計模式建議** - Based on the given [language] code, recommend a suitable design pattern to improve its structure: `[code snippet]`. - 根據給定的[語言]程式碼,推薦合適的設計模式來改進其結構:`[程式碼片段]`。 - Identify opportunities to apply the [design pattern] in the following [language] codebase: `[repository URL or codebase description]`. - 確定在以下 [語言] 程式碼庫中應用 [設計模式] 的機會:`[存儲庫 URL 或程式碼庫描述]`。 - Suggest an alternative design pattern for the given [language] code that may provide additional benefits: `[code snippet]`. - 為可能提供額外好處的給定 [語言] 程式碼建議替代設計模式:`[程式碼片段]`。 **Example:** Based on the given Python code, recommend a suitable design pattern to improve its structure: **例子:** 根據給定的Python程式碼,推薦合適的設計模式來改進其結構: ``` class TotalPriceCalculator: def calculate_total(self, items): pass class NormalTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity return total class DiscountedTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity * 0.9 # apply 10% discount return total class Order: def __init__ (self, items, total_price_calculator): self.items = items self.total_price_calculator = total_price_calculator def calculate_total(self): return self.total_price_calculator.calculate_total(self.items) class Item: def __init__ (self, name, price, quantity): self.name = name self.price = price self.quantity = quantity ``` ### **算法開發** - Suggest an optimal algorithm to solve the following problem: `[problem description]`. - 建議解決以下問題的最佳算法:`[問題描述]`。 - Improve the efficiency of the given algorithm for `[specific use case]`: `[algorithm or pseudocode]`. - 為“[特定用例]”提高給定算法的效率:“[算法或偽程式碼]”。 - Design an algorithm that can handle `[large-scale data or high-throughput]` for `[specific task or operation]`. - 為“[特定任務或操作]”設計一種可以處理“[大規模資料或高吞吐量]”的算法。 - Propose a parallel or distributed version of the following algorithm to improve performance: `[algorithm or pseudocode]`. - 提出以下算法的並行或分佈式版本以提高性能:`[算法或偽程式碼]`。 ### **程式碼翻譯** - Translate the following `[source language]` code to `[target language]`: `[code snippet]`. - 將以下“[源語言]”程式碼翻譯成“[目標語言]”:“[程式碼片段]”。 - Convert the given `[source language]` class or module to `[target language]` while preserving its functionality and structure: `[code snippet]`. - 將給定的“[源語言]”類或模塊轉換為“[目標語言]”,同時保留其功能和結構:“[程式碼片段]”。 - Migrate the following `[source language]` code that uses `[library or framework]` to [target language] with a similar library or framework: `[code snippet]`. - 將以下使用“[庫或框架]”的“[源語言]”程式碼遷移到具有類似庫或框架的“目標語言”:“[程式碼片段]”。 **Example:** Translate the following Python code to JavaScript: **示例:**將以下 Python 程式碼轉換為 JavaScript: ``` def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) ``` ### **個性化學習** - Curate a list of resources to learn `[programming language or technology]` based on my current skill level: `[beginner/intermediate/advanced]`. - 根據我目前的技能水平,策劃學習`[編程語言或技術]`的資源列表:`[初學者/中級/高級]`。 - Recommend a learning path to become proficient in `[specific programming domain or technology]` considering my background in `[existing skills or experience]`. - 考慮到我在“[現有技能或經驗]”方面的背景,推薦精通“[特定編程領域或技術]”的學習路徑。 - Suggest project ideas or coding exercises to practice and improve my skills in `[programming language or technology]`. - 建議專案想法或編碼練習,以練習和提高我在“[編程語言或技術]”方面的技能。 ### **程式碼可視化** - Generate a UML diagram for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成一個 UML 圖:“[程式碼片段]”。 - Create a flowchart or visual representation of the given `[language]` algorithm: `[algorithm or pseudocode]`. - 建立給定“[語言]”算法的流程圖或可視化表示:“[算法或偽程式碼]”。 - Visualize the call graph or dependencies of the following `[language]` code: `[code snippet]`. - 可視化以下“[語言]”程式碼的呼叫圖或依賴關係:“[程式碼片段]”。 **Example** : Generate a UML diagram for the following Java code: **示例**:為以下 Java 程式碼生成 UML 圖: ``` public abstract class Vehicle { private String model; public Vehicle(String model) { this.model = model; } public String getModel() { return model; } public abstract void start(); public abstract void stop(); } public class Car extends Vehicle { public Car(String model) { super(model); } @Override public void start() { System.out.println("Starting car engine"); } @Override public void stop() { System.out.println("Stopping car engine"); } } public class Motorcycle extends Vehicle { public Motorcycle(String model) { super(model); } @Override public void start() { System.out.println("Starting motorcycle engine"); } @Override public void stop() { System.out.println("Stopping motorcycle engine"); } } ``` ### **資料可視化** - Generate a bar chart that represents the following data: `[data or dataset description]`. - 生成代表以下資料的條形圖:`[資料或資料集描述]`。 - Create a line chart that visualizes the trend in the following time series data: `[data or dataset description]`. - 建立一個折線圖,將以下時間序列資料的趨勢可視化:`[資料或資料集描述]`。 - Design a heatmap that represents the correlation between the following variables: `[variable list]`. - 設計一個表示以下變數之間相關性的熱圖:`[變數列表]`。 --- 以上,簡單分享,希望對您有幫助!

Git 入門上手教材:第6課 ── 學會 git pull

## 課程目標 - 學會 git pull ## 課程內容 學會把專案上傳 github 了,這次來試試把專案從 github 載下來吧 假設你現在使用另一台新電腦,專案還不在你的電腦上 打開專案頁面 https://github.com/howtomakeaturn/my-first-testing-repo 頁面上有一個 `Code` 的按鈕,點下去有 clone(複製)的指示 在電腦上先移動到別的資料夾底下,使用 clone 指令把專案抓下來 ``` git clone [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 完成之後,會看到在新資料夾底下,有一份一模一樣的專案! --- 在新資料夾底下,把 `my-work-3.html` 裡面隨意加上幾個字,接著 ``` git add my-work-3.html git commit -m 'commit from new folder' git push ``` 打開 github,會在上面看到有被更新! --- 回到之前的「舊資料夾」底下,把 `my-work-4.html` 裡面隨意加上幾個字,接著 ``` git add my-work-4.html git commit -m 'commit from old folder' git push ``` 會發現上傳失敗! ``` To github.com:howtomakeaturn/my-first-testing-repo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ``` 原因是,git 發現,你從兩個不同的地方,分別更新過不同檔案,git 怕你會搞混編輯歷史紀錄 (github 上現在有4筆 commit,目前資料夾上也是4筆 commit,git 無法分辨哪個第4筆是最新的) 所以 git 希望你能先把最新版本抓下來,再送出你的版本,比較不會有爭議! 把新版本抓下來的指令是 ``` git pull ``` 抓完之後,因為 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起了 會請你打一段小訊息,備註這次合併 通常你就使用 `ctrl + x` 或者 `:q` 離開終端機編輯器就可以了 完成之後,使用 `git log` 會看到,現在有6筆 commit 紀錄,最後一筆是剛剛自動合併的 commit ``` Merge branch 'main' of github.com:howtomakeaturn/my-first-testing-repo ``` 使用 `git status` 也會看到 ``` On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean ``` git 提示你目前比雲端版本還多了 2 筆 commit(一筆是你剛加的,一筆是關於自動合併的) 使用 `git push` 通通推上去 github 吧! --- 看到這邊你可能會想,剛剛那筆自動合併的 commit 好像有點多餘? 就把 `commit from new folder` 以及 `commit from old folder` 按照時間順序排列,不就好了嗎? 其實,那是因為這兩筆 commit 內容沒有重疊,所以看起來很單純 實務上很多時候,兩筆 commit 會更新到「相同的檔案」之中的「同樣幾行程式碼」 這時 git 如果按照時間順序排列,就會讓「較晚送出 commit 的人」把「較早送出 commit 的人」的工作內容覆蓋掉! 這樣一來,根本沒辦法團隊工作:晚提交的人,會一直破壞掉早提交的內容! 所以 git 一律會多一筆「合併 commit」。平常就自動合併沒問題,有衝突時,就可以在這筆 commit 處理 有點不懂沒關係,我們下一課會練習 ## 課後作業 接續前一課的作業,專案已經傳到 github 了 假設你原本是用家裡的電腦開發,現在你打算帶著筆電,出門到咖啡廳繼續開發 請拿出你的筆電,把 github 上那個專案 `git clone` 到筆電上面 如果你沒有筆電,沒關係,在電腦上另外找個資料夾,用 `git clone` 從 github 抓專案下來 這樣兩個資料夾對應同一個專案,也可以,模擬跨裝置同步專案 --- 現在分別有兩個資料夾,內容一模一樣,我這邊分別用 `at-home` 以及 `at-laptop` 稱呼兩個資料夾 請按照以下步驟,送出 commit **第一步** 到 `at-home` 資料夾,建立一個檔案 `create-this-file-at-home.html` 內容放 ``` <p>我在家裡新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到 github 上面就被更新了 **第二步** 到 `at-laptop` 資料夾,建立一個檔案 `create-this-file-at-laptop.html` 內容放 ``` <p>我在咖啡廳新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到錯誤訊息! git 會跟你說,有衝突,請先將資料夾內容下載同步,再更新 **第三步** 所以請輸入 `git pull` 先把資料夾更新到最新版本 接著用 `git log` 看一下,會看到有關 `create-this-file-at-home.html` 那個檔案的 commit **第四步** 這時再 `git push` 出去 你會看到 github 上面就被更新了 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第1課 ── 學會 git 初始化

## 課程目標 - 學會 git 初始化 ## 課程內容 這次的課程,主要是透過每課作業練習實務情境 關於 git 的基本安裝,網路上有非常多教學,請根據你的作業系統,自己找一套安裝方法 不論是使用「終端機」讓你輸入指令,或者是有 GUI(圖形化介面)讓你點擊 UI 執行指令,都可以 關於 git 的基本觀念,學起來可深可淺,我只會簡單說明工作上需要的觀念 覺得黑箱或者想深入研究的話,可以上網搜尋相關關鍵字,深入理解 git 底層機制 --- 在要使用 git 追蹤的資料夾內,首先要使用的指令是 ``` git init ``` 這會初始化資料夾環境,讓 git 開始追蹤資料夾內所有檔案變化的一舉一動 其實不用想得太神奇,這指令只是在資料夾內建立一個隱藏的資料夾 `.git/` 而已(你可以根據你的作業系統,想辦法找到這個隱藏的資料夾) 後續的 git 指令,背後都是去查看 `.git/` 的內容而已 --- 初次使用 git,打指令可能會被要求設定名稱信箱,這些要用來記錄在 git 歷史訊息內,辨識操作者 ``` git config --global user.name "您的名稱" git config --global user.email "您的信箱" ``` --- 接著來試用兩個指令 首先是查看目前的工作狀態 ``` git status ``` 因為還沒有任何程式碼,所以應該會顯示「沒東西」的中文或英文訊息 接著來查看歷史編輯紀錄 ``` git log ``` 一樣會顯示「沒紀錄」的中文或英文訊息 這兩個基本指令,對於學習非常有幫助 在每次打任何 git 指令之前與之後,都打打看這兩個指令,可以幫助認識當前追蹤狀況 ## 課後作業 請開一個新資料夾,用 git 初始化這個資料夾 接著分別輸入 `git status` 與 `git log` 應該會看到 git 回應「沒東西」與「沒紀錄」的訊息 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 `git status` 與 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git status` 與 `git log` 的內容,上傳到留言區

[心態分享] 新手學前端應該具備的心態:絕對不是謙虛,假謙虛的心態:做作又噁心!

## 前情提要 最近在網上想找一些學習前端的夥伴,發現要組個討論會非常的難。 是因為沒有人學前端嗎?不是,與事實相反,非常多人學。那麼是因為大家程度太差嗎? 也不是,其實自學的人吸收能力都不錯。 那到底是因為什麼,其實是源自於一個魯蛇心態:「貶低自己、迂迴溝通」 ## 觀念解說 什麼意思?貶低自己?沒錯,很多前端新手當要進行自我介紹或是參加討論, 都因為自尊心太高,要幫自己打上一堆預防針:「我還是菜鳥,我什麼都不會。」 當人家問你說寫過什麼,就說:「都只是一些人家的作業,我沒有做什麼耶」 你以為謙虛是一種美德,事實上這種噁心的做作,只是降低大家討論進步的溝通效率, 要人家稱讚你老半天說:「不會啦!很棒,有東西就拿出來」 你才願意把你自己的作品連結丟出來。 事實上你明明就有自己嘗試做過一些東西,一定要迂迴老半天才願意拿出來,真的太假掰。 ## 健康的心態 那麼前端的新手應該具備什麼心態呢?我們要培養的不是假裝謙虛:「我什麼都不會啦,只是照著做」 「就看網路課程而已,我只是剛摸過js」 「對框架沒概念耶,只是看過VUE的課程。」 就省去這些假掰的噁心詞彙,你學過什麼就說出來,把自己會的東西講出來, 明明學過,又不願意老實講,真的很糟糕。 這不僅是對自己的尊重也是尊重別人。 別人沒有義務必須要每一次的對話都要先稱讚你,才有辦法跟你討論正事。 格局多大,完全建立在你自己的心態健康不健康之上。 做過什麼作品,就算是抄課程上的那就拿出來講,表達出來才有辦法討論。 不是明明你也想要找學習夥伴討論、交流,真的要互相討論的時候才拿出來當作藉口。 那你到底是想要進步,還是你只是想要人家安慰? ## 總結心得 我不知道這是源自於人格上的自卑,又或是東方文化容易被打擊所培養的自我防禦意識。 但在前端程式的交流,真的要練習培養大方的態度, 實事求是,不需要你把自己包裝的多厲害,只要不要你裝模作樣說自己什麼都不會、 什麼都沒寫過, 問了老半天才要把你明明偷偷嘗試過的五種作品拿出來,才發現你bs5也碰過、VUE也學了, 那講了老半天的預防針到底有什麼意義? 請培養健康正確的心態,不要看不起自己,也請尊重別人跟你溝通的對談成本。 真的沒有人有義務一路上安慰你,想要討論交流,你必須擁有正確大方地表達、人格態度。

[好文轉載]哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?

[【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?](https://ithelp.ithome.com.tw/articles/10312056) ## 前情提要 如果說蟑螂怕拖鞋,老鼠愛大米,任何事物都有相生相剋的道理,那麼前端最害怕什麼呢? 恐怕就是todo-list。 這應該是前端的四大惡夢之一,並不是因為太難了,而是因為太簡單而且太無聊了, 不只無聊,還是每次教學都必須寫的一個磨難,簡直是瞬間殺死靈魂中隊前端的愛。 今天要來用不同風格寫出todo-list,把代辦事項寫出新滋味。 body裡面一行都沒有也能搞? 就是可以搞,讓我們馬上來欣賞這段有特別滋味的玩法!ε(*´・∀・`)з゙ ## 程式碼 ``` <!DOCTYPE html> <html> <head> <title>Todo List</title> </head> <body></body> <script> //渲染DOM AddHtml(); //資料內容 function AddHtml() { const Data = { h1: "Todo List", button: "Add", }; //主體的DOM const html = `<h1>${Data.h1}</h1> <input type="text" id="input" /> <button onclick="CheckNull()">${Data.button}</button> <ul id="list"></ul>`; //渲染至畫面上 document.body.innerHTML += html; } //邏輯確認:是否有輸入值 function CheckNull() { if (!input.value.trim("")) { return; } else { AddItem(); } } //新增代辦事項 function AddItem() { const li = `<li>${document.getElementById("input").value}</li>`; document.getElementById("list").innerHTML += li; input.value = ""; } </script> </html> ``` [可以貼到try it的地方執行看看效果](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_form_submit) ## 觀念筆記 所謂MVC架構就是模型、視圖、控制,背後其實有一個元素貫串任何程式,那就是:「邏輯」 每當你要下手寫一個程式卻不知道怎麼開始動手, 那就是邏輯沒有通順。 網頁不外乎就是畫面,以及資料,還有使用者的操作。 對於todo-list來說就是一個簡單的input畫面,使用者輸入的資料,點下按鈕送出的操作。 這段程式特地不寫任何一行body裡面的東西, 玩弄了一般人對於程式區分的概念。 用模板符的特性讓所有一切交給變數與函式處理,最後三個function: AddHtml、CheckNull、AddItem完美演繹了代辦清單這個網頁所需要構成的底層邏輯。 必須先加入畫面,然後確認使用者操作的條件,最後新增資料。 這樣子的流程對於新手或許不習慣,但是以邏輯面來看比一般人的寫法清晰許多。 這也是未來框架導入後,對資料流更敏感的培養練習。 ## 心得 無聊的todo-list竟然可以搞成這樣!? 真的是太有趣了(๑╹◡╹๑)! 原來前端的惡夢也可以變成寫不同風格的天堂,沒錯,寫程式就是這麼千變萬化! 重點是背後的邏輯抓到了,那麼想要怎麼寫,真的就是藝術的發揮。 請繼續關注, 跟著我們這個系列繼續動手玩創意!!未來還有更多更新鮮的花招呢(。◕∀◕。)