Day 141 (Week21), 2021/08/30 (Monday)

學習時數:9 hr

Done

  • [done] w17 hw2 餐廳網頁功能製作(抽獎機率的計算跟更新 database 資料)

To Do @ this week

  • [ ] w17 & w18 餐廳網頁改寫

學習心得紀錄

Objective 客觀

餐廳網頁登入

一開始做抽獎的時候,沒有做登入功能,然後現在做好了抽獎功能,才回過頭來做登入功能,結果發現有一點卡卡的,因為還要去思考其他頁面也要有登入的考量,有時候會搞不清楚做到哪,在 ./index.js 路由的寫 middleware,判斷登入,還要做一些跟資料庫有關的驗證(不過餐廳網頁沒有用到,部落格在編輯、更新文章有用到),還要回過頭確認一下其他頁面是否需要登入。
所以下次還是要在做某一個頁面時,就跟著做登入的功能,不然我覺得有點亂掉,也卡了一陣子。

抽獎品項的驗證

一開始只專注於頁面切版、編輯、新增獎項,並沒有注意到這個重要的細節,分為下列幾項:

(1) <input> 前端輸入格式,DataType 資料庫後端儲存格式

一開始沒有多想,就想說在前端使用 <input> 建一個輸入框,然後在上面填上人數(number)、獎項(string)、抽獎機率(值是整數還是小數?然後最大值最小值是?再來是機率的最小單位為整數還是整位的幾位小數?)

結果最開始,所有存進資料庫的獎項、敘述、機率、名額全部的資料格式都是 string,這個到了我要開始從獎項設置機率後,要來計算「未中獎」的機率時,發現問題了,問題就是存進資料庫的資料都是字串,在 JavaScript 寫 code 時,還要將其轉成整數。有鑑於存入的資料格式跟我預期想的不一樣,就開始轉而研究 sequelize migration

seqeulize migration

其實我碰到這個還滿頭痛的...還沒有摸懂怎麼更新資料庫的欄位及資料格式。
每次都是有要 update 資料庫內的欄位名稱或格式時,才使用 CLIxxxx:migrate:undo 指令回復,然後再使用 xxxx:migrate 利用 sequelize CLI 指令,重新建立資料庫。然後偶爾有出錯,就只會砍掉重來,刪除掉 ./migration/xxx-create-user.js 以及 ./models/user.js 然後再利用 sequelize-CLI 再來建立一個新 database table ,我知道這是一個壞方法...有空再來研究這到底要怎麼使用QQ,每次只要一需要改這些欄位、資料格式就有點頭痛。
有一次只改了 ./migration/xxx-create-user.js 裡頭的欄位名稱,然後再 xxx migrate:undo 再執行,結果都失敗,後來發現連 ./models/user.js 也要一起修改裡面的欄位名稱。
總之這大概紀錄一下遇到的崩潰點QQ。

(2) 輸入框 URL 驗證部分

其實我這部分沒有細想,一開始只有陽春的 <input type='text'></input>在測試時,輸入 efwefewf ,竟然都可以輸入到資料庫,那不就哪裡怪怪的嗎?應該要輸入的是網址的內容,怎麼連亂碼都可以輸入進資料庫呢?後來想起來 HTML 的 <input> 有簡易的前端驗證,如果要再嚴謹一點的話,好像要把「運動表單」的驗證再複習一遍 QQ。

(3) 加總機率 <= 100

從 17 週剛開始時,我就在想中獎加權要怎麼寫,如果簡單的像是段考的加權平均的話,那就只要單項獎項 / 加總就是機率,但後來想想,咦,這樣的抽獎機率好像不太直觀,如果來個機率呢?會不會比較直觀?然後就踏上了崩潰的開始QQ。
首先從機率下手,我想了一大堆...最小單位為 1% 還是 0.01 %,那麼在前端的 HTML input 標籤,就要設定 stepminmin,在資料庫就要設定資料格式為整數或小數?那設定了獎項的中獎機率,那也有沒中獎的呀?那沒中獎的要怎麼算呢?我當時想到的是 1 - 中獎機率總和,恩...後來我發現真的是搞死自己,就浮出一堆問題XD,像是資料庫的資料格式、如何加總、如何驗證新增及編輯後的機率會不會大於一等等,卡了我應該有一兩天。
然後做著做著,我就想到一件非常重要的事情:那就是機率加總,如果加總機率大於 100,那不救出包了嗎!?然後我就在想:咦,是不是要在新增之前驗證一下:新增的這個值加上原本的中獎機率及未中獎機率會不會超過 100;編輯也是相同的想法:如果編輯寫上新的機率,那會不會加總起來超過 100?超過的話,當然不可以給他寫進資料庫呀...不然就出錯了!然後大悲劇就此展開QQ!

未中獎機率 = 1 - 總中獎機率

做了很久都失敗,一直在想怎麼會第一次 load 頁面,未中獎機率為 64 %,然後 reload 重新整理一次頁面,未中獎機率變成 99%,或者是 -1 % 的怪數字,照理來說是固定的呀!怎麼會因為 loading 頁面後跳動呢?後來將他改成小數後兩位的機率,更是如此...還出現了 -1.0000000003 %99 % 的奇怪數字,花了一個晚上一直在想是發生什麼問題,一度還以為會不會是溢位(其實對溢位還是不太瞭解),不過應該是不太會溢位...因為數字不大,自己也是不太瞭解 doublesinglefloat 的概念,下次記著一定要查清楚QQ~

歪樓了,然後我睡覺前,一直在想...我後來發現兇手原來是我把他放在了 render 後台管理獎項的 prizeController.backStagePage 上,難怪每一次重新整理頁面,他就幫我重算一次,然後在計算尚未中獎的 function 裡面也沒有寫好,第一次計算的加總機率時,不包含「未中獎」的機率,但是再重新整理後, function 將「未中獎」當成加總的成員之一了,所以才出現互補為 100 % 的奇怪跳動兩種的數值。
然後我就在想到底是哪裡出了錯?果然是卡在一個地方就會陷在同一個錯誤的腦袋迴路裡,陷入無限迴圈出不來QQ,後來到了十二點只好洗洗睡,然後躺上床,我就想到底哪裡出了錯?有一個規律就是兩個數字隨著重新整理在跳動,定是哪裡出了問題,也有可能是 function。

新增及編輯前的機率是否大於 1 的驗證

想了很久,原本想說可以很帥氣的包成一個 function,然後 return true or false,結果...我發現了好多問題,需要從 db.findAll 取資料,還要使用 JavaScript 計算機率等等,如果通通放在 controller 寫計算好像會太冗,我就還是額外寫一個 js 的 function,使用和 controller 一樣的方式輸出 module,再在 controller 裡面引入 function。
然後接下來頭疼的是要怎麼計算機率是否大於一這件事。
總中獎機率為資料庫各獎項機率總和,未中獎機率為 1 - 總中獎機率,如果新增或編輯後的中獎機率大於未中獎機率的話,那就會機率大於一,因此要擋住此輸入到資料庫內,否則機率會出錯;相對的,新增或編輯後的中獎機率小於未中獎機率的話,那就是 OK 的,可以寫入資料庫。乍看之下真簡單,寫成 code 就想了滿久的,一開始想說排除要被修改掉的機率,將剩下的各獎項機率加總,再加上新輸入的機率,但是我發現要「排除」要被修改掉的機率有點難,要有 for loop 還要有 if 來寫,後來想了半天的結果是各個獎項機率相加,再扣掉被修改掉的機率,再加上輸入的新機率,這樣就可以得到是否大於 100 %。

(4) 要確認「加總機率 <= 100%」的時機

現在發現一個問題就是我的 controller 算出了未中獎機率,也 render 在了後台頁面,但是我的資料庫沒有跟著修改耶!,會發現這個原因是當我在編輯獎項機率時,也成功將新的獎項機率寫入資料庫,然後成功的在頁面更新了未中獎機率,然後突然想到:到底有沒有把更新的獎項機率寫入資料庫呢?才來查看 database 有沒有同步更新,後來發現居然未中獎的機率沒有同步更新,晴天霹靂!
那這樣後台怎麼會知道未中獎機率被更新了呢?然後獎項機率被更新後,原本的機率加總就不會等於 100 % 了,那這樣就出包了呀!就開始在思考要怎麼樣在可以驗證機率加總有沒有為 100 % 的情況下,還要在驗證過後,是否更新資料庫內的未中獎機率及欲編輯的獎項機率?

(5) 很混亂的 controller 及 function export module

驗證機率是否為 100 % 、計算未中獎機率、抽獎的 code,寫的有點長,放在 prizeController 好像有點亂,就想說在別的檔案寫成 module 輸出,再在 prizeController 引用,這樣在 prizeController 就比較乾淨跟明瞭,但是在驗證機率是否為 100 % 、計算未中獎機率、抽獎的 code,這三項過程中都需要取資料庫的資料,來進行計算,就不知道是要放在 專案/scripts/lottery.js 還是放在 controllers/lottery.js?說是 controllers 好像也算是處理 data,放在 scripts 的話,也是跟 JavaScript 有關的 code,再加上還要一直從 dataBase 取資料,一直在想取資料是要直接在 function 內取,還是放在 function 內的 parameter 輸進 functions 內計算,這樣就得綁在 controllers 裡面,因為還要將未中獎機率的 function,回傳未中獎機率的值,再 render 未中獎機率的值給 ejs。

感受

想的真的是腦袋炸裂,但又不想放棄QQ!
其實有在想要不要止血,先跳過這個 17 18 週,前進 21 週的react,但想說做了兩週的 17 週作業,就剩下了抽獎後台編輯跟刪除功能,何不再加把勁?然後就發現中獎機率好像沒有自己想像中順利XD。
做完中獎機率,就又會想說:都完成 95 %,剩下最後的部署跟 ESLint 了!何不再加把勁?

Decisional 決定行動

卡在「計算未中獎機率」以及「機率加總是否為 100% 的驗證」,隔一天繼續!

#Sequelize #Express #draw lottery







你可能感興趣的文章

Leetcode 刷題 pattern - Fast & Slow Pointer

Leetcode 刷題 pattern - Fast & Slow Pointer

[Python] Csv資料分割

[Python] Csv資料分割

Gaussian Mixture Model - 詳細推導

Gaussian Mixture Model - 詳細推導






留言討論