B 站上講如何寫論文的文章不少,但這麼精簡幹練的很少。
影片分成多個主題,每個主題用五分鐘講完,內容沒有任何一句廢話,搭配一兩張提綱挈領的板書直指要點。之後有時間可能再重看做閱讀筆記。
星期一, 12月 19, 2022
星期日, 12月 11, 2022
健身房攻防紀實
原本去的小健身房租約到期倒了,不得不換健身房。工作場所附近只有一家健身房器材符合需求,其他間不符需求。但這家健身房有業務、糾紛多、價格有陷阱,因此去之前做了功課,問了有簽的朋友,成功講到比較合理的價格。這次過程大概是這樣的:
我:您好,我想詢問一年、兩年方案分別怎麼算
業:我們入會費處理費 6888,兩年月費 1988。但我可以給您作主入會 3888,月費 1788(微笑)
我:你們這分店開幾年了?
業:四年
我:可是我朋友之前來,月費只簽 988 耶~~~(爆擊)
業:(眩暈)那個是開幕期間,設備不完善或施工中,所以才有這個價格 blahblahblah
我:1788 太貴了,我希望簽 1288!(1288 為攻略上 2022 年的成交價)
業:我去問一下長官看可不可以(遁走去小房間,結束這回合)
業:(回來)我可以給您用 XXXX 專案,這方案 0 入會費,只綁一年而且月費就是 1288,請問您今天可以簽約嗎?
我:我希望將合約帶回去審閱,我簽約習慣先看。我今天運動就單次付費 OOO 元
業:不用擔心太多,我們有七天鑑賞期,不滿意可退費。這樣也不用多付一次 OOO 元 blahblahblah
我:可是你們七天鑑賞期不是規定不能使用器材嗎?(甜笑)
業:(眩暈)...合約上是不行,但我可以作主 blahblahblah
我:(內心 OS:印象中合約還有條,簽約後雙方合意以合約紙本為主,口頭約定不算數吧?)
我希望合約可以帶 回 去 審 閱,我今天就單次付費,當然簽約我還是樂意找您 blahblah
業:(打斷我)我懂您意思,但我希望各退一步,您約帶回去,今天付費 OOO 就用信用卡可以嗎?
最後我信用卡只刷單次付費的錢,約帶回來檢視完畢後,就進行簽約了。簽約首刷金額有把我的單次體驗費用扣除,等於讓我免費體驗一次感覺還不錯。很成功的沒踩到陷阱,當然我知道健身房絕對不虧。平局結束第一回合。
我懷疑這間健身房的話術是中央制定,全台統一。導致業務出的招 100% 在攻略上都見過(攤手)。之後應該就是應對教練課推銷吧。
星期日, 11月 06, 2022
Jupyter notebook module 找不到除錯
今天玩 python NLP 遇到鬼打牆現象:明明已經 !pip install spacy 但 jupyter 執行 import spacy 一直說 module not found。 排查後才發現是 jupyter kernel 的問題。我 docker container 原本就自帶 python 3.7,apt-get install 又自己裝了一套 python 3.9 並只認自帶的版本,兩者各自獨立,前者裝的 package 後者找不到。
後來 Dockerfile 做了些設定
apt-get install jupyter-client
pip install ipykernel
python -m ipykernel install --user
其中裝 jupyter-client 是為了能執行 jupyter kernelspec list。後兩者則是讓 jupyter 認我裝的 python 而非 jupyter 自帶的。Dockerfile 改好後 rebuild 問題解決。
全文連結Docker network interface 好文
太久沒玩 docker 又犯了小白錯誤。
在 container 裡面裝了 jupyter-notebook,結果在 container 裡面 wget 連的到。但切回 host 和外部環境就連不上。docker file EXPOSE 有開 port,docker run port 有 forward 但就是莫名 connection refused。
後來搜尋後才發現這是典型錯誤。jupyter-notebook bind 的 127.0.0.1 屬於自己 network namespace,我的 127.0.0.1 不是你的 127.0.0.1。後來加個 -ip="*" 廣開 binding 解決。
星期五, 10月 28, 2022
星期三, 10月 26, 2022
VirtualBox Ubuntu VM 更改檔案空間大小
圖轉載自這裡
之前曾多次遇到 VirtualBox VM 空間不夠問題,建立 VM 時給的硬碟空間太小,docker 弄一弄 VM 硬碟空間就不夠了。但按照 Stack Overflow 上的解法怎麼改,分割大小都是舊的,最後往往重裝 VM 解決。但每次都一堆 docker image 重抓真的非常麻煩。後來讀文章才整理出解法。
問題根本可以用這張圖說明,現在的 Linux (我用 Ubuntu 20.04 LTS)在檔案系統上疊太多層抽象化,要正確擴充可用空間大小必須每一層都改到。在 VirtualBox 的步驟大概是
1. 修改「實體硬碟」的大小
VirtualBox 需要把所有 Snapshot 取消。有 Snapshot 那 VM 寫入的「硬碟」實際上有可能分散到 snapshot 裡。然後 GUI 的虛擬媒體管理員直接調大小。
2. 修改 Partition 大小
先用 lsblk 看要擴容的檔案系統到底實際是掛在哪顆硬碟上。我是 /dev/sda3,這時
sudo growpart /dev/sda 3
下達後用 lsblk 檢查,/dev/sda3 應該已經擴大,但下方掛的 Logical volume 大小還是舊的,sudo pvdisplay 大小也是舊的
3. 擴大 Physical volume 大小
pvresize /dev/sda3
再來用 sudo pvdisplay 看大小對了,但 lsblk 看到的 ─ubuntu--vg-ubuntu--lv (logical volume)和 df -h 看的大小還是舊的
4. 調整 Logical volume 大小
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
應該要可以看到 Size of logical volume ... changed from...,再來
sudo vgdisplay
應該就要看到 VG Size 為新的大小,此時 df -h 看到的 Filesystem 大小還是舊的,此時應接最後一道工法
5. 調整 file system 大小
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
最後 df -h 看到分割區大小變大,打完收工!現在 Linux 的檔案系統真的抽象化堆的太誇張了....全文連結
星期一, 10月 24, 2022
星期五, 10月 14, 2022
AI 研究小感
壓力好像真的是寫程式的動力。
星期三, 10月 12, 2022
大富翁三
大富翁系列是小時候很喜歡的遊戲之一,特別是二代、三代、四代(五代以後玩不習慣,都是玩了秒刪)。Steam 出了 DOSBox 版就入手了,二三代是重溫,四代是補票 XD
這幾天花了八小時把三代破過一輪,實現了孫小美的勝利 XD 以現在眼光來看,遊戲不困難,AI 太笨,特別是不會濫用道具和炒股存股。三代的道具店遙控骰子和路障還可以無限制買,搭配黑市存夠道具和卡片後基本就鎖定勝局,連 S/L都不大需要。
這塊地很值錢呢,他是我的了(使用購地卡)~
踩到噴錢的地點了,喔嫁禍卡和免費卡的複合式反應裝甲還有四層那沒事了~
AI 真是好心人有高價卡片都捨不得用拿來送我呢,看我用搶奪卡搶奪你所有的搶奪卡再搶走你其他高價卡~
不過 AI 雖笨,但回憶無價,當年玩二代三代的時候還是國小屁孩。現在重溫兼補票,很遺憾 Steam 版四代目前沒有超時空之旅,看未來官方會不會補了。
星期二, 9月 27, 2022
老同學 Godie 見面
Godie 是當年小學同學,後來又剛好同高中並且一起加入資訊社 TFCIS,上次見面應該是快 20 年前應該是 302 一起打 CS。命運的安排讓老同學上週五來奇美演講,就趁機掀吃飯了。
Godie 演講完後弄了自己的行程,順便回老家探望雙親順便換掉西裝,時間到在醫院見面,然後由我帶去吃附近唯一一家有冷氣且相對高檔的義大利餐廳 XDDD
隔了快 20 年,老同學們邊吃飯邊講古,我國小的事情只記得零碎片段,只零星記得幾個人名和一些瑣事,例如小六時幫 Godie 競選某個職位 XD
倒是 Godie 和一些同學有緣讀同所國中,一直保持聯絡最後也加了臉書。看到當年洽北北女同學變成照片中洋溢著幸福的二寶媽、另一個男同學變大人變帥還剛好在奇美(電子)工作,真的有時光飛逝滄海桑田的感覺。
吃飯中也聊了生活其他面向、工作、情感、居住無所不聊。連創業都聊,例如未來如果一起弄套交友軟體,一定要有特殊功能可以把優質對象直接下架並內線介紹給公司高層 etc XDDD。
這場快樂的吃飯以我地頭蛇請客結束。有老朋友來看我太難得了,也算是對當年大專乙組一題奪冠遲來的補請客了 :D
全文連結
星期四, 9月 22, 2022
Docker 取回硬碟空間
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Docker container 長時間執行後常遇到大量佔據硬碟空間,docker system prune 沒用,一個可能兇手就是大量 container log。用指令把冗餘 log file 清掉就能取回空間。新版 docker 好像有 log rotation 機制,有機會再研究
全文連結
星期一, 9月 12, 2022
台北旅行遊記
工作累積太多疲勞,剛好遇到中秋連假,就額外多請幾天,湊了六天連假來自助小旅遊。
本來考慮去九族文化村和日月潭,但想到本肥年近 40、體重近 90,續航力不佳,戶外景點很怕玩三小時人就沒力,然後就得回飯店待機。所以後來決定去台北。台北戶外玩累還可以玩室內行程,最不濟還有書局。這次行程玩了許多過去沒玩過,或很久沒來過的點。
這次去了陽明山。但這次沒做太多功課,純粹隨緣,結果有點失敗。大部分時間花在走路和搭公車移動上,吸了很多芬多精但沒看到太多景點有點可惜。
陽明山上散步吸芬多精,來的時間不對,動線沒規劃完整,沒看很多景點,但至少吸了芬多精 XD
路上遇到野怪 -- 貓貓。貓貓看來並不怕人。至少肯擺 pose 給拍照
數位放大後的貓貓,不親人但也不怕人
回來前一天去了貓空。貓空是從來沒玩過的景點。貓空景點相對集中,下捷運動物園站後搭纜車到貓空站,然後徒步移動走玩右線和一部分左線。貓空真的有點日本小鎮的感覺。
貓空天恩宮,路過拍照,沒進去看
在貓空纜車上照到的街景
貓空夕陽照,剛好抓到太陽下山的 timing
Y 區地下街照片,Y區地下街這次沒玩到太多,室內行程都去天瓏書局看書了
西門町夜景,新換的 S20FE 夜拍確實比前一支 LG V20 給力。
虎之穴店門口,還沒進店門在樓梯應該是可以拍照的 XD
天瓏書局,台南北門路的宏華收了以後,就沒有充滿電腦書的書店了。誠品電腦書不少,北門路也有天瓏台南據點。但純就數量而言台南沒一個比的上台北天瓏的量。
台北宅行程必逛安利美特,就算什麼都沒買來吸吸宅氣也好。永恆不變的入口照 XD
永遠的經典新世紀福音戰士。動畫擺了 N 年但永遠沒看完的一天 XD
新流行的作品,但個人對腐是完全不能接受的 XD
這次旅行唯一小遺憾就是沒掀到 Twsam,他說可愛小寶寶剛回家應該無法分身!看來未來幾年掀到的機率也非常渺茫了 QQ。當年 TFCIS iii 程設組五人,kochi 已知結婚生子,DNA 結婚更早,現在 Twsam 的狀態也從已知單身忽然跳到有小孩(看過低調的沒看過這麼低調的 XDDDD),DreamLinuxer 在美國,所以進度停滯不前的單身漢就剩下我了嗎?
星期日, 8月 28, 2022
Bioshock remastered
好久沒廢寢忘食打 FPS 。這款躺在 Steam 吃灰很長一段時間,忘記為什麼忽然想拿出來打,但來了興趣就一口氣破完。
遊戲充滿了各種對立、矛盾元素。遊戲發生在海底遠離主世界塵囂的的烏托邦 -- 銷魂城(Rapture city)。裡面建築風格明明是幾十年前的美國,卻有遠超地表的超級黑科技,例如能讓人飛簷走壁、發射火球、閃電、甚至粒子化瞬間移動的基改技術。
但美侖美奐的城市卻因濫用基改物質(ADAM)和內鬥等因素,最後變成反烏托邦。美麗如渡假飯店的城市,內部最常見的住民卻是被 ADAM 侵蝕神智、精神失常的瘋子,或是被肉體心靈雙重改造蒐集 ADAM 的 Little girl 和其保護者 Big daddy。
遊戲的主線故事也牽涉到善惡兩極反轉,遊戲以主角墜機剛好來到銷魂城開始,在戰友透過收音機指導棋的幫助下,一路披荊斬棘幫自己逃生,並尋找殺死戰友家人、控制城市的惡魔。最後真相揭曉,惡魔也許不是好人,但戰友卻不是戰友。最後主角成功解除自身被埋下的心靈暗示,踏過屍山血海打死最終 BOSS,迎來結局。
遊戲的戰鬥系統有其特色,在後續系列作也持續使用。主角有 FPS 標配的槍械類武器的同時,也能透基改 plasmid 掌控各種能力,例如放電、引火、召喚蟲群、催眠他人等類法術能力、或提昇駭客技術、提高抗性等自我改造。主角也有駭客技術,遇到機械類敵人也能選擇解拼圖、改寫敵人邏輯取得控制權。遊戲連貨幣都有兩種,能買槍械子彈恢復藥劑的金錢,還有可以用來買 plasmid 或提自己能力的 ADAM。
遊戲過關還是要用點心思,特別是跟 Big Daddy 的戰鬥,對手攻高血厚硬拼往往拼不過,特別是什麼都缺的前期。要打贏必須用策略,例如激怒 Big Daddy 後把他引到被我方控制的火箭炮台。透過能造成麻痺的電擊 plasmid 不停強控、直到他被火箭炮擊殺。或是用催眠 plasmid 控制另外一個 Big Daddy 製造內鬥再減尾刀等。地圖本身也有少量解謎元素,例如被冰封的門要用點火能力打開、放在拿不到地方的鑰匙要用格空取物能力取得。
遊戲武器、Plasmid 都有升級系統。武器可以透過特定地點升級,解鎖更強的威力、豁免自己武器傷害等升級。Plasmid 可以在遊戲過程中買、合成更強的版本,付出 ADAM 解鎖更多安裝位置等。
遊戲有多重結局。結局好壞取決於怎麼處理 Little Sister。打倒 Big Daddy 後選擇殺掉 Little Sister 可以獲得更多 ADAM 卻會導向壞結局。選擇救贖 Little Sister 解除讓其變回常人,得到的 ADAM 會少一些,但從頭到尾都選救贖,遊戲才能有好解局。但救贖之路科學家其實會送禮表達感謝,算上禮物價值後其實 ADAM 沒少拿多少,我選擇救贖、最後看到好結局。
破關後再選 new game 發現有二周目 new game plus,但暫時沒力氣玩了。
星期四, 8月 11, 2022
Autohotkey 抓多螢幕解析度方法
在公司打報告,希望用 OCR 判讀螢幕數字並自動抄錄以減少作業時間。這功能需要每個螢幕的長寬大小(pixel)才能讓程式知道 OCR 該看螢幕截圖的哪個位置。
原本是用 Autohotkey 的 SysGet Monitor 解決。但 SysGet 傳回的資料是錯的,也沒體力除錯了。為了省工不想寫額外程式,希望能用簡單的腳本解決。後來發現 powershell 可以做這件事情
Get-WmiObject -Class Win32_VideoController | Out-File screen.out
輸出結果導向到檔案儲存,然後回 Autohotkey 從檔案中用 regex 從 VideoModeDescription 讀出解析度數值,然後做些加減乘除就有各螢幕大小和座標了。 值得一提的是其他的失敗方案:
Add-Type -AssemblyName System.Windows.Forms
System.Windows.Forms.Screen]::AllScreens
這個 powershell 方法能得到全螢幕解析度,但會受到 scaling factor 干擾,得到的 width、height 必須乘以該螢幕的對應 scaling factor 才能還原為真實的螢幕解析度,但找了一陣子沒發現快速得到 scaling factor 的方法,因此就放棄此法。
[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize
這個方法則是只能得到主螢幕解析度,看不到第二第三顆的。
年紀真的大了,花了一個半小時研究城市又開始眩暈 QQ
--------------------------------------------
$pinvokeCode = @"
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace Resolution
{
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
[Flags()]
public enum DisplayDeviceStateFlags : int
{
/// <summary>The device is part of the desktop.</summary>
AttachedToDesktop = 0x1,
MultiDriver = 0x2,
/// <summary>The device is part of the desktop.</summary>
PrimaryDevice = 0x4,
/// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
MirroringDriver = 0x8,
/// <summary>The device is VGA compatible.</summary>
VGACompatible = 0x10,
/// <summary>The device is removable; it cannot be the primary display.</summary>
Removable = 0x20,
/// <summary>The device has more display modes than its output devices support.</summary>
ModesPruned = 0x8000000,
Remote = 0x4000000,
Disconnect = 0x2000000
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DISPLAY_DEVICE
{
[MarshalAs(UnmanagedType.U4)]
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string DeviceString;
[MarshalAs(UnmanagedType.U4)]
public DisplayDeviceStateFlags StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string DeviceKey;
}
class User_32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
[DllImport("user32.dll")]
public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
}
public class Displays
{
public static IList<string> GetDisplayNames()
{
var returnVals = new List<string>();
for(var x=0U; x<1024; ++x)
{
DISPLAY_DEVICE outVar = new DISPLAY_DEVICE();
outVar.cb = (short)Marshal.SizeOf(outVar);
if(User_32.EnumDisplayDevices(null, x, ref outVar, 1U))
{
returnVals.Add(outVar.DeviceName);
}
}
return returnVals;
}
public static string GetCurrentResolution(string deviceName)
{
string returnValue = null;
DEVMODE1 dm = GetDevMode1();
if (0 != User_32.EnumDisplaySettings(deviceName, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
returnValue = dm.dmPelsWidth + "," + dm.dmPelsHeight;
}
return returnValue;
}
public static IList<string> GetResolutions()
{
var displays = GetDisplayNames();
var returnValue = new List<string>();
foreach(var display in displays)
{
returnValue.Add(GetCurrentResolution(display));
}
return returnValue;
}
private static DEVMODE1 GetDevMode1()
{
DEVMODE1 dm = new DEVMODE1();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}
}
}
"@
Add-Type $pinvokeCode
[Resolution.Displays]::GetResolutions();
結果本以為能用的方法失敗,最後換了這個方法,在 Autohotkey 中呼叫 powershell.exe 執行這段腳本,用 Out-File 導出成文字檔用 regex parse。 話說 powershell 可以直接執行 C# 代碼耶,作為「腳本語言」這會不會太強了點?XDDDDD
全文連結星期日, 7月 24, 2022
星期日, 7月 10, 2022
醫療人員寫程式有用嗎?
改自 ptt 的發文
以個人經驗來說,醫療人會點程式有沒有用?個人經驗是有的,我自己弄的東西:
關鍵字搜尋引擎
有引擎前,蒐集 case 主要靠自己作筆記。有引擎後 keyword 和查詢條件丟下去 case就噴出來。可能辛苦作筆記收了不曉得多久才能收一兩百個,引擎只要用正確的搜尋條件一分鐘就生出一千個。
查資料自動化
最近做回溯研究收案超過兩千個。這幾天弄出 RPA 機器人可以自動填病歷號查資料,申請通過正式上線。一樣的事情,別人可能要弄經費、請助理、花不知道多久搞定。我自己做可能電腦多開幾個晚上還不用想辦法找錢。
各種自動化和改善工作流程
學會 Autohotkey,可以打 fu 自動變成 Advise follow-up,一鍵自動從其他表單帶入資料、一鍵文字自動排版...
隨著技能樹越來越深廣,能做的事情還能越來越炫炮,例如
幫普通表單程式加上改字型、拼字檢查、自動完成、顏色佈景...等功能。潛在應用的地方很多,例如 HIS 或 RIS 各式表單程式。
以前會想:這種事委託專門單位、學校、或是外包廠商不就能做?自己會的價值在哪裡?
後來發現專門單位可以非常忙,手上待處理的案件可以到四位數。需求如果對全院不夠重要、急迫不一定能可以做,可以做也可能要排隊,排隊成功程式開始做也可能要反覆修改處理眉角問題,每次修改可能又是另一個循環。學校或外包廠商做,要想辦法弄資源,弄計畫、請經費、etc,一個程式綁一堆東西,原始碼還可能在別人手上、以後只能一直投入。自己弄就沒有上述一堆問題、程式想改就開記事本改就好。
「又快又好」是可能形成價值的。以大規模撈 case 查資料做回溯性研究為例,別人流程是:
1. 寫申請單委託資訊單位
2. 花時間排隊(可以等很久)
3. 得到結果,發現眉角問題、協商修正 * N(用 nodule 查結果 Nodule、nodlue 沒撈到 etc.)
4. 請助理一筆筆查資料整理
5. 生成那張跑統計的 Excel 表格。
而如果都能自己做呢?可能 IRB 通過的當天,下班前搜尋引擎就把 case 列出來了。然後多花幾個晚上用機器人把資料查好。最後用 python 字串、報表分析,很快就能統計好大部分資料,這時候可能別人還在排隊。大幅改善效率,就能大幅降低投入成本和時間,就能顯著提高研究成功率。這時哪怕作為醫療人員和研究者的本職技能都不頂尖,別人也會願意合作。
就算一時做不了這些事,起碼也能讓自己上班更輕鬆。別人花時間按 Enter 和空白幫報告排版還是從其他系統抄數字,你一鍵就無腦完成,更快下班不好嗎?如果喜歡寫,替自己節省精力,創造機會的同時還能做喜歡的事,緩解 burnout 不香嗎?
所以如果本來就有寫程式的興趣,可以繼續鑽研深入,然後設法找自己周圍有必要但別人顧不到的事,遵循法規、看好政治和環境允許的限度,抓準機會切進去,programming skill 不會虧待我們。
至於學哪些語言,我是學 Python 和 Autohotkey 為主。AHK 主攻辦公室自動化,Python 補一些 AHK 不好做的事情,例如運用瀏覽器自動化測試套件自動點頁面之類。Python 也可以銜接 Machine Learning 和 Deep learning。另外零碎玩過一些 Rust、C/C++、PHP 之類的東西,但這些對醫療職業可能就不那麼直接有用。
值得一提的是數學,有後悔沒趁年輕的時候學好數學,最近鑽研 Deep learning 和統計都遇到數學的檻,回頭補同濟的高等數學。結果現在奔四體質變差很多,用腦一多就 tinnitus 甚至 vertigo,而且有些基礎的東西忘了還要「復健」。所以如果還在學校,學習數學其實是好選擇。程式語法那些在有明確目的的情形下快速入門不難,但數學就不行。線性代數和微積分剛好也是現在 deep learning 會用到的東西。
星期四, 7月 07, 2022
星期一, 7月 04, 2022
魔法少女天穹法妮雅
夏特時收的小遊戲。一打開就廢寢忘食通關主線。「實用」部份非常實用該有的都有,不多描述>////<
撇開實用,RPG 的部份也屬於上乘,劇情就簡單流暢的王道魔法少女變身救世,戰鬥方面多種難度可選,角色 Build 有彈性,近身格鬥或各系魔法隨選。
蒐集要素多,各式打材料、拼練成,開寶箱或練成的特殊道具可以開特殊玩法,例如把魔攻倍增普攻變 1 的特殊道具,可以打造純粹的魔法砲台少女,或是花海量資源和肝才能疊出的自動秒殺裝再瘋狂跑圖練級,不小心就跑到 99 級 etc. 。
遊戲還有多週目要素,可以繼承等級、道具、魔法提昇難度進行
無論是作為 RPG 本身的劇情或「實用」成份都屬於上乘。Steam 上的好東西越來越多了。 全文連結
星期六, 6月 25, 2022
吐槽 VB6
最近又一次受 VB6.0 荼毒迫害。
最近和其他單位同事合作回溯性分析,分析公司用戶資料。資料能透過資訊系統一筆筆查,問題是筆數多(N>2K),資料分散在不同報表程式和網頁表單上。因各種因素,不能直連 production DB 下 SQL。反覆請人代撈實務不可行。但政策不禁自動化軟體代替鍵盤滑鼠操作報表軟體,只要遵循審查流程。
然後就又跟 VB6.0 槓上了。很大部份資料需透過一 VB6.0 報表軟體查詢。報表軟體上有 ListView 顯示用戶的多筆紀錄,操作者點選 ListView 上的紀錄,程式跳出對應該紀錄的進一步細節。
真人鍵盤滑鼠操作沒啥問題,用自動化 VB6 就開始不講武德。
在家中做模擬,就發現 MSDN 上的東西很多對 VB6 沒用。例如,MSDN 說 LVM_SETITEMSTATE 可以改變 ListView 目前被圈選的 item。實際使用畫面上 ListView 被 highlight 的 item 會變,但後續 side effect 不會觸發。又例如 MSDN 說 LVM_SETITEM 可改變 ListView 呈現的資料,結果實際使用只會改畫面上的資料,隨便重排資料修改就不見了。
那用 code injection 解決呢?很久前就試過,VB6 編出來的 code 本質是編成 native code 的虛擬機操作,大量意義不明的中間變數和莫名操作,一切 control flow 最終回歸 MSVBVM60.DLL 和元件庫。有效操作被嚴重稀釋。逆向天然自帶虛擬機的 binary 嚴重超過我業餘用戶的能力,我連自己寫的 mock 都沒辦法分析,生產環境中的報表軟體就不用試了。
最後,又一次倒在 VB6 鐵拳之下,還是只有模擬鍵盤滑鼠按鍵的方式可行。方案沒技術含量,而且使用期間電腦不能操作,但自動點選存資料還是弄出來了,之後走審查流程後就在公司內正式開發、使用。順利的話能解決分析需求,還有機會與另外一個 side project (搜尋引擎)形成連動,做成一條龍。
業餘 side project 坑好像越挖越大,一開始是好玩,然後是實用,現在目標變成發展產業鏈了 XDD。但還是要吐槽 VB6,根本就上個時代的遺毒...
星期四, 6月 23, 2022
星期四, 6月 09, 2022
星期二, 5月 31, 2022
閃紅的艾麗絲
別人的遊玩影片 XD
某次趁特價入手的 Steam ARPG 小品黃油(羞)。最近剛普通難度通過一輪。
故事中規中矩,就英雄巫女拯救世界。特色是動作非常有打擊感確實夠要求技術。另外有豐富的收集、再挑戰和多周目元素。第一周照攻略花了很多時間弄了釣魚、蒐素材繼承武器 etc.。破台一輪後出現挑戰模式,可以獎勵點數強化下週目角色等。
攻略中那種無傷打出幾百連擊實在太誇張了,我劇情黨後期只用一兩招反覆搭配食物補血硬換而已....哪天想打困難、地獄模式再開來研究吧 XD
星期日, 5月 29, 2022
星期五, 5月 27, 2022
Windows 下簡單安裝 Python 3.9 和 PIP 方法
雖說在 Windows 下寫 Python 大多時候我靠 WinPython 解決,但特殊情況下可能需要可攜、精簡的 Python 執行環境。官方的 python windows embeddable package 內容簡單,但缺少 PIP,而這篇文提供了裝好 PIP 的方法。
修改 python39._pth
第一行加入 Lib/site-packages,最後一行 import site 移除註解,改好後檔案類似
Lib/site-packages
python39.zip
.
# Uncomment to run site.main() automatically
import site
下載安裝 PIP
接下來進 python 根目錄,下載 get-pip.py,然後用 python 執行
python get-pip.py
設定可臨時改動 PATH 的腳本
set PATH=%PATH%;%CD%;%CD%\Scripts
寫好存檔後在 python 目錄下執行。
一切弄好後,試驗 pip install selenium 成功!
全文連結星期一, 5月 23, 2022
Dungeon Hack 遊玩心得
小時候 DOS 時代的的回憶,中文操作手冊還保留很久當成故事書看 XD。真的二十年沒玩了,趁最近上架 Steam 就買回來懷舊。Steam 版還是有小問題,就是沒有雲端存檔,要手動備份同步存檔,不過 DOS 遊戲目錄結構簡單,存檔位置很好找。
以現在眼光來看,遊戲有些機制其實太 hard core。高難模式死掉強制刪存檔。某些會負能量攻擊或石化的敵人太強,一打中就是掉等級或秒殺。遊戲還很少鑑定手段拿了一堆藥和裝備不知道幹麻,等快過了才從攻略網站知道有艾恩石可以防石化即死或負能量打落等級。
遊戲平衡也不大行,牧師太強勢了,治療、提供食物、防負能量打落等級、水下呼吸、解詛咒裝備、解毒....都集中在同一個職業,導致有沒有兼職牧師打起來根本就是兩款遊戲。
不過這遊戲不是玩遊戲性,是玩懷舊時光穿梭回憶小時候的,小時候很害怕陰暗地下城的氣氛,英文還不好,好像從來沒下過第二層,這次 Steam 版終於破了一輪 XD
星期三, 5月 18, 2022
系列文章:Step by step guide to master natural language processing
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8
Part 9
Part 10
Part 11
Part 12
Part 13
Part 14
Part 15
Part 16
Part 17
Part 18
Part 19
Part 20
簡介 NLP 的一系列文章,深入淺出,涵蓋面夠廣。裡面的 python 代碼不是重點,對概念的簡單說明和範例才是 XD。TutorialsPoint 也有簡介 NLP 的文章但寫的太 formal。缺點大概就是寫到 Topic modeling 以後「筆力」就不大夠了。但整個系列作為讀書前的導讀應該還是不錯的。 全文連結
星期四, 5月 05, 2022
星期二, 5月 03, 2022
閱讀:Clinical Notes — The “Negative” Story
否定語句(Negation,例如 No evidence of embolism)在放射科報告很常見,但特定情況下會造成困擾,例如我目前經營的搜尋引擎,輸入關鍵字會連否定句裡面的內容也被列入搜尋結果。
這篇 Medium 的文章深入淺出的總結了 negation 有關的概念並總結了一些處理方法。對常見 negation pattern 的總結是亮點,例如
Termination patterns: abdominal pain denied
Prefixes: non-diabetic, non-hypertensive
Double negation: not abnormal, not unusual
Symbols usage: Hypertension +, Diabetes -
Positive/Negative usage: Hypertension positive, Diabetes negative.
Yes/No phrases: Hypertension — No, Diabetes — Yes, Urinary problems — No.
Use of more generic language than clinical terminology: No complaint of high sugar (rather than No Diabetes).
其實還有一些是作者沒提到的,例如病歷上的英文可能不符合英文文法(例:no fracture or dislocation seen),這對基於語法分析的方法(例如 NegBio)可能會有影響。symbol 實際上病歷也有很多種,(+)(V)(O) 我都看過 XD
這篇的缺點是引用的處理方法(NegEx 等)有些舊了。連 NegBio 都沒提到,更後面的 deep learning 方法當然沒有了。
星期一, 5月 02, 2022
星期日, 5月 01, 2022
蕭邦夜曲 9-2 惡搞
「蕭邦承接了菲爾德的夜曲風格,當中一個十分重要的特徵就是右手部分如歌似的旋律,這種聲樂的特質給予樂曲情感深度。」
Youtube 演算法自動推薦,聽歌聽到一半毫無防備就中招了 XDDDD
星期六, 4月 23, 2022
星期日, 4月 10, 2022
文石 BOOX Note5 入手!
閱讀大量文件時,用電腦或 ipad 看久眼睛很累,還是習慣用 e-ink 電子書閱讀器。
原本機器是 N 年前從露天花幾千元入手,賣家裝好多看系統的二手 Amazon DXG。多年來使用愉快,只有中間換過幾次電池。
但最近好幾次看 PDF,電腦上沒問題,但 DXG 全部顯示空白頁面,Google 起來疑似多看系統 bug。而 DXG 的多看好像 N 年沒更新,至少我找不到,決定換新機。
新機首先希望是 10.3 吋。6 吋、8 吋看久實在不舒服,不要求能放口袋。另外希望可以看不同店家的電子書,不要鎖死在閱讀器官方商城,所以只考慮開放系統。
原本想買 HyRead 產品,但現場試用有莫名卡頓感,PTT 上也有類似抱怨,一些慣用操作如文件放大旋轉瀏覽也不順。Boox 的機器試用就順手很多,決定改買 Boox Note5。請店員設定,裝好 Google Play 後帶回家。
新機放大旋轉檢視 PDF,換頁流暢度遠勝舊機,少了切幻燈片的卡頓感,一時還不大習慣 XD。App 試了 JPTT 和內建瀏覽器 Wifi 上網。第三方 App 能裝能用,以後裝不同商城電子書或裝 App 看不同格式文件應該沒問題。
DXG 就從此安心退役了。
新舊機器比較圖,左方 DxG 右方 Boox Note5,新機器的螢幕大一些,也沒有佔空間的實體鍵盤。
新機器看 PDF,大螢幕看起來還是比較輕鬆。
FFMpeg 影片批次轉檔
出去玩時喜歡手機錄影,每次回來都一堆影片檔。原始檔案都很大,直接上傳太佔空間,需要批次壓縮。
原本作法是用 anyvideo converter 批次處理,但 GUI 操作繁瑣,也不喜歡裝癰腫的軟體。後來發現 ffmpeg 也可以做一樣的事情。
FFMpeg 命令列產生器
先用上方連結點選 GUI,頁面會自動轉成 FFMpeg 需要的命令列參數。可以把它記下,不用每次都去網頁點,我得到的參數是這樣的:
ffmpeg -i 輸入影片 -c:v libx264 -preset slow -crf 20 -c:a copy 輸出影片
套上 Windows cmd 下可用的迴圈語法,就是
for /r "來源目錄" %a in (*.mp4) do ffmpeg -i "%a" "輸出目錄\%~na.mp4" -c:v libx264 -preset slow -crf 20 -c:a copy
用這方式就不需要每次都開 GUI 調參,目錄指定好就流水線處理到底了。全文連結
星期二, 3月 29, 2022
星期二, 3月 22, 2022
Unsupervised Text Classification with Lbl2Vec
介紹文
今天被 Medium 演算法推薦,蠻有趣的思路。
這個庫的功用是做 text classification。特點是對每個 category 設定至少一個關鍵字後,就可以用 unsupervised 的方式對文本進行分類。
整體原理其實接近人類分類的方式。人類大量分類文章的時候,可能看文章出現特定關鍵字就歸類到特定分類了。
而 Lbl2Vec 如果我理解沒錯(錯了再改 XD),則是先將 word 和 text 在同樣的 feature space 做 embedding,先將 text 依據對 keyword 的「距離」先分類一次,去掉 outlier 後求每個分類的 centroid,再根據新算出的分類 centroid 正式分類所有 text。
這樣分類的方法可以不用標註部分資料,只要每個分類都能找出至少一個 keyword 就好。之前研究的地址分區里問題感覺或許可以用,也許未來有緣就當作備案試試看。
負面範例:Predicting Tesla Stocks (TSLA) using Python & PyCaret
難得 Medium 的演算法會推薦辣眼睛的文章,放在腦海裡越想後勁越強 XD
文章標題很吸引人,利用 python 和 PyCaret 來預測特斯拉股價。但看到一半,作者吹噓「用了 PyCaret,模型不調參 R square 也就是正確率有 99%」就喉頭一甜,差點吐血。
網頁下拉,細看 test data 的 feature,赫然看到 feature 裡面有今日高低價。已知今日高低價,用模型求收盤價???如果投資者買賣股票的時候能預知今日高低價,又何需機器學習?
有這種條件,模型乾脆再簡化點,直接高低價相加取平均當模型輸出就好,連 linear regresser 都不用,拿來有漲跌幅限制的國家使用 performance 會更好 XD
另外作者選用的所有模型都只是拿單日開盤資訊 fit 收盤價,完全不參考過去行情。模型不用參考過去行情,僅憑單日資料就有 99% 「正確率」,作者不覺得哪裡不對?
討論區反而有亮點,PyCaret 開發者親自回應,指出文章 technical flaw 很多,這種文章只會傷害 PyCaret。很遺憾我調包俠無法看出全部問題就是了 QQ
----
結果作者還來回應我的吐槽,作者指出「可以用 API 做更細的時間粒度,例如以 5min 為單位預測股價」。
問題根本不在這裡好吧?看起來就是作者隨便拿了 data,就隨便丟給模型去 fit,對 feature 完全不理解,連常識等級的 domain knowledge 都沒有。看到結果也無法反思。
這種派大星都可以當 data scientist 在 Medium 寫文章教人,我忽然覺得我也可以學好 XD
----
結果我 Medium 第一個 follower 就是被我吐槽的作者 XD
星期四, 3月 03, 2022
DuckDNS
VPS 買的 noip 域名到期了。noip 免費版每個月就要手動更新一次不然域名會失效。每年 24.95 美金也覺得不值得。我只是要連到自己的 VPS 而已。隨手搜尋一下免費 DNS 就換到 DuckDNS。
DuckDNS 官網看起來簡陋,看起來像小團隊自架的免費服務,但使用起來很簡單。直接用 Google account 登入,頁面填想要的域名,照著 install 頁面設定 crontab 定時執行 HTTP update API,不到 10 分鐘新域名就可以用了。install 頁面還很貼心的會根據實際使用者自動修改頁面中的教學,自動帶入正確的域名和 API key。只要 curl 和 crontab 有裝,直接一步步複製貼上頁面的指令就好。
應該會改用這家了,只要把一些工作用腳本指向新域名就好 XD
星期一, 2月 28, 2022
Gunbuster 觀後感
Gunbuster 是 1988 年的老動畫,之所以認識這部動畫,是因為追動漫鋼琴時偶然追到了 Pianeet 的 Gunbuster Fantasy 組曲。因為曲子好聽去追原動畫 XD
這部動漫的監督是新世紀福音戰士的庵野秀明。本作的本意是彌補製作「王立宇宙軍」造成的巨大虧損。動畫刻意集合了各種「宅」要素力求打開市場,結果「王立宇宙軍」沒紅,這部為了彌補虧損而做的作品反而大紅了。
前三集是真實系開局,天真活潑 or 傻白甜女主經歷艱辛登上宇宙。後來經過各種挫折,特別是在戰場上無能導致坑死自己初戀後,逐漸成長為獨當一面的 Gunbuster 駕駛員。
本作對人物和感情刻劃非常深刻,因為反覆在接近光速的情形下執行任務,與地球上的朋友無可避免出現「時間差」。姊姊與教練的悲戀。為了挽救人類,兩人選擇自我犧牲選擇進入 Buster Machine 3 號,容格乘著量產機陪同赴死被勸回,歷經萬年漂流返回地球,地球亮出「歡迎回家」伴隨著音樂全劇落幕。聲優真摯的演技和悲壯的音樂更把整部作品盤活。
神作。
星期五, 2月 25, 2022
成人鋼琴班愉快學琴中, 老師教新曲子,趁這首還沒忘之前留影紀念。這已經是錯音、漏音、糊掉最少的版本。
從「自我檢查」的角度來說,錄音錄影其實比單純錄音就好,搭配影像還可以回憶當時用力的情形。
總而言之,不漏音好難,控制手速避免不自主飆車好難。彈到後面手軟掉變成不曉得什麼東西 XD
全文連結星期日, 2月 20, 2022
李宏毅老師 youtube 深度學習課程:attention、transformer、BERT
【機器學習2021】Transformer (上)
【機器學習2021】Transformer (下)
【機器學習2021】自注意力機制 (Self-attention) (上)
【機器學習2021】自注意力機制 (Self-attention) (下)
【機器學習2021】自督導式學習 (Self-supervised Learning) (二) – BERT簡介
【機器學習2021】自督導式學習 (Self-supervised Learning) (三) – BERT的奇聞軼事
為了研究 BERT 能否解決 negation detection 決定線上進修,剛好找到李宏毅老師的課。
之前上過吳恩達老師在 deeplearning.ai 的深度學習課程。兩位老師的課都非常的深入淺出,吳老師的課有作業,李老師的課程內容比較新,技術細節講的比較深細。
看了幾堂 attention、transformer 和 BERT 的簡介有相見恨晚的感覺。 暫時沒時間寫濃縮筆記,先發文佔樓,以後想更再更吧。這個清單還沒放上李老師對 BERT variant 的簡介,有看再放上來。
全文連結星期三, 2月 02, 2022
「超速學習」閱讀心得
一直對「如何學習」很有興趣,這本讀完感覺不錯,決定用它寫心得,寫心得的同時也是運用其中的技巧,鞏固內化書本上的知識,也方便未來的自己提取技巧不用整本重讀。
這本書重要概念大概如下:
後設學習
確定「為什麼、做什麼、及怎麼做」,「怎麼做」可以切分成「概念、事實、程序」。後設學習可以佔整體計畫的 10% 時間。後設學習可避免學習毫無目的性,在無限的知識中沒有效率的「漫遊」
專心致志
講拖延症、專心的重要性和專心的技巧。
實質上我認為最好的技巧,也是書本沒有講的,是每天花時間冥想。冥想可以實際上改造大腦。變得可以忍受工作和學習中的難受、沉悶和從根本上控制住分心(掉舉)。
直截了當
用「最短路徑」去達成學習目標,例如學語言,就直接去需要該語言的生活環境,學工作技能就從做中學。
反覆操練
其實覺得這個名字不完整,因為書中的例子還包含很多「分而治之」(divide and conquer)的技巧,例如學音樂把譜分段,並針對不會的困難段落反覆練習。
提取記憶
用測驗、回想...來鞏固記憶,不是學完就算了。
意見回饋
我想這是自學者最欠缺的。其實有人潑冷水比自己「十年磨一劍」好的多。
我學專業技能之所以能有進度,很大是因為學長姐,臨床同仁甚至病人會給「回饋」。做了錯誤的判斷就會從回饋得到「重拳」,就會一直進步。
但「重拳」太重也可能把人擊垮,可能必須在「不痛不癢的回饋」和「太重的重拳」中間拿一個度。
保留記憶
書中提出了幾種技巧來克服「遺忘曲線」的問題。淺見比較有用的方法是「過度學習:超越完美的練習」和「記憶法」。考專科的時候不自覺的用了這些技巧。
培養直覺
覺得翻譯為「技能直覺化」比較好。將學到的技能內化為直覺。
個人經驗上這是個水磨功夫,只有不斷反覆熟悉技能、接受回饋,試著簡化提取要點才能題取出技能的「神髓」才能內化為直覺。
例如當年自學軟體重構的相關知識,書都會教「何時該重構」,但實質上我不是用背的,而是很多次栽在充滿壞味道上的坑以後,對坑的感知因為大量經驗內化形成直覺,跟本不用背,也不會忘記,甚至書本講的「何時該重構」也只是印證了我的經驗而已。
勇於實驗
書中提到各種實驗技巧,在不會太痛苦的前提下,擴展現有的技能樹使之更全面,跨出舒適圈。
看完這本書以後,覺得最無腦的技能入門方式其實是去上針對性、有提供測驗的線上課。線上課除了最後兩步(培養直覺、勇於實驗)外幾乎都涉獵到了。至於後兩者也只能技能稍微入門後再自己反覆錘鍊、內化和擴展了。
星期六, 1月 22, 2022
Linux 監控 CPU 使用率腳本
Linode 寄信提示 CPU 異常使用率,超過 90% 使用率,一次好幾小時。根據網路拼湊、修改出腳本來定期監控 CPU 使用率。原則上五分鐘監控一次,使用率超過 70% 觸發 log,log 寫在監控腳本同目錄下。
cpuuse=$(cat /proc/loadavg | awk '{print $3}'|cut -f 1 -d ".")
if [ "$cpuuse" -ge 70 ]; then
MESSAGE=$(date +%s).log
echo "CPU current usage is: $cpuuse%" >> $MESSAGE
echo "" >> $MESSAGE
echo "+------------------------------------------------------------------+" >> $MESSAGE
echo "Top 20 processes which consuming high CPU" >> $MESSAGE
echo "+------------------------------------------------------------------+" >> $MESSAGE
echo "$(top -bn1 | head -20)" >> $MESSAGE
echo "" >> $MESSAGE
echo "+------------------------------------------------------------------+" >> $MESSAGE
echo "Top 10 Processes which consuming high CPU using the ps command" >> $MESSAGE
echo "+------------------------------------------------------------------+" >> $MESSAGE
echo "$(ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10)" >> $MESSAGE
else
echo "CPU usage OK"
fi
腳本存好,chmod +x 以後下 crontab
crontab -e
*/10 * * * * /bin/bash /opt/scripts/cpu-alert.sh
以目前使用者身份執行腳本一次(不一定跟 cron 同使用者!),確認腳本沒問題
crontab -l | grep -v '^#' | cut -f 6- -d ' ' | while read CMD; do eval $CMD; done
全文連結
星期四, 1月 20, 2022
QNAP docker 建置 nginx reverse proxy
Bug 還在協商溝通,暫時解不掉,只能先想辦法繞過。因關鍵服務大多利用 HTTP,所以決定用 nginx 建立 reverse proxy 解決。
整件事最大困難:QNAP 系統高度自製,很多資料找不到。很多工具沒有裝(例如 apt-get)。
本來考慮用 QNAP 軟體市集找 nginx,失敗,改用 container station 上。用 nginx container,以 docker volume 覆蓋設定檔。
然後發現 container station GUI 並不友好。例如 exposed port、volume 等參數每次建立 container 都要重新指定,非常麻煩。docker volume 還只能指定一整個目錄,無法只覆蓋目錄下的單一檔案,所以萬一 config 檔同目錄還有其他檔案就不好處理。
後來解法是 ssh,command line 用 docker 指令就好。container station 的 GUI 只是套殼,其實沒必要用。docker 指令操作結果也會反映在 container station 的介面上。File Station 看到的 Public 資料夾在 /share/Public。文字編輯可以用 Text Editor 就不必用沒調整過的 vi,還支援瀏覽器貼上!
QNAP 上 docker 操作 nginx 我用的指令如下:
docker run --rm -p 9080:9080 -p 8888:8888 -p 9090:9090 --name nginx -v ${PWD}/minimal.conf:/etc/nginx/nginx.conf:ro -d nginx
nginx.conf 設定檔長這樣
events {}
http {
client_max_body_size 0;
server {
listen 9080;
server_name <QNAP 內網 IP>:9080;
proxy_set_header Host <QNAP 內網 IP>:9080;
location / {
proxy_pass http://<VM IP>:80;
}
}
server {
listen 9090;
server_name <QNAP 內網 IP>:9090;
proxy_set_header Host <QNAP 內網 IP>:9090;
location / {
proxy_pass http://<VM IP>:808;
}
}
server {
listen 8888;
server_name <QNAP 內網 IP>:8888;
location / {
proxy_pass http://<VM IP>:8888;
}
}
}
port 9080 和 9090 分別對應不同 Laravel 服務。port 8888 給 jupyter-notebook 用。jupyter-notebook 必須修改 NotebookApp.allow_origin 允許 cross origin API 不然修改會無法存檔。
nginx 設定 client_max_body_size 是避免用 notebook 上傳檔案的時候因檔案太大導致上傳失敗,設定 proxy_set_header Host 可避免 Laravel 的 redirection 錯誤導向到 VM IP。
Laravel app 也必須修改,包括:
.env
PROXY_URL = <QNAP 內網 IP>:port
PROXY_SCHEMA = http
app/Http/Middleware\TrustProxies.php
protected $proxies = [
'**'
];
routes/web.php
$proxy_schema = env('PROXY_SCHEMA');
if (!empty($proxy_url)) {
URL::forceRootUrl($proxy_url);
}
if (!empty($proxy_schema)) {
URL::forceScheme($proxy_schema);
}
設定好後需重啟 Laravel
其他工具也可以透過 docker 使用。例如使用 git docker container 把 working directory 掛載進去做 commit。就可以繞過 QNAP 一堆東西都沒裝,偏偏還不好修改的問題。
全文連結
星期二, 1月 18, 2022
星期一, 1月 17, 2022
有趣的網路 bug
幫公司做的土炮搜尋引擎和某些服務放在某虛擬機,稱 VirtA
VirtA 放在實體 NAS 上,稱為 NasA
公司內某些 PC,可以連 NasA 但連不到 VirtA,所有 port 都不通。tracert 顯示封包到 default gateway 就掉包。公司內不同網段的 PC 則完全正常,但產生連線問題的 PC 逐漸增加。
聯絡了資訊單位和科內真資訊大佬,做了各種諮詢和推論。最後被科內大老依照經驗找到問題,原來是 NasA 的實體網卡!讓虛擬機從不同網卡出去,bug 就不見了。
原本懷疑 routing 和 default gateway router 的問題,結果不是,真是活久見 XD
話說,我不是甲方嗎?
---
結果空歡喜一場,問題還是在 route...
全文連結