<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Nekoya</title><description>Yuuzi</description><link>https://blog.yuuzi.cc/</link><language>zh_TW</language><item><title>數位訊號處理筆記</title><link>https://blog.yuuzi.cc/posts/learnings/dsp/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/learnings/dsp/</guid><description>有種死到臨頭開始覺得以前的自己實在混的可以，決定把這學期數位訊號處理上的內容做成筆記，希望能幫到未來的我或是其他需要的人</description><pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;最近突然覺得自己常常耍廢摸魚得過且過感覺未來會暴死，經過深刻的反省之後決定把這學期上課的內容整理成筆記放到 blog 裡，希望這個系列能夠安穩落地。因為目前才剛開始教所以分類會有些隨便，以後滾動調整吧～&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;緒論&lt;/h1&gt;
&lt;h2&gt;關於訊號&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;訊號：資訊的流動&lt;/li&gt;
&lt;li&gt;訊號處理：生成、轉換和解釋資訊的關鍵技術&lt;/li&gt;
&lt;li&gt;數位訊號處理：使用電腦處理訊號&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;訊號的分類與轉換&lt;/h2&gt;
&lt;p&gt;訊號主要分為兩大類 ：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;連續時間訊號 (Continuous-time, CT)&lt;/strong&gt;：標記為 $x(t)$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;離散時間訊號 (Discrete-time, DT)&lt;/strong&gt;：標記為 $x[n]$，其中 $n$ 為整數 $(0, 1, 2, \ldots)$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;w1_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;連續時間訊號經過取樣(Sampling)後轉換為離散訊號，取樣率是一個至關重要的參數，它決定了你每秒鐘要抓取多少個點。取樣率越高，還原出來的訊號就越接近原始的連續狀態。&lt;/p&gt;
&lt;h3&gt;類比轉數位 (A/D Conversion)&lt;/h3&gt;
&lt;p&gt;訊號從連續時間訊號轉為類比訊號需要經過兩個步驟，分別是取樣(Sampling)以及量化(Quantization)：&lt;/p&gt;
&lt;p&gt;$$
CT \xrightarrow{Sampling} DT \xrightarrow{Quantization} Digital
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;取樣（時間離散化）&lt;/strong&gt;：將 $x(t)$ 轉換為 $x[n]$，決定了訊號的&lt;strong&gt;頻率範圍&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;取樣週期($T$)：兩次取樣之間的時間間隔&lt;/li&gt;
&lt;li&gt;取樣率/頻率($f_s$)：$f_s = \frac{1}{T}$&lt;/li&gt;
&lt;li&gt;關係式：$t = n \cdot T$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;量化（數值離散化）&lt;/strong&gt;：將連續的振幅值轉為有限精度的數位資料，決定了訊號的&lt;strong&gt;動態範圍與細節&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;基礎離散時間訊號&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;單位樣本序列 (Unit Sample Sequence / Impulse)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;標記為 $δ[n]$，其定義如下 ：&lt;/p&gt;
&lt;p&gt;$$
δ[n] =
\left{
\begin{array}{ll}
1, &amp;amp; n = 0 \
0, &amp;amp; n \neq 0
\end{array}
\right.
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w1_2.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;單位步階序列 (Unit Step Sequence)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;標記為 $u[n]$，其定義如下 ：&lt;/p&gt;
&lt;p&gt;$$
u[n] =
\left{
\begin{array}{ll}
1, &amp;amp; n \ge 0 \
0, &amp;amp; n &amp;lt; 0
\end{array}
\right.
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w1_3.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;指數序列 (Exponential Sequence)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;形式為 $x[n] = A \cdot \alpha^n$，$A$ 與 $\alpha$ 可為實數或複數&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;重要數學性質與表示法&lt;/h2&gt;
&lt;h3&gt;任意序列的表示 (Representation of Arbitrary Sequence)&lt;/h3&gt;
&lt;p&gt;任何離散序列 $x[n]$ 都可以表示為一組加權且延遲的單位脈衝之和 ：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w1_4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;寫成一般式（$a_k$ 即為 $x[k]$ 的值）：&lt;/p&gt;
&lt;p&gt;$$
x[n]=\sum_{k=-\infty}^\infty {{\color{#3071c4} a_k} \cdot \delta[n-k]}=\sum_{k=-\infty}^\infty {{\color{#3071c4} x[k]} \cdot \delta[n-k]}
$$
&lt;img src=&quot;w1_5.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$u[n]$ 與 $\delta[n]$ 的關係&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;累加關係：&lt;/strong&gt; $u[n]=\sum_{k=0}^\infty \delta[n-k]$ 或 $u[n]=\sum_{k=-\infty}^n \delta[k]$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;差分關係：&lt;/strong&gt; $\delta[n]=u[n]-u[n-1]$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;複數平面與尤拉公式 (Euler&apos;s Formula)&lt;/h3&gt;
&lt;p&gt;在處理複數指數訊號時常用到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;尤拉公式：$e^{j \phi}=\cos \phi+j\sin \phi$&lt;/li&gt;
&lt;li&gt;極座標表示：$A=|A| e^{j \phi_1}$，$\alpha= |\alpha| e^{j \phi_2}$&lt;/li&gt;
&lt;li&gt;因此 $x[n]=A \alpha^n= |A| |\alpha|^n e^{j(n \phi_2 + \phi_1)}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;✍️TODO 以後想到再補圖&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;訊號取樣的影響&lt;/h1&gt;
&lt;h2&gt;取樣與混疊&lt;/h2&gt;
&lt;h3&gt;基本定義&lt;/h3&gt;
&lt;p&gt;假設一個連續時間訊號 $x(t) = \cos(\omega t)$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\omega$：角頻率 (Radian Frequency)，單位：rad/s（徑度/秒）&lt;/li&gt;
&lt;li&gt;$t$：連續時間，單位：sec（秒）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note
複習一下高中內容：在圓周運動或簡諧運動的數學推導中，如果使用「圈數」，公式裡會不斷出現 $2 \pi$ 這個係數，顯得累贅。為了讓方程式更簡潔，我們直接把 $2 \pi$ 乘進去，定義出角頻率（以 $\omega$ 表示）
:::&lt;/p&gt;
&lt;h3&gt;取樣過程（Sampling Process）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;每隔 $T$ 秒取樣一次，$T$: 取樣週期 (Sampling Period)
$$
\begin{aligned}
{\text{時間 } t\text{：}} &amp;amp; 0, T, 2T, 3T, \ldots \
t &amp;amp;= nT \
n &amp;amp;= 0, 1, 2, 3, \ldots
\end{aligned}
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;離散化
$$
\begin{aligned}
x(t) &amp;amp;= \cos(\omega {\color{#3071c4}t}) \
&amp;amp;\downarrow {\color{#3071c4}t = nT} \
x({\color{#3071c4}nT}) &amp;amp;= \cos(\omega {\color{#3071c4}nT}) \
&amp;amp;\Downarrow \
x[n] &amp;amp;= \cos(\omega nT)
\end{aligned}
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;取樣頻率轉換
取樣頻率：$f_s = \frac{1}{T}$ Hz，取樣角頻率為 $\omega_s = \frac{2 \pi}{T}$ rad/s
:::tip
$\omega = 2 \pi f \xrightarrow{f = \frac{1}{T}} \omega = \frac{2 \pi}{T}$
:::&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;離散時間的週期性 (Periodicity in Discrete Time)&lt;/h3&gt;
&lt;p&gt;假設這裡有兩個訊號：$x$ 和 $x_1$&lt;/p&gt;
&lt;p&gt;$$
\left{
\begin{array}{ll}
x &amp;amp;= \cos(\omega t) \
x_1 &amp;amp;= \cos((\omega + {\color{#3071c4}\omega_s})t)
\end{array}
\right.
$$&lt;/p&gt;
&lt;p&gt;很明顯這是兩個不一樣頻率的訊號，但如果我們對它們進行採樣，會發現一個很有趣的現象：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
x_1(t) &amp;amp;= \cos((\omega+\omega_s)t) \
&amp;amp;\downarrow t = {\color{#3071c4}nT} \
x_1[n] &amp;amp;= \cos((\omega+\omega_s){\color{#3071c4}nT}) \
&amp;amp;\because \omega_s = \frac{2\pi}{T} \
\therefore x_1[n] &amp;amp;= \cos((\omega+\frac{2\pi}{T})\cdot nT) \
&amp;amp;= cos(\omega nT+\frac{2\pi}{\cancel{T}}\cdot n\cancel{T}) \
&amp;amp;= cos(\omega nT+{\underbrace{2\pi n}_{\color{#e53935}{2\pi\text{ 的整數倍，不影響值}}}}) \
&amp;amp;= cos(\omega nT)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;可以觀察到雖然 $x$ 跟 $x_1$ 不同，但取樣後都是 $cos(\omega nT)$，$\therefore x[n] = x_1[n]$。&lt;/p&gt;
&lt;p&gt;:::note
這裡再假設一個 $x_2(t) = \cos((-\omega+{\color{#3071c4}\omega_s})t)$，取樣後會得到 $x_2[n] = \cos(-\omega nT)$，但因為 cosine 是偶函數，所以 $x_2[n] = \cos(-\omega nT) = \cos(\omega nT) = x[n]$
:::&lt;/p&gt;
&lt;p&gt;我們可以得到一個結論，在離散的世界裡，很多不同頻率的連續波，採樣後居然會看起來一模一樣，這個就是所謂的 &lt;strong&gt;「混疊現象」(Aliasing Phenomenon)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w2_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;small&amp;gt;🔗圖片來源：https://www.ni.com/docs/zh-TW/bundle/labwindows-cvi/page/advancedanalysisconcepts/aliasing.html&amp;lt;/small&amp;gt;&lt;/p&gt;
&lt;h2&gt;奈奎斯特-香農取樣定理&lt;/h2&gt;
&lt;p&gt;我們現在知道如果取樣頻率不夠高，就會在這種週期性的訊號上產生混疊現象，那如果不想要產生混疊現象的話，具體來說需要多高的取樣頻率呢？&lt;strong&gt;奈奎斯特-香農取樣定理&lt;/strong&gt;給出了答案，並定義了所謂的&lt;strong&gt;奈奎斯特頻率 (Nyquist Frequency)&lt;/strong&gt;，又或者稱作&lt;strong&gt;奈奎斯特極限 (Nyquist Limit)&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;奈奎斯特極限：&lt;/strong&gt; 能被系統唯一表示的最高頻率為 $\frac{\omega_s}{2}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;發生混疊的條件：&lt;/strong&gt; 如果輸入訊號的最高頻率 $\omega_N &amp;gt; \frac{\omega_s}{2}$，就會發生混疊&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;取樣定理：&lt;/strong&gt; 假設一個連續時間訊號 $x(t)$，它是一個&lt;strong&gt;頻帶受限訊號 (band-limited signal)&lt;/strong&gt;，最高頻率為 $\omega_N$，寫成數學式：$X(j\omega) = 0 \text{ for } |\omega| \ge \omega_N$（所有比 $\omega_N$ 大的頻率都不存在 $\rightarrow X(j\omega) = 0$）。如果我們以 $\omega_s \ge 2\omega_N$ 的頻率對其進行取樣，那麼這個連續訊號 $x(t)$ 就可以 &lt;strong&gt;唯一地 (uniquely)&lt;/strong&gt; 被它的離散取樣點 $x[n]$ 所決定。換句話說，只要取樣正確，就能拿這些離散的點拼湊回原本的 $x(t)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip[頻帶受限訊號 (Band-Limited Signal)]
指其頻譜能量集中在有限的頻率範圍內的訊號，簡單來說，它的頻率是有上限的 ($\omega_{max} &amp;lt; \infty$)。
:::&lt;/p&gt;
&lt;h4&gt;完美還原訊號的數學條件&lt;/h4&gt;
&lt;p&gt;$$
\begin{aligned}
&amp;amp;\text{if } \overbrace{\omega_s}^{\color{#3071c4}\text{取樣頻率}} \ge \overbrace{2\omega_N}^{\color{#e53935}\text{最高訊號頻率}} \
&amp;amp;\text{i.e. , Nyquist Limit } \frac{\omega_s}{2} \
&amp;amp;\omega_N \le \frac{\omega_s}{2} \color{#3071c4}{\Rightarrow \omega_s \ge 2\omega_N} \
&amp;amp;\omega_s = \frac{2\pi}{T} \Rightarrow T = \frac{2\pi}{\omega_s}
\end{aligned}
$$&lt;/p&gt;
&lt;h2&gt;反混疊濾波器&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;✍️TODO 以後補&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;範例與練習&lt;/h2&gt;
&lt;h3&gt;Ex.1&lt;/h3&gt;
&lt;p&gt;Determine which input signals to a digital filter or DSP system will be aliased by the given period $\text{Т}$?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$x(t) = 2\cos(10t)\text{ , T = 0.1s}$&lt;/li&gt;
&lt;li&gt;$x(t) = 8\cos(15t)\text{ , T = 0.2s}$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note[ANS]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$\omega_s = \frac{2\pi}{T} = \frac{2\pi}{0.1} = 20\pi$ &amp;lt;br&amp;gt;
Nyquist Frequency: $\frac{\omega_s}{2} = 10\pi\approx 31.4$ &amp;lt;br&amp;gt;
$\therefore \omega_N = 10 &amp;lt; \frac{\omega_s}{2}$，沒有混疊&lt;/li&gt;
&lt;li&gt;同理，$\frac{\omega_s}{2} = \frac{\frac{2\pi}{0.2}}{2} = 5\pi\approx 15.7$ &amp;lt;br&amp;gt;
$\therefore \omega_N = 15 &amp;lt; \frac{\omega_s}{2}$，沒有混疊
:::&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Ex.2&lt;/h3&gt;
&lt;p&gt;Determine if the following signals will be aliased. If the signal is aliased into having the same sample value as a lower frequency sinusoidal signal, determine the lower sinusoidal signal.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$x(t) = 7\cos(25t)\text{ , T = 0.1s}$&lt;/li&gt;
&lt;li&gt;$x(t) = 3\cos(160t)\text{ , T = 0.02s}$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::note[ANS]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$\frac{\omega_s}{2} = \frac{\frac{2\pi}{0.1}}{2} = 10\pi\approx 31.4$ &amp;lt;br&amp;gt;
$\therefore \omega_N = 25 &amp;lt; \frac{\omega_s}{2}$，沒有混疊&lt;/li&gt;
&lt;li&gt;$\frac{\omega_s}{2} = \frac{\frac{2\pi}{0.02}}{2} = 50\pi\approx 157$ &amp;lt;br&amp;gt;
$\therefore \omega_N = 160 &amp;gt; \frac{\omega_s}{2}$，有混疊 &amp;lt;br&amp;gt;
由於&lt;a href=&quot;#%E9%9B%A2%E6%95%A3%E6%99%82%E9%96%93%E7%9A%84%E9%80%B1%E6%9C%9F%E6%80%A7-periodicity-in-discrete-time&quot;&gt;混疊高頻摺疊至低頻的現象&lt;/a&gt;，$-\omega_1 + \omega_s = 160$ &amp;lt;br&amp;gt;
又 $\omega_s = 100\pi \Rightarrow \omega_1 = 100\pi - 160$ &amp;lt;br&amp;gt;
$\therefore x_1(t) = 3\cos((100\pi - 160)t) \approx 3\cos(154.2t)$
:::&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h1&gt;數位濾波器規格&lt;/h1&gt;
&lt;h2&gt;基礎概念與公式&lt;/h2&gt;
&lt;p&gt;在介紹數位濾波器之前，要先了解一下下面這三個東西，它們是衡量一個濾波器好不好用、有沒有效的核心概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;增益 (Gain)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$Gain = \frac{\text{輸入訊號的振幅}}{\text{輸出訊號的增幅}}$&lt;/li&gt;
&lt;li&gt;如果 $Gain = 1$，代表訊號無損通過。在濾波器中，這就是我們希望保留訊號的區域，稱為 &lt;strong&gt;通帶 (Pass Band)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;如果 $Gain$ 趨近於 $0$，代表訊號被擋下或大幅削弱。這就是我們希望濾除雜訊的區域，稱為 &lt;strong&gt;阻帶 (Stop Band)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;損失 (Loss)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;增益的倒數，即 $Loss = {(Gain)}^{-1}$，本質上是一樣的東西，只是換個角度描述&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分貝 (dB)：&lt;/strong&gt; 現實世界的訊號強弱差異極大，如果我們在定義濾波器規格的時候只使用倍數來表示，數值會變得極端並且難以繪圖，比如 $\text{通帶}:\text{阻帶} = 1 : 10^{-6}$。為了閱讀和計算的方便性，分貝這個單位就出現了，它利用對數的性質將巨大的倍數差異壓縮成好處理的數字
&lt;ul&gt;
&lt;li&gt;分貝轉換公式：$Gain_{\color{#3071c4}{dB}} = 20\cdot\log_{\color{#e53935}{10}}(Gain)$&lt;/li&gt;
&lt;li&gt;無變化時（$1$ 倍）：$Gain = 1$，$20\cdot\log_{10}(1) = 0\text{ dB}$，因此 $0\text{ dB}$ 在圖表中常常被用來代表訊號的基準線&lt;/li&gt;
&lt;li&gt;訊號放大時（假設 $2$ 倍）：$20\cdot\log_{10}(2) \approx 6\text{ dB}$&lt;/li&gt;
&lt;li&gt;訊號衰減時（假設 $10^{-4}$ 倍）：$20\cdot\log_{10}(10^{-4}) = -80\text{ dB}$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip[REMARK]
以分貝作為單位的時候，增益和損失的關係變得更加簡單：
$$
\begin{aligned}
&amp;amp; \because\cancel{20}\cdot\log_{10}(Loss) = \cancel{20}\cdot\log_{10}((gain)^{-1}) \
&amp;amp; \therefore Loss = -Gain
\end{aligned}
$$
:::&lt;/p&gt;
&lt;h4&gt;奈奎斯特頻率 / 摺疊頻率（Nyquist / Folding frequency）&lt;/h4&gt;
&lt;p&gt;$$
\begin{aligned}
\frac{\omega_s}{2} &amp;amp;= \frac{\cancel{2}\pi \cdot f_s}{\cancel{2}} \
\because T &amp;amp;= \frac{1}{f_s}, \quad T: \text{Sampling Period} \
\therefore \frac{\omega_s}{2} &amp;amp;= \pi \cdot \frac{1}{T} = \frac{\pi}{T}
\end{aligned}
$$&lt;/p&gt;
&lt;h2&gt;濾波器與規格參數&lt;/h2&gt;
&lt;p&gt;頻率響應的圖表主要由通帶 (Pass Band)、阻帶 (Stop Band) 與 過渡帶 (Transition Band) 組成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;增益規格（Gain spec.）：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$g_{pmax}$​：通帶內允許的最大增益&lt;/li&gt;
&lt;li&gt;$g_{pmin}$​：通帶內允許的最小增益&lt;/li&gt;
&lt;li&gt;$g_{smax}$：阻帶內允許的最大增益&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;頻率規格（Frequency spec.）：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;$\omega_{p}$​：通帶內的最高頻率&lt;/li&gt;
&lt;li&gt;$\omega_{s}$​：阻帶內的最低頻率&lt;/li&gt;
&lt;li&gt;$\omega_{f}$​：摺疊頻率，也就是奈奎斯特頻率，取樣頻率的一半 $\frac{\omega_{sampling}}{2}$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;低通濾波器規格 (Lowpass Digital Filter Specification)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;概念圖
&lt;img src=&quot;w3_1_1.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;規格定義圖
&lt;img src=&quot;w3_1_2.svg&quot; alt=&quot;&quot; /&gt;
:::note
在工程設計中，只要增益曲線（綠線）不要碰到「容差邊限」或稱「禁制區」（黑色的斜線區域）就是合格的濾波器了
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;高通濾波器規格 (Highpass Digital Filter Specification)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;概念圖
&lt;img src=&quot;w3_2_1.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;規格定義圖
&lt;img src=&quot;w3_2_2.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;帶通濾波器規格 (Bandpass Digital Filter Specification)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;概念圖
&lt;img src=&quot;w3_3_1.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;規格定義圖
&lt;img src=&quot;w3_3_2.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;帶阻濾波器規格 (Bandstop Digital Filter Specification)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;概念圖
&lt;img src=&quot;w3_4_1.svg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;規格定義圖
&lt;img src=&quot;w3_4_2.svg&quot; alt=&quot;&quot; /&gt;
:::tip
某些帶阻濾波器又被稱為&lt;strong&gt;帶陷濾波器 (Notch Filter)&lt;/strong&gt;，Notch 是凹口或是刻痕的意思，一般來說，Notch Filter 專指頻帶非常窄的帶阻濾波器。
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;濾波器的實際應用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;低通濾波器
&lt;ol&gt;
&lt;li&gt;降噪，如 ECG 或 EEG 等生醫訊號及音訊處理&lt;/li&gt;
&lt;li&gt;抗混疊濾波器&lt;/li&gt;
&lt;li&gt;影像處理&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;高通濾波器
&lt;ol&gt;
&lt;li&gt;去除直流成分&lt;/li&gt;
&lt;li&gt;影像邊緣偵測&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;帶通濾波器
&lt;ol&gt;
&lt;li&gt;無線通訊&lt;/li&gt;
&lt;li&gt;生醫訊號處理&lt;/li&gt;
&lt;li&gt;語音訊號處理&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;帶阻濾波器
&lt;ol&gt;
&lt;li&gt;消除電源線干擾&lt;/li&gt;
&lt;li&gt;語音通訊&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;全通濾波器（增益維持1）
&lt;ol&gt;
&lt;li&gt;相位補償&lt;/li&gt;
&lt;li&gt;多通道通訊系統中的訊號對齊&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;範例與練習&lt;/h2&gt;
&lt;h3&gt;Ex.1&lt;/h3&gt;
&lt;p&gt;Draw the graphical specification for a digital highpass filter out to the folding frequency in rad/s that will not change the gain above 500 rad/s by more than ±3 dB, while reducing the gain below 200 rad/s by more than 40 dB.
The sampling time T = 0.001 s.&lt;/p&gt;
&lt;p&gt;:::note[ANS]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先確定 x 軸的盡頭，也就是 $\omega_f$ 的部分，由於取樣時間 $T = 0.001\text{s}$ &amp;lt;/br&amp;gt;
$\because\text{Nyquist Frequency} = \frac{\pi}{T}$ &lt;a href=&quot;#%E5%A5%88%E5%A5%8E%E6%96%AF%E7%89%B9%E9%A0%BB%E7%8E%87--%E6%91%BA%E7%96%8A%E9%A0%BB%E7%8E%87nyquist--folding-frequency&quot;&gt;💡為什麼？&lt;/a&gt;&amp;lt;/br&amp;gt;
$\therefore \omega_f = \frac{\pi}{0.001} = 1000\pi$&lt;/li&gt;
&lt;li&gt;畫出阻帶，題目說 200 rad/s 以下增益要衰減 40 dB，因此阻帶容許最大增益為 -40 dB，即 $g_{smax} = -40\text{ db}$&lt;/li&gt;
&lt;li&gt;畫出通帶，題目說 500 rad/s 以上增益改變不能超過 ±3 dB，以無損增益 0 dB 為基準，可得知允許的範圍最高 $g_{pmax} = 3\text{ dB}$，最低 $g_{pmin} = -3\text{ dB}$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;規格圖如下所示：
&lt;img src=&quot;w3_5_1.svg&quot; alt=&quot;&quot; /&gt;
:::&lt;/p&gt;
&lt;h3&gt;Ex.2&lt;/h3&gt;
&lt;p&gt;Draw the graphical specification for a bandstop digital filter out to its folding frequency that will reduce the gain between 1,000 rad/s and 5,000 rad/s by more than 60 dB, but will not reduce the gain above 10,000 rad/s or below 150 rad/s by more than 3 dB. The sampling rate is 10,000 Hz.&lt;/p&gt;
&lt;p&gt;:::note[ANS]
$\text{Nyquist Frequency} = \frac{\omega_s}{2} = \frac{\cancel{2}\pi\cdot f_s}{\cancel{2}} = 10000\pi$ &amp;lt;/br&amp;gt;
後面跟上一題類似故省略 &amp;lt;/br&amp;gt;
規格圖如下所示：
&lt;img src=&quot;w3_5_2.svg&quot; alt=&quot;&quot; /&gt;
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Z 轉換&lt;/h1&gt;
&lt;p&gt;取樣並獲得了離散的數據後，我們通常想要對它進行一些處理，例如我們上一個主題講到的濾波器，用來去除雜訊或增強特定頻率。但在時域進行分析非常困難，因此我們會希望對訊號進行轉換，並在「頻域」來分析離散系統。&lt;/p&gt;
&lt;p&gt;在連續系統中，我們使用拉普拉斯轉換 (Laplace Transform)；而在離散系統中，對應的工具就是 &lt;strong&gt;Z 轉換 (Z-Transform)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w4_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;為什麼要轉到頻域？&lt;/h2&gt;
&lt;p&gt;工程師偏好在頻域處理問題，最主要的原因是運算邏輯的簡化：在時域極為複雜的「卷積」運算，轉到頻域後會變成簡單的「乘法」。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w4_2.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;時域 (Time Domain)&lt;/th&gt;
&lt;th&gt;頻域 (Frequency Domain)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;運算邏輯&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;卷積 (Convolution) $*$&lt;/td&gt;
&lt;td&gt;乘法 (Multiplication) $\cdot$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;連續訊號&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$y(t) = x(t) * h(t)$&lt;/td&gt;
&lt;td&gt;$Y(s) = X(s) \cdot H(s)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;離散訊號&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$y[n] = x[n] * h[n]$&lt;/td&gt;
&lt;td&gt;$Y(z) = X(z) \cdot H(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;正規化角頻率 (Normalized Angular Frequency)&lt;/h3&gt;
&lt;p&gt;在處理離散訊號時，為了避免公式裡一直帶著取樣週期 $T$ 而顯得臃腫，我們通常會定義一個新的變數：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
f(t) &amp;amp;= \cos(\omega{\color{#3071c4}\cdot} t) \
&amp;amp;\quad {\color{#3071c4}let}\downarrow{\color{#3071c4}t=n\cdot t}{\color{#e53935}\text{ &amp;lt;Sampling&amp;gt;}} \
f[n] &amp;amp;= \cos(\omega{\color{#3071c4}\cdot n\cdot t}) = \cos(\omega T\cdot n) \
&amp;amp;\quad {\color{#3071c4}let}\downarrow{\color{#3071c4}\Omega=\omega T} \
&amp;amp;= \cos({\color{#3071c4}\Omega}n)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;這裡的 $\Omega = \omega T$ 稱為 &lt;strong&gt;離散角頻率&lt;/strong&gt; 或 &lt;strong&gt;正規化角頻率&lt;/strong&gt;，單位為 rad。&lt;/p&gt;
&lt;h2&gt;Z 轉換定義&lt;/h2&gt;
&lt;p&gt;將離散訊號 $f[n]$ 進行 Z 轉換得到 $F(z)$ 的一般式如下：&lt;/p&gt;
&lt;p&gt;$$
F(z) = \sum\limits_{n=-\infty}^{\infty}f[n]\cdot z^{-n}
$$&lt;/p&gt;
&lt;p&gt;若訊號具備因果性（即從 $n = 0$ 開始），則公式縮減為：
$$F(z) = \sum\limits_{n=0}^{\infty}f[n]\cdot z^{-n}$$&lt;/p&gt;
&lt;h2&gt;基礎訊號轉換範例&lt;/h2&gt;
&lt;h3&gt;1. 單位樣本/脈衝訊號 (Unit Impulse)&lt;/h3&gt;
&lt;p&gt;根據定義，$\delta[n]$ 只在 $n=0$ 時有值，其餘皆為 0。&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
z(\delta[n]) &amp;amp;= \sum\limits_{n=-\infty}^{\infty}\delta[n]\cdot z^{{\color{#e53935}-n}} \
&amp;amp;= \delta[0]\cdot z^{{\color{#e53935}-}0} = 1\cdot 1 = 1
\end{aligned}
$$&lt;/p&gt;
&lt;h4&gt;💡 Example: 組合脈衝訊號&lt;/h4&gt;
&lt;p&gt;Use the unit-sample signal to describe a sampled data where the initial sample $x[0]=2$, $x[3]=-2$ and the rest of the samples are zero.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1. 寫出離散表示式：&lt;/strong&gt;
&lt;img src=&quot;w4_3.svg&quot; alt=&quot;&quot; /&gt;
$$x[n] = 2\cdot \delta[n] - 2\cdot \delta[n-3]$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2. 進行 Z 轉換：&lt;/strong&gt;
$$
\begin{aligned}
X(z) &amp;amp;= \sum\limits_{n=-\infty}^{\infty}x[n]\cdot z^{-n} \
&amp;amp;= x[0]\cdot z^{-0} + x[3]\cdot z^{-3} \
&amp;amp;= 2 - 2z^{-3}
\end{aligned}
$$&lt;/p&gt;
&lt;h3&gt;2. 單位步階訊號 (Unit-step Signal)&lt;/h3&gt;
&lt;p&gt;對於 $u[n]$，訊號在 $n \ge 0$ 時恆為 1。&lt;/p&gt;
&lt;p&gt;:::tip[REMARK]
當 $|r| &amp;lt; 1$ 時，無窮等比級數之和為：
$1 + r + r^2 + r^3 + \dots = \frac{1}{1-r}$
:::&lt;/p&gt;
&lt;p&gt;將 $u[n]$ 代入 Z 轉換公式，令 $r = z^{-1}$：
$$
\begin{aligned}
Z(u[n]) &amp;amp;= 1 + z^{-1} + z^{-2} + z^{-3} + \dots \
&amp;amp;= \frac{1}{1-z^{-1}} = \frac{z}{z-1}
\end{aligned}
$$&lt;/p&gt;
&lt;h2&gt;Z 轉換常用對照表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Analog Signal&lt;/th&gt;
&lt;th&gt;Sampled Signal&lt;/th&gt;
&lt;th&gt;Z-transformed Signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;$A\delta[n]$&lt;/td&gt;
&lt;td&gt;$A$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$Au(t)$&lt;/td&gt;
&lt;td&gt;$Au[n]$&lt;/td&gt;
&lt;td&gt;$\frac{Az}{z - 1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$Ae^{-at}u(t)$&lt;/td&gt;
&lt;td&gt;$Ae^{-aTn}u[n]$&lt;/td&gt;
&lt;td&gt;$\frac{Az}{z - e^{-aT}}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;$Ac^n u[n]$&lt;/td&gt;
&lt;td&gt;$\frac{Az}{z - c}, c = e^{-aT}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$Atu(t)$&lt;/td&gt;
&lt;td&gt;$AnTu[n]$&lt;/td&gt;
&lt;td&gt;$\frac{ATz}{(z - 1)^2}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$A\cos(\omega t)u(t)$&lt;/td&gt;
&lt;td&gt;$A\cos(\omega Tn)u[n]$&lt;/td&gt;
&lt;td&gt;$\frac{Az[z - \cos(\omega T)]}{z^2 - 2z\cos(\omega T) + 1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$A\sin(\omega t)u(t)$&lt;/td&gt;
&lt;td&gt;$A\sin(\omega Tn)u[n]$&lt;/td&gt;
&lt;td&gt;$\frac{Az\sin(\omega T)}{z^2 - 2z\sin(\omega T) + 1}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$Ae^{-at}\cos(\omega t + \alpha)u(t)$&lt;/td&gt;
&lt;td&gt;$Ac^n \cos(\omega Tn + \alpha)$&lt;/td&gt;
&lt;td&gt;$\frac{Az[z\cos(\alpha) - c \cos(\alpha - \omega T)]}{z^2 - 2cz\cos(\omega T) + c^2}$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;差分方程式與轉移函數&lt;/h2&gt;
&lt;p&gt;在連續時間系統中，我們使用微分方程式 (Differential Equation) 來描述系統，並利用拉普拉斯轉換求解；而在離散時間系統中，我們則使用 &lt;strong&gt;差分方程式 (Difference Equation)&lt;/strong&gt; 來描述，並透過 Z 轉換來處理。&lt;/p&gt;
&lt;h3&gt;Z 轉換的平移特性&lt;/h3&gt;
&lt;p&gt;這裡先提一下 Z 轉換的平移特性，在時域延遲 $k$ 個單位的 $x[n-k]$，經過 Z 轉換後會乘上 $z^{-k}$，即為 $z^{-k}\cdot X(z)$&lt;/p&gt;
&lt;h4&gt;證明：&lt;/h4&gt;
&lt;p&gt;$$
\begin{aligned}
\mathcal{Z}{x[n-k]} &amp;amp;= \sum_{n=-\infty}^{\infty} x[n-k] \cdot z^{-n} \
&amp;amp;\text{let } u = n-k \Rightarrow {\color{#3071c4}n = u+k} \
\therefore \mathcal{Z}{x[n-k]} &amp;amp;= \sum_{{\color{#3071c4}n}=-\infty}^{\infty} x[u] \cdot z^{-{\color{#3071c4}(u+k)}} \
&amp;amp;= \sum_{{\color{#3071c4}u}=-\infty}^{\infty} x[u] \cdot z^{-u} \cdot {\color{#e53935}z^{-k}} \
&amp;amp;= z^{-k} \cdot \underbrace{\sum_{u=-\infty}^{\infty} x[u] \cdot z^{-u}}_{{\color{#3071c4}=X(z)}} \
&amp;amp;= z^{-k} \cdot X(z)
\end{aligned}
$$&lt;/p&gt;
&lt;h4&gt;簡單總結：&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原始時域訊號&lt;/th&gt;
&lt;th&gt;Z 轉換後頻域訊號&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$x[n]$&lt;/td&gt;
&lt;td&gt;$X(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$x[n-k]$&lt;/td&gt;
&lt;td&gt;$z^{-k}\cdot X(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$f[n]$&lt;/td&gt;
&lt;td&gt;$F(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$f[n-k]$&lt;/td&gt;
&lt;td&gt;$z^{-k}\cdot F(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$f[n+k]$&lt;/td&gt;
&lt;td&gt;$z^{k}\cdot F(z)$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;舉個栗子|⩊･)ﾉ🌰&lt;/h3&gt;
&lt;p&gt;有個 DSP 系統，它的差分方程式為：$y[n] -2\cdot y[n-1] = 0.5\cdot x[n-1]$，求它的 Block Diagram 。&amp;lt;/br&amp;gt;
畫出來要像下面這樣：
&lt;img src=&quot;w5_1.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我們對差分方程式進行整理：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
y[n] -2\cdot y[n-1] = 0.5\cdot x[n-1] \
\therefore y[n] = 0.5\cdot x[n-1] + 2\cdot y[n-1]
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;於是我們就能畫出：
&lt;img src=&quot;w5_2.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;轉移函數&lt;/h3&gt;
&lt;p&gt;系統的轉移函數定義為輸出 $Y(z)$ 與輸入 $X(z)$ 的比值。承接上面的例子，首先對差分方程式進行 Z 轉換，根據上面證明的平移特性，我們可以很快的寫出：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
y[n] -2\cdot y[n-1] &amp;amp;= 0.5\cdot x[n-1] \
&amp;amp; \downarrow \text{ Z-Transform} \
Y(z) -2\cdot z^{-1}\cdot Y(z) &amp;amp;= 0.5\cdot z^{-1}\cdot X(z) \
\therefore Y(z) (1-2z^{-1}) &amp;amp;= 0.5\cdot z^{-1}\cdot X(z)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;這個轉移函數 $T(z)$ 是描述系統特性的核心，它決定了系統面對任何輸入時的反應：
&lt;img src=&quot;w5_3.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;$$
{\color{#e53935}T(z)}\equiv\frac{Y(z)}{X(z)} = \frac{0.5\cdot z^{-1}}{1-2\cdot z^{-1}}
$$&lt;/p&gt;
&lt;p&gt;只要有了 $T(z)$，我們就能輕鬆算出任何輸入對應的結果：$Y(z) = T(z)\cdot X(z)$&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;數位濾波器與 DSP 系統的頻率響應&lt;/h1&gt;
&lt;p&gt;Z 轉換出來的結果轉移函數 $T(z)$，是一個包含所有可能 $z$ 值的複數平面。這個平面通常可用來分析系統的「穩定性」，但它還不是我們直觀能看懂的物理頻率，因此這個章節重點在於如何從 Z 域轉換到頻域，並計算系統的增益與相位。&lt;/p&gt;
&lt;p&gt;再複習一下這張圖，講 &lt;a href=&quot;#z-%E8%BD%89%E6%8F%9B&quot;&gt;Z 轉換&lt;/a&gt; 的時候出現過：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;w5_4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;當初在 Z 域以及頻域之間的箭頭打了一顆星星，現在就要來提到這個部分，一樣拿連續時間系統跟離散時間系統做一個對照：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;連續時間系統：&lt;/strong&gt; 拉普拉斯轉換（$s$ 域）$\rightarrow$ 鎖定虛數軸（$s = jw$）$\rightarrow$ 變成傅立葉轉換（頻域）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;離散時間系統：&lt;/strong&gt; Z 轉換（$z$ 域）$\rightarrow$ 鎖定單位圓（$z = e^{j\Omega}$）$\rightarrow$ 變成離散時間傅立葉轉換（頻域）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;為什麼 $z = e^{j\Omega}$？&lt;/h3&gt;
&lt;p&gt;$$
\begin{aligned}
x(t-T) \xrightarrow{\mathcal{L}\text{-trf}} \mathcal{L}{x(t-T)} &amp;amp;= {\color{#e53935}e^{-sT}}\cdot X(s) \
x[nT-T] \xrightarrow{\text{z-trf}} Z{x[n-1]} &amp;amp;= {\color{#e53935}z^{-1}}\cdot X(z) \
z^{-1} = e^{-sT} = (e^{sT})^{-1} \text{ } &amp;amp; \therefore z = e^{sT} \
\because s = j\omega \Rightarrow \text{Frequency} &amp;amp; \text{ response} \
\therefore z = e^{{\color{#3071c4}j\omega} T} = e^{j{\color{#3071c4}\Omega}}
\end{aligned}
$$&lt;/p&gt;
&lt;h2&gt;系統的頻率響應分析&lt;/h2&gt;
&lt;h3&gt;振幅響應與增益 (Magnitude Response / Gain)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;系統的增益即為轉移函數在 $z = e^{j\Omega}$ 時的絕對值大小：$\text{Gain} = |T(z)|_{z=e^{j\Omega}}$&lt;/li&gt;
&lt;li&gt;若要以分貝表示，公式為：$\text{Gain}&lt;em&gt;{\text{dB}} = 20\cdot\log(|T(z)|&lt;/em&gt;{z=e^{j\Omega}})$&lt;/li&gt;
&lt;li&gt;可利用尤拉公式 (Euler formula) $e^{j\Omega} = \cos(\Omega) + j\sin(\Omega)$ 將數值代入轉移函數，計算特定頻率下的增益&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip[Remark: Euler Formula]
$$
\begin{aligned}
e^{j\theta} &amp;amp;= \cos(\theta) + j\sin(\theta), \quad j = \sqrt{-1} \
\therefore z = e^{j\Omega} &amp;amp;= \cos(\Omega) + j\sin(\Omega)
\end{aligned}
$$
代入轉移函數後會得到一個複數 $T(e^{j\Omega}) = a + jb$，其絕對值（也就是增益）算法為：
$$|T(e^{j\Omega})| = \sqrt{a^2 + b^2}$$
:::&lt;/p&gt;
&lt;h3&gt;相位響應 (Phase Response)&lt;/h3&gt;
&lt;p&gt;除了振幅（增益）會改變之外，訊號經過系統後，波形的「相位」也會產生偏移。
將 $z = e^{j\Omega}$ 代入轉移函數後得到的複數 $a + jb$，我們也可以求出它的角度，這個角度就是相位的變化量 $\phi$：&lt;/p&gt;
&lt;p&gt;$$
\phi = \tan^{-1}\left(\frac{b}{a}\right) = \tan^{-1}\left(\frac{\text{虛部 Im}}{\text{實部 Re}}\right)
$$&lt;/p&gt;
&lt;h3&gt;極點與零點 (Poles &amp;amp; Zeros)&lt;/h3&gt;
&lt;p&gt;轉移函數 $T(z)$ 通常可以表示成一個帶有分子跟分母的有理函數 (Rational function)：
$$T(z) = \frac{Y(z)}{X(z)} = \frac{N(z)}{D(z)}$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;零點 (Zeros)：&lt;/strong&gt; 讓分子 $N(z) = 0$ 的 $z$ 值。在這些特定的 $z$ 值下，系統的輸出為 0（增益為 0），代表這些頻率的訊號會被完全阻擋。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;極點 (Poles)：&lt;/strong&gt; 讓分母 $D(z) = 0$ 的 $z$ 值。在這些特定的 $z$ 值下，系統增益會趨近於無限大，極點的位置對於判斷一個系統是否「穩定」非常關鍵。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;範例與練習&lt;/h2&gt;
&lt;p&gt;Determine the gain in dB at 2 rad/s and 37 rad/s for the digital fitter with the following transfer function with the sampling period $T = 0.02\text{s}$. Also state if it is a highpass or lowpass filter. $T(z) = \frac{0.8333(z-1)}{z-0.667}$.&lt;/p&gt;
&lt;p&gt;:::note[ANS]
&lt;strong&gt;Step 1. 先把公式準備好&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;將尤拉公式 $z = e^{j\Omega} = \cos(\Omega) + j\sin(\Omega)$ 代入轉移函數：
$$
T(e^{j\Omega}) = \frac{0.8333(\cos\Omega - 1 + j\sin\Omega)}{(\cos\Omega - 0.667) + j\sin\Omega}
$$
接著我們要算增益的絕對值（分子分母分別取絕對值 $\sqrt{\text{實部}^2 + \text{虛部}^2}$）：
$$
|T(e^{j\Omega})| = \frac{0.8333 \cdot \sqrt{(\cos\Omega - 1)^2 + (\sin\Omega)^2}}{\sqrt{(\cos\Omega - 0.667)^2 + (\sin\Omega)^2}}
$$&lt;/p&gt;
&lt;p&gt;分子根號內展開：$\cos^2\Omega - 2\cos\Omega + 1 + \sin^2\Omega = 2 - 2\cos\Omega$ &amp;lt;/br&amp;gt;
分母根號內展開：$\cos^2\Omega - 1.334\cos\Omega + 0.444889 + \sin^2\Omega = 1.444889 - 1.334\cos\Omega$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2. 代入 $\omega = 2\text{ rad/s}$&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\Omega = \omega T = 2 \times 0.02 = 0.04\text{ rad}$&lt;/li&gt;
&lt;li&gt;$\cos(0.04) \approx 0.9992$&lt;/li&gt;
&lt;li&gt;代入剛剛整理好的絕對值公式：
&lt;ul&gt;
&lt;li&gt;分子：$0.8333 \times \sqrt{2 - 2(0.9992)} = 0.8333 \times \sqrt{0.0016} = 0.8333 \times 0.04 \approx 0.0333$&lt;/li&gt;
&lt;li&gt;分母：$\sqrt{1.444889 - 1.334(0.9992)} = \sqrt{1.444889 - 1.3329} \approx \sqrt{0.1119} \approx 0.3345$&lt;/li&gt;
&lt;li&gt;$\text{Gain} = \frac{0.0333}{0.3345} \approx 0.0995$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;換算 dB：$20\log_{10}(0.0995) \approx \mathbf{-20.04\text{ dB}}$（增益大幅衰減！）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 3. 代入 $\omega = 37\text{ rad/s}$&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\Omega = \omega T = 37 \times 0.02 = 0.74\text{ rad}$&lt;/li&gt;
&lt;li&gt;$\cos(0.74) \approx 0.7385$&lt;/li&gt;
&lt;li&gt;代入絕對值公式：
&lt;ul&gt;
&lt;li&gt;分子：$0.8333 \times \sqrt{2 - 2(0.7385)} = 0.8333 \times \sqrt{0.523} \approx 0.8333 \times 0.7232 \approx 0.6026$&lt;/li&gt;
&lt;li&gt;分母：$\sqrt{1.444889 - 1.334(0.7385)} = \sqrt{1.444889 - 0.9851} \approx \sqrt{0.4597} \approx 0.6780$&lt;/li&gt;
&lt;li&gt;$\text{Gain} = \frac{0.6026}{0.6780} \approx 0.8888$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;換算 dB：$20\log_{10}(0.8888) \approx \mathbf{-1.02\text{ dB}}$（接近 0 dB，訊號無損通過！）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 4. 判斷濾波器類型&lt;/strong&gt;
根據上面的計算：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;低頻率 ($\omega = 2$) 時，訊號衰減很嚴重 (-20 dB)&lt;/li&gt;
&lt;li&gt;高頻率 ($\omega = 37$) 時，訊號順利通過 (-1 dB)&lt;/li&gt;
&lt;li&gt;結論：這是一個高通濾波器
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;IIR 濾波器設計&lt;/h1&gt;
&lt;p&gt;前面介紹了數位濾波器的規格以及 Z 轉換如何幫助我們在頻域進行分析，接下來就要進入重頭戲了：如何實際設計出一個濾波器！我們首先從 IIR 濾波器開始談起。&lt;/p&gt;
&lt;h2&gt;系統與差分方程式&lt;/h2&gt;
&lt;p&gt;複習一下，在 DSP 系統中，輸入訊號 $x[n]$ 經過系統 $T$ 轉換後會得到輸出 $y[n]$，我們可以將其表示為 $y[n]=T(x[n])$。
常見的系統運算包含了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;延遲系統 (Delay System)：&lt;/strong&gt; 輸出直接是過去輸入的延遲，表示為 $y[n]=x[n-d]$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移動平均系統 (Moving-Average System)：&lt;/strong&gt; 輸出是過去幾個輸入訊號的平均，例如三階的移動平均可以寫成 $y[n]=\frac{1}{3}(x[n]+x[n-1]+x[n-2])$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果我們把這些概念推廣，系統的輸出其實可以由「過去的輸出」與「現在及過去的輸入」組合而成，形成了&lt;strong&gt;一般差分方程式&lt;/strong&gt; (General Difference Equation)，公式如下：&lt;/p&gt;
&lt;p&gt;$$
y[n]=a_{1}y[n-1]+a_{2}y[n-2]+\dots+a_{p}y[n-p] + b_{0}x[n]+b_{1}x[n-1]+\dots+b_{q}x[n-q]
$$&lt;/p&gt;
&lt;p&gt;$p$ 和 $q$ 分別代表回饋 (Feedback, 過去的輸出) 與前饋 (Feedfoward, 現在與過去的輸入) 的階數。&lt;/p&gt;
&lt;h3&gt;轉移函數 (Transfer Function)&lt;/h3&gt;
&lt;p&gt;在時域看這長長一串方程式有點痛苦，所以我們把它丟進 Z 轉換的魔法陣裡。利用上一章提到的平移特性（$x[n-k] \xrightarrow{\mathcal{Z}} z^{-k}X(z)$），我們可以把差分方程式整理成系統的轉移函數 $H(z)$：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
Y(z) &amp;amp;= a_{1}z^{-1}Y(z) + a_{2}z^{-2}Y(z) + \dots + a_{p}z^{-p}Y(z) \
&amp;amp;\quad + b_{0}X(z) + b_{1}z^{-1}X(z) + \dots + b_{q}z^{-q}X(z)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;經過移項與提出公因數後，我們就能得到系統的轉移函數 $H(z)$：&lt;/p&gt;
&lt;p&gt;$$
H(z) = \frac{Y(z)}{X(z)} = \frac{b_{0}+b_{1}z^{-1}+b_{2}z^{-2}+\dots+b_{q}z^{-q}}{1-a_{1}z^{-1}-a_{2}z^{-2}-\dots-a_{p}z^{-p}}
$$&lt;/p&gt;
&lt;p&gt;:::note
這裡的 $H(z)$ 跟前面提到的 $T(z)$ 基本上是同一個東西，其實在 DSP 中用 $H(z)$ 應該是比較普遍的，之後不管看到 $T(z)$ 還是 $H(z)$ 都要知道是在說轉移函數（系統函數）。
:::&lt;/p&gt;
&lt;h2&gt;FIR 與 IIR 濾波器&lt;/h2&gt;
&lt;p&gt;根據差分方程式中是否含有「過去的輸出（即 Feedback）」，我們可以將數位濾波器分為兩大家族：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;FIR（Finite Impulse Response, 有限脈衝響應）：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;系統中&lt;strong&gt;沒有回饋 (No feedback)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;也就是差分方程式中的係數 $a_{1}=a_{2}=\dots=a_{p}=0$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IIR（Infinite Impulse Response, 無限脈衝響應）：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;系統中&lt;strong&gt;具有回饋 (has feedback)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;代表 $a_{1} \neq 0$ 或是 $a_{2} \neq 0$ $\dots$ $a_{k} \neq 0$ 等，這會導致脈衝響應在理論上會無限延伸下去&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;四大基本類比濾波器&lt;/h2&gt;
&lt;p&gt;要無中生有設計出一個數位 IIR 濾波器有點難，所以工程界習慣先參考已經發展非常成熟的「類比濾波器」，再將其轉換成數位濾波器。最經典的有以下四種：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Butterworth Filter
&lt;img src=&quot;./w6_1.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Chebyshev Type I Filter
&lt;img src=&quot;./w6_2.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Chebyshev Type II Filter (Inverse Chebyshev Filter)
&lt;img src=&quot;./w6_3.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Elliptic Filter (Cauer Filter)
&lt;img src=&quot;./w6_4.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;small&amp;gt;🔗圖片來源：https://pages.hmc.edu/mspencer/e157/fa24/slides/09.pdf&amp;lt;/small&amp;gt;&lt;/p&gt;
&lt;p&gt;各種數位濾波器的特色如下表所示：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;濾波器&lt;/th&gt;
&lt;th&gt;通帶&lt;/th&gt;
&lt;th&gt;阻帶&lt;/th&gt;
&lt;th&gt;過渡帶斜率&lt;/th&gt;
&lt;th&gt;Ripple 位置&lt;/th&gt;
&lt;th&gt;階數需求&lt;/th&gt;
&lt;th&gt;設計難度&lt;/th&gt;
&lt;th&gt;適用情境&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Butterworth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;完全平坦&lt;/td&gt;
&lt;td&gt;單調下降&lt;/td&gt;
&lt;td&gt;最慢&lt;/td&gt;
&lt;td&gt;無&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;最簡單&lt;/td&gt;
&lt;td&gt;音訊、量測&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chebyshev I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有 ripple&lt;/td&gt;
&lt;td&gt;單調下降&lt;/td&gt;
&lt;td&gt;較快&lt;/td&gt;
&lt;td&gt;通帶&lt;/td&gt;
&lt;td&gt;較低&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;通訊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chebyshev II&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;平坦&lt;/td&gt;
&lt;td&gt;有 ripple&lt;/td&gt;
&lt;td&gt;較快&lt;/td&gt;
&lt;td&gt;阻帶&lt;/td&gt;
&lt;td&gt;較低&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;精準通帶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elliptic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有 ripple&lt;/td&gt;
&lt;td&gt;有 ripple&lt;/td&gt;
&lt;td&gt;最快&lt;/td&gt;
&lt;td&gt;通帶/阻帶&lt;/td&gt;
&lt;td&gt;最低&lt;/td&gt;
&lt;td&gt;最複雜&lt;/td&gt;
&lt;td&gt;高效率頻譜&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;IIR 濾波器設計：脈衝不變法&lt;/h2&gt;
&lt;p&gt;了解了類比濾波器後，我們如何把它「轉」成數位濾波器呢？這裡介紹一種最直觀的方法：&lt;strong&gt;脈衝不變法&lt;/strong&gt; (Impulse Invariant Method)。&lt;/p&gt;
&lt;p&gt;它的核心概念非常簡單粗暴：我們希望設計出來的數位濾波器，它的脈衝響應剛好等於類比濾波器脈衝響應在離散時間下的取樣點！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在類比系統中：若輸入為脈衝訊號 $\delta(t)$（對應拉普拉斯轉換 $X(s)=1$），則系統輸出 $Y(s) = T(s)$。&lt;/li&gt;
&lt;li&gt;在數位系統中：若輸入為脈衝序列 $\delta[n]$（對應 Z 轉換 $X(z)=1$），則系統輸出 $Y(z) = T(z)$。&lt;/li&gt;
&lt;li&gt;數學關係：$T(z) = \mathcal{Z}\left{ \left. \mathcal{L}^{-1}[T(s)] \right|_{t=nT} \right}$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;舉個栗子|⩊･)ﾉ🌰&lt;/h3&gt;
&lt;p&gt;假設我們已知一個一階類比低通濾波器（直流增益為 1，截止頻率 $\omega_c = 10\text{ rad/s}$），其轉移函數為 $T(s) = \frac{10}{s+10}$。
現在我們想要使用脈衝不變法來找它的數位濾波器差分方程式，假設取樣週期 $T = 0.1\text{s}$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1. 求出連續時間脈衝響應&lt;/strong&gt; &amp;lt;/br&amp;gt;
對 $T(s)$ 取反拉普拉斯轉換：
$$
y(t) = \mathcal{L}^{-1}\left[\frac{10}{s+10}\right] = 10 \cdot e^{-10t}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2. 代入離散時間進行取樣&lt;/strong&gt; &amp;lt;/br&amp;gt;
將 $t = nT = 0.1n$ 代入上述方程式：
$$
y[n] = \left. 10 \cdot e^{-10t} \right|_{t=0.1n} = 10 \cdot e^{-10(0.1n)} = 10 \cdot e^{-n}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3. 進行 Z 轉換&lt;/strong&gt; &amp;lt;/br&amp;gt;
將取樣後的 $y[n]$ 進行 Z 轉換求出 $Y(z)$：
$$
Y(z) = \mathcal{Z}{10 \cdot e^{-n}} = \frac{10z}{z-e^{-1}}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4. 進行增益補償並求出 $H(z)$&lt;/strong&gt; &amp;lt;/br&amp;gt;
為了補償取樣過程中產生的 $1/T$ 倍頻譜放大效應，須將 Z 轉換結果乘上取樣週期 $T$ 以校正增益，使其與原類比濾波器量級一致：
$$
H(z) = T \cdot Y(z) = 0.1 \cdot \frac{10z}{z-e^{-1}} = \frac{1}{1-e^{-1}z^{-1}}
$$&lt;/p&gt;
&lt;p&gt;:::tip[為什麼要乘上取樣週期 $T$？]
如果不做增益補償，系統會怎麼樣？我們實際拿上面這個例子算一下「直流增益」（也就是頻率為 0 時的倍率，代入 $s=0$ 或 $z=1$）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原本的類比濾波器：&lt;/strong&gt; $T(s) = \frac{10}{0+10} = 1$ （訊號 1 倍無損通過）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;未乘 T 補償的數位濾波器：&lt;/strong&gt; $Y(z) = \frac{10}{1-e^{-1}} \approx 15.8$ （訊號直接被暴增近 16 倍，系統大爆走）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;乘上 $T\ (0.1)$ 補償後：&lt;/strong&gt; $H(z) = \frac{10}{1-e^{-1}} \cdot 0.1 \approx 1.58$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;雖然脈衝不變法因為天生的「高頻混疊」缺陷，導致補償後無法完美回到 1，但至少乘上 $T$ 後，已經把增益量級拉回正確的基準線了！
:::&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 5. 轉回差分方程式&lt;/strong&gt; &amp;lt;/br&amp;gt;
有了轉移函數，我們將其還原為輸入與輸出的關係：
$$
\begin{gathered}
\frac{Y(z)}{X(z)} = \frac{1}{1-e^{-1}z^{-1}} \
Y(z) \cdot (1-e^{-1}z^{-1}) = X(z) \
Y(z) - e^{-1}z^{-1}Y(z) = X(z)
\end{gathered}
$$&lt;/p&gt;
&lt;p&gt;最後反 Z 轉換回時域，大功告成！這就是我們要的 IIR 濾波器：
$$
y[n] - e^{-1}y[n-1] = x[n] \quad \Rightarrow \quad {\color{#3071c4}y[n] = e^{-1}y[n-1] + x[n]}
$$&lt;/p&gt;
&lt;p&gt;&lt;em&gt;✍️TODO：圖之後補&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;進階範例|⩊･)ﾉ🥥：二階系統的脈衝不變法&lt;/h3&gt;
&lt;p&gt;Find the digital IIR filter for the second-order lowpass analog filter given by the following equation for $T(s) = \frac{15}{s(s+15)}$ for a sampling period $T = 0.05 \text{ s}$.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1. 部分分式展開 (Partial Fraction Expansion, PFE)&lt;/strong&gt; &amp;lt;/br&amp;gt;
為了方便進行反拉普拉斯轉換，我們先把 $T(s)$ 拆開：
$$
T(s)=\frac{15}{s(s+15)}=\frac{A}{s}+\frac{B}{s+15}
$$
經過計算可得 $A=1, B=-1$。 &amp;lt;/br&amp;gt;
所以 $T(s)={\color{#0D9488}\frac{1}{s}}-{\color{#D97706}\frac{1}{s+15}}$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2. 轉換至時域&lt;/strong&gt; &amp;lt;/br&amp;gt;
查閱拉普拉斯轉換表，我們可以得到連續時間的脈衝響應：$y(t) = {\color{#0D9488}1} - {\color{#D97706}e^{-15t}}$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3. 進行取樣與 Z 轉換&lt;/strong&gt; &amp;lt;/br&amp;gt;
代入 $t=nT$，並進行 Z 轉換求出 $T(z)$（原理與一階系統相同，這裡快速帶過）。最終整理後可得到系統的轉移函數：
$$
T(z) = \frac{0.0264z^{-1}}{1 - 1.472z^{-1} + 0.472z^{-2}}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4. 轉回差分方程式&lt;/strong&gt; &amp;lt;/br&amp;gt;
將轉移函數 $T(z) = \frac{Y(z)}{X(z)}$ 展開並交叉相乘：
$$
\begin{gathered}
Y(z)(1 - 1.472z^{-1} + 0.472z^{-2}) = X(z)(0.0264z^{-1}) \
Y(z) - 1.472z^{-1}Y(z) + 0.472z^{-2}Y(z) = 0.0264z^{-1}X(z)
\end{gathered}
$$
接著利用 Z 轉換的平移特性，將等式反轉換回時域，就能得到最終的差分方程式：
$$
y[n] = 1.472 \cdot y[n-1] - 0.472 \cdot y[n-2] + 0.0264 \cdot x[n-1]
$$&lt;/p&gt;
&lt;h2&gt;方法 2: 步階不變法&lt;/h2&gt;
&lt;p&gt;脈衝不變法雖然直觀，但因為脈衝訊號在頻域包含無限高的頻率成分，取樣時非常容易發生「混疊現象 」。為了解決這個問題，我們可以改用「單位步階訊號 (Unit Step)」$x(t)=u(t)$ 作為輸入來設計濾波器，這就稱為&lt;strong&gt;步階不變法&lt;/strong&gt; (The Step Invariant IIR Filter)。&lt;/p&gt;
&lt;p&gt;它的核心概念是：讓數位濾波器的&lt;strong&gt;步階響應&lt;/strong&gt;，等於類比濾波器步階響應的取樣值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;設計公式推導：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在連續系統中，單位步階的拉普拉斯轉換 $X(s) = \frac{1}{s}$。&lt;/li&gt;
&lt;li&gt;系統輸出 $Y(s) = X(s) \cdot T(s) = \frac{T(s)}{s}$。&lt;/li&gt;
&lt;li&gt;取樣後轉換到離散系統，輸出 $Y(z) = \mathcal{Z}\left{ \left. \mathcal{L}^{-1}\left[\frac{T(s)}{s}\right] \right|_{t=nT} \right}$。&lt;/li&gt;
&lt;li&gt;由於在數位系統中，單位步階序列的 Z 轉換為 $X(z) = \frac{z}{z-1}$，而且 $Y(z) = X(z) \cdot T(z)$。&lt;/li&gt;
&lt;li&gt;移項後可以得到步階不變法的設計公式：
$$
T(z) = \frac{z-1}{z} \cdot \mathcal{Z}\left{ \left. \mathcal{L}^{-1}\left[\frac{T(s)}{s}\right] \right|_{t=nT} \right}
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;舉個栗子|⩊･)ﾉ🌰&lt;/h3&gt;
&lt;p&gt;Finding the Step Invariant IIR filter to approximate a first-order lowpass Butterworth (analog) filter $T(s) = \frac{10}{s+10}$, assuming sampling time $T = 0.1 \text{ s}$.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1：求類比系統的步階響應 $Y(s)$&lt;/strong&gt; &amp;lt;/br&amp;gt;
為了求步階響應，我們假設輸入 $X(s)$ 為單位步階函數 $\frac{1}{s}$
$$
Y(s) = T(s) \cdot X(s) = \frac{10}{s+10} \cdot \frac{1}{s} = \frac{10}{s(s+10)}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2：進行部分分式展開 (PFE)&lt;/strong&gt; &amp;lt;/br&amp;gt;
將 $Y(s)$ 拆解以利於進行反拉普拉斯轉換：
$$\frac{10}{s(s+10)} = \frac{A}{s} + \frac{B}{s+10}$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;求 $A$：令 $s=0$，則 $A = \frac{10}{0+10} = 1$&lt;/li&gt;
&lt;li&gt;求 $B$：令 $s=-10$，則 $B = \frac{10}{-10} = -1$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此得到：
$$
Y(s) = \frac{1}{s} - \frac{1}{s+10}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3：轉換回連續時域 $y(t)$&lt;/strong&gt; &amp;lt;/br&amp;gt;
對 $Y(s)$ 取反拉普拉斯轉換：
$$
y(t) = \mathcal{L}^{-1} \left{ \frac{1}{s} - \frac{1}{s+10} \right} = (1 - e^{-10t})u(t)
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4：對時域訊號進行取樣得到 $y[n]$&lt;/strong&gt; &amp;lt;/br&amp;gt;
將 $t = nT$ 代入，其中 $T = 0.1$
$$
y[n] = 1 - e^{-10(0.1n)} = 1 - e^{-n}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 5：求 $y[n]$ 的 Z 轉換 $Y(z)$&lt;/strong&gt; &amp;lt;/br&amp;gt;
根據 Z 轉換表&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\mathcal{Z}{1} = \frac{z}{z-1}$&lt;/li&gt;
&lt;li&gt;$\mathcal{Z}{e^{-n}} = \frac{z}{z-e^{-1}}$
$$
Y(z) = \frac{z}{z-1} - \frac{z}{z-e^{-1}} = \frac{z(z-e^{-1}) - z(z-1)}{(z-1)(z-e^{-1})} = \frac{z(1-e^{-1})}{(z-1)(z-e^{-1})}
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 6：套用修正公式求得 $T(z)$&lt;/strong&gt; &amp;lt;/br&amp;gt;
根據步階不變法定義，$T(z) = \frac{Y(z)}{X(z)}$，而數位單位步階 $X(z) = \frac{z}{z-1}$。因此，我們必須將 $Y(z)$ 乘上修正項 $\frac{z-1}{z}$
$$
\begin{gathered}
T(z) = \frac{z-1}{z} \cdot Y(z) = \frac{z-1}{z} \cdot \frac{z(1-e^{-1})}{(z-1)(z-e^{-1})} \
T(z) = \frac{1-e^{-1}}{z-e^{-1}}
\end{gathered}
$$&lt;/p&gt;
&lt;p&gt;這就是最終的數位轉移函數。可以發現，分子變成了一個常數，這能確保數位系統的直流增益（當 $z=1$ 時）與類比系統（當 $s=0$ 時）保持一致。&lt;/p&gt;
&lt;h2&gt;方法 3: 雙線性轉換&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;雙線性轉換&lt;/strong&gt; (The Bilinear Transform, BLT) 是一種基於「積分器 (Integrator)」概念的轉換方法。相較於前面兩種方法是在時域上對齊響應，雙線性轉換純粹是一種代數轉換，它透過一個數學映射關係，將整個類比系統的 $s$ 平面映射到數位系統的 $z$ 平面。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;轉換公式：&lt;/strong&gt; &amp;lt;/br&amp;gt;
非常簡單粗暴，直接將轉移函數 $T(s)$ 中的 $s$ 替換為以下公式，即可求得數位濾波器 $T(z)$：
$$
s = \frac{2}{T} \cdot \frac{z-1}{z+1}
$$&lt;/p&gt;
&lt;h3&gt;舉個栗子|⩊･)ﾉ🌰&lt;/h3&gt;
&lt;p&gt;Given the following first-order highpass analog filter $T(s) = \frac{s}{s+10}$, use the BLT method to find an IIR digital filter $T(z)$ to approximate it for $T = 0.05 \text{ s}$.&lt;/p&gt;
&lt;p&gt;直接代入轉換公式 $s = \frac{2}{0.05} \cdot \frac{z-1}{z+1} = 40 \cdot \frac{z-1}{z+1}$：
$$
T(z) = \frac{40 \frac{z-1}{z+1}}{40 \frac{z-1}{z+1} + 10} = \frac{40(z-1)}{40(z-1)+10(z+1)} = \frac{40z-40}{50z-30}
$$
直接得到解答！考試考這個拜託（Ｘ
$$
T(z) = \frac{4 \cdot (z-1)}{5z-3}
$$&lt;/p&gt;
&lt;h2&gt;轉換方法特性比較&lt;/h2&gt;
&lt;p&gt;最後，總結一下目前這三種時域對齊轉換法的特性與差異：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;脈衝不變法&lt;/th&gt;
&lt;th&gt;步階不變法&lt;/th&gt;
&lt;th&gt;雙線性轉換&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;保留的響應&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;脈衝響應&lt;/td&gt;
&lt;td&gt;步階響應&lt;/td&gt;
&lt;td&gt;頻率響應特性（將 $s$ 平面映射至 $z$ 平面）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;輸入/數學假設&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;假設輸入為脈衝&lt;/td&gt;
&lt;td&gt;假設輸入為分段常數&lt;/td&gt;
&lt;td&gt;基於積分器與梯形積分概念&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主要缺點&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有明顯的混疊現象&lt;/td&gt;
&lt;td&gt;混疊現象較少&lt;/td&gt;
&lt;td&gt;頻率軸會產生扭曲 (Frequency Warping)，設計時需先進行頻率預先扭曲 (Pre-warping) 處理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;混疊現象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;發生高頻混疊&lt;/td&gt;
&lt;td&gt;減輕高頻混疊&lt;/td&gt;
&lt;td&gt;沒有混疊現象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;應用範圍&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;主要用於低通、頻帶受限的濾波器&lt;/td&gt;
&lt;td&gt;應用範圍更廣泛&lt;/td&gt;
&lt;td&gt;各種類型皆適用，特別適合高通與帶阻濾波器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;未完待續...&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;:::note
部份圖片來源自：陳榮銘 教授 數位訊號處理課程投影片
:::&lt;/p&gt;
</content:encoded></item><item><title>教你如何在 Markdown 中用 Code Blocks 語法包住 Code Blocks 語法（套娃）</title><link>https://blog.yuuzi.cc/posts/guides/nest-code-block/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/nest-code-block/</guid><description>不要問我為什麼要做這種事，剛好有人在問特殊的 Code Blocks 配置，我才好奇有沒有辦法可以這樣展示</description><pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;事情是這樣的，我無聊在逛 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt; 的 &lt;a href=&quot;https://github.com/saicaca/fuwari/issues/613&quot;&gt;issue&lt;/a&gt;，剛好看到有人在問 Fuwari 的 Code Blocks 有沒有辦法不摺疊程式碼（當超過一行的時候），以前 Fuwari 跟 GitHub 一樣太長的話就會讓 Code Blocks 區塊可以左右滾動，不過近期更新後預設就變成會摺疊程式碼了，但依然保留了方法回到原本的不摺疊，這個時候我就要展示給提問者看語法怎麼打對吧？但 GitHub 也支援 Markdown 語法，如果我直接打出來會被解析成 Code Blocks 區塊，對方就看不到語法了，那怎麼辦？多包一層可行嗎？答案是可以，但不是直接包。&lt;/p&gt;
&lt;h2&gt;直接包會怎麼樣？&lt;/h2&gt;
&lt;p&gt;如果直接在 Code Blocks 區塊外面再包 Code Blocks 區塊，他們不會 1-4 配對然後框住 2-3，通常會出現這種狀況：&lt;/p&gt;
&lt;h3&gt;內部 Code Blocks 無指定語言&lt;/h3&gt;
&lt;p&gt;如果內部沒有指定語言的話，一般會被解析成兩個空的 Code Blocks 區塊&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;print(&apos;Ciallo～(∠・ω&amp;lt; )⌒☆&apos;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;內部 Code Blocks 有指定語言&lt;/h3&gt;
&lt;p&gt;這種情況 GitHub 和 Fuwari（本 Blog 模板） 有著相似的行為，因為第二組語法失效的緣故會 1-3 配對，然後第四組成為孤兒，變成沒有包起來的 Code Blocks 區塊&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```py
print(&apos;Ciallo～(∠・ω&amp;lt; )⌒☆&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;我必須補上第五組來完成 Code Blocks 不然我之後打的內容都會被算在 Code Blocks 區塊裡了 &amp;lt;-- 像這樣
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我在上面提到的 issue 中遇到的狀況就是第二種，因為我要展示特殊的 Code Blocks 語法所以會在第二組上添加額外的資訊，導致出現上面第二種的狀況，那到底怎麼在 Code Blocks 區塊內展示 Code Blocks 語法呢？&lt;/p&gt;
&lt;h2&gt;解法&lt;/h2&gt;
&lt;p&gt;在這之前我還是得說每個 Markdown 解析不一定一樣，許多服務也有很多自定義的擴充、閹割語法，但我現在要講的方法應該是個通解，雖然不一定 100% 有效，但至少大部分應該都會支援（吧？&lt;/p&gt;
&lt;p&gt;總之要在 Code Blocks 中玩套娃的方法就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「 用更多的點包起來 」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;沒錯，你只要在外層用 4 個點來表示 Code Blocks，那 GitHub 就會知道要把 1-4 配對，而不是 1-2 配對或 1-3 配對（找最近的），就像這樣：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```py
print(&apos;Ciallo～(∠・ω&amp;lt; )⌒☆&apos;)
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功包起來了，同理要再套一層就要變成 5 個點：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;````
```py
print(&apos;Ciallo～(∠・ω&amp;lt; )⌒☆&apos;)
```
````
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;恭喜你學會 Markdown 版的俄羅斯娃娃了ww，我是今天才知道這件事，可能算是一種已知用火吧，如果你也跟我一樣遇到了這種奇葩問題，那麼希望這篇文章能解答你的疑惑！&lt;/p&gt;
</content:encoded></item><item><title>修復 VS Code 在 Git 差異檢視時無法透過 Ctrl + S 快捷鍵儲存變更的問題（Gemini Code Assist 你壞事做盡）</title><link>https://blog.yuuzi.cc/posts/notes/how-a-gemini-plugin-broke-my-ctrl-s/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/how-a-gemini-plugin-broke-my-ctrl-s/</guid><description>最近突然發現在 Git 差異檢視介面修改 code 的時候，一直無法透過 Ctrl + S 進行儲存，變成都要切回檔案儲存，直到今天我終於受不了了，才發現是有延伸模組在內鬼RRR...</description><pubDate>Fri, 29 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近突然發現在 Git 差異檢視介面修改 code 的時候，一直無法透過 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt; 進行儲存，變成都要切回檔案才能儲存。因為我習慣在這個界面最終確認目前的改動是否可以提交或暫存，往往會在檢查的過程中看到有些瑕疵要進行修改，結果這個小問題真的讓我快要抓狂，問了 LLMs 叫他們幫我查一下 VS Code 最近有沒有對這塊進行改動，也沒查出一個所以然，用關鍵字搜了幾篇文章感覺跟我的狀況也都沒關係，只好自己來除錯了！！順便分享 VS Code 工作不如預期的時候我通常怎麼解決的～&lt;/p&gt;
&lt;h2&gt;STEP. 1 萬能法寶 - 延伸模組平分&lt;/h2&gt;
&lt;p&gt;這個功能非常好用，根本是抓內鬼神器！簡單來說它就是透過二分搜的概念，一直切成兩等份然後問你錯誤是否能復現，照著回答就能迅速幫你抓出內鬼的延伸模組：&lt;/p&gt;
&lt;h3&gt;呼叫方式&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;Shift&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;P&amp;lt;/kbd&amp;gt;&lt;/li&gt;
&lt;li&gt;輸入 &lt;code&gt;bisect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;點擊 &lt;code&gt;Help: Start Extension Bisect&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;p&gt;然後就會跳出這個對話框，照著測試並回答就行了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;抓出內鬼&lt;/h3&gt;
&lt;p&gt;透過這個功能我迅速的抓到是 Gemini Code Assist 在搞，我就知道又是你，你最爛！！&lt;/p&gt;
&lt;p&gt;好啦其實這個插件曾經好用過，但也曾經讓我的 VS Code 變得奇卡無比，現在又給我搞出這個麻煩，已經有點想蛋雕它了，反正我現在 Vibe Coding 也不是在用這個插件，但偶爾簡單的任務交給它做又還挺方便的，實在有點食之無味，棄之可惜啊...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其實到這裡直接停用也行啦，但我還是想知道他到底是為啥搞到我的，也希望他能繼續跟我的 VS Code 友好相處。&lt;/p&gt;
&lt;h2&gt;STEP. 2 深入尋找問題根源&lt;/h2&gt;
&lt;p&gt;其實我上面說問 LLMs 的事也不是完全沒收穫，至少它告訴了我快捷鍵綁定的界面怎麼叫出來，總之一樣先 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;Shift&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;P&amp;lt;/kbd&amp;gt;，然後輸入 &lt;code&gt;workbench.action.files.save&lt;/code&gt; 就能直接叫出「鍵盤快速鍵」界面並且自動搜尋上面這個關鍵字，馬上就能找到 VS Code 存檔的快捷鍵設定：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這個時候其實可以直接在搜尋欄搜尋 &lt;code&gt;&quot;Ctrl + S&quot;&lt;/code&gt; 之類的也行，但我誤打誤撞找到另一種方法：先假裝要改設定，接著按 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt; 就會出現下面這個連結「n 個現有命令有此按鍵繫結」：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;點擊它就能展示所有剛好是配置 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt; 的快捷設定：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此時眼尖的你一定發現貓膩了！Gemini Code Assist 有個不知道來幹啥的功能也是綁定 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt;，而且觸發條件是 &lt;code&gt;inGeminiDiffView || isInDiffEditor&lt;/code&gt;，這代表只要一進到 Git 差異檢視介面這條件一定是 &lt;code&gt;True&lt;/code&gt; 的，非常無恥( •́ὤ•̀)，那接下來不外乎就是兩個選擇...&lt;/p&gt;
&lt;h3&gt;選擇1：改快捷鍵&lt;/h3&gt;
&lt;p&gt;簡單暴力，直接明瞭，改掉這個衝突的快捷鍵設定基本上沒啥缺點，除了我可能會忘記這個新設的快捷鍵導致整個功能廢掉以外，不過我連這個功能是幹嘛的都不是很清楚，畢竟我使用這個插件非常的輕度，感覺就是要偵測使用者是不是按儲存之類的，然後進行下一步動作（我猜，總之我不是用這個方法&lt;/p&gt;
&lt;h3&gt;選擇2：改條件&lt;/h3&gt;
&lt;p&gt;我想到既然我習慣在 Git 差異檢視介面按 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt; 來儲存變更，那我就把這部份改回去就好了啊～原本的條件是 &lt;code&gt;inGeminiDiffView || isInDiffEditor&lt;/code&gt;，那 &lt;code&gt;inGeminiDiffView&lt;/code&gt; 的部分我就留著給它，到時候按 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt; 也直覺，但 &lt;code&gt;isInDiffEditor&lt;/code&gt; 的部分就不準給我改行為，所以我直接把 OR 後面都拿掉，這樣在一般的 Git 差異檢視介面就不會被這個插件的快捷鍵設定干擾了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;問題解決&lt;/h2&gt;
&lt;p&gt;果不其然，當我修改完這個條件後，VS Code 又回到我認識的樣子了，非常感動！話說雖然這個問題除錯起來不算複雜，但要是不知道有這些相關的功能或設定的話，除錯起來可能還真的挺惡夢的，還好我知道「延伸模組平分」這個功能，否則一個一個把延伸模組給停用是真的太費手了ww&lt;/p&gt;
&lt;p&gt;總之就先分享到這啦，遇到這個白癡問題又讓我水了一篇，感覺會有這個問題的人應該也不會太多吧哈哈，就看看能不能幫到剛好看到這篇文章的人囉～&lt;/p&gt;
</content:encoded></item><item><title>透過編輯 desktop.ini 來恢復本地化資料夾名稱</title><link>https://blog.yuuzi.cc/posts/notes/desktop-ini-localized-folder-name/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/desktop-ini-localized-folder-name/</guid><description>昨天剛把下載以及圖片的資料夾路徑改到D槽，結果重新開機後發現資料夾沒有自己本地化了，於是嘗試修復一下！</description><pubDate>Tue, 26 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;昨天發現C槽的讀寫次數大約是D槽的2倍，為了讓我的系統碟更長壽一點，我決定把下載跟圖片的預設路徑改到D槽，分擔下載以及截圖的工作來平衡一下看看。然後我就想說既然以前預設的資料夾也不是叫「下載」跟「圖片」，這種系統級的資料夾應該會幫我自動處理好本地化對吧？結果重新開機後「下載」跟「圖片」就變成「Downloads」跟「Pictures」了（新路徑我自定義的資料夾名稱），你可能會說那就把新路徑的資料夾改成中文不就好了？No～No～No～，這樣太不優雅了，肯定是想個辦法把本地化搞回來！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;查看 desktop.ini 的內容&lt;/h2&gt;
&lt;p&gt;查了一下資料後發現應該是 &lt;code&gt;desktop.ini&lt;/code&gt; 這個系統級檔案在控制本地化之類的行為，於是我看了一下我下載資料夾的 &lt;code&gt;desktop.ini&lt;/code&gt; 檔案，嗯～只有指定了icon，這是我昨天透過 GUI 設置的，讓資料夾一目了然這是下載資料夾，顯然我沒有配置本地化的資訊：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[.ShellClassInfo]
IconResource=C:\Windows\System32\imageres.dll,175
[ViewState]
Mode=
Vid=
FolderType=Generic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;於是我參考了一下&lt;a href=&quot;https://superuser.com/questions/1172765/how-do-i-restore-the-localized-name-for-documents-folder-windows-10&quot;&gt;這篇文章&lt;/a&gt;，它整理了 Windows 常見資料夾的的字串資源 ID，雖然文章很舊了但我實測有效，下載的 ID 是 &lt;code&gt;-21798&lt;/code&gt;，因此對 &lt;code&gt;desktop.ini&lt;/code&gt; 進行以下修改：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[.ShellClassInfo]
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798
IconResource=C:\Windows\System32\imageres.dll,175
[ViewState]
Mode=
Vid=
FolderType=Generic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;順便整理一下這些常見資料集的 ID 列表：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;中文名稱&lt;/th&gt;
&lt;th&gt;英文名稱&lt;/th&gt;
&lt;th&gt;資源識別字串&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;資源回收筒&lt;/td&gt;
&lt;td&gt;Recycle Bin&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-8964&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;連絡人&lt;/td&gt;
&lt;td&gt;Contacts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%CommonProgramFiles%\system\wab32res.dll,-10100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;桌面&lt;/td&gt;
&lt;td&gt;Desktop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21769&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文件&lt;/td&gt;
&lt;td&gt;Documents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21770&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;下載&lt;/td&gt;
&lt;td&gt;Downloads&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21798&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;我的最愛&lt;/td&gt;
&lt;td&gt;Favorites&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21796&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;連結&lt;/td&gt;
&lt;td&gt;Links&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21810&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;音樂&lt;/td&gt;
&lt;td&gt;Music&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21790&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;圖片&lt;/td&gt;
&lt;td&gt;Pictures&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21779&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;儲存的遊戲&lt;/td&gt;
&lt;td&gt;Saved Games&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21814&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;搜尋&lt;/td&gt;
&lt;td&gt;Searches&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-9031&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;影片&lt;/td&gt;
&lt;td&gt;Videos&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21791&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用桌面&lt;/td&gt;
&lt;td&gt;Public Desktop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21799&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用文件&lt;/td&gt;
&lt;td&gt;Public Documents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21801&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用下載&lt;/td&gt;
&lt;td&gt;Public Downloads&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21808&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用音樂&lt;/td&gt;
&lt;td&gt;Public Music&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21803&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用圖片&lt;/td&gt;
&lt;td&gt;Public Pictures&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21802&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;公用影片&lt;/td&gt;
&lt;td&gt;Public Videos&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@%SystemRoot%\system32\shell32.dll,-21804&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;同理，圖片的 ID 是 &lt;code&gt;-21779&lt;/code&gt;，順便照著文章把 InfoTip 補上，雖然不太重要ww&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[.ShellClassInfo]
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688
IconResource=C:\WINDOWS\System32\SHELL32.dll,127
[ViewState]
Mode=
Vid=
FolderType=Pictures
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大功告成，將 &lt;code&gt;desktop.ini&lt;/code&gt; 以 &lt;code&gt;ANSI&lt;/code&gt; 或 &lt;code&gt;UTF-16 LE&lt;/code&gt; 編碼儲存避免出問題，然後重新啟動後就能看到本地化回來囉！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這樣檔案總管可以看到本地化名稱，Terminal一樣可以看到資料夾的原始名稱，熟悉的味道回來了～&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>使用 FFmpeg 製作高品質 GIF，不再有噪點以及殘影！</title><link>https://blog.yuuzi.cc/posts/notes/ffmpeg-gif-palette/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/ffmpeg-gif-palette/</guid><description>以往在用 FFmpeg 轉換圖片或影片為 GIF 的時候，出來的品質總是很難讓我滿意，最近我終於找到原因還有方法了，原來爛的不是工具而是我自己（哭～</description><pubDate>Sat, 19 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;每次用 FFmpeg 轉換圖片或影片為 GIF 的時候，明明原始圖片或影片品質很高，但經過處理轉出來之後就直接慘掉，不單單是畫質死亡而已，而是多出了一堆不明的噪點或是殘影，但用很多線上的工具卻又可以比較好的轉換，沒道理啊，線上工具都可以了，我大 FFmpeg 哪有做不到的道理，說不定線上工具也是用 FFmpeg 咧！直到最近我才終於知道 FFmpeg 要轉換 GIF 的正確姿勢，原來是少用了調色板～總之就來紀錄一下吧！先上前後對比：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/6dMl7Qd.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;差異非常明顯（左 - 未使用調色板 / 右 - 使用調色板，&lt;a href=&quot;https://x.com/Kuro_Tofu/status/1905739431258308845&quot;&gt;圖源 - KuroTofu :3&lt;/a&gt;）&lt;/p&gt;
&lt;h2&gt;為什麼要用調色板？&lt;/h2&gt;
&lt;p&gt;簡單來說，問題出在 GIF 格式只能使用最多 256 種顏色來顯示圖像（每個影格一個調色板）。而從圖片或影片轉換過來的原始素材，用的顏色肯定不只有這麼少。因此在轉換為 GIF 時，必須進行&lt;strong&gt;色彩量化（Color Quantization）&lt;/strong&gt;，也就是從原始的豐富色彩中挑選出「最佳」的 256 種顏色來代表整個畫面。&lt;/p&gt;
&lt;p&gt;不使用調色板時，FFmpeg 在處裡色彩量化的時候可能會採用比較簡單或逐幀獨立的方式處理你的影像：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;簡易處理：為了彌補色彩不足使用&lt;strong&gt;抖色（Dithering）技術&lt;/strong&gt;，簡單來說就是透過人眼的錯覺來表現沒有的顏色，就像 Minecraft 的地圖繪一樣，當這些雜點不夠精細就會變成像是噪點的樣子。&lt;/li&gt;
&lt;li&gt;逐幀獨立：如果是使用為了每個影格去最優化的逐幀獨立方式，雖然每一個影格拆開來看都更精緻，但組在一起就有可能出現&lt;strong&gt;色彩閃爍（Color Flashing）&lt;/strong&gt;，或是類似的顏色在不同影格被量化到不同的調色板索引導致運動中物體邊緣不平滑的過渡造成的&lt;strong&gt;時間不一致性（Temporal Inconsistency）&lt;/strong&gt;，也就是所謂的殘影。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以我們需要透過 &lt;code&gt;palettegen&lt;/code&gt; 和 &lt;code&gt;paletteuse&lt;/code&gt; 來生成全域最佳化的調色板並套用到影片或GIF上！&lt;/p&gt;
&lt;h2&gt;影片/GIF 轉 GIF&lt;/h2&gt;
&lt;h3&gt;生成調色板&lt;/h3&gt;
&lt;p&gt;首先透過 &lt;code&gt;palettegen&lt;/code&gt; 來生成全域最佳化的調色板：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i input.mp4 -filter_complex &quot;[0:v] fps=15,scale=320:-1:flags=lanczos,palettegen&quot; palette.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;參數說明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i input.mp4&lt;/code&gt;：指定要輸入的影片&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-filter_complex&lt;/code&gt;：使用複雜濾鏡來處理影像，讓我們後面可以接多個濾鏡來處理影像&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[0:v]&lt;/code&gt;：選擇第一個影像串流&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fps=15&lt;/code&gt;：設定影片的 FPS 為 15，一般 GIF 這個影格率就能有不錯的效果，自行取捨品質與檔案大小&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scale=320:-1:flags=lanczos&lt;/code&gt;：縮放到寬度 320，後面的 -1 表示高度自動調整，並且使用 Lanczos 演算法，其他演算法可以參考下面表格&lt;/li&gt;
&lt;li&gt;&lt;code&gt;palettegen&lt;/code&gt;：生成調色板&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;演算法名稱&lt;/th&gt;
&lt;th&gt;速度&lt;/th&gt;
&lt;th&gt;畫質&lt;/th&gt;
&lt;th&gt;說明/備註&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fast_bilinear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最快&lt;/td&gt;
&lt;td&gt;最低&lt;/td&gt;
&lt;td&gt;結果模糊，僅在速度是唯一考量時使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;neighbor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;很快&lt;/td&gt;
&lt;td&gt;最低&lt;/td&gt;
&lt;td&gt;結果像素化、鋸齒感強，速度極致或特殊藝術效果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bilinear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;適中偏快&lt;/td&gt;
&lt;td&gt;中偏低&lt;/td&gt;
&lt;td&gt;比 &lt;code&gt;fast_bilinear&lt;/code&gt; 稍好，仍偏模糊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bicubic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;適中&lt;/td&gt;
&lt;td&gt;中偏高&lt;/td&gt;
&lt;td&gt;常用的預設值，速度與畫質平衡點不錯&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;area&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;適中偏快&lt;/td&gt;
&lt;td&gt;中偏高 (縮小)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;推薦用於縮小&lt;/strong&gt;，能較好保留細節，放大效果差&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lanczos&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;慢&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;通用高品質選擇，結果通常較銳利&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sinc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;慢&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;與 &lt;code&gt;lanczos&lt;/code&gt; 相似的高品質選擇，可能略有差異&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;spline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;慢&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;另一種高品質選擇，有其獨特視覺風格&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::note
選擇困難症就跟我選一樣的：&lt;code&gt;lanczos&lt;/code&gt;，普遍效果很好
:::&lt;/p&gt;
&lt;h3&gt;套用調色板至 GIF 影像&lt;/h3&gt;
&lt;p&gt;生成完調色板後，就可以利用 &lt;code&gt;paletteuse&lt;/code&gt; 來套用調色板：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i input.mp4 -i palette.png -filter_complex &quot;[0:v] fps=15,scale=320:-1:flags=lanczos,paletteuse&quot; output.gif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;記得 &lt;code&gt;-filter_complex&lt;/code&gt; 後面的參數要和上面設定的一樣，&lt;code&gt;output.gif&lt;/code&gt; 就會是調整好的 GIF 了！至於如果要單純調整 GIF 的大小的話也一樣，把指令中輸入影片的部分改成 GIF 就可以了！&lt;/p&gt;
&lt;h2&gt;進階用法：無法直接用於影片/GIF的複雜處理&lt;/h2&gt;
&lt;p&gt;如果你要對影片/GIF進行一些複雜的處理，而且處理的工具只能處理圖片，比如 &lt;a href=&quot;https://github.com/danielgatis/rembg&quot;&gt;Rembg&lt;/a&gt; 等工具，那我們可以透過將影片/GIF一張一張拆解成圖片，全部處理過後再轉回影片/GIF！由於 GIF 比較難搞，接下來我就以這張 GIF 為例來說明：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/kN7rKVd.gif&quot; alt=&quot;&quot; /&gt;
&lt;a href=&quot;https://x.com/Kuro_Tofu/status/1909354462994731029&quot;&gt;🔗圖源 - KuroTofu :3&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;確認原始的影片/GIF影格率&lt;/h3&gt;
&lt;p&gt;為了避免組回來後速度跑掉，我們要先確認原本的影格率：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffprobe -v error -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 input.gif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;25/1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這裡的 &lt;code&gt;avg_frame_rate&lt;/code&gt; 是平均影格率，&lt;code&gt;25/1&lt;/code&gt; 就是 25 個影格每秒，先記下這個數字。&lt;/p&gt;
&lt;h3&gt;使用 FFmpeg 切割影片/GIF為圖片&lt;/h3&gt;
&lt;p&gt;先開一個資料夾放切出來的圖片：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir frames
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上面的 GIF 為例，先切割出圖片：&lt;/p&gt;
&lt;p&gt;GIF：(禁用 CRF)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i input.gif -vsync 0 frames/frame_%04d.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;影片：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -i input.gif frames/frame_%04d.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
如果影片/GIF很長，你可能要調整 &lt;code&gt;%04d&lt;/code&gt; 這個部分，使得有更多的編號空間來當作圖片的檔名，比如 &lt;code&gt;%05d&lt;/code&gt;。
:::&lt;/p&gt;
&lt;h3&gt;對圖片進行複雜處理&lt;/h3&gt;
&lt;p&gt;接下來就能對圖片進行你想要的複雜處理了，我這裡就以 &lt;a href=&quot;https://github.com/danielgatis/rembg&quot;&gt;Rembg&lt;/a&gt; 為例，將所有圖片進行去背：&lt;/p&gt;
&lt;p&gt;Bash 腳本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir processed_frames
for f in frames/*.png; do
    rembg i &quot;$f&quot; &quot;processed_frames/$(basename &quot;$f&quot;)&quot;
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Batch 腳本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir processed_frames
for %%f in (frames\*.png) do (
    rembg i &quot;%%f&quot; &quot;processed_frames\%%~nxf&quot;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Powershell 腳本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;New-Item -ItemType Directory -Force -Path processed_frames
Get-ChildItem frames\*.png | ForEach-Object {
    $outputFile = Join-Path processed_frames $_.Name
    rembg i $_.FullName $outputFile
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
因為我是用 2D 動漫類型的 GIF，所以我偷偷選擇了 &lt;code&gt;isnet-anime&lt;/code&gt; 模型來提升去背品質。然後如果你也想安裝 Rembg 來去背的話，你可以參考我以前的&lt;a href=&quot;https://blog.yuuzi.cc/posts/guides/conda-rembg-gpu/&quot;&gt;教學&lt;/a&gt;
:::&lt;/p&gt;
&lt;h3&gt;生成調色板並組合回影片/GIF&lt;/h3&gt;
&lt;p&gt;到這一步就和前面差不多了，所以我就快速帶過，之前記下來的影格率現在用到了，記得在 &lt;code&gt;-framerate&lt;/code&gt; 後面填上當初顯示的影格率：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -framerate 25 -i processed_frames/frame_%04d.png -filter_complex &quot;[0:v] scale=320:-1:flags=lanczos,palettegen=reserve_transparent=on&quot; palette.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因為我是做了去背的操作，所以我多了一個調色板的設定：&lt;code&gt;reserve_transparent=on&lt;/code&gt;，將第一個顏色保留給透明度資訊。接下來將調色板套用並組回影片/GIF：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ffmpeg -framerate 25 -i processed_frames/frame_%04d.png -i palette.png -filter_complex &quot;[0:v] scale=320:-1:flags=lanczos,paletteuse=alpha_threshold=128&quot; output.gif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這裡同樣因為我做了去背的操作，所以我在調色板加上了 &lt;code&gt;alpha_threshold=128&lt;/code&gt;，將透明度資訊套用到調色板上（Alpha 值 &amp;lt; 128 的像素被視為完全透明），下面展示成品：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/70ZNtKu.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;除了右下角去背有點瑕疵以及愛心不見以外效果不錯，不過畢竟這篇文章不是來教去背的所以這不是重點啦～只是隨便找個操作來演示一下，總之這就是完整的流程了，應該足夠詳細了吧！希望能幫助到被 FFmpeg 指令搞到頭昏眼花的人～&lt;/p&gt;
</content:encoded></item><item><title>輕鬆去除圖片背景：使用 Conda 建置 Rembg 環境並啟用 GPU 加速</title><link>https://blog.yuuzi.cc/posts/guides/conda-rembg-gpu/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/conda-rembg-gpu/</guid><description>網路上許多教學都很隨便，只好發揮一下以前搞 TensorFlow 的經驗，盡量詳細的教學並確保順利運行！</description><pubDate>Sun, 13 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近有一些小小的需求需要對圖片進行去背，奈何我用一些常見的修圖工具修起來都不太理想，雖然應該是我技術問題，但我就不是相關科系的齁～身為一個資工系小白肯定是要發揮一下自己的專長，現代問題使用現代手段解決啊！！於是我就找到了這個非常多星星的U質專案：&lt;strong&gt;Rembg&lt;/strong&gt;！他有提供 CPU 以及 GPU 版本的，既然有 GPU 版本的那當然沒道理不用對吧？事不宜遲，進教學！&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;danielgatis/rembg&quot;}&lt;/p&gt;
&lt;h2&gt;安裝顯示卡驅動&lt;/h2&gt;
&lt;p&gt;因為每個人的作業系統不一樣，加上網路上各種作業系統安裝顯卡驅動的教學文章都已經很成熟了，這裡就不多做贅述。首先，透過指令確認是否已經安裝了顯卡驅動：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出現這個畫面就是安裝好驅動了，如果沒有安裝顯卡驅動就去先去安裝一下吧，要特別注意太舊的驅動可能不會支援比較新版本的 CUDA，雖然之後會用到 CUDA 跟 cuDNN 的套件看起來沒有太硬性規定 CUDA 的版本，但還是先注意一下！&lt;/p&gt;
&lt;h2&gt;安裝 Conda&lt;/h2&gt;
&lt;p&gt;我個人喜歡用虛擬環境，這樣可以很有效的獨立不同專案依賴的套件，Conda 是廣為人知的套件/環境管理系統，我們要透過他來管理不同專案要使用到的套件以及 CUDA、cuDNN 等等，方便在不同專案之間快速切換。&lt;/p&gt;
&lt;p&gt;:::note
我這裡會使用 Miniconda，它比 Anaconda 更輕量，只需要安裝最小需求的套件：&lt;a href=&quot;https://docs.anaconda.com/miniconda/&quot;&gt;Miniconda 文檔&lt;/a&gt;。
:::&lt;/p&gt;
&lt;p&gt;這一步和上一步類似，各種作業系統的教學也都很成熟了，官方的文檔也寫的蠻清楚的，這裡就不詳細說明。&lt;/p&gt;
&lt;h2&gt;創建 Conda 虛擬環境&lt;/h2&gt;
&lt;p&gt;安裝好 Conda 後，就可以創建虛擬環境了!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda create -n rembg python=3.12.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
根據 &lt;a href=&quot;https://github.com/danielgatis/rembg/blob/main/README.md&quot;&gt;Rembg 官方文檔&lt;/a&gt;，Python版本應該 &amp;gt;= 3.10 並 &amp;lt; 3.14（隨著更新可能會改變，具體範圍請到文檔中確認）
:::&lt;/p&gt;
&lt;p&gt;創建好環境後進入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda activate rembg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安裝 CUDA 以及 cuDNN&lt;/h2&gt;
&lt;p&gt;這點比較重要，也是很容易出事的地方，這兩個套件是要啟用 GPU 加速不可或缺的，並且版本不可以隨便，這兩者之間必須要相容，否則無法順利運行，因為接下來我們會先安裝 GPU 版本的 onnxruntime，所以以他提供的對應表格為參考：&lt;a href=&quot;https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html&quot;&gt;ONNX 文檔&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這裡簡單列出一些常見的版本（其實就是從文檔幹下來的）：&lt;/p&gt;
&lt;h3&gt;CUDA 12.x&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ONNX Runtime&lt;/th&gt;
&lt;th&gt;CUDA&lt;/th&gt;
&lt;th&gt;cuDNN&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.20.x&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;9.x&lt;/td&gt;
&lt;td&gt;Available in PyPI. Compatible with PyTorch &amp;gt;= 2.4.0 for CUDA 12.x.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.19.x&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;9.x&lt;/td&gt;
&lt;td&gt;Available in PyPI. Compatible with PyTorch &amp;gt;= 2.4.0 for CUDA 12.x.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.18.1&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;9.x&lt;/td&gt;
&lt;td&gt;cuDNN 9 is required. No Java package.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.18.0&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;Java package is added.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.17.x&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;Only C++/C# Nuget and Python packages are released. No Java package.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;CUDA 11.x&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ONNX Runtime&lt;/th&gt;
&lt;th&gt;CUDA&lt;/th&gt;
&lt;th&gt;cuDNN&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.20.x&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;Not available in PyPI. See &lt;a href=&quot;https://onnxruntime.ai/docs/install&quot;&gt;Install ORT&lt;/a&gt; for details. Compatible with PyTorch &amp;lt;= 2.3.1 for CUDA 11.8.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.19.x&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;Not available in PyPI. See &lt;a href=&quot;https://onnxruntime.ai/docs/install&quot;&gt;Install ORT&lt;/a&gt; for details. Compatible with PyTorch &amp;lt;= 2.3.1 for CUDA 11.8.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.18.x&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;Available in PyPI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.17 - 1.15&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.2.4 (Linux), 8.5.0.96 (Windows)&lt;/td&gt;
&lt;td&gt;Tested with CUDA versions from 11.6 up to 11.8, and cuDNN from 8.2 up to 8.9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;因為截至目前 &lt;code&gt;onnxruntime-gpu&lt;/code&gt; 最新版是 &lt;code&gt;1.21.0&lt;/code&gt;，所以我選擇了 CUDA &lt;code&gt;12.5.1&lt;/code&gt; 以及 cuDNN &lt;code&gt;9.3&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;依照表格選好 onnxruntime 以及與其對應的 CUDA 和 cuDNN 版本後，安裝套件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda install nvidia/label/cuda-{cuda_version}::cuda
conda install -c conda-forge cudnn={cudnn_version}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CUDA 方面我是使用 &lt;a href=&quot;https://anaconda.org/nvidia/cuda&quot;&gt;nvidia 頻道&lt;/a&gt; 的完整包，另外，雖然 Rembg 在文檔中是要求 cudnn-devel，但我實測一般的 cuDNN 就可以了，但我不確定有沒有什麼使用情境會出現問題，這裡留一個問號，畢竟裝 cudnn-devel 比較麻煩，我懶～&lt;/p&gt;
&lt;h2&gt;安裝 onnxruntime&lt;/h2&gt;
&lt;p&gt;首先，確認你的系統支不支援 &lt;code&gt;onnxruntime-gpu&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;到 &lt;a href=&quot;https://onnxruntime.ai/getting-started&quot;&gt;onnxruntime.ai&lt;/a&gt; 依照圖中勾選，作業系統就因人而異。（繼續借 Rembg 文檔的東西來用）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;點好之後就會告訴你怎麼安裝囉！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;那我是用 CUDA 12.x 的嘛，所以我只需要直接 &lt;code&gt;pip install onnxruntime-gpu&lt;/code&gt; 就好了！&lt;/p&gt;
&lt;h2&gt;安裝 Rembg&lt;/h2&gt;
&lt;p&gt;最後就是安裝 Rembg 啦，如果只要套件本體：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install &quot;rembg[gpu]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果要套件本體和 CLI 工具，我會推薦裝這個，可以直接用命令行操作：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install &quot;rembg[gpu,cli]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就都安裝好啦～快拿點圖去試試吧！這篇著重在安裝而不是使用，如果我以後有用出一點心得再來分享使用的訣竅，基本用法都在 &lt;a href=&quot;https://github.com/danielgatis/rembg?tab=readme-ov-file#usage-as-a-cli&quot;&gt;Rembg 文檔&lt;/a&gt; 了！&lt;/p&gt;
&lt;h2&gt;（可選）更換模型&lt;/h2&gt;
&lt;p&gt;Rembg 有提供不少不同的模型可供選擇，在這裡列一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;u2net&lt;/strong&gt;: 適用於通用應用的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;u2netp&lt;/strong&gt;: u2net 模型的輕量版。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;u2net_human_seg&lt;/strong&gt;: 適用於人體分割的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;u2net_cloth_seg&lt;/strong&gt;: 針對人像的服裝分割預訓練模型，將服裝區分為三類：上半身、下半身與全身。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;silueta&lt;/strong&gt;: 與 u2net 類似，但尺寸縮減至 43Mb。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isnet-general-use&lt;/strong&gt;: 適用於通用應用的新預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isnet-anime&lt;/strong&gt;: 高精準度的動漫角色分割模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sam&lt;/strong&gt;: 適用於各種用途的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-general&lt;/strong&gt;: 適用於通用應用的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-general-lite&lt;/strong&gt;: 輕量版通用應用預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-portrait&lt;/strong&gt;: 適用於人像的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-dis&lt;/strong&gt;: 適用於二值影像分割 (DIS) 的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-hrsod&lt;/strong&gt;: 適用於高解析度顯著目標偵測 (HRSOD) 的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-cod&lt;/strong&gt;: 適用於隱蔽物體偵測 (COD) 的預訓練模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;birefnet-massive&lt;/strong&gt;: 包含龐大數據集的預訓練模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你跟我一樣是想去除動漫風格插圖的背景，可以嘗試使用 &lt;code&gt;isnet-anime&lt;/code&gt; 這個模型，效果通常會比預設的還要更好：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這裡舉一個我從&lt;a href=&quot;https://www.twitch.tv/nacho_dayo&quot;&gt;甘城馬麻&lt;/a&gt;直播上截圖下來的圖片舉例，左 - 原圖 | 中 - 預設模型  | 右 - isnet-anime 模型，可以看到有很明顯的差異！&lt;/p&gt;
</content:encoded></item><item><title>Git 衝突解決指南：同步原始倉庫並保留本地 Commit</title><link>https://blog.yuuzi.cc/posts/guides/sync-fork-with-upstream/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/sync-fork-with-upstream/</guid><description>剛好要同步更新一下這個 blog，就順手紀錄一下！</description><pubDate>Thu, 10 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;很明顯的這個 blog 是直接套別人寫好的模板來改的，過了好一陣子是時候把更新都拉過來了，想當然而的又會出現衝突，所以就趁著這個機會順便寫一篇文章好了！話說上一篇解決 Arch Linux 問題的文章還真的幫助到了未來的自己，果然隨手紀錄一下自己又在搞什麼鬼還是挺有幫助的！&lt;/p&gt;
&lt;h2&gt;開始同步&lt;/h2&gt;
&lt;h3&gt;Step.1 新增上游遠端（Upstream Remote）&lt;/h3&gt;
&lt;p&gt;先檢查一下當前有哪些遠端設定，我因為之前弄過了所以已經新增好了上游遠端：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果還沒有上游遠端的話就加上去：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote add upstream &amp;lt;upstream-repo-URL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step.2 取得上游的變更&lt;/h3&gt;
&lt;p&gt;執行指令抓取上游 repo 的最新更新：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git fetch upstream
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這個指令會將上游 repo 的所有分支下載到本地，但不會自動合併。&lt;/p&gt;
&lt;h3&gt;Step.3 切換到你要更新的分支&lt;/h3&gt;
&lt;p&gt;這裡就是因人而異了，現在大部分的 repo 的主要分支都是 &lt;code&gt;main&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;比較古老的 repo 可能會是 &lt;code&gt;master&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout master
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step.4 合併上游的更新&lt;/h3&gt;
&lt;p&gt;有兩種常見方式可以合併上游變更到你的分支中：&lt;code&gt;merge&lt;/code&gt; 或 &lt;code&gt;rebase&lt;/code&gt;。&lt;/p&gt;
&lt;h4&gt;Step.4.1 方法A：merge&lt;/h4&gt;
&lt;p&gt;這種方式會將上游的變更與你目前的 commit 歷史合併，產生一個新的 merge commit。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git merge upstream/main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我這次選擇 merge：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一樣，某些 repo 可能會是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git merge upstream/master
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Step.4.2 方法B：rebase&lt;/h4&gt;
&lt;p&gt;這種方式會把你的變更移動到上游最新 commit 之後，使 commit 歷史更為整潔。如果你的變更已經推到遠端，使用 rebase 可能會帶來一些問題。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rebase upstream/main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rebase upstream/master
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step.5 解決衝突&lt;/h3&gt;
&lt;p&gt;想當然而會有衝突，不然你現在就不會在看這篇文章了，沒衝突的話直接在 Github 上按一下 sync 就直接搞定走人：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add &amp;lt;resolve-conflicting-files&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或是你像我一樣懶惰直接：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下來要提交：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;merge&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;git commit -m &quot;commit message&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;rebase&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;git rebase --continue
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step.6 推送到遠端&lt;/h3&gt;
&lt;p&gt;完成合併或 rebase 後，將更新推送到你在 GitHub 上的 fork：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果使用 rebase 並且已經推到遠端過，可能需要強制推送（強制推送的時候要特別注意，尤其是和團隊協作時）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git push -f origin main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就搞定啦，等以後我又忘記的時候就來看自己寫的東東（欸嘿～&lt;/p&gt;
</content:encoded></item><item><title>Arch 升級軟體時出現 404 錯誤的解決方法</title><link>https://blog.yuuzi.cc/posts/notes/resolving-404-error-in-arch-updates/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/resolving-404-error-in-arch-updates/</guid><description>一大早就遇到問題，extra.db 死活更新不了，還好成功解決了紀錄一下方法！</description><pubDate>Tue, 22 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;今天早上打開 Arch WSL 看一下，隨手更新一下軟體，欸？怎麼就報錯了，昨天還有夢到用 &lt;code&gt;pacman&lt;/code&gt; 時出錯，雖然跟夢境的報錯不一樣，但這果然是預知夢嗎，太黑暗了...總之，我還蠻幸運的很快就解決了，沒有用到太多奇怪的技巧。&lt;/p&gt;
&lt;h2&gt;報錯&lt;/h2&gt;
&lt;p&gt;例行更新環節，想到就更新一下結果報錯：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;➜ sudo pacman -Syu
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;:: Synchronizing package databases...
 core is up to date
 extra.db failed to download
error: failed retrieving file &apos;extra.db&apos; from mirrors.kernel.org : The requested URL returned error: 404
error: failed to synchronize all databases (failed to retrieve some files)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;嘗試清理緩存那些的，但沒有用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Sc
sudo pacman -Scc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 &lt;code&gt;debug flag&lt;/code&gt; 來查看更詳細的問題:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Syu --debug
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;主要印出這些問題，有些 info 我就省略了太長&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
debug: adding new server URL to database &apos;extra&apos;: https://mirrors.kernel.org/archlinux/extra/os/x86_64
...
debug: extra.db: curl returned result 0 from transfer
debug: extra.db: response code 404
error: failed retrieving file &apos;extra.db&apos; from mirrors.kernel.org : The requested URL returned error: 404
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣看起來，嘗試從 &lt;code&gt;mirrors.kernel.org&lt;/code&gt; 下載 &lt;code&gt;extra.db&lt;/code&gt; 時出遇到 HTTP 404 錯誤，請求的資源不存在，這在加上 debug flag 之前就大概看出端倪了。&lt;/p&gt;
&lt;p&gt;這種情況大概是以下這幾種可能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;靜像站暫時故障&lt;/li&gt;
&lt;li&gt;靜像站正在同步中&lt;/li&gt;
&lt;li&gt;靜像站路徑變更了&lt;/li&gt;
&lt;li&gt;本地的靜像列表過期&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;既然推測如此，那就先用最簡單的方式，更新一下靜像站的列表試試，先備份本來的列表避免出問題，然後更新 mirrorlist：&lt;/p&gt;
&lt;p&gt;:::note[沒有 &lt;code&gt;reflector&lt;/code&gt; 套件的話要先安裝]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S reflector
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 備份現有的 mirrorlist
sudo cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup

# 更新 mirrorlist
sudo reflector --country &apos;&amp;lt;country&amp;gt;&apos; --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;country&amp;gt;&lt;/code&gt; 的部分自己替換成自己所在的國家，這裡的意思大概是，指定位於特定國家的靜像站，選擇最近 12 小時內同步過的鏡像站，只選擇支持 HTTPS 協議的鏡像站，按照下載速率對鏡像站進行排序，最後保存到 &lt;code&gt;/etc/pacman.d/mirrorlist&lt;/code&gt; 檔案中，&lt;code&gt;--age&lt;/code&gt; 的參數也可以修改。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;好欸！成功解決！&lt;/p&gt;
&lt;h2&gt;其他可能的方法&lt;/h2&gt;
&lt;p&gt;:::warning
因為我只嘗試了上面的方法就成功解決了，接下來只是我查到可能可行的方法，不一定管用或者安全，請謹慎評估風險並充分理解指令的內容再進行操作。
:::&lt;/p&gt;
&lt;h3&gt;重新初始化 pacman 金鑰&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 移除舊的金鑰
sudo rm -rf /etc/pacman.d/gnupg

# 初始化金鑰
sudo pacman-key --init

# 重新加載金鑰
sudo pacman-key --populate archlinux
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;清除套件快取並強制重新同步&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Scc  # 清除快取
sudo pacman -Syy  # 強制重新同步資料庫
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;最後嘗試更新&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Syu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果還是有問題，可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;檢查 &lt;code&gt;/etc/pacman.conf&lt;/code&gt; 確保倉庫設定正確&lt;/li&gt;
&lt;li&gt;確認網路連線狀況&lt;/li&gt;
&lt;li&gt;嘗試使用其他鏡像站&lt;/li&gt;
&lt;li&gt;檢查系統時間是否正確&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>分享 Zsh 的設定檔以及使用的插件</title><link>https://blog.yuuzi.cc/posts/notes/share-zsh-config-and-plugins/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/share-zsh-config-and-plugins/</guid><description>最近剛把 Bash 蛋雕，紀錄並分享一下自己用了什麼插件還有做了些設定</description><pubDate>Sun, 20 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近搞了 Arch WSL，CLI 當然是沒少用，Bash 理所當然的就被我蛋雕了，嘗鮮了一下 Zsh 發現真的很頂，馬上就回不去了，之後有空看看要不要把實驗室的電腦也換成 Zsh 好了。這篇文章應該會不定期更新，如果以後有修改配置或是又玩了什麼新東西的話～&lt;/p&gt;
&lt;h2&gt;美化&lt;/h2&gt;
&lt;p&gt;我這裡選擇了 &lt;a href=&quot;https://ohmyposh.dev/&quot;&gt;Oh My Posh&lt;/a&gt; 來美化 Zsh，一來是它在很多 CLI 中都可以使用，二來因為我是用 WSL，主題直接拿裝在 Windows 來用，非常方便，我研究了一陣子，看到很多人使用 &lt;a href=&quot;https://ohmyz.sh/&quot;&gt;Oh My Zsh&lt;/a&gt;，但我覺得我暫時還不會用到太多的功能，用這種集成的工具就太多了，還是比較喜歡就只拿需要的部分，所以後面插件的管理我也會選用其他的管理工具來幫助我。&lt;/p&gt;
&lt;p&gt;至於如何用 Oh My Posh 來美化 Zsh，我想&lt;a href=&quot;https://ohmyposh.dev/docs&quot;&gt;文檔&lt;/a&gt;已經寫得很清楚了，基本上都是指令貼一貼就搞定，所以我這裡只講一下配置的重點。&lt;/p&gt;
&lt;p&gt;安裝完後 Oh My Posh 可能會出現要你把 &lt;code&gt;/home/{user}/.local/bin&lt;/code&gt; 加到環境變數，這個要特別注意，這行一定要在 Oh My Posh 的 init 指令前面，否則下次進 Zsh 就會回到光溜溜的狀態 ww&lt;/p&gt;
&lt;p&gt;這個在前：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export PATH=$PATH:/home/&amp;lt;user&amp;gt;/.local/bin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這個在後：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eval &quot;$(oh-my-posh init zsh --config &amp;lt;config_json_file_path&amp;gt;)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip[WSL 小技巧]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nerdfonts.com/&quot;&gt;Nerd Fonts&lt;/a&gt; 要裝在 Windows 上，不是裝在 WSL 裡。&lt;/li&gt;
&lt;li&gt;本地的 C 槽就是 &lt;code&gt;/mnt/c&lt;/code&gt;，D 槽就是 &lt;code&gt;/mnt/d&lt;/code&gt;，以此類推，如果你跟我一樣要直接用放在 Windows 上的主題，路徑要改成這樣。
:::&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;插件及工具&lt;/h2&gt;
&lt;h3&gt;Completion&lt;/h3&gt;
&lt;p&gt;這個部分是設定自動完成有關的，第一行 &lt;code&gt;zstyle &apos;:completion:*&apos; menu yes select&lt;/code&gt; 是讓我們可以用方向鍵控制選單的選擇，而 &lt;code&gt;bindkey &apos;^[[Z&apos; reverse-menu-complete&lt;/code&gt; 是讓 &amp;lt;kbd&amp;gt;Shift&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;Tab&amp;lt;/kbd&amp;gt; 可以切換到上一個選項，換句話說，&amp;lt;kbd&amp;gt;Tab&amp;lt;/kbd&amp;gt;是往下，&amp;lt;kbd&amp;gt;Shift&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;Tab&amp;lt;/kbd&amp;gt; 是往上。不過我後來裝了 &lt;code&gt;fzf-tab&lt;/code&gt; 後就覆蓋掉本來的選單了，所以我這裡就先註解掉。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zstyle &apos;:completion:*&apos; menu yes select
bindkey &apos;^[[Z&apos; reverse-menu-complete
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;fzf scripts&lt;/h3&gt;
&lt;p&gt;fzf 跟其他插件不太一樣，所以我這裡是直接用 &lt;code&gt;pacman&lt;/code&gt; 來管理，可以自己換成你使用的套件管理工具：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S fzf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這裡載入了 fzf 的一些腳本，可以在 fzf 中使用快捷鍵和自動補全，比如 &amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;R&amp;lt;/kbd&amp;gt; 可以搜尋前面輸入的字串，&amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;T&amp;lt;/kbd&amp;gt; 可以切換到上一個搜尋結果，&amp;lt;kbd&amp;gt;Ctrl&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;G&amp;lt;/kbd&amp;gt; 可以切換到下一個搜尋結果，以及其他的指令。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source /usr/share/fzf/key-bindings.zsh
source /usr/share/fzf/completion.zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;zinit&lt;/h3&gt;
&lt;p&gt;最後是 &lt;a href=&quot;https://github.com/zdharma-continuum/zinit&quot;&gt;zinit&lt;/a&gt; 的設定，zinit 是一個很好用的 Zsh 插件管理工具，可以自動安裝插件，並且可以在切換 Zsh 之間快速切換插件。我會看上它是因為這張表，不過畢竟我也剛入坑，就選了一個看起來簡單好設置，又挺輕量的管理工具來用了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;目前我裝了這些插件，大都蠻常見的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Aloxaf/fzf-tab&quot;&gt;fzf-tab&lt;/a&gt;: 為 Zsh 的補全功能提供模糊搜尋選項，方便快速選取。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-syntax-highlighting&quot;&gt;zsh-syntax-highlighting&lt;/a&gt;: 讓 Zsh 的指令及腳本文件高亮顯示，方便閱讀。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-autosuggestions&quot;&gt;zsh-autosuggestions&lt;/a&gt;: 自動填入命令行中的參數，提升命令執行效率。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-completions&quot;&gt;zsh-completions&lt;/a&gt;: 提供大量的 Zsh 補全功能，包括 git 和 npm 的補全。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-history-substring-search&quot;&gt;zsh-history-substring-search&lt;/a&gt;: 提供快速搜尋前面輸入的字串的功能，方便快速查找指令。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agkozak/zsh-z&quot;&gt;zsh-z&lt;/a&gt;: 提供 Zsh 的 z 指令，方便快速切換到不同的 Zsh 上下文。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;zinit light Aloxaf/fzf-tab
zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-history-substring-search
zinit light agkozak/zsh-z
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;加載和初始化命令補全&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;autoload -Uz compinit
compinit
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;完整 Zsh 設定檔（.zshrc）&lt;/h2&gt;
&lt;p&gt;:::note
有些硬編碼的路徑請換成自己的，還有自動生成的部分最好不要自己亂改，除非你知道自己在幹什麼。
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=1000
SAVEHIST=1000
bindkey -v
# End of lines configured by zsh-newuser-install

# The following lines were added by compinstall
zstyle :compinstall filename &apos;/home/yuuzi261/.zshrc&apos;
zstyle &apos;:completion:*:descriptions&apos; format &apos;[%d]&apos;
zstyle &apos;:completion:*&apos; list-colors ${(s.:.)LS_COLORS}
# End of lines added by compinstall

### Environmental Variables ###
export PATH=$PATH:/home/yuuzi261/.local/bin     # oh my posh

# &amp;gt;&amp;gt;&amp;gt; conda initialize &amp;gt;&amp;gt;&amp;gt;
# !! Contents within this block are managed by &apos;conda init&apos; !!
__conda_setup=&quot;$(&apos;/home/yuuzi261/miniconda3/bin/conda&apos; &apos;shell.zsh&apos; &apos;hook&apos; 2&amp;gt; /dev/null)&quot;
if [ $? -eq 0 ]; then
    eval &quot;$__conda_setup&quot;
else
    if [ -f &quot;/home/yuuzi261/miniconda3/etc/profile.d/conda.sh&quot; ]; then
        . &quot;/home/yuuzi261/miniconda3/etc/profile.d/conda.sh&quot;
    else
        export PATH=&quot;/home/yuuzi261/miniconda3/bin:$PATH&quot;
    fi
fi
unset __conda_setup
# &amp;lt;&amp;lt;&amp;lt; conda initialize &amp;lt;&amp;lt;&amp;lt;
### END of Environmental Variables ###

# oh my posh init
eval &quot;$(oh-my-posh init zsh --config /mnt/c/Users/Yuuzi/AppData/Local/Programs/oh-my-posh/themes/catppuccin_mocha_enhancement.omp.json)&quot;

# Completion
# zstyle &apos;:completion:*&apos; menu yes select
# bindkey &apos;^[[Z&apos; reverse-menu-complete

# fzf scripts
source /usr/share/fzf/key-bindings.zsh
source /usr/share/fzf/completion.zsh

### Added by Zinit&apos;s installer
if [[ ! -f $HOME/.local/share/zinit/zinit.git/zinit.zsh ]]; then
    print -P &quot;%F{33} %F{220}Installing %F{33}ZDHARMA-CONTINUUM%F{220} Initiative Plugin Manager (%F{33}zdharma-continuum/zinit%F{220})…%f&quot;
    command mkdir -p &quot;$HOME/.local/share/zinit&quot; &amp;amp;&amp;amp; command chmod g-rwX &quot;$HOME/.local/share/zinit&quot;
    command git clone https://github.com/zdharma-continuum/zinit &quot;$HOME/.local/share/zinit/zinit.git&quot; &amp;amp;&amp;amp; \
        print -P &quot;%F{33} %F{34}Installation successful.%f%b&quot; || \
        print -P &quot;%F{160} The clone has failed.%f%b&quot;
fi

source &quot;$HOME/.local/share/zinit/zinit.git/zinit.zsh&quot;
autoload -Uz _zinit
(( ${+_comps} )) &amp;amp;&amp;amp; _comps[zinit]=_zinit

# Load a few important annexes, without Turbo
# (this is currently required for annexes)
zinit light-mode for \
    zdharma-continuum/zinit-annex-as-monitor \
    zdharma-continuum/zinit-annex-bin-gem-node \
    zdharma-continuum/zinit-annex-patch-dl \
    zdharma-continuum/zinit-annex-rust

### End of Zinit&apos;s installer chunk

### zinit plug ###
zinit light Aloxaf/fzf-tab
zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-history-substring-search
zinit light agkozak/zsh-z
### end zinit plug ###

# Initialize compinit
autoload -Uz compinit
compinit
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>透過 Conda 在 Arch Linux 安裝 TensorFlow GPU 支援所需的 CUDA 以及其他依賴套件（其他 Linux 發行版也行）</title><link>https://blog.yuuzi.cc/posts/guides/install-tensorflow-on-arch-linux-with-gpu-support/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/install-tensorflow-on-arch-linux-with-gpu-support/</guid><description>這我折騰了一整天終於找到穩定又快速的方法了，如果你也對這個很頭痛就快來看看！</description><pubDate>Fri, 18 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;這次學到的教訓就是不要用 TensorFlow 跟 Keras，有問題絕對不是 Arch Linux 的問題，都是我太爛駕馭不了的問題（Ｘ。總之我試了一天終於找到省事又方便的方法了，中間經歷了不少彎路，結果其實意外的簡單，趕緊把這些經驗記錄下來避免忘記也看看能不能幫到有需要的人！&lt;/p&gt;
&lt;h2&gt;安裝顯示卡驅動&lt;/h2&gt;
&lt;p&gt;這一步網路上很多資料了，這邊就先跳過，加上這一次我是用 WSL 來做，所以驅動早就搞定了，如果你跟我一樣也是用 WSL，並且驅動也早就裝好的話，那就可以直接跳過這一步，真爽！不過要注意驅動不能太舊，不然到時候沒有支援你要的 CUDA 版本就笑不出來了。&lt;/p&gt;
&lt;p&gt;可以輸入下面的指令來確認驅動是否已經安裝，並且可以查看安裝的版本以及&lt;strong&gt;最高&lt;/strong&gt;支援的 CUDA 版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果驅動有正確安裝大概會出現這樣的畫面：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這裡有一篇很&lt;a href=&quot;https://ivonblog.com/posts/archlinux-install-nvidia-drivers/&quot;&gt;完整的教學&lt;/a&gt;可以看看他怎麼安裝驅動的，裝好再回來這裡，畢竟 CUDA 那些我不是很喜歡直接裝在系統環境，要切換版本比較不方便。&lt;/p&gt;
&lt;h2&gt;安裝套件/環境管理系統 Conda&lt;/h2&gt;
&lt;p&gt;Conda 是廣為人知的套件/環境管理系統，平常有在接觸 Python 的人應該不陌生，我們要透過他來管理不同專案要使用到的套件以及 CUDA、cuDNN 等等，方便在不同專案之間快速切換。&lt;/p&gt;
&lt;p&gt;:::note
我這裡會使用 Miniconda，它比 Anaconda 更輕量，只需要安裝最小需求的套件：&lt;a href=&quot;https://docs.anaconda.com/miniconda/&quot;&gt;Miniconda 文檔&lt;/a&gt;。
:::&lt;/p&gt;
&lt;p&gt;因為每個人的硬體以及作業系統不同，所以我這裡以 &lt;code&gt;Linux x86-64&lt;/code&gt; 的版本為例，其他版本請見官方文檔，其實我下面的指令也是從文檔複製過來的笑死：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安裝好後使用這個指令暫時進入 conda 環境：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/miniconda3/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然後透過指令初始化 shell，這樣每次開啟 shell 就能直接用了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda init --all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不想每次開啟都進入 base 環境，可以使用下面的指令關閉這個功能（選用）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda config --set auto_activate_base false
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安裝 TensorFlow、CUDA 以及其他依賴套件&lt;/h2&gt;
&lt;p&gt;接下就進入重頭戲了，我們必須確定 TensorFlow、CUDA、cuDNN 的版本是相容的，不然就會無法使用 GPU，首先，先確認要安裝的 TensorFlow 版本，所有版本與 CUDA 的對應關係都在 &lt;a href=&quot;https://www.tensorflow.org/install/source&quot;&gt;TensorFlow 文檔&lt;/a&gt;了，而且中文版已經年久失修，一定要切到英文版的才有比較新的資料，非常的坑，我這裡也列一下比較新的幾個。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TensorFlow 版本&lt;/th&gt;
&lt;th&gt;Python 版本&lt;/th&gt;
&lt;th&gt;CUDA&lt;/th&gt;
&lt;th&gt;cuDNN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2.17.0&lt;/td&gt;
&lt;td&gt;3.9 - 3.12&lt;/td&gt;
&lt;td&gt;12.3&lt;/td&gt;
&lt;td&gt;8.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.16.1&lt;/td&gt;
&lt;td&gt;3.9 - 3.12&lt;/td&gt;
&lt;td&gt;12.3&lt;/td&gt;
&lt;td&gt;8.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.15.0&lt;/td&gt;
&lt;td&gt;3.9 - 3.11&lt;/td&gt;
&lt;td&gt;12.2&lt;/td&gt;
&lt;td&gt;8.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.14.0&lt;/td&gt;
&lt;td&gt;3.9 - 3.11&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.13.0&lt;/td&gt;
&lt;td&gt;3.8 - 3.11&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.12.0&lt;/td&gt;
&lt;td&gt;3.8 - 3.11&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;8.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.11.0&lt;/td&gt;
&lt;td&gt;3.7 - 3.10&lt;/td&gt;
&lt;td&gt;11.2&lt;/td&gt;
&lt;td&gt;8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;選好版本後就可以開始著手安裝啦！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda create -n {env_name} python={py_version}
conda activate {env_name}
conda install nvidia/label/cuda-{cuda_version}::cuda
conda install -c conda-forge tensorflow={tf_version} cudnn={cudnn_version}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或是一行搞定：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda create -n {env_name} -c conda-forge python={py_version} nvidia/label/cuda-{cuda_version}::cuda cudnn={cudnn_version} tensorflow={tf_version}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CUDA 方面我是使用 &lt;a href=&quot;https://anaconda.org/nvidia/cuda&quot;&gt;nvidia 頻道&lt;/a&gt;的完整包，我試了一陣子的 &lt;a href=&quot;https://anaconda.org/conda-forge/cudatoolkit&quot;&gt;cudatoolkits&lt;/a&gt; 總是缺東缺西的，實驗下來這樣比較穩！這樣一來即使系統環境完全沒有 CUDA 等相關套件依然可以非常順暢的透過虛擬環境使用 TensorFlow + GPU，現在就來測試看看能不能抓到 GPU：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -c &quot;import tensorflow as tf; print(tf.config.list_physical_devices(&apos;GPU&apos;))&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上面一坨 info 基本上對結果沒有影響，主要看最下面那一行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[PhysicalDevice(name=&apos;/physical_device:GPU:0&apos;, device_type=&apos;GPU&apos;)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就是有抓到了，可以開始愉快的訓練模型囉，如果你有多張 GPU 這裡可能就會出現不止一個。其實這樣整理下來確實步驟挺簡單的，不過我沒有研究如果要 TensorRT 的話怎麼辦，我目前是沒有這個需求，如果以後有遇到再來研究好了，印象中 TensorRT 有授權的問題似乎比較麻煩。&lt;/p&gt;
</content:encoded></item><item><title>在 WSL2 中安裝 Arch Linux</title><link>https://blog.yuuzi.cc/posts/guides/arch-wsl-install/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/arch-wsl-install/</guid><description>TensorFlow 不支援 Windows + GPU，所以 Linux 啟動，既然要用就要用最香的 Arch Linux！</description><pubDate>Thu, 17 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;因為 TensorFlow 這傢伙從 2.11 版本開始不支援 Windows 使用 GPU 了，想要在本地用到我整天風扇轉都不屑轉的 4070 果然還是得 WSL 啟動，不過為什麼是選擇 Arch Linux 呢？那當然是因為 Arch-chan 很可愛...我是說 Arch Linux 十分的香，你都點進來這個文章了怎麼會想問理由呢？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.jpg&quot; alt=&quot;&quot; /&gt;
鎮樓圖，繪師：&lt;a href=&quot;https://www.pixiv.net/users/60562229&quot;&gt;Ravimo&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;啟用 Windows 功能&lt;/h2&gt;
&lt;p&gt;搜尋&lt;code&gt;Windows 功能&lt;/code&gt;，進入&lt;code&gt;開啟或關閉 Windows 功能&lt;/code&gt;介面，勾選&lt;code&gt;Windows 子系統 Linux 版&lt;/code&gt;以及&lt;code&gt;虛擬機器平台&lt;/code&gt;，按下確定後並重新啟動。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下來打開 PowerShell，執行下面的指令，來確保 WSL 的組件是最新的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wsl --update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因為 WSL 2 在安裝的過程中會遇到的問題比較少，所以這裡我們果然選擇使用 WSL 2，如果你想要使用 WSL 1，可以參考&lt;a href=&quot;https://wsldl-pg.github.io/ArchW-docs/How-to-Setup/&quot;&gt;文檔&lt;/a&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wsl --set-default-version 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;下載並安裝 ArchWSL&lt;/h2&gt;
&lt;p&gt;因為 Windows 沒有提供 Arch Linux 的 WSL 發行版本，所以這裡我們要用到 &lt;a href=&quot;https://github.com/yuk7/ArchWSL&quot;&gt;ArchWSL&lt;/a&gt; 這個項目，它可以幫我們少走很多條彎路。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;yuk7/ArchWSL&quot;}&lt;/p&gt;
&lt;p&gt;進入&lt;a href=&quot;https://github.com/yuk7/ArchWSL/releases&quot;&gt;下載頁面&lt;/a&gt;選擇要下載的版本，這裡我直接選擇用第一個方法，也就是用 zip 安裝，這應該是步驟最簡單的方式。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下來將載下來的 zip 檔案解壓縮到你要存放 WSL 的資料夾，像我這裡就是放在 &lt;code&gt;D:\AppData\WSL\Arch&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::important
資料夾的選擇上必須確保你有完整的訪問權限，不然會導致無法修改 &lt;code&gt;rootfs&lt;/code&gt;，比如 &lt;code&gt;C:\Program Files&lt;/code&gt; 就不可以用！
:::&lt;/p&gt;
&lt;p&gt;接下來執行 &lt;code&gt;Arch.exe&lt;/code&gt; 來安裝 Arch WSL！安裝成功的話會出現這個畫面，按下 &lt;code&gt;Enter&lt;/code&gt; 鍵關閉視窗。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;第一次安裝的話重新啟動 Windows Terminal 後通常就可以在選單找到我們剛剛安裝好的 ArchWSL 了，如果沒有自動新增的話也可以自己建立一份設定檔，我先稍微修改一下這個預設的設定檔，因為 Linux 的企鵝感覺不是這麼好看（Tux 愛好者：企鵝怎麼你了?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定檔的指令可以參考下面，請根據你實際的路徑跟檔案名稱調整：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:\Windows\system32\wsl.exe -d Arch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後就可以直接透過下拉式選單打開 ArchWSL 了，進去之後要進行一些簡單的設定即可開始使用。&lt;/p&gt;
&lt;h2&gt;設定 ArchWSL&lt;/h2&gt;
&lt;p&gt;首先先在終端機打開 ArchWSL，可以看到一開始是 &lt;code&gt;root&lt;/code&gt; 帳號，根據&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E6%9D%83%E9%99%90%E5%8E%9F%E5%88%99&quot;&gt;最小權限原則&lt;/a&gt;，我們需要創建一個帳號供日常使用，只有必要時才透過 &lt;code&gt;sudo&lt;/code&gt; 指令提升權限。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一步先為 &lt;code&gt;root&lt;/code&gt; 新增密碼：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;接下來建立 sudoers 文件:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;%wheel ALL=(ALL) ALL&quot; &amp;gt; /etc/sudoers.d/wheel
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;新增使用者&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;useradd -m -G wheel -s /bin/bash {username}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;為使用者建立密碼&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;passwd {username}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;關閉 ArchWSL，使用 powershell 進入到安裝 ArchWSL 的資料夾底下，執行下面的指令，將剛剛創建的使用者設為預設使用者&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Arch.exe config --default-user {username}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果出現報錯的話可以試試這個指令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.\Arch.exe config --default-user {username}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::info
如果預設使用者沒有成功變更，可以重新啟動電腦或參考&lt;a href=&quot;https://github.com/yuk7/ArchWSL/issues/7&quot;&gt;這裡&lt;/a&gt;。
:::&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;再次打開 ArchWSL，並初始化金鑰環，要使用 Arch Linux 的套件管理工具 pacman 的話這是必須的&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman-key --init
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman-key --populate
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Sy archlinux-keyring
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -Su
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到這裡就完成最基本的安裝了，接下來就依照自己的個人需求安裝套件吧！&lt;/p&gt;
&lt;h2&gt;使用 systemctl（可選）&lt;/h2&gt;
&lt;p&gt;可以參考&lt;a href=&quot;https://wsldl-pg.github.io/ArchW-docs/How-to-Setup/&quot;&gt;文檔&lt;/a&gt;或是&lt;a href=&quot;https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/&quot;&gt;微軟的 blog&lt;/a&gt;。&lt;/p&gt;
</content:encoded></item><item><title>永久免費啟用 Windows 的方法，一鍵啟用！</title><link>https://blog.yuuzi.cc/posts/guides/activate-windows/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/activate-windows/</guid><description>我...我只是要給虛擬機用而已，自己的主機有乖乖買正版喔，微軟把拔高抬貴手</description><pubDate>Sun, 08 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在 Github 上看到開源的啟用 Windows 工具，趕緊打開虛擬機試試，去掉討人厭的浮水印，這也是為了日後教學截圖品質的考量（被打。對不起了微軟把拔，但連虛擬機也用正版的話有點負擔不起 QwQ...&lt;/p&gt;
&lt;h2&gt;啟用 Windows&lt;/h2&gt;
&lt;p&gt;這個工具關聯到了 3 個 Github 儲存庫，不過最有關係的應該就是下面這個，但其實也不太重要，主要是進到&lt;a href=&quot;https://massgrave.dev/&quot;&gt;這個網站&lt;/a&gt;照著教學走就對了，下面附上圖文教學。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;massgravel/massgrave.dev&quot;}&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打開 &lt;code&gt;Powershell&lt;/code&gt;，不是 &lt;code&gt;CMD&lt;/code&gt; 要特別注意&lt;/li&gt;
&lt;li&gt;複製並貼上下面這行指令並執行&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;irm https://get.activated.win | iex
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;接下來等它一下就會跳出這個介面
&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;選擇你要啟用的方式，按下對應的按鍵，我這裡就選擇第一個，出現下面這個畫面就是成功囉
&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;接下來按任何按鍵回到本來的頁面，之後按 &amp;lt;kbd&amp;gt;5&amp;lt;/kbd&amp;gt; 確認一下啟用的狀態，確認啟用後按 &amp;lt;kbd&amp;gt;0&amp;lt;/kbd&amp;gt; 關閉視窗&lt;/li&gt;
&lt;li&gt;重新啟動電腦應該就可以看到 Windows 已經啟用囉
&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>紀錄一下重搞 oh my tmux 的過程</title><link>https://blog.yuuzi.cc/posts/notes/oh-my-tmux-record/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/oh-my-tmux-record/</guid><description>原生 oh my tmux 主題風格真的太強烈了，趁著懶癌不注意來修改一下</description><pubDate>Fri, 06 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近又看不下去實驗室電腦的原生 tmux / oh my tmux 主題了，不夠可愛的東西很難一直用下去，但之前遇到太多主題都有字體顯示不出來的問題，明明 &lt;a href=&quot;https://www.nerdfonts.com/&quot;&gt;Nerd Font&lt;/a&gt; 都裝了，也不知道是實驗室的電腦真的有什麼問題還是這就是用 powershell 連線過去的原罪，廢話太多了總之這次我盡可能的找到了比較順眼、顯示也比較沒 bug 的主題開搞。&lt;/p&gt;
&lt;h2&gt;安裝 tmux &amp;amp; oh my tmux&lt;/h2&gt;
&lt;h3&gt;tmux&lt;/h3&gt;
&lt;p&gt;畢竟是 Linux 的東西，果然又是套件管理工具出場了，這裡就以我實驗室電腦的 &lt;code&gt;Ubuntu&lt;/code&gt; 為例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install tmux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其他不同的 Linux 自行 Google 吧，既然都在玩 Linux 了這點事應該是小事一樁，安裝好後輸入 &lt;code&gt;tmux&lt;/code&gt; 執行，底部應該會有一條綠色的狀態列，這裡不展開細說 tmux 的具體用法，離題了。&lt;/p&gt;
&lt;h3&gt;oh my tmux&lt;/h3&gt;
&lt;p&gt;安裝 oh my tmux 的步驟都在儲存庫的 README 了：&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;gpakosz/.tmux&quot;}&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Requirements&lt;/code&gt; 那個欄位要特別注意，該有的都要有，然後如果有既有的設定檔記得備份，不要像我一樣勇往直前。安裝路徑有三個地方可以選，選自己喜歡的，這裡以根目錄為例，想安裝到其他地方就去 README 看：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd
git clone https://github.com/gpakosz/.tmux.git
ln -s -f .tmux/.tmux.conf
cp .tmux/.tmux.conf.local .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就安裝好了，可以開始來設定 oh my tmux。&lt;/p&gt;
&lt;h2&gt;設定 oh my tmux&lt;/h2&gt;
&lt;p&gt;:::caution
雖然 README 也有說但這裡特別提一下，所有設定檔的更改請在 &lt;code&gt;tmux.conf.local&lt;/code&gt; 或 &lt;code&gt;.tmux.conf.local&lt;/code&gt; 進行，不要動 &lt;code&gt;tmux.conf&lt;/code&gt; 或 &lt;code&gt;.tmux.conf&lt;/code&gt;，不然接下來你就只能靠你自己的聰明才智 debug 了！
:::&lt;/p&gt;
&lt;p&gt;接下來就修改 &lt;code&gt;tmux.conf.local&lt;/code&gt; 或 &lt;code&gt;.tmux.conf.local&lt;/code&gt; 來啟用自己喜歡的插件吧，因為我對 tmux 也不是說很熟，如果你也對 tmux 不熟的話我會建議啟用這個插件，它大致有以下這些功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用滑鼠滾輪查看歷史紀錄&lt;/li&gt;
&lt;li&gt;快速複製終端機內文字&lt;/li&gt;
&lt;li&gt;使用滑鼠調整分割頁面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;右鍵可以叫出上圖的選單，常用的功能都在上面了，基本使用上可以大幅減少打指令的機會，對於 tmux 小白來說一瞬間可以少記好幾條指令，超級方便，有兩種方式可以啟用，我推薦第二種一勞永逸。&lt;/p&gt;
&lt;h3&gt;第一種方法&lt;/h3&gt;
&lt;p&gt;使用前綴指令 &lt;code&gt;ctrl + b&lt;/code&gt; 或是 &lt;code&gt;ctrl + a&lt;/code&gt;，接下來輸入 &lt;code&gt;:&lt;/code&gt;，進入指令模式，接著輸入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:setw -g mouse on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就完成了，不過每次重啟都要重新輸入很不方便，直接寫進設定檔吧！&lt;/p&gt;
&lt;h3&gt;第二種方法&lt;/h3&gt;
&lt;p&gt;編輯 &lt;code&gt;tmux.conf.local&lt;/code&gt; 或 &lt;code&gt;.tmux.conf.local&lt;/code&gt; 檔案，裡面應該已經幫你寫好了，找到 &lt;code&gt;set -g mouse on&lt;/code&gt; 這行直接取消註解就 OK 了，如果沒有就自己加上。&lt;/p&gt;
&lt;p&gt;當然還有很多實用插件可以自由摸索，選擇自己需要的，我這裡就不多做介紹，畢竟我這次不是不滿意使用體驗，而是不滿意顏值啊！&lt;/p&gt;
&lt;h2&gt;更換 oh my tmux 的主題&lt;/h2&gt;
&lt;p&gt;終於進入正題了，這裡先列出一些我覺得還不錯看的主題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nordtheme
::github{repo=&quot;nordtheme/tmux&quot;}&lt;/li&gt;
&lt;li&gt;tokyo-night-tmux
::github{repo=&quot;janoamaral/tokyo-night-tmux&quot;}&lt;/li&gt;
&lt;li&gt;rose-pine
::github{repo=&quot;rose-pine/tmux&quot;}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這次我安裝的是 &lt;code&gt;rose-pine&lt;/code&gt;，不是因為我覺得它最好看，只是剛好這個主題對實驗室電腦來說比較沒 bug，然後套了我的 Windows Terminal 主題後視覺上沒有太大影響而採用，以後我應該還是去玩一下 WSL 或是灌個 Arch 來玩玩吧，最近看到很多 Arch rice 的影片有燒到我。&lt;/p&gt;
&lt;p&gt;雖然每個主題有些微差異，但不外乎基本支援透過 &lt;a href=&quot;https://github.com/tmux-plugins/tpm&quot;&gt;TPM&lt;/a&gt; 這個 tmux 插件管理工具來安裝，不過有些主題雖然也是透過 &lt;code&gt;TPM&lt;/code&gt; 安裝，但會跟 oh my tmux 衝突，要特別注意一下，對我就是在說你 &lt;a href=&quot;https://github.com/catppuccin/tmux&quot;&gt;Catppuccin&lt;/a&gt;！&lt;/p&gt;
&lt;h3&gt;安裝 TPM&lt;/h3&gt;
&lt;p&gt;安裝 TPM 其實也蠻簡單的，第一步先把整個儲存庫 clone 下來：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接著一樣編輯 &lt;code&gt;tmux.conf.local&lt;/code&gt; 或 &lt;code&gt;.tmux.conf.local&lt;/code&gt;，把下面這些指令放到設定檔的最下面。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# List of plugins
set -g @plugin &apos;tmux-plugins/tpm&apos;
set -g @plugin &apos;tmux-plugins/tmux-sensible&apos;

# Other examples:
# set -g @plugin &apos;github_username/plugin_name&apos;
# set -g @plugin &apos;github_username/plugin_name#branch&apos;
# set -g @plugin &apos;git@github.com:user/plugin&apos;
# set -g @plugin &apos;git@bitbucket.com:user/plugin&apos;

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run &apos;~/.tmux/plugins/tpm/tpm&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::important
這裡注意，不管以後加了什麼插件，這些東西都要保持在最底部，尤其是 &lt;code&gt;run &apos;~/.tmux/plugins/tpm/tpm&apos;&lt;/code&gt; 這行絕對要是最後一行！
:::&lt;/p&gt;
&lt;p&gt;然後重新載入 tmux 的設定&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# type this in terminal if tmux is already running
tmux source ~/.tmux.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果剛好沒有 tmux 在執行也可以直接殺掉 tmux server，很多時候莫名奇妙沒有套用都是重新啟動就好了，重新啟動可以解決 99%的問題（X&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tmux kill-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣一來就安裝好了，TPM 有 3 種特殊指令可以用：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; + &amp;lt;kbd&amp;gt;I&amp;lt;/kbd&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;從任何 git 儲存庫安裝新插件&lt;/li&gt;
&lt;li&gt;刷新 tmux 環境&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; + &amp;lt;kbd&amp;gt;U&amp;lt;/kbd&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更新插件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; + &amp;lt;kbd&amp;gt;alt&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;u&amp;lt;/kbd&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;刪除/解除安裝不在插件清單中的插件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;透過 TPM 安裝 tmux 主題&lt;/h3&gt;
&lt;p&gt;有了 TPM 安裝主題就會變得超級簡單，通常只要遵循該主題作者提供的設定檔複製貼上到 &lt;code&gt;tmux.conf.local&lt;/code&gt; 或 &lt;code&gt;.tmux.conf.local&lt;/code&gt;，然後透過上面介紹的 TPM 指令操作一下就可以了，以我這次安裝的 &lt;code&gt;rose-pine&lt;/code&gt; 為例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -g @plugin &apos;rose-pine/tmux&apos;
# ... alongside
set -g @plugin &apos;tmux-plugins/tpm&apos;
# To update plugin for future revisions or bug fixes, do the &quot;Prefix + U&quot; keycombo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一行就搞定安裝了，不過接下來的設定稍微比較麻煩一點，不同作者也是看心情寫註解，有時候不自己試試看也不知道那些設定具體是在幹麻，就只能看著 README 或文檔摸索，如果你也跟我一樣用 &lt;code&gt;rose-pine&lt;/code&gt; 的話，我這裡有我調整過的設定檔可以參考，再依照自己的喜好調整一下應該會比重頭來快一點點：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -g @plugin &apos;rose-pine/tmux&apos;
set -g @rose_pine_variant &apos;main&apos;

set -g @rose_pine_host &apos;on&apos; # Enables hostname in the status bar
set -g @rose_pine_date_time &apos;%H:%M&apos; # It accepts the date UNIX command format (man date for info)
set -g @rose_pine_user &apos;on&apos; # Turn on the username component in the statusbar
set -g @rose_pine_directory &apos;on&apos; # Turn on the current folder component in the status bar

set -g @rose_pine_window_separator &apos;   &apos; # Replaces the default `:` between the window number and name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;效果大概如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;總之這次就是簡單調整一下底部的狀態列，比原生的 tmux 一整條綠色或是 oh my tmux 預設那誇張鮮豔的配色來的好上不少，當然這絕對不是我最滿意的樣子，不過畢竟就實驗室電腦，也不用培養太多感情，至少現在看著它已經順眼不少！&lt;/p&gt;
</content:encoded></item><item><title>分享一個好看 Fastfetch 配置，經過修改後 Windows 也可以使用！</title><link>https://blog.yuuzi.cc/posts/notes/good-looking-fastfetch-configuration/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/notes/good-looking-fastfetch-configuration/</guid><description>改完之後雖然程式沒有半點進步但感覺整個人都不一樣了（不要瞎掰好嗎</description><pubDate>Tue, 03 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;雖然我上一篇才寫了一篇和 Neofetch 有關的文章，不過那其實是我以前寫然後搬來這裡的，最近跳槽到 Fastfetch 我覺得在 Windows 速度很可以啊，畢竟他是用 C 寫的，而 Neofetch 則是用 bash 實現的。這篇不會細講怎麼將 ASCII 藝術放入 Fastfetch，老實說我也還沒玩得很明白，暫且是透過 Python 腳本把以前用 jp2a 轉換的 ASCII 藝術改寫成 for Fastfetch 的，總之廢話不多說進入正題。&lt;/p&gt;
&lt;h2&gt;更新 (2024/10/15)&lt;/h2&gt;
&lt;p&gt;原作者把文給刪了，&lt;a href=&quot;https://www.reddit.com/r/GarudaLinux/comments/1dcq0dl/making_fastfetch_more_beautiful_linux/&quot;&gt;所以這裡放上新的連結&lt;/a&gt;，下面教學步驟的連結我也會一起換掉，如果比較喜歡作者原本的舊版，可以直接拉到最下面載我提供的版本來改。&lt;/p&gt;
&lt;h2&gt;安裝 Fastfetch&lt;/h2&gt;
&lt;p&gt;安裝 Fastfetch 很簡單，從自己的 OS 選擇自己喜歡的方式，我簡單瀏覽過看起來方法並不少，Fastfetch 的 Repo 位址 👇&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;fastfetch-cli/fastfetch&quot;}&lt;/p&gt;
&lt;h2&gt;設定 config&lt;/h2&gt;
&lt;p&gt;接下來就要設定 config 了，畢竟原版配置說不上醜，就是不夠優雅，不夠個性對吧，這裡我找到了一個&lt;a href=&quot;https://www.reddit.com/r/GarudaLinux/comments/1dcq0dl/making_fastfetch_more_beautiful_linux/&quot;&gt;由 reddit 用戶 aayush-le 寫好的配置&lt;/a&gt;，我覺得挺好看的，總之先照著他說的做，我這裡簡單翻譯成中文好了&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先到當前使用者的 &lt;code&gt;.config&lt;/code&gt; 資料夾裡面 → &lt;code&gt;/home/&amp;lt;your_username&amp;gt;/.config&lt;/code&gt;，如果沒找到就自己創一個&lt;/li&gt;
&lt;li&gt;如果在 &lt;code&gt;.config&lt;/code&gt; 資料夾裡面沒有看到 &lt;code&gt;fastfetch&lt;/code&gt; 資料夾，那就自己創一個 → &lt;code&gt;mkdir fastfetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;透過 fastfetch 提供的指令創建一個預設的 config 文件 → &lt;code&gt;fastfetch --gen-config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;移除預設的 config 文件 → &lt;code&gt;rm fastfetch/config.jsonc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;下載這個作著提供的 config 文件 → &lt;code&gt;wget https://raw.githubusercontent.com/xerolinux/xero-layan-git/main/Configs/Home/.config/fastfetch/config.jsonc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;重新啟動你的終端機&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這裡的指令都是 for Linux 的，當然 Windows 也基本兼容這些指令，如果沒有 &lt;code&gt;wget&lt;/code&gt; 的話也可以試試 &lt;code&gt;curl&lt;/code&gt;，都沒有的話就自己裝一下，其實方式百百種啦總之能下載下來到對的位置就 OK 了！經過這些步驟基本上在終端機輸入 &lt;code&gt;fastfetch&lt;/code&gt; 應該已經會有像是這樣的畫面了，借用原作者的圖，接下來就可以再依照自己的喜好客製化囉：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;為 Windows 做一些修改&lt;/h2&gt;
&lt;p&gt;如果你和我一樣是 Windows 用戶，你會看到有一些些不對勁，第一眼就是作業系統那一欄是 Linux 的圖標，不過這也很正常，畢竟這些圖標都是硬編碼的，我們只要自己改就好了，以下是我做了一些修改後的簡單 Demo：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;雖然原作者第一欄我不知道為什麼 Windows 沒辦法顯示，也可能是我這裡的問題，畢竟只要沒有值就不會顯示。我主要修改了 Linux 的圖標為 Windows 的，然後添加了一些原本沒有的欄位，每個欄位不喜歡的話註解掉就可以了，再來就是修復了 OS Age 的欄位，因為那欄是用 bash 指令寫的，Powershell 想當然而沒辦法跑，於是我改成了 Powershell 的指令，不過這個欄位畢竟是用指令跑的，多少會影響性能，如果很介意多等約 1 秒才能看到結果的話也可以自行移除，下面我就放上我修改的 config 文件供大家參考。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/Yuuzi261/7cea2f8fdd9a46e2b5651b1de44355ad&quot;&gt;📄 文件連結&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>使用自定義圖像作為 Neofetch 的 ASCII Logo</title><link>https://blog.yuuzi.cc/posts/guides/neofetch-with-ascii-logo/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/neofetch-with-ascii-logo/</guid><description>用 OS 的 logo 太沒個性了，肯定是要換的吧？</description><pubDate>Sun, 01 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;使用 jp2a 轉換圖片為 ASCII 藝術&lt;/h2&gt;
&lt;p&gt;單純使用 jp2a 轉換的話它會直接輸出到 terminal 上面，但上面的顏色訊息無法複製，所以我們要透過這個&lt;a href=&quot;https://gist.github.com/OpenBagTwo/54f209cbe8abbd04b9d5b0b880b6a8a2&quot;&gt;&lt;strong&gt;簡單的腳本&lt;/strong&gt;&lt;/a&gt;處理 jp2a 的輸出並寫入到一個 txt 檔案裡面，這個檔案就可以在之後被我們指定為 neofetch 的 ASCII logo。&lt;/p&gt;
&lt;p&gt;依照腳本原作者的指南，我們首先要在主機上準備好腳本和圖片 &lt;em&gt;(必須是 jpg 格式)&lt;/em&gt; ，接著輸入以下指令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jp2a logo.png --color-depth=4 --width=48 | ./jp2a2neofetch.py &amp;gt; neofetch_logo.txt
neofetch --ascii neofetch_logo.txt --ascii_colors 1 4 5 6 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一行指令的 &lt;code&gt;--color-depth&lt;/code&gt; 和 &lt;code&gt;--width&lt;/code&gt; 可以自行定義，依照自己的需求修改，如果發現圖片轉換後發現白色/黑色的背景也被轉換為文字，可以使用 &lt;code&gt;-i&lt;/code&gt; 加在 &lt;code&gt;jp2a&lt;/code&gt; 指令的後面。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;將預設 Logo 設為自定義的 ASCII 藝術&lt;/h2&gt;
&lt;p&gt;如果每次都要打這些參數，不免讓人覺得有些不方便，所以接下來我們要修改設置文件，將自定義的圖片作為預設。&lt;/p&gt;
&lt;p&gt;首先要找到設置文件，Linux 預設放在 &lt;code&gt;~/.config/neofetch/config.conf&lt;/code&gt;，Windows 則是 &lt;code&gt;%userprofile%\.config\neofetch\config.conf&lt;/code&gt;，找到之後編輯文件。&lt;/p&gt;
&lt;p&gt;找到 &lt;code&gt;image_source=&quot;auto&quot;&lt;/code&gt; 這行，將 &lt;code&gt;auto&lt;/code&gt; 改成自定義圖片的路徑就可以囉。這樣只打 &lt;code&gt;neofetch&lt;/code&gt; 也能顯示自定義的圖片了!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>不啟用 Windows 也能開啟深色主題的方法</title><link>https://blog.yuuzi.cc/posts/guides/darkmode-without-enable-windows/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/darkmode-without-enable-windows/</guid><description>聽起來是個很奇怪的需求，但我真的遇到了，順便紀錄在這裡</description><pubDate>Fri, 30 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;寫教學文要是沒有圖誰看的下去？Github 上的 README 要是一張圖都沒有我就失去耐心了！於是弄了一個 VM 讓我可以重現安裝或是設置之類的過程。因為淺色主題太亮了所以只要我能切深色主題就切深色主題，包括現在這個網站，要是網站是深色的圖片卻是淺色的自己看了也不爽，那簡單啊！把 VM 也弄成深色主題不就好了？說幹就幹．．．欸？Windows 沒啟用不能個人化？！於是我就去官網拿了半年的免費金鑰試著啟用 Windows，想當然而是沒成功不然就不會有這篇文章了。不過既然我只是要深色模式，那沒必要執著於啟用 Windows 吧？這個想法突然閃過腦門．．．&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;正文&lt;/h2&gt;
&lt;p&gt;查了一下發現只要修改註冊表就可以了，不過在註冊表裡慢慢找太累了，直接用指令比較省事！首先新增一個文字文件隨便命名，以 &lt;code&gt;.reg&lt;/code&gt; 結尾就行，比如我將他命名為 &lt;code&gt;darkmode.reg&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;:::important
注意副檔名必須是 &lt;code&gt;.reg&lt;/code&gt; 而不是 &lt;code&gt;.txt&lt;/code&gt; 喔，如果平常沒有顯示副檔名的人可能會不小心變成 &lt;code&gt;XXX.reg.txt&lt;/code&gt;
:::&lt;/p&gt;
&lt;p&gt;用任何文字編輯器開啟這個檔案，然後貼上下面這串指令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize]
&quot;AppsUseLightTheme&quot;=dword:00000000
&quot;SystemUsesLightTheme&quot;=dword:00000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;貼好後存檔並執行這個檔案，出現這個警告不要擔心，直接按是就可以了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;成功的話應該會出現這個提示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下來應該就可以看到某些東西已經變成深色的了，不過像是工具列之類的還是保持淺色，這時只要重新啟動就會全部正確套用了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>2024年的現在，安裝 Python 到底有多簡單？</title><link>https://blog.yuuzi.cc/posts/guides/install-python/</link><guid isPermaLink="true">https://blog.yuuzi.cc/posts/guides/install-python/</guid><description>之前寫過一篇新手向的安裝教學，這次就來寫寶寶向的吧，有手就行！</description><pubDate>Thu, 29 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;方法 1：直接從 Microsoft Store 安裝&lt;/h1&gt;
&lt;p&gt;對沒錯，Microsoft Store 裡可以直接安裝 Python，一鍵安裝連環境變數都幫你搞定，打開 Microsoft Store 搜尋 &lt;code&gt;python&lt;/code&gt;，就可以看到很多種版本可以選：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;至於要下載哪一版取決於你的需求，以及你所想要使用的套件的相依性，初學者的話也不用想太多，直接載最新的也行，想要穩定一點就載最新的前一版，這裡我就以 &lt;code&gt;3.11&lt;/code&gt; 為例：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;點進來後直接按 &lt;code&gt;取得&lt;/code&gt;，接著等它下載就可以了。安裝好後打開 &lt;code&gt;Powershell&lt;/code&gt;，輸入 &lt;code&gt;python -V&lt;/code&gt; 確認是否成功安裝，這裡可以看到它輸出 &lt;code&gt;3.11.9&lt;/code&gt;，和我們在商店選擇的版本一致。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下來輸入 &lt;code&gt;pip -V&lt;/code&gt; 來確認 pip 是否成功安裝，pip 是 Python 的軟體包管理系統，Python 很具代表性的一大特色就是有許多第三方的 package 可以下載，所謂站在巨人的肩膀上就是這麼一回事！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出現類似這種訊息就是代表成功囉！從商店下載的好處就是以往初學者如果從官網下載，一直按下一步的話，可能就會有環境變數沒加到啊、pip 沒一起下載之類的問題，從商店下載可以少走一些彎路。&lt;/p&gt;
&lt;h1&gt;方法 2：從官網下載並安裝 Python&lt;/h1&gt;
&lt;p&gt;2 年前有在 HackMD 寫過類似的文章了，趁著這個機會再載載看過了 2 年有什麼改變。&lt;/p&gt;
&lt;h2&gt;下載&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;搜尋 Python&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;進入 Python 主頁&lt;/strong&gt; 找到 &lt;code&gt;Downloads&lt;/code&gt; 點進去
&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;選擇版本&lt;/strong&gt; 雖然對於初學者來說安裝最新版也不會有太大的問題，加上寫文章的現在 &lt;code&gt;3.13&lt;/code&gt; 已經預發佈了，&lt;code&gt;3.12&lt;/code&gt; 理論上是非常穩定的，所以還是像我上面說的，取決於你的需求，這裡一樣以 &lt;code&gt;3.11.9&lt;/code&gt; 為例
&lt;img src=&quot;6.png&quot; alt=&quot;&quot; /&gt;
這個時候你會發現有很多選項，其實就是依照你的作業系統來選擇，我目前是使用 Windows x86-64 架構的作業系統，所以毫無懸念就是要選 Windows 64-bit 的選項，這裡選擇下載 &lt;code&gt;Windows Installer&lt;/code&gt;，也就是最常見的那種安裝檔，這裡我也會使用這個檔案作為接下來的示範&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;開始安裝&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;執行剛剛載下來的安裝檔
&lt;img src=&quot;7.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;勾選 &lt;code&gt;Add Python 3.exe to PATH&lt;/code&gt;
&lt;img src=&quot;8.png&quot; alt=&quot;&quot; /&gt;
:::important
對於初學者來說要編輯環境變數並不是這麼容易，這裡直接勾選讓程式自動幫你加
:::&lt;/li&gt;
&lt;li&gt;接下來選擇 &lt;code&gt;Customize installation&lt;/code&gt;，進行自定義安裝，&amp;lt;font color = red&amp;gt;並且在 pip 這欄打勾&amp;lt;/font&amp;gt;，如同上面所說，pip 是 Python 的軟體包管理系統，之後會很常用到，比較新版的 Python 安裝程式已經會預先幫你打勾了，其他的就看個人需求
&lt;img src=&quot;9.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;之後基本上一路 Next 即可，詳細設定這裡不一一細說，至於安裝位置的部分，用預設的路徑即可，除非你有特殊需求或路徑潔癖（有這種潔癖嗎？
&lt;img src=&quot;10.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;按下安裝就大功告成啦，如果是 Windows 用戶，這一步可能會出現 &lt;code&gt;Disable path length limit&lt;/code&gt; 選項，我會建議點選以免因為過深的資料夾嵌套導致程式無法正常運行
&lt;img src=&quot;11.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;li&gt;重新啟動電腦並輸入 &lt;code&gt;python -V&lt;/code&gt; 和 &lt;code&gt;pip -V&lt;/code&gt; 來確認安裝
&lt;img src=&quot;12.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;從官網下載安裝程式來安裝和兩年前差別不大，pip 預設打勾是初學者福音。不過作為一個有多年 Python 經驗的雜魚程式設計師，當專案一多需要的套件也就混亂了起來，每個套件相依的 Python 版本也不同，不同專案也可能需要相同但不同版本的套件，造成管理上的困難，這時候就輪到虛擬環境出場啦！之後有空應該會出一篇 miniconda 的教學，至於 Anaconda 太肥了我不喜歡，嬌小可愛的酪梨誰不愛呢？&lt;/p&gt;
&lt;p&gt;警察大人你聽我解釋．．．&lt;/p&gt;
</content:encoded></item></channel></rss>