文章

[LeetCode] 寫了400題 LeetCode 後的經驗

圖片
相信大部分人寫 LeetCode 是為了面試,我也不例外,我的 LeetCode 過程大概可以分成三段: 一開始覺得很難,就斷斷續續的寫,也不知道方向在哪 面試將近,每天瘋狂地刷題目 面試後,每天寫 daily challenge 磨練自己的技巧 我就列出一些我覺得我寫 LeetCode 犯的一些錯誤,還有後來要怎麼避免的方法。 LeetCode 常犯的錯誤 錯誤 1: 按照題號寫 一開始只是覺得說哪天會要面試,所以我先來寫寫看,所以就從題號 1, 2, 3, ... 往後慢慢寫。後來發現這樣寫其實不是很好的做法,因為: 遇到 hard 的題目就會讓人卡住花很多時間,而這些 hard 題目要達到 optimized solution 的一些步驟會需要練過一些 easy 或 medium 的題目的解法才會知道怎麼寫 遇到困難一點的題目就會讓人害怕不想繼續解 相反地,遇到連續好幾題太簡單的題目也會讓人失去興趣 後來我就開始搜尋網路上有沒有人推薦 LeetCode 要寫哪些題目,於是就找到了幾個不錯的資源: LeetCode 本身自己的 Study Plan ,像是 LeetCode 75, Data Structure, Algorithm, Dynamic Programming, Programming Skills, Graph Theory 免費版的其實我都解過一輪了,但有的題目沒有官方解答,就只能去挖討論版的解答 NeetCode 150/Blind 75 ,reddit r/LeetCode 滿推的清單,也有按照 pattern 分類,可以重複練習不熟的 pattern LeetCode Patterns ,除了列出 patterns 以外還有問過題目的公司清單,題目都滿經典的,就算是 easy problem 也其實都值得讓人思考各式各樣不同的寫法 以上清單的題目其實都高度重複,我在面試前會專注去練這家公司愛考的 pattern (像是 Google HR 就說 DP & Graph 題目可以多練)。 錯誤 2: 太在意語法和 Clean Code LeetCode 的 solution 以及討論區的解答其實可以分成兩大類: competitive programming 與 clean code。但其實我覺得自己需要走哪個風格要看你寫 LeetC...

[試算表] 追蹤台股 Google Spreadsheet (未實現損益/已實現損益)

圖片
在 Dcard 上發了一篇文結果引起超多網友回應想要看試算表,我就來整理一下我追蹤台股用的 Google 試算表給大家。 這個試算表我目標是以 "簡單" 為主,底下我也會講解公式的運作原理,希望大家能以此試算表輕鬆擴充自己想要的功能。 功能 未實現損益 (Unrealized Gain/Loss 表) 不管同一支股票是不是有部分已經賣出,只要你還持有未賣出的股票這邊都看的到。 已實現損益 (Realized Profit/Loss 表) 我過去的績效如何? 在這個表一目了然。 未實現損益: 詳細資料 (Unrealized Stats 表) 我還持有多少股? 每股市值多少? 每股的成本是多少? 在這個表可以快速追蹤。 手機友善 (Mobile Friendly) 我為了在手機上也可以快速看我想看的資訊,把 "Unrealized Gain/Loss" 做成比較窄的版型。 只要下載 Google Sheets app 打開試算表就可以了。 Google Spreadsheet 連結 Google Drive 連結 Stock Tracking 使用方式 請先點 "檔案" -> "建立副本",copy 一份試算表到你自己的 Google Drive 將 "Current Price" 表單中填上你想要追蹤的股票代號和名稱 將 "Transactions" 表單中刪除範例資料,但請務必留下第 2 列 (因為有公式),然後慢慢往下填入你的資料 Step 1: 檔案 -> 建立副本 Step 2: 新增/刪除股票代號和名稱 (紅框圈起處),灰色底欄位代表有公式 Step 3: 在 "Transactions" 表填入資料到白色底欄位 (紅框圈起處),灰色底欄位代表要讓公式自動計算 未實現損益的正確算法 其實在發 Dcard 文之前我自己也像 另外一個表單 犯了同樣的錯誤,就是只有在股票全部賣光光 (持有 0 股) 後計算的未實現損益才會正確。還沒全部賣光怎麼辦? 難道就不顯示了嗎? 飲料的例子 只要股票中途賣出一部分,目前還持有部分股票的話,感覺計算就突然變得很複雜。但不用怕,我們來用飲料當作股票舉個超簡單的例子 (1 杯=1...

[Qt] PySide 如何 debug 沒有 stack trace 的 Segmentation Fault

圖片
雖然 PySide 是 open source 也很好用,但如果我們用 PySide 寫了一些有 bug 的程式,GUI 在做了某個操作後就會無預警 crash 消失不見,只留下哀傷的一行訊息在 console 上: Segmentation fault 現在是要怎麼 debug?  最近我就想用 QTableView + QAbstractItemModel 做一個可以動態新增資料的 table,但是以下的程式碼跑起來就會遇到 segmentation fault (完整的程式碼在文章最下面): from typing import Any, List import sys from PySide2 import QtCore, QtWidgets class DataModel(QtCore.QAbstractItemModel): ... class MainDialog(QtWidgets.QDialog): ... if __name__ == "__main__": ... 看了一下我也不知道問題在哪,我也不太曉得 QAbstractItemModel 哪幾個 functions 是一定要 override 的,現在該怎辦? 解法1: 暫時切換成 PyQt 當我們把一開始的 import 全部換成: from PyQt5 import QtCore, QtWidgets 再跑一次程式,這時候 GUI 不僅不會 crash,console 上還會多一行完整的訊息: NotImplementedError: QAbstractItemModel.index() is abstract and must be overridden Oh 原來我忘記要 override "index" function 了。 解法2: 用 gdb 來 debug 如果遇到提示還不夠明顯的狀況,我們可以用 gdb 來 debug。 等等! gdb 不是給 C++ 用的嗎? 和 Python 有什麼關係? 原來 PySide (Qt for Python) 只是像是用 Python 的殼把 Qt C++ 的程式碼包起來,詳細的運作原理可以參考  Qt for Python/Shibok...

[技巧] 同硬碟不同OS動態切換 Rustup/Cargo 路徑

問題 Linux 上不管切換到 x86 還是 Arm 工作上都是用同一個 mount 到的路徑,所以 $HOME 其實資料都一樣。 但如果我在 x86 上安裝 Rustup 和 Cargo 到預設的路徑 ~/.rustup 和 ~/.cargo,假設我安裝了 exa ,切換到 Arm 上後就會跳出下面這樣的錯誤訊息: -bash: /xxx/.cargo/bin/exa: cannot execute binary file 原因 因為 Cargo 的 packages 當初是在 x86 上編譯的,當然就沒辦法在 Arm 平台上執行。 解決方式 第一個直覺想法就是,有沒有辦法在 x86 與 Arm 上都安裝同一個 package,只是安裝在不同路徑。查了一下網路就看到如何 客製化 Rustup/Cargo 安裝在自訂的路徑 : Rustup: 執行 rustup-init 前設定 RUSTUP_HOME Cargo: 執行 rustup-init 前設定 CARGO_HOME 利用這樣的環境變數,我們就可以寫一些 Bash scripts 來達到多個 OS 上的安裝和動態切換。 Bash Script: 安裝 Rustup 在不同的 OS 上 例如我們在 x86 上安裝就可以這樣寫: #!/bin/bash export RUSTUP_HOME="$HOME/x86_64/rustup" export CARGO_HOME="$HOME/x86_64/cargo" cd "$RUSTUP_HOME" # Download rustup script curl https://sh.rustup.rs -sSf >rustup.sh # Install rustup bash rustup.sh -y --no-modify-path 在 Arm 上安裝就換一下 RUSTUP_HOME 和 CARGO_HOME 路徑就好: #!/bin/bash export RUSTUP_HOME="$HOME/arm64/rustup" export CARGO_HOME="$HOME/arm64/cargo" cd "$RUSTUP_H...

[Side Project] 用 PySide2 (Qt Python) 實作 Prototype Pattern 與樂譜編輯器

圖片
最近讀書會剛好要報 Prototype Pattern,看了一下  Design Patterns: Elements of Reusable Object-Oriented Software 的 prototype 這章節。書中一開始動機說明一個五線譜的 GUI 編輯器,後面 sample code 卻是用像是 toy example 的迷宮,這樣真的兜不攏也看不太懂。 網路上找了一下也沒有人為了 prototype pattern 做五線譜的範例,剛好最近工作上會碰到 PySide2 ,於是我想想,乾脆來把五線譜的範例做出來順便練習一下 Qt 的 QGraphicsView 要怎麼使用,也順便展示 prototype pattern 的優缺點。 Side Project on  GitHub 簡單的樂譜編輯器 GUI Users 可以從左邊拖曳樂譜上的符號到右邊的畫板上,畫板 (canvas) 上的符號也可以事後再進行拖曳、旋轉。 就算簡單也該有的功能 為了讓範例簡單,我就只做了書中提到的 half note 和 whole note,不要加進一大堆其他符號來讓整個 example 複雜化。但相對地我們也不能弄得太簡單太像 toy example 看了沒感覺。 我就多做了幾個比較像 real project 的功能: 拖曳的符號會像是磁鐵一樣 snap to lines/spaces 到最近的五線譜線上或空格(間) 內 拖曳符號時我把預設有的圖示 (indicator) 隱藏,拖曳中 (dragging) 也看的到放開 (drop) 後的樣子 我限制拖曳的符號只能在畫板 (canvas) 中移動,不給使用者拖曳到不見或卡在邊邊一半 Prototype Pattern 優點 1: 可以 Reuse Framework 不用 prototype pattern 我們會怎麼做創 object 的 framework? 我們可能就會創出一大堆平行化的 GraphicTool ( 橘色 的部分) 用來造代表樂譜符號的 Graphic: 書中說 framework 不應該知道 application 任何細節才對,萬一今天 application 改成做遊戲地圖編輯器呢? 難道要創更多 GraphicTool? 那可能我們會先發瘋。 所以 prototy...

[工作經驗] 程式讀書會其實是學新東西的好機會

圖片
各式各樣的程式讀書會在公司已經辦了很久了,每過一段時間我們就會找一本有人有興趣的書,大家每週找一小時開會報告,大家輪流報告書的一個章節。 最近報的書大概就是 Threading Building Blocks, Approximation Algorithm 和 Design Patterns。有些是有人工作上需要用到,剛好大家一起報一起學新東西,也有一些是為了像是我們剛進公司的新手複習的。 跳脫不了常規的簡報格式 每一團讀書會的人都不太一樣,早就讀過相關類型的人其實就不會來 meeting,有老鳥和新手一起的,也有只有對這主題有興趣的人來參加,或是只有三四人的讀書會也是有。 可是參加了一陣子後突然發現讀書會變得非常"規格化",這什麼意思呢? 因為大家因為還要忙於平常的工作,常常導致最後一週突然想起下週換他報告,只好臨時準備一下。 這時候不知道要怎麼做簡報怎麼辦? 簡單啦,我看一下上次的人怎麼報的就好了。 於是就把上一個人的簡報或好幾年前有報過相關的簡報抄來改一下,結果大家的簡報都長得很像這樣: ( source ) 而且不只一頁,幾乎是每一頁都長這樣。但這也怪不了大家,因為這本來就不是我們的主要工作,況且時間這麼少,能有什麼變化? 沒時間準備讀書會怎麼辦? 我們有沒有辦法同時做到以下的兩件事: 讓大家快速了解某章節的內容 自己又學會新東西 這是我在突然發現我要報讀書會只剩三天的準備時間時思考的事情。 我心中想: Oh no 完蛋了,只剩三天我還不如就直接把前幾年的人做的投影片拿來朗誦一遍就好了吧? 但喜歡跳脫框架的我又覺得: 不行啊,只會抄前人的,可以學到什麼? 但當我打開前人做的投影片的那瞬間,我意識到我只能跳脫框架了,因為我發現幾年前做同一個主題的人竟然只是把書中的內容截圖下來放進投影片。沒錯真的每一頁都只有截圖不誇張。 這也怪我前幾次都用了很創新的方式來呈現讀書會:有次我用 Jupyter Notebook + Plotly Express 來做 interactive 的教學、又有一次我真的用 Qt 做出一個能做 syntax highlighting 的小程式。這讓我真的沒辦法抄一抄就好。 於是我就靈機一動突然想到,那我給我自己辦一場 hackathon 如何? React JS 黑客松 我要報的 Head First Design ...

把任何網頁都果凍化 (Jellify) 的書籤

圖片
上次 用 Google Apps Script 做的 side project 就比較商業化,這次來做一個比較有趣的 side project 。上次比較可惜的是沒有完整記錄做 side project 的過程,這次我從 idea 到做完的經過都把它紀錄下來,跟大家分享一下做這個 side project 的種種過程與挑戰。 最終成品 直接用一張 GIF 展示最快 (28MB 看不到請等他一下): Online Demo:  https://sc420.github.io/jellify-ur-website/ GitHub:  https://github.com/sc420/jellify-ur-website Idea 發想 做 side project 最難的就是無中生有,做人家做過的好像就沒什麼挑戰,做人家完全沒做過的也不知道能不能做出來。 一開始的構想 其實一開始我是想做 ANTLR + HTML canvas 的 side project。因為公司剛好也正在做 ANTLR 來 parse 一些東西,但對於這個 library 不熟自然就想多玩玩看,想說藉著 side project 也可以練習到。 不過 ANTLR 能做的事基本上還是要 parse 一種程式語言,不管是 C++ 程式碼還是 JSON 甚至到自訂格式的計算機。想了想覺得如果要用網頁的方式呈現還是對大部分的人有點生硬。 原本是想說讓大家在網頁上隨便輸入一串 JavaScript,讓大家一步一步看他被 syntax highlighting 的過程。後面想說更有趣的話我可以搭配 canvas 和變成考題的方式,類似之前有看過 JavaScript quiz,輸入正確的 JavaScript 否則寫錯的程式碼就會在網頁上炸開來。 如果要讓字母爆炸就代表我需要自己知道 JavaScript 每一個字要上什麼顏色,就會需要 ANTLR。要爆炸需要一個物理引擎。 延伸的構想 後來覺得實在太困難,ANTLR 我又不熟、物理引擎我也不熟,這樣兩個不熟加起來就很容易做不出來,而且好像也不太有趣。 但是為了調查能不能做出來的時候我有跑去看一個找到的物理引擎 Matter.js 的 demo,還有看到 Matter.js GitHub 的 gallery 那邊也有大家有趣的應用,看到一...

此網誌的熱門文章

[試算表] 追蹤台股 Google Spreadsheet (未實現損益/已實現損益)

互動式教學神經網路反向傳播 Interactive Computational Graph

[Side Project] Google Apps Script 實作 Google Sheet 抽股票的篩選工具