2020年3月31日 星期二

Leetcode題解 Python: Unique Binary Search Trees II

今天碰到這一題,卡關很久,來記錄一下。

二元樹算是目前遇到稍微棘手級別,棘手級別目前只有莫隊算法,還沒有花時間去弄通它。

這一題屬於「遞迴」的範圍之內,給一個數字,要你回傳有相同節點數的所有可能。

一開始直覺,就是把數列排序,取一個數字,由於是二元樹,左邊皆小於該節值,右邊則大於,所以左邊樹結就是該數字左邊的所有項目組合,右邊等同處理。

接下來,要設一個節點,該節點左邊的等於左邊的遞迴結果,右邊等同處理。

2020年3月26日 星期四

python 群益API SKCOM工具

SKCOM-tool Github

python 群益API SKCOM工具 版本(API):2.13.20

檢查三格位置的SKCOM.dll版本差異與位置: 1.當前的COM元件 2.系統已註冊的COM元件 3.comtypes client所用的COM元件

並且給予相對應的建議動作。 方便查詢出目前電腦上所使用的版本。

「三個位置的SKCOM都是最新版本就沒有問題。」



若不需要GUI,執行「F.py」,查看輸出即可。

2020年3月25日 星期三

python 初學者速理解 yield與generator

這我很久以前碰過,但是也不清不楚,return 與 yield 都能回傳值,那為什麼有甚麼區分?

yeild用於function中回傳值,回傳的類型是產生器generator,這個產生器會產生回傳值,但本身並不是想要的回傳值。

所以很直覺地使用len()或是[:]切片在產生器上,會回報錯誤。

yeild產生器像是在函式中的斷點,可以得到當下變數的數值。意味著你可以在函式外影響函式內的值,也會直接牽連到yield。

要從產生器內取出回傳值,用 next() 或用 for迴圈 都可以,for迴圈會跑到產生器停止,無法再用next()取得值就跳出。

而generator進度是會保存下來的,因此一旦全部跑完一次,想要重頭,那就得重新產生generator一次。ex1a(Github)

yield能用在哪?從generator取值感覺並不直覺好用。

2020年3月19日 星期四

PYTHON 群益API 2.13.20 錯誤代碼2017 錯誤原因與解法

從2.13.16版本之後,登入前就需要 SKReplyLib_OnReplyMessage 回傳指定值 0xFFFF 才可以登入。

一開始我也是矇了,不管怎麼傳就好像沒有作用?明明照著說明做了啊!

錯誤通常分兩種,第一種就是真的忘記寫到 OnReplyMessage 然後回傳 0xFFFF或寫錯,這種就不在這裡討論。第二種就是都按照說明寫了也確認無誤,但還是不知所以然的錯誤。

到底  2017 SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST 是從何而來?網路上沒有一個明確的解釋與通用的解法,這可以是基於討論的人並不多。

的確,確實回傳值設甚麼都沒有作用,那不是錯覺,那是真的。COM接口的Py檔中 OnReplyMessage 是沒有回傳值。

於是這形成了最怪異的事情,不管怎麼樣登入,由於接口的 OnReplyMessage 沒有回傳值 sConfirmCode,所以 SKCenterLib_Login 永遠都接收不到註冊公告,永遠的錯誤代碼 2017。

問題點是錯在哪裡?本來有個見解,在 2020-03-20 被提醒之後,終於確認是暫存檔的問題。(不是dll

執行以下幾行就能夠刪除掉舊版COM的py檔模型。
import comtypes.client, os
try:
    os.remove(comtypes.client.gen_dir + r"\_75AAD71C_8F4F_4F1F_9AEE_3D41A8C9BA5E_0_1_0.py")
    os.remove(comtypes.client.gen_dir + r"\SKCOMLib.py")
except:
    pass
繼續追根究柢下去。

Python 群益API Error in sys.excepthook

從一開始使用群益API時,就經常收到這個錯誤輸出。
Error in sys.excepthook:

Original exception was:
不以為意,因為運行不會受到任何影響。

關於這個錯誤,用GOOGLE搜尋會找到一篇文章,有做探討。

確實是直指出錯誤問題來源,但是並沒有解釋到底為什麼會出錯。

前幾天著手多進程,因此更瞭解當中的運作模式,這篇會更詳細講看法與解法。

2020年3月16日 星期一

Python 資料讀寫方法比較與資料壓縮比較 (二) 多進程

上一回邊寫時就在思考多進程是否能夠幫助提升資料讀寫的速度。

答案是否定的,為什麼?

首先是資料大小,資料規模不到一定程度,光是多進程的準備時間就輸了一大截。

接著是沒有考慮到資料轉傳,測試皆採取原地寫入原地讀出,未經壓縮的資料寫入比較快,同時讀出也比較快,即便它的容量可能是上百倍甚至更多,省下處理的時間就有優勢。

多進程的優勢在於啟動更多的 cpu 計算能力,對於 壓縮 與 解壓縮 需要用到 cpu 計算的,如果需要越多計算,多進程的優勢就會能體現。如 lzma 。

此外,將越多任務交給多進程處例,有助於提升速度。例如把資料json化、bytes化、壓縮化及解壓縮等盡可能在各進程上執行,主線程只是發包資料到各進程去。

透過 win10工作排程器 定時以 potplayer 播放音樂(二)

既上一篇之後,又出現了沒有辦法自動播放的現象。

然而這次就有找到要如何觸發這種沒有辦法自動播放的現象,就是打開別的播放清單,然後方形的停止鍵,等到播放器完整停止後關掉,下次運行以開啟播放清單就不會順利自動播放。

這次又再一次面對這個問題,花時間搜尋,卻發現想找的cmd指令在播放器所在的資料夾有 CmdLine64.txt ,終於可以了解有甚麼cmd指令。

最終嘗試各種結果,我找到了更好的指令。

在工作排程器,工作,內容,動作,改成:

程式碼:PotPlayerMini64.exe
引數:"C:\BGM.dpl"
位置:J:\Program Files\DAUM\PotPlayer\


就不用再掉原本執行的批次檔 (.bat)。 上一篇

2020年3月15日 星期日

Python 資料讀寫方法比較與資料壓縮比較

python內置的讀寫方式是透過 open() 。

如果有一筆資料,例如有五萬筆的串列,要寫入檔案並且讀出,甚麼樣的方式會是最快的?

這裡先寫結論,個人依照讀寫完成速度的私心排行:

「bstr json > json zlib > json gz > str json」

""" 完成速度排行榜
Method: bstr json, Compress Ratio: 0.06:1
Data size: 400064(0.39MB), Wspeed:4.16025 MB/s, Rspeed:2.97668 MB/s, Uspeed:1.73516 MB/s
Method: json zlib, Compress Ratio: 15.32:1, level = 6
Data size: 400064(0.39MB), Wspeed:2.99731 MB/s, Rspeed:2.76445 MB/s, Uspeed:1.43809 MB/s
Method: str json, Compress Ratio: 0.06:1
Data size: 400064(0.39MB), Wspeed:3.16940 MB/s, Rspeed:2.35598 MB/s, Uspeed:1.35141 MB/s
Method: json gz, Compress Ratio: 15.31:1, CompressLevel = 9
Data size: 400064(0.39MB), Wspeed:2.93210 MB/s, Rspeed:2.36939 MB/s, Uspeed:1.31044 MB/s
Method: json xz, Compress Ratio: 330.09:1, preset = 6
Data size: 400064(0.39MB), Wspeed:0.81887 MB/s, Rspeed:1.98104 MB/s, Uspeed:0.57938 MB/s
Method: json json, Compress Ratio: 0.06:1
Data size: 400064(0.39MB), Wspeed:0.57614 MB/s, Rspeed:2.28234 MB/s, Uspeed:0.46002 MB/s
Method: bstr list, Compress Ratio: 0.08:1
Data size: 400064(0.39MB), Wspeed:3.77832 MB/s, Rspeed:0.34935 MB/s, Uspeed:0.31978 MB/s
Method: str str(list), Compress Ratio: 0.10:1
Data size: 400064(0.39MB), Wspeed:3.58643 MB/s, Rspeed:0.33802 MB/s, Uspeed:0.30890 MB/s
Method: str str(tuple), Compress Ratio: 0.10:1
Data size: 400064(0.39MB), Wspeed:3.59002 MB/s, Rspeed:0.33762 MB/s, Uspeed:0.30860 MB/s
Method: json bz, Compress Ratio: 137.76:1, CompressLevel = 9
Data size: 400064(0.39MB), Wspeed:0.22510 MB/s, Rspeed:1.76317 MB/s, Uspeed:0.19962 MB/s
"""

2020年3月8日 星期日

Python @ Property 修飾符 初學者速理解

初學者第一次看到「@」,像我,就滿頭問號。

網路上教學很多,而且不難懂,只是沒有我的風格。(推薦: 官方文件)

@又名Property屬性,property() 是python的內置函數。在定義 類別class 的時候,也經常設定其相關屬性。

Property由四個部分組成:getter setterdeleter、 doc。
以a為例,getter、 setter、 deleter分別對應:
a # call getter
a = 1 # call setter
del a # call deleter
發生以上三種狀況,就會分別執行對應的函式。

Python pyqt + logging 整合範例1

當有了圖形化介面的時候,發現工作列卡一個 cmd 實在想隱藏起來。
用 pythonw + .pyw,就能不卡 cmd。
但是一旦將 cmd 隱藏起來,就看不到輸出了甚麼。
logging可以將紀錄在輸出並同時保存下來,操作起來比 open() 還便捷。

GUI的操作功能得寫在一塊,格局被侷限了。
如果想整合更多的功能,而且是單獨寫過寫好的部分,或是打開音樂播放器聽音樂與執行某串程式碼等。
大夥都進來專案,會讓專案顯得異常混雜,也可能產生多個同名同功能但不同亞種的函式,搞得你混淆誰新誰舊。
此外,這些功能不需要傳入或只有固定參數,啟動後就能自動獨立運行完成。

那些其他程式運作情形,可以靠logging紀錄,不一定要回傳給主程式。
主程式透過查閱記錄,就能在GUI上觀察到程式進度。

然而可預期的錯誤能被處理,不可預期的錯誤會讓程式跳掉而無法用logging傳出ERROR以上的紀錄。
為了避免看不到錯誤訊息的憾事,得將錯誤訊息輸出保存下來以供來日查閱。

2020年3月7日 星期六

Python logging 初學者速理解

給對於 logging 未曾接觸過,或剛接觸過的人。

logging 可以將記錄輸出,也可同時將記錄保存。除錯除了靠print大法,也可以靠logging保存下來的日誌中找出錯誤點。

有些程式運行會因為時間改變環境而出現問題,出現嚴重錯誤就會跳掉。沒有辦法總是在編寫或除錯模式下運行,出錯就告訴你哪裡有問題。若程式未能紀錄到當下運行狀況,就少了線索去發現問題所在。

logging有很多教學,也有繁體中文教學,寫得也不錯。

這裡就簡單寫下一點筆記,幫助初學者快速理解logging運作。

透過 win10工作排程器 定時以 potplayer 播放音樂

用 工作排程器 在早上自動播放是我的習慣,不過有一個問題,它不一定每次都能播放出來。

這邊講一下基本準備:

將想要播放的音樂清單,用 potplayer 輸出成播放清單(.dpl)。
操作:把音樂擺入播放清單,按F2儲存。

在win10系統,螢幕左下有放大鏡,搜尋「工作排程器」就可以叫出來。
不然「開始」→「windows 系統管理工具」→「工作排程器」。

透過建立工作,觸發條件自行設定,我個人是設定每日早上七點。

動作新增一個:
啟動程式
程式或指令碼輸入程式名也就是 PotPlayerMini64.exe
引數為播放清單的位置如 xxx/xxx/xxx.dpl
開始位置為執行程式所在資料料夾,x:\Program Files\DAUM\PotPlayer

2020年3月6日 星期五

Python pyqt5 與 matplotlib 結合示範之範例2

範例2是關於一元二次方程的線圖。

展示以下功能
1.可以添加一元二次方程至清單或從清單刪除之
2.依清單內的項目勾選狀況顯示或隱藏一元二次方程
3.在狀態列會顯示滑鼠指到線的相關資料

這次的重心,是要做出一個可調整的清單,也可分別勾選項目顯示與否。

如果線的數量未知,那就得以可擴充可變動的前提去寫。

對於不同情況,可能想看的線是不同的。有時候會覺得太多線,而想減少顯示在繪圖區的線。

這次各線都呈現在一個軸上,就沒有做區分。要控多軸,就再加點條件判斷就可以了。

因為範例1的cmd不會被錄到,所以這次把資訊顯示在狀態列上。


2020年3月5日 星期四

Adobe Acrobat Reader DC 造成的記憶體不足

最近買了一條記憶體,跟我電腦上的是同樣大小8GB。原因是電腦出現記憶體不足崩潰的現象。

記憶體比兩年前便宜很多,順便一看SSD也是,這題外了。

查了一下解法,既然記憶體便宜許多,那就多裝一條不就解了?我看我的記憶體使用率普遍達70%以上,一個要認真操起來,絕對爆掉。

遺憾是沒有因為裝上一條新的記憶體而解決問題。

尋找根源,我學習到一些找出真兇的方法。可是那時我並沒有找到出來,狀況也隨裝上記憶體好轉。

今天再發生一次,很幸運的是,這次只有提示「記憶體不足」,沒有像之前整台電腦崩潰,看來裝新記憶體還是有幫助的。

在工作管理員的「效能」頁面
記憶體「使用中」的部分沒有全滿。
記憶體「已認可」的部分達到上限!

這樣子,推論出只要「已認可」用罄就會造成記憶體不足的現象發生。

Python pyqt5 與 matplotlib 結合示範之範例1

對於寫 python 的人來說,為了讓程式更方便使用,會想要寫點圖形化介面。

對於 python 來說,最基本的圖形化介面是 tkinter ,網路上也有許多相關教學。不過用程式碼去定義視窗與物件排版,是需要比較學習與辛苦的。

之前我寫過 c# ,用 visual studio 去寫。按鈕、標籤可以直接拖曳到版面上,效率是比較高的,也易懂執行出來的成果會長怎樣。

對於 python 來說,有 qt 可以直接設計界面的,用 qt designer 也生成一個版面,將按鈕、標籤等拖曳到版面中排版,基本樣貌可以直接反應出來。

想要學習 pyqt ,建議直接找書,按部就班,基本上就能學習到讓 python + pyqt 搭配 qt designer 設計。

寫這範例,並不是手把手從零教學,而是展示一些搭配的效果。適合給初學者想再進階的人。

像是將 matplotlib 的繪圖鑲入,並且可以用qt物件去操控繪圖。

如果想要寫股票走勢,用選單選取股票,就能讓繪圖區跑出折線圖或K線圖,甚至可以做即時走勢,如果有辦法弄到即時資料就絕對可以。

2020年3月2日 星期一

Python win32gui LoadImage Error 一個很容易解決的情況


ERROR:root:Some trouble with the icon (檔案位置): (0, 'LoadImage', 'No error message is available')

吃到這個消息,如果又想用自製 ico 檔的,將原圖片透過這個網站將圖片轉成 .ico 就可以解決了。

JPG轉ICO - 在線轉換圖標文件

本來我也認為是 ico 類的檔案,不過卻是用小畫家隨便畫了個 16*16 的圖片,然後將 副檔名 改成 .ico ,結果卻過不去,依然報錯。改回 .jpg 報錯。

上網搜尋,遇到問題不多,畢竟這是很小問題,哈哈。網路上的解法大多認為所用 .ico 是正確格式,有人用了網路大神的方法依舊無法解決問題,跟我一樣。

印象中 .ico 也是圖片檔,於是直覺用小畫家弄一個,但 .ico 需要有有固定格式,所以得透過轉換程序才能正常使用,不能用修改副檔名的方式。