<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://geoqiao.github.io/</id>
  <title>geoqiao's Blog</title>
  <updated>2026-04-04T08:08:32.641867+00:00</updated>
  <author>
    <name>geoqiao</name>
    <email>geoqiao@example.com</email>
  </author>
  <link href="https://geoqiao.github.io/" rel="alternate"/>
  <generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator>
  <subtitle>1. 目前是一名金融行业贷后策略分析师；这里是我的个人空间，记录一些想记录的。
2. 这个网页基于GitHub Pages &amp; GitHub Actions 自动部署。
3. 主体 main.py 自己完成，前端主题由AI生成。
</subtitle>
  <entry>
    <id>https://geoqiao.github.io/blog/2-excel-xue-xi-jing-yan-fen-xiang.html</id>
    <title>excel 学习经验分享</title>
    <updated>2026-03-21T09:06:17+00:00</updated>
    <content type="html"><![CDATA[<h2>描述</h2>
<ol>
<li>
<p>这是一个分享个人 excel 经验的文档。</p>
</li>
<li>
<p>不分享特定函数的使用方法；实际上，你可以在百度/谷歌轻松搜索到答案。</p>
</li>
<li>
<p>分享一些思路，这些思路可以用在 SQL 和 Python 的学习中。</p>
</li>
</ol>
<h2>函数与 <code>y=x+2</code></h2>
<p><code>y=x+2</code> 是一个非常简单的数学方程，如果我们给定符合格式的 X 的值，代入这个方程式，就可以得到期望的 Y 值。</p>
<p>例如：假设 <code>x=2</code>，则 Y = 2+2，即 Y = 4；但是，假设 <code>x=假设</code>，却得不到任何值。</p>
<p>这是因为，在这里变量 X 只能为一个数字格式，方程式才能被正确计算。</p>
<p>同理，excel<span class="pangu"></span>的函数也是如此，例如常用的<span class="pangu"></span>vlookup、xlookup、sumifs、if<span class="pangu"></span>等等，只要在单元格内输入 <code>=vlookup(函数要求的参数格式)</code>，即可得到期望的结果。你可以在<span class="pangu"></span>Google<span class="pangu"></span>或者百度搜索到函数的用法。
以此类推，excel<span class="pangu"></span>的任一函数都可以这样看待。当使用次数多了之后，便不用每次都去搜索参数格式。</p>
<h2>数据透视表</h2>
<p>数据透视表是一个数据分析工作中非常实用的工具。</p>
<h3>数据透视表优势</h3>
<ol>
<li>很多时候数据透视表的性能（运行速度）要好于使用函数的方式。</li>
<li>使用上不需要手动输入参数，只需要会使用鼠标<code>拖、拉、拽</code>三招就可以。</li>
<li>会了<code>拖、拉、拽</code>，就会了一半的<span class="pangu"></span>BI<span class="pangu"></span>工具，操作方式真的很像市面上所有的主流 BI 工具如<span class="pangu"></span>tableau、powerbi、finebi。</li>
</ol>
<h3>数据透视表操作流程</h3>
<ol>
<li>
<p>准备数据：首先需要准备好需要进行分析的数据，并将其放入 Excel 中。</p>
</li>
<li>
<p>选择数据透视表：在 Excel 中，选择需要进行分析的数据区域，然后在菜单栏中选择“插入”选项卡中的“数据透视表”。</p>
</li>
<li>
<p>设定数据源：在弹出的“数据透视表创建向导”中，选择“选择多个合适的数据源”选项，并将数据源区域的范围填入。</p>
</li>
<li>
<p>设定行、列及值：在“数据透视表字段列表”中，将需要分析的数据字段拖动到“行”、“列”、“值”区域中。</p>
</li>
<li>
<p>设定筛选器：可以在“数据透视表字段列表”中，将需要进行筛选的数据字段拖动到“筛选器”区域中，并进行筛选。</p>
</li>
<li>
<p>设定样式：根据需要，可以在“设计”选项卡中设定数据透视表的样式。</p>
</li>
<li>
<p>更新数据：当需要更新数据时，只需右键单击数据透视表并选择“刷新”即可。</p>
</li>
</ol>
]]></content>
    <link href="https://geoqiao.github.io/blog/2-excel-xue-xi-jing-yan-fen-xiang.html"/>
    <published>2023-07-15T02:54:59+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/3-with-sql-as-english.html</id>
    <title>with_sql _as_english</title>
    <updated>2026-03-21T09:06:07+00:00</updated>
    <content type="html"><![CDATA[<h2>描述</h2>
<ol>
<li>分享自己学习 SQL 的经验。</li>
<li><code>WITH 临时表名 AS 子查询</code> 是 SQL 中一个常用的语法，这篇分享会介绍这个语法。</li>
<li>SQL 很简单，只需要知道一些英文单词什么意思，就可以读懂。</li>
</ol>
<h2>英文单词列表</h2>
<p>select：选择<strong>哪些字段</strong>
from：从<strong>哪个表</strong>选择这段
where：从某个表中符合<strong>哪些条件的数据</strong>进行选择
left join：就是 excel 中的 vlookup</p>
<h2>用 excel 思维读 SQL 代码</h2>
<p>理解了以上的几个单词，你就可以读懂 SQL 代码了，比如如下的代码片段：</p>
<pre><code class="language-sql">SELECT
	table1.id
	,table2.name
FROM table1
LEFT JOIN table2
ON table1.id = table2.id
WHERE table1.column1 = &#x27;1&#x27;
</code></pre>
<p>在这个示例中，<code>table1</code>  和  <code>table2</code>  是两个不同的表，我们在 <code>table1</code> 中写了一个 <code>vlookup</code> ，这个公式以两张表中的 <code>id</code> 字段为条件关联，把 <code>table2</code>  中的 <code>name</code> 字段匹配到了 <code>table1</code> ，并且匹配完成后进行了一个筛选，只选择 <code>table1</code> 中 <code>column1</code> 字段为 <code>&#x27;1&#x27;</code> 的行。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/3-with-sql-as-english.html"/>
    <published>2023-07-15T03:09:11+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/4-guan-yu-li-shi.html</id>
    <title>关于历史</title>
    <updated>2026-03-21T09:06:25+00:00</updated>
    <content type="html"><![CDATA[<p>吃饭的时候突然想到，把历史比喻成一个车轮真的是生动形象且具体。</p>
<p>在某种角度上来看，这个车轮一直在向前滚动；另一种种角度上，车轮又在不断循环，车轮的材质变化，滚动的速度也不一样。</p>
<p>一些东西一直再改变，但一些东西一直没变。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/4-guan-yu-li-shi.html"/>
    <published>2023-07-15T03:17:05+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/5-kong-tiao-bo-xue-li-lun-de-ti-chu.html</id>
    <title>空调剥削理论的提出</title>
    <updated>2026-03-21T09:06:34+00:00</updated>
    <content type="html"><![CDATA[<h2>两大基本原理</h2>
<p><strong>首先</strong>，在开始阐述空调剥削理论之前，先来了解一下这个理论成立的两大基本原理：</p>
<p><strong>空调制冷原理</strong>和<strong>能量守恒</strong></p>
<h3>空调制冷原理</h3>
<p><strong>空调制冷原理</strong>是指空调制冷运作的原理。空调器通电后，制冷系统内制冷剂的低压蒸汽被压缩机吸入并压缩为高压蒸汽后排至冷凝器，室内空气不断循环流动，达到降低温度的目的。</p>
<p>轴流风扇吸入的室外空气流经冷凝器，带走制冷剂放出的热量，使高压制冷剂蒸汽凝结为高压液体。高压液体经过过滤器、节流机构后喷入蒸发器，并在相应的低压下蒸发，吸取周围的热量。同时贯流风扇使空气不断进入蒸发器的肋片间进行热交换，并将放热后变冷的空气送向室内。</p>
<p>说白了就是吸入的空气经过冷凝器把放出的热量排出到室外，再把冷却后的空气送到室内，以达到制冷的目的。</p>
<h3>能量守恒</h3>
<p><strong>能量守恒定律</strong>（energy conservation law）即热力学第一定律，是指在一个封闭（孤立）系统的总能量保持不变。其中总能量一般说来已不再只是动能与势能之和，而是静止能量（固有能量）、动能、势能三者的总量。</p>
<p>能量守恒定律可以表述为：一个系统的总能量的改变只能等于传入或者传出该系统的能量的多少。总能量为系统的机械能、热能及除热能以外的任何内能形式的总和。</p>
<p>如果一个系统处于孤立环境，即不可能有能量或质量传入或传出系统。对于此情形，能量守恒定律表述为：</p>
<blockquote>
<p>“孤立系统的总能量保持不变。”</p>
</blockquote>
<p>能量既不会凭空产生，也不会凭空消失，它只会从一种形式转化为另一种形式，或者从一个物体转移到其它物体，而能量的总量保持不变。能量守恒定律是自然界普遍的基本定律之一。</p>
<h2>那么胡思乱想来了</h2>
<p><strong>这两个原理往出一摆，聪明的可能就猜出来了</strong></p>
<p>能量守恒定律用在现在的空调制冷上面得出了一个可怕的结论：</p>
<blockquote>
<p>空调在长期来看不仅不利于制冷，反而导致了全球变暖！</p>
</blockquote>
<h3>为什么会变暖</h3>
<p>是这样，室内的那部分空气的热量排到室外，室外单位体积空气的热量就会升高，室外的总体热量升高。</p>
<p>室外是哪里？室外，指露天场所。也就是整个自然环境啊。整个自然环境的整体热量升高，那不就是全球变暖嘛！</p>
<p>这里大家可能又要问了，这室内和室外是一体的呀，都属于地球的生态环境的一部分呀。</p>
<p>是呀，可使用空调的时候为了保证制冷效果，都是关着门窗，这就造成了室内和室外环境的分离，空调是两者之间的唯一通路。所以，室内和室外就是地球这个孤立系统的两个不同部分。</p>
<h3>变暖和剥削有什么关系</h3>
<p>那全球变暖就变暖吧，空调咋又和剥削连到一块了？</p>
<p>是这样，按照现在的技术，当室外温度到<span class="pangu"></span>43<span class="pangu"></span>摄氏度以上的时候（来自百度百科），空调的制冷效果就会失效。那么可以想象，随着空调导致全球变暖愈发严重，当气温超过<span class="pangu"></span>43<span class="pangu"></span>摄氏度时，现有的空调就没用了。当然，不排除技术的进步。但是技术的进步也会导致成本的增加，那时候不是所有人都能用得起空调。</p>
<p>到此，也就得出了——空调剥削理论。</p>
<h2>这个理论有两层含义：</h2>
<p><strong>第一层是，技术的进步没能克服<span class="pangu"></span>43<span class="pangu"></span>摄氏度的气温，空调没用了。也就是空调作为一个没有生命，没有意识的机器，剥削了包括人类在内的地球全体。</strong></p>
<p><strong>第二层是，技术的进步克服了<span class="pangu"></span>43<span class="pangu"></span>摄氏度的气温，空调依然有作用，但使用成本大大增加。即能够使用空调的少数人类剥削包括用不上空调的其余人类在内的地球全体。</strong></p>
]]></content>
    <link href="https://geoqiao.github.io/blog/5-kong-tiao-bo-xue-li-lun-de-ti-chu.html"/>
    <published>2023-07-15T03:25:05+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/6-out-of-the-depth-of-misfortune-comes-bliss.html</id>
    <title>Out of the depth of misfortune comes bliss</title>
    <updated>2026-03-21T09:06:44+00:00</updated>
    <content type="html"><![CDATA[<p>大方无隅</p>
<p>大器晚成</p>
<p>大音希声</p>
<p>大象无形</p>
<p>大直若屈</p>
<p>大巧若拙</p>
<p>大辩若讷</p>
<p>大盈若冲</p>
<p>大成若缺</p>
<p>大勇若怯</p>
<p>大智若愚</p>
<p>大璞不完</p>
<p>时来运转</p>
<p>乐极生悲</p>
<p>苦尽甘来</p>
<p>物极必反  </p>
<p>否极泰来</p>
<p>否极泰来</p>
<p>否极泰来</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/6-out-of-the-depth-of-misfortune-comes-bliss.html"/>
    <published>2023-07-15T03:34:29+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/7-zong-dei-huo-zhe-ba.html</id>
    <title>总得活着吧？</title>
    <updated>2026-02-23T03:48:01+00:00</updated>
    <content type="html"><![CDATA[<p>世俗价值都是禁不起推敲的，推敲下去觉得活着没意义。  </p>
<p>你越想意义就越痛苦。所以人们只能有两个选择，肉体自杀和哲学自杀。</p>
<h2>哲学自杀</h2>
<p>哲学自杀就是不再想这个问题了，老子选择信仰个宗教，伊斯兰或者马克思，或者世俗主义，或者纯粹享乐比谁啪的多，比谁赚得多…总之信个世俗价值的东西。你可以随便吃饭时候问一下同桌人，生活的意义是啥，别人不是笑你就是说想这干嘛，但他们是无法给出答案的。这就是所谓哲学自杀。人如果不愿放弃，继续思考，结果必然面对找不到意义的尴尬，也就是加缪的名词‘荒谬’，很可能走向虚无。</p>
<h2>肉体自杀</h2>
<p>肉体自杀就是没办法不想意义的问题，但是想来想去没有答案，没有答案还是没有办法不想。最后，只能选择终身一跃，为了彻底暂停思考或者探索另一种可能。</p>
<h2>没有哲学自杀但还没走到肉体自杀？</h2>
<p>人如果不愿放弃，继续思考，结果必然面对找不到意义的尴尬，也就是加缪的名词‘荒谬’，很可能走向虚无。
在荒谬虚无走到底点，人的反抗激情就回归了。于是众多存在主义者就揭竿而起，擦，既然没有意义，老子就自己给自己定义意义。我得先做选择，选择后先去做，再去想。
但是自己定义意义会出问题，比如脑门被夹了，定义出奸淫幼童这种意义怎么办？于是萨特就提出了承担责任，也就是说，不管你选择了啥，顺着选择做了啥，都要承担对应责任。责任更像一种惩罚，奸淫幼童就要承担被道德、法律制裁的责任。存在主义者的要求就是人要为自己行动承担责任。</p>
<h2>知其不可为而为之</h2>
<p>就比如，生活给了你一巴掌，让你去死；你不仅不能听它的，还得回它一巴掌，再加一句：操！生命的意义就在这句粗口里。</p>
<p>知道人终有一死，但现在，我选择活。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/7-zong-dei-huo-zhe-ba.html"/>
    <published>2023-07-15T14:40:01+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/8-ji-yu-github-issues-de-ge-ren-blog-da-jian.html</id>
    <title>基于 GitHub issues 的个人 blog 搭建</title>
    <updated>2026-02-23T03:45:53+00:00</updated>
    <content type="html"><![CDATA[<h2>背景</h2>
<p>我最近碰到了以下问题：</p>
<ol>
<li>偶尔想写点东西，想有一个个人 blog</li>
<li>不懂代码：听到部署、买域名、备案、服务器这些词就头疼想逃避</li>
<li>不想花钱：买服务器、域名一年好几百甚至可能上千</li>
</ol>
<h2>解决方案</h2>
<p>基于<a href="https://github.com/yihong0618">yihong0618</a>的 gitblog 项目，在 GitHub 上搭建一个基于 issues 的个人博客。</p>
<p><strong>这个方法有以下几个优点：</strong></p>
<ol>
<li>完全免费：不会碰到域名、服务器、备案、一年多少钱这些问题</li>
<li>非常简单：会下载文件、上传文件、编辑文件就可以完成</li>
<li>自动化：大佬已经写好了一些函数和脚本，可以自动化完成一些操作</li>
</ol>
<p><strong>搭建前需要什么：</strong></p>
<ol>
<li>可以登录使用 GitHub </li>
<li>注册一个 GitHub 账号</li>
</ol>
<h2>操作教程</h2>
<p>操作教程可以参考这个<a href="https://zhuanlan.zhihu.com/p/400962805">知乎链接</a>，教程写的非常详细，部分页面<span class="pangu"></span>UI<span class="pangu"></span>因版本问题跟现在有点区别，但是基本不影响操作。</p>
<p>不过需要补充一点，按教程操作完成后需要把 GitHub Action 的读写权限打开。操作方式为 Settings - Actions - General - 勾选 Read and write permissions - save，如下图所示：</p>
<h2>结语</h2>
<p>以上就是全部内容，非常感谢 @yihong0618 老师的代码。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/8-ji-yu-github-issues-de-ge-ren-blog-da-jian.html"/>
    <published>2023-07-18T13:10:40+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/9-what-s-on-my-mac.html</id>
    <title>What's on my Mac</title>
    <updated>2026-02-23T03:45:43+00:00</updated>
    <content type="html"><![CDATA[<p>和大多数人一样，拿到一台<span class="pangu"></span>MacBook<span class="pangu"></span>第一件事就是找各种软件，以下是我目前在用的一些。它们的整体使用体验都很不错，且部分软件可以联动形成 workflow ，供大家参考。</p>
<h2>启动器类- Raycast</h2>
<p>目前免费的启动器类<span class="pangu"></span>app，可以启动、替代很多软件。自带的窗口管理功能替代 magnet、rectangle 等等窗口管理软件；自带的文件搜索功能替代了访达；还有一系列提升工作效率的插件。不了解的人可以<a href="https://telegra.ph/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%94%A8raycast%E6%9B%BF%E4%BB%A3%E4%BA%86alfred-07-17">参考这里</a>。</p>
<h2>自动切换输入法- Input Source Pro</h2>
<p>自动切换输入法。给不同 app、网站设置不同输入法。属于平时特别没有存在感，但一旦某天出 bug 就会想砸电脑的那种 app。</p>
<h2>截图-Shottr</h2>
<p>截图软件，小巧、免费、功能俱全。长截图、OCR、顺序标注，除了贴图，其他功能几乎都有，而且体验很棒。</p>
<h2>解压缩-Keka</h2>
<p>免费好用的解压缩软件。</p>
<h2>鼠标体验-Mac Mouse Fix</h2>
<p>开源、免费、改善<span class="pangu"></span>Mac<span class="pangu"></span>鼠标滚动体验。Mos<span class="pangu"></span>同样好用，但是似乎最新版本与 Shottr 长截图有冲突，故放弃。</p>
<h2>刘海管理-Bartender4</h2>
<p>刘海屏永远的痛，同类免费软件总是不如预期，故 618 打折入手正版<span class="pangu"></span>Bartender。</p>
<h2>RSS<span class="pangu"></span>源-RSSHub Radar</h2>
<p>一款可以发现当前网页<span class="pangu"></span>Rss<span class="pangu"></span>订阅的浏览器扩展，支持 Safari、Chrome。</p>
<h2>RSS<span class="pangu"></span>阅读- Netnewswire</h2>
<p>开源免费的 RSS 阅读器，我用它替代了 reeder4。主要原因是他支持<span class="pangu"></span>macOS<span class="pangu"></span>原生的翻译功能，选词右键就可以，reeder4<span class="pangu"></span>不行。</p>
<h2>文档日记写作- Typora + Obsidian</h2>
<p>markdown 编辑器。Typora 编辑体验好，Obsidian 管理文件好用。简单设置一下可以同步图片。</p>
<h2>GTD - Itsycal 、reminder</h2>
<p>Itsycal 是一款日历插件，可以在状态栏点击直接添加日程，和原生 Calendar 同步。有预定日期的会议、比较确定的日程通过 Itsycal 记录在日历里面，日期不确定的待办事项记在 Reminder。焦虑感和慌张感会少很多。</p>
<h2>浏览器插件</h2>
<p>常用的<span class="pangu"></span>Chrome<span class="pangu"></span>插件</p>
<p>屏蔽广告：uBlock Origin</p>
<p>多端、多浏览器密码同步：Bitwarden</p>
<p>rss<span class="pangu"></span>源：RSSHub Radar</p>
<p>Trancy：YouTube<span class="pangu"></span>神器、英语学习神器（YouTube<span class="pangu"></span>有很多公开课，比如<span class="pangu"></span>CS50P<span class="pangu"></span>等等）</p>
<h1>其他</h1>
<p>微信、telegram、VSCode、Chrome。。。</p>
<p>office 被我卸载了，因为想学 pandas，强迫自己用 pandas 读表</p>
<p>Report content on this page</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/9-what-s-on-my-mac.html"/>
    <published>2023-07-29T06:20:29+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/10-shottr-yuan-sheng-qing-qiao-qie-gong-neng-qiang-da-de.html</id>
    <title>Shottr- 原生、轻巧且功能强大的免费macOS截图工具</title>
    <updated>2026-02-23T03:45:13+00:00</updated>
    <content type="html"><![CDATA[<p>| <a href="https://shottr.cc/">Shottr<span class="pangu"></span>官网</a></p>
<ul>
<li>
<p><strong>截图</strong>：不得不说，作为截图工具的基础功能，shottr 并没有特别出彩的地方，UI 也谈不上漂亮。但是基础的区域截图、顺序标记都有，操作起来也非常直觉。而且在其他同类<span class="pangu"></span>app<span class="pangu"></span>中要付费的滚动截图功能也是免费的。</p>
</li>
<li>
<p><strong>打码</strong>：把打码功能单独拎出来说，是因为 shottr 的操作特别直觉。只要框选区域，按下<span class="pangu"></span>delete<span class="pangu"></span>键即可。最新出的<span class="pangu"></span>Blur Text<span class="pangu"></span>和<span class="pangu"></span>Erase Text<span class="pangu"></span>功能可以自动识别图中的文字，在这个模式里按下<span class="pangu"></span>delete<span class="pangu"></span>后只给文字打码。唯一的不足就是目前对中文文字识别似乎还不太精确，反馈<span class="pangu"></span>issue<span class="pangu"></span>后，开发者回复：“Text recognition is performed by macOS embedded OCR engine and its quality is out of my hands.”。</p>
</li>
<li>
<p><strong>OCR</strong>：不像其他截图<span class="pangu"></span>app，需要先截图，然后选中图中文字复制。shottr<span class="pangu"></span>只需要⌥+T<span class="pangu"></span>框选需识别区域，文字便会自动复制到剪贴板。谁身边还没有一群就喜欢发图片，但从不考虑你需要复制图中手机号/ID<span class="pangu"></span>的同事呢？</p>
</li>
<li>
<p><strong>另外</strong>：不管截图还是<span class="pangu"></span>OCR，内容都会保存在剪贴板中。即时使用的内容可以直接粘贴，非即时使用的内容也可以搭配剪贴板工具进行管理。因为我的剪贴板内容管理需求并不高，所以<a href="https://telegra.ph/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%94%A8raycast%E6%9B%BF%E4%BB%A3%E4%BA%86alfred-07-17">使用<span class="pangu"></span>Raycast</a>的 clipboard 功能就完全够用了。</p>
</li>
<li>
<p><strong>贴图</strong>。就是把图片钉在屏幕最上层</p>
</li>
</ul>
<p>整体体验下来，我认为 shottr<span class="pangu"></span>非常适合经常需要<strong>对截图进行简单编辑</strong>或者经常使用<strong>OCR<span class="pangu"></span>功能</strong>的朋友，shottr 能轻松满足你的需求。而且，向开发者邮件反馈<span class="pangu"></span>issue，开发者回复都非常积极。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/10-shottr-yuan-sheng-qing-qiao-qie-gong-neng-qiang-da-de.html"/>
    <published>2023-07-29T06:28:23+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/11-python-huan-jing-an-zhuang-anaconda-wei-li.html</id>
    <title>Python环境安装-Anaconda为例</title>
    <updated>2024-05-15T16:06:43+00:00</updated>
    <content type="html"><![CDATA[<p>学习 Python 第一步就是需要安装一个 Python 环境，这可劝退了大部分人。</p>
<h2>安装 Python 环境的几种传统方式</h2>
<ol>
<li>系统自带，直接用系统的。比如 macOS 一般自带 Python3。</li>
<li>终端使用 Homebrew 类似的包管理工具安装。安装后自己修改路径，安装需要使用的 Python 库。一般成功后终端输入<code>python3</code>就可以成功进入 Python 环境了。</li>
<li><a href="https://www.python.org/">Python 官网</a>最直接的方式，甚至官网也有详细的安装教程。</li>
</ol>
<p>以上几种方式，对于已有编程经验或者计算机基础知识的人来说，完全可以，可操作空间极大，完全可以自定义一个个性化的 Python 环境。</p>
<p>但是对于刚入门的小白，我以重装系统的惨痛教训建议：不要使用以上的方法安装 Python！</p>
<h3>为什么不推荐？</h3>
<p>因为终端操作有一定门槛，新手第一次安装遇到报错很容易直接劝退；就算折腾一番安装好了，后续各种后续看不懂的终端命令也够折磨人的了。</p>
<blockquote>
<p>人的焦虑和恐惧来自于没有安全感，对工具的掌控程度越高，安全感越多</p>
</blockquote>
<p>我也不知道我怎么就安装了好几个版本的 Python，Google 搜如何解决，随便在某 code 网站复制了一个命令，然后，电脑就什么都没了，重装系统都进行不下去，最后只能求助于天才吧。</p>
<h2>新手友好的 Python 环境安装-Anaconda</h2>
<p>作为 95 后，小时候没少玩 DNF、穿越火线、英雄联盟。那时候还不像现在网速这么快，每次更新加载都很慢，每次等待都想踹主机。但我家里穷，只敢心里想想不敢真的踹。那每次大更新我都直接卸载重装。</p>
<p>对于安装游戏、卸载游戏我相当在行，想安装在 D 盘，绝不会让游戏安装到 C 盘。</p>
<h3>为什么讲到这个呢？</h3>
<p>因为<strong>安装 Anaconda 的过程</strong>，就像给电脑安装游戏一样简单。</p>
<ol>
<li>找到<a href="https://www.anaconda.com/">Anaconda 官网</a></li>
<li>下载安装包</li>
<li>安装安装包（就是屏幕上弹出一个框框，就是需要一直点下一步的那个熟悉的框框</li>
<li>选择喜欢的编辑器，新建<code>.ipynb</code>文件，kernel 选择前面带 base 的就行</li>
<li>大部分库基本都有，比如 pandas、numpy 等等，不需要二次手动安装</li>
</ol>
<h2>用什么编辑器呢？</h2>
<p>说实话很多编辑器都很好用，但我们的原则是必须简单、免费。</p>
<p>那就有两个选择：</p>
<p>一个是 jupyter notebook ，很适合新手。写一行、运行一行，非常好入门。</p>
<p>另一个是 VSCode，可以安装 jupyter notebook 插件，以及 Python 的语法高亮插件。我个人感觉要比纯粹的 jupyter notebook 功能更强大，使用体验也更好。</p>
<p>我自己是在用 VSCode，因为 VSCode 创建文件夹、管理文件夹的方式跟在资源管理器/访达里面创建删除的体验没啥区别，非常直觉。</p>
<h2>总结</h2>
<p>以上就是全部内容，其实跟标题相关的就四五行。具体安装教程没有写，是因为真的和小时候下载安装游戏的流程一模一样。</p>
<p>如果过程中碰到什么问题，可以及时 Google 搜索。当然，如果你愿意的话，可以直接在这个 issue 下面评论，我会尽快回复的。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/11-python-huan-jing-an-zhuang-anaconda-wei-li.html"/>
    <published>2023-07-30T11:09:46+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/12-zhong-qi-qing-yong-obsidian.html</id>
    <title>重器轻用-Obsidian</title>
    <updated>2026-02-23T03:45:00+00:00</updated>
    <content type="html"><![CDATA[<h2>什么是 Obsidian</h2>
<p>Obsidian 是一个个人知识管理和笔记应用程序，它使用<strong>Markdown</strong>语法来编写和格式化笔记，帮助用户组织、链接和探索知识。它支持<strong>双向链接</strong>、标签、搜索和<strong>插件扩展</strong>，并且完全本地化存储，让用户轻松构建和管理一个互相关联的知识网络。</p>
<p>总结下来三个优点：</p>
<ol>
<li>Markdown 语法：简单排版秒杀 Word、Notes、OneNote 等一众软件</li>
<li>双向链接：在笔记与笔记之间关联</li>
<li>插件扩展：是的，甚至可以使用插件搭建一个本地版本的 Notion</li>
</ol>
<h2>为什么使用 Obsidian</h2>
<p>总结下来有以下几个原因：</p>
<ol>
<li>有时候脑子里有些奇怪的想法，想记录下来，类似 flomo 那种</li>
<li>有时候想写一点东西，分享自己的经验、记录自己。</li>
<li>不想使用在线服务（想法天马行空，不想被审查</li>
</ol>
<p>恰好，Obsidian 完全满足以上需求：</p>
<ol>
<li>完全本地，想跨设备同步可以使用 iCloud</li>
<li>有类 flomo 插件，完全可以当作本地版本的 flomo 使用</li>
<li>玩法花样多，想折腾也有折腾空间</li>
</ol>
<h2>我如何使用 Obsidian</h2>
<p>我使用工具类 app 有个特点，在一开始喜欢折腾，恨不得把所有功能都试一遍、所有主题都换一遍；在熟悉之后，又进行瘦身，把不用的功能都关掉，只保留最常用的几个功能。</p>
<p>以下是我现在的使用配置：</p>
<ol>
<li>不使用模板：因为使用模板需要不定时维护，也许突然想改、优化，这很消耗精力，这让我没办法专心记录</li>
<li>仅安装 memos、PanGu 插件：memos 插件可以把 Obsidian 变成一个本地版 flomo，随时随地记录灵感；PanGu 插件可以优化排版（使文章中的英文字母单词前后增加空格</li>
<li>双向链接：不定期更新以写完文章的双向链接</li>
</ol>
<p>OK，这就是我的全部用法了。</p>
<p>Obsidian 很强，如果你想用它替代 Notion、Xmind、白板工具、PPT、稍后读等等，都是可以实现的。但是，这些功能对于普通用户来说都很重，消耗太多精力。</p>
<p>我认为最重要的是：精力集中在<strong>使用工具</strong>，而不是<strong>如何使用工具</strong>上。</p>
<p>对比 Notion，想用得好，自己又得做产品经理，又得做开发，搞一个模板可能没用几次可能就有新场景需要满足，又要优化模板，最后成长的架构思维和设计能力，这是我不想从一个<strong>知识管理</strong>软件上体验到的。</p>
<p>Obsidian 给了我一个可以重器轻用的选择，这非常重要。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/12-zhong-qi-qing-yong-obsidian.html"/>
    <published>2023-08-19T07:57:20+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/13-wo-de-di-yi-ge-wan-zheng-de-ji-qi-xue-xi-xiang-mu.html</id>
    <title>我的第一个完整的机器学习项目-Titanic总结</title>
    <updated>2024-05-15T16:06:28+00:00</updated>
    <content type="html"><![CDATA[<h2>背景</h2>
<p>最近一直在学习<span class="pangu"></span>Python，尝试使用<span class="pangu"></span>Python<span class="pangu"></span>解决一些工作上的问题。这里记录参加这次比赛的心得总结，并会给出我的<a href="https://github.com/geoqiao/Python_DA_100_day/blob/main/kaggle_competition/titanic.py">代码示例(rank：top16%)</a></p>
<p>Titanic<span class="pangu"></span>是一个机器学习的入门级分类问题的比赛，数据集记录了<span class="pangu"></span>titanic<span class="pangu"></span>乘客的一些信息如性别、票价、船舱等级等信息。数据集被分成<span class="pangu"></span>train_data 和 test_data<span class="pangu"></span>两部分。参赛者需要根据<span class="pangu"></span>train_data<span class="pangu"></span>的数据信息，利用模型对数据集进行学习，并且预测<span class="pangu"></span>test_data<span class="pangu"></span>中乘客是否最终幸存。</p>
<p>titanic<span class="pangu"></span>数据集的优势是：</p>
<ol>
<li>数据相对干净，没有特别复杂的数据清理难度</li>
<li>相对简单，可以体验<span class="pangu"></span>machine learning<span class="pangu"></span>项目的全流程</li>
<li>比赛不会关闭，可以多次迭代提交</li>
<li>官方有详细的置顶示例项目，基本上如何参加比赛、提交代码、提交预测都有提到，对<span class="pangu"></span>kaggle<span class="pangu"></span>新手十分友好</li>
<li>简单，不会劝退机器学习新手</li>
</ol>
<h2>比赛过程</h2>
<p>整个比赛过程，我总共提交了三次，以下是我的参赛过程。</p>
<ol>
<li>
<p>第一次提交-熟悉比赛流程：<br />
在第一次提交之前，我决定使用<span class="pangu"></span>XGBoost<span class="pangu"></span>模型来熟悉比赛的整体流程。这有助于我了解数据集的特征、目标变量以及评估指标。熟悉比赛流程对于理解后续的模型选择和优化非常重要。</p>
</li>
<li>
<p>第二次提交-尝试随机森林：<br />
在第二次提交时，我决定尝试随机森林模型。然而，结果并不如第一次提交的好。这个经验教会了我，同一模型在不同数据集上的表现可能会有所不同。因此，在机器学习项目中，尝试多个模型是一种明智的策略，这样可以找到最适合数据集的模型。</p>
</li>
<li>
<p>第三次提交-模型清理与比较：<br />
根据前两次提交的结果，我意识到模型可能受到了一些问题的影响。因此，我决定对数据进行更多清理工作，包括处理缺失值、处理异常值、one-hot<span class="pangu"></span>编码、字符转数字等。尝试决策树、随机森林和支持向量机（SVM）等不同模型，并比较它们的评分结果。通过这些比较，我能够更好地理解不同模型的优缺点，并选择最合适的模型进行后续优化。</p>
</li>
<li>
<p>第三次提交-参数优化：<br />
在比较了不同模型后，我选择了决策树模型，并使用网格搜索方法进行参数优化。参数优化可以帮助我们找到最佳的参数组合，从而提高模型的性能。通过不断尝试不同的参数组合，我成功地提高了模型的准确性。</p>
</li>
<li>
<p>排名提升：<br />
通过应用上述经验，成功地将排名从初始的<span class="pangu"></span>12000<span class="pangu"></span>名提升到<span class="pangu"></span>2300<span class="pangu"></span>名。这个过程中，我学会了如何有效地处理数据、选择适当的模型以及优化参数。不仅如此，我还学会了如何利用<span class="pangu"></span>Kaggle<span class="pangu"></span>平台上的资源和社区，获取更多有关机器学习的知识和技巧。</p>
</li>
</ol>
<h2>总结收获</h2>
<ol>
<li>XGBoost<span class="pangu"></span>真的很强，大部分数据集可以先用<span class="pangu"></span>XGBoost<span class="pangu"></span>跑一遍试试水。
a. 会自己处理缺失值，我习惯使用<span class="pangu"></span>seaborn<span class="pangu"></span>的<span class="pangu"></span>heatmap<span class="pangu"></span>看有无缺失值，有些列如果缺失值很少的话会很难看到。
b.快且效果好，相对与其他模型需要适当调整参数来说，xgboost<span class="pangu"></span>闭眼跑都能获得不错的效果</li>
<li>对于<span class="pangu"></span>one-hot<span class="pangu"></span>处理特征、字符标签转数字等场景，pandas<span class="pangu"></span>有成熟的方法，想象中很麻烦的操作其实只需要一行代码。</li>
<li>在<span class="pangu"></span>test_data<span class="pangu"></span>没有标签的情况下，训练集也可以二次拆分为训练集和测试集，用来在比较模型在不同训练集的表现。</li>
<li>当然，引入<span class="pangu"></span>KFold 和 cross_val_score<span class="pangu"></span>也可以解决问题。</li>
</ol>
<h1>下一步计划</h1>
<ol>
<li>将学习到的经验应用的工作中的分类问题：预测客户是否会按时还款</li>
<li>Python<span class="pangu"></span>基础：写干净的代码真的很重要，比如这个代码示例，第二次看我已经优点头疼了，函数为什么要那么定义。</li>
<li>写一篇机器学习相关概念的解释<span class="pangu"></span>blog，例如：kmeans、SVM、随机森林、决策数、XGBoost、</li>
</ol>
]]></content>
    <link href="https://geoqiao.github.io/blog/13-wo-de-di-yi-ge-wan-zheng-de-ji-qi-xue-xi-xiang-mu.html"/>
    <published>2023-08-31T13:47:47+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/14-coke-machine-challenge.html</id>
    <title>Coke Machine Challenge </title>
    <updated>2024-05-15T16:05:43+00:00</updated>
    <content type="html"><![CDATA[<h2>什么是 Coke Machine</h2>
<p>Coke Machine 是<a href="https://cs50.harvard.edu/python/2022/">CS50P</a>课程中 loop 章节的其中一个课后练习，这个课后练习需要使用 Python 语言中的 loop 语法实现一个可乐售卖机，具体要求如下：</p>
<blockquote>
<p>Suppose that a machine sells bottles of Coca-Cola (Coke) for 50 cents and only accepts coins in these denominations: 25 cents, 10 cents, and 5 cents.</p>
<p>In a file called <code>coke.py</code>, implement a program that prompts the user to insert a coin, one at a time, each time informing the user of the amount due. Once the user has inputted at least 50 cents, output how many cents in change the user is owed. Assume that the user will only input integers, and ignore any integer that isn’t an accepted denomination.</p>
</blockquote>
<p>实际上，这是一个很简单的实现，但是我在这里被困了 2 个小时，这里重新记录一遍过程，当作<strong>错题集</strong>。</p>
<h2>任务拆解</h2>
<ol>
<li>假设输入只有 25、10、5 几种情况，且只输入整数格式，忽略任何不符合要求的数字</li>
<li>文件名为 coke.py</li>
<li>提示用户投入一枚硬币，每次都要通知应付金额</li>
<li>一旦用户投入的金额大于等于 50，输出找零金额</li>
</ol>
<h2>代码实现</h2>
<h3>初始化</h3>
<p>可乐需要 50 美分；一开始没有任何硬币投入；投入的硬币只有三种情况；提示用户可乐的价格。</p>
<p>代码如下：</p>
<pre><code class="language-python">amount_due = 50
change = 0
coin_list = [5,10,25]
print(f&quot;Amount Due: {amount_due}&quot;) # 告诉客户coke价格
</code></pre>
<h3>付费环节</h3>
<p>由于条件限制，用户无法一次投入 50 美分，需要多次投入（循环），每次都要提醒用户还要投多少钱。</p>
<pre><code class="language-python">while amount_due &gt; 0: # 循环开始的条件，如果用户还需要投的钱大于0，则说明钱还不够
    coin = input(&quot;Insert a coin (25, 10, or 5): &quot;)
    # 这里用try 语句来避免用户输入一些无法转换为整数的文本内容
    try:
        coin = int(coin)
    except ValueError:
        print(&quot;Invalid coin&quot;)
        continue
    # if语句用来判断用户投入的硬币是否符合要求
    if coin in coin_list:
        amount_due -= coin # 总共需要投入的减去已经投入的就是还需要投入的
        change += coin # 这里用来统计用户总共投入的多少
        print(f&quot;Amount Due: {amount_due}&quot;)
    else: # 如果用户投入的硬币不符合要求，重新提示可乐价格
        print(&quot;Amount Due: 50&quot;)
</code></pre>
<h3>付费结束之后</h3>
<p>付费结束之后，有可能刚好投入了 50 美分，但也有可能客户给多了，需要给用户找零，代码如下：</p>
<pre><code class="language-python"># 还需要付费金额小于等于0，即付够钱了
# 仍需付费金额的绝对值，即为需要找零的钱
if amount_due &lt;= 0:
    print(f&quot;Change Owed: {abs(amount_due)}&quot;)
</code></pre>
<h2>完整代码</h2>
<p>把以上代码优化一下，当 coke.py 当作脚本运行是可以处罚，但是当 import 到其他 Python 文件中则不会触发：</p>
<pre><code class="language-python">def coke():
    amount_due = 50
    change = 0
    coin_list = [5, 10, 25]
    print(f&quot;Amount Due: {amount_due}&quot;)

    while amount_due &gt; 0:
        coin = input(&quot;Insert a coin (25, 10, or 5): &quot;)
        try:
            coin = int(coin)
        except ValueError:
            print(&quot;Invalid coin&quot;)
            continue

        if coin in coin_list:
            amount_due -= coin
            change += coin
            print(f&quot;Amount Due: {amount_due}&quot;)
        else:
            print(&quot;Amount Due: 50&quot;)

    if amount_due &lt;= 0:
        print(f&quot;Change Owed: {abs(amount_due)}&quot;)

if __name__ == &quot;__main__&quot;:
    coke()
</code></pre>
<p>重写一遍才发现，<code>change</code>这个变量好像根本没用。</p>
<p>本来是想记录一下用户投入了多少美分，然后用总共投入的钱减去可乐的价格，就是需要找零的钱。现在看来这个变量完全可以去掉，从而使代码更加简洁。</p>
<p>我就不删了，希望之后重看的时候还能发现这个不完美的地方。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/14-coke-machine-challenge.html"/>
    <published>2023-09-03T13:02:25+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/15-zong-you-yi-xie-app-zhi-neng-windows-yong.html</id>
    <title>总有一些 app 只能 Windows 用</title>
    <updated>2024-05-26T08:43:17+00:00</updated>
    <content type="html"><![CDATA[<p>总有一些 app 只有 Windows 版本，最近对象就碰到这样一个问题，不得已只能安装一个虚拟机了。</p>
<h2>结论</h2>
<ol>
<li>我最终选择了 VMware</li>
<li>现在体验最好的虚拟机还是 PD，如果有钱可以无脑选择 PD</li>
<li>VMware 也很强，丝滑感跟 PD 还有差距，但是胜在个人使用免费，且功能够用。</li>
</ol>
<h2>为什么选择 VMware？</h2>
<ol>
<li>PD 太贵，破解太麻烦，macOS 每出一个大版本基本都要重新购买一次</li>
<li>VMware 已经支持 M 系列芯片</li>
<li>VMware 个人版本免费</li>
<li>VMware tech preview 版本已经支持 macOS 与虚拟机之间互相拖拽文件、复制粘贴</li>
</ol>
<h2>安装教程</h2>
<p>安装教程很简单，但是相比 PD 麻烦一点。这里推荐这个<a href="https://youtu.be/vtck5BVjVHM?si=nsNpgXIZAT-QihfH">教程</a>，基本讲的很详细，需要注意的是，如果有拖拽文件、复制粘贴的需求，需要下载 tech preview 版本。其余操作都一样。</p>
<p>需要关注以下几个点，大家在安装的时候可以注意一下，会节省很多时间：</p>
<ol>
<li>下载 VMware 的时候需要关闭 clashx pro 的增强模式。否则会导致安装后 VMware 的网络功能失效。其他代理工具没试过，暂不知道是否 surge 等会不会出现同样的问题。</li>
<li>使用 Google 搜索 VMware tech preview 官网下载。因为关闭增强模式后终端没有代理，Homebrew 等工具无法下载。</li>
<li>视频中提到的：镜像安装开始的时候一定要 Enter 跳过；无网络链接那一步使用快捷键调出命令行；虚拟机安装完成后安装 VMware tools 为虚拟机安装驱动。</li>
</ol>
<h2>相关链接</h2>
<p>VMware tech preview 下载：<a href="https://customerconnect.vmware.com/downloads/get-download?downloadGroup=FUS-TP2023">Download VMware Fusion Public Tech Preview 2023</a></p>
<p>VMware 正式版下载：<a href="https://www.vmware.com/cn/products/fusion/fusion-evaluation.html">下载 VMware Fusion | VMware | CN</a></p>
<p>安装教程：<a href="https://youtu.be/vtck5BVjVHM?si=nsNpgXIZAT-QihfH">YouTube</a></p>
]]></content>
    <link href="https://geoqiao.github.io/blog/15-zong-you-yi-xie-app-zhi-neng-windows-yong.html"/>
    <published>2023-09-24T14:02:41+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/16-vim-don-t-be-afraid.html</id>
    <title>Vim？ Don't be afraid ！</title>
    <updated>2024-05-15T16:04:50+00:00</updated>
    <content type="html"><![CDATA[<p>作为一名初学者，遇到问题时经常 Google 相关教程。不可避免的，某些教程默认读者会使用 Vim。</p>
<p><code>vim ~/.zshrc</code> 一旦<code>ENTER</code>按下去，就完蛋了。这他妈什么界面？我的终端怎么变成这样，什么命令都无法输入？我该怎么返回上一步？直接退出的话教程就跟不上了怎么办？</p>
<p>真的是太难了，刚开始不了解终端，不了解每条命令的原理，碰见 Vim 真的让人慌张。</p>
<p>这个 issue 用来帮助读者克服 Vim 恐惧，再也不用担心搜到的教程含有 Vim 命令。</p>
<h2>什么是 Vim</h2>
<p>Vim 简单来说就是一个编辑器，在终端中输入<code>vim</code>就可以打开这个编辑器，如果输入<code>vim &lt;file path&gt;</code> 就可以在终端中使用 Vim 打开对应文件。当然，也有很多大佬使用 Vim 作为他们的代码编辑器。</p>
<h2>如何使用 Vim</h2>
<p>知道了 Vim 是个编辑器就简单了：对于任何编辑器，只要会修改、保存、退出就可以使用。</p>
<h3>修改-<code>i</code></h3>
<p>使用<code>vim &lt;file path&gt;</code>命令打开对于文件后，默认是<code>Normal mode</code>，即只读模式，无法直接修改。</p>
<p>在只读模式中按下<code>i</code>键，即可进入编辑模式，就是我们正常打开文件的样子。然后就可以正常编辑编辑文件了。</p>
<blockquote>
<p><code>i</code>是什么？<code>i</code>是<code>insert</code>的缩写</p>
</blockquote>
<h3>保存-<code>：w&lt;Enter&gt;</code></h3>
<p>编辑结束之后，<code>Shift+冒号</code>键，进入命令模式，紧接着输入<code>w</code>，并按下<code>Enter</code>键，Vim 便会帮我们保存之前的修改。</p>
<h3>退出-<code>：q&lt;Enter&gt;</code></h3>
<p>跟保存操作类似，<code>Shift+冒号</code>键，进入命令模式，紧接着输入<code>q</code>，并按下<code>Enter</code>键，便会退出 Vim 界面，返回到终端</p>
<blockquote>
<p>tips：<code>:wq&lt;Enter&gt;</code>可以保存并退出 Vim</p>
</blockquote>
<h2>结语</h2>
<p>使用 Vim 在终端中临时修改文件的效率高很多，所以经常在教程中碰到。它同时也是一款传说中无所不能的代码编辑器，不过我并不推荐使用。对于像我这样的初学者，VSCode 更加简单好用。</p>
<blockquote>
<p>tips: 如果你安装了 VSCode，也可以在终端中输入<code>code &lt;file path&gt;</code>使用 VSCode 打开并修改对应文件</p>
</blockquote>
]]></content>
    <link href="https://geoqiao.github.io/blog/16-vim-don-t-be-afraid.html"/>
    <published>2023-10-22T06:52:44+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/17-app-defaults-2023.html</id>
    <title>App Defaults 2023</title>
    <updated>2026-02-23T03:44:20+00:00</updated>
    <content type="html"><![CDATA[<h1>背景</h1>
<p>一段时间之前写过一篇<a href="https://github.com/geoqiao/geoqiao.github.io/issues/9">what's on my mac</a>，推荐过一些自己使用的 Mac 应用。</p>
<p>最近逛 Twitter 刷到<a href="https://defaults.rknight.me/">App Defaults</a>项目，这是一份 RSS 订阅清单，包含了很多播客作者的 App Defaults 文章，可以直接通过 OPML 文件订阅。</p>
<p>这次一些软件发生了变化，对之前的文章做一个更新。</p>
<h1>App Defaults 2023</h1>
<ul>
<li>💾 <strong>Operating System</strong>: macOS</li>
<li>📬 <strong>Mail client</strong>: mail.app</li>
<li>🗒 <strong>Notes</strong>: <a href="https://obsidian.md/">Obsidian</a>,and this is <a href="https://github.com/geoqiao/geoqiao.github.io/issues/12">how i use Obsidian</a></li>
<li>📅 <strong>Calendar</strong>: Calender.app with <a href="https://github.com/sfsam/Itsycal">ltsycal</a></li>
<li>📎<strong>TODO list</strong>： Reminders.app</li>
<li>📰 <strong>RSS reader</strong>: <a href="https://netnewswire.com/">NetNewsWire</a>. It's open source and free and powerful for Mac and iOS.</li>
<li>🌐 <strong>Browser</strong>: <a href="https://arc.net/">Arc</a>(desktop), Safari(mobile)</li>
<li>🔖 <strong>Bookmarks</strong>: No more bookmarks , typing websites when need.</li>
<li>📔 <strong>Reading</strong>:  I use Arc(iOS) as Read It Later app</li>
<li>🎙 <strong>Podcasts</strong>: <a href="https://www.snipd.com/">Snipd</a>, podcast with AI, free version is enough.</li>
<li>🔐 <strong>Password Manager</strong>: <a href="https://bitwarden.com/">Bitwarden</a></li>
<li>📊 <strong>Word processing, Spreadsheet</strong>: Microsoft Excel &amp; Python with pandas</li>
<li>📝 <strong>Editor</strong>: Obsidian for .md, vim for system files and quick edits, VS Code for coding(Data cleansing and analysis with Python)</li>
<li>🐍<strong>Python environment management</strong>：<a href="https://rye-up.com/">Rye</a></li>
<li>🪄 <strong>Launcher:</strong> <a href="https://www.raycast.com/">Raycast</a></li>
<li>📖 <strong>Translation app:</strong> <a href="https://github.com/tisfeng/Easydict">Easydict</a></li>
</ul>
<h1>总结</h1>
<p>以上就是我目前高频使用的软件了，还有很多没写上去，大家可以参考 <a href="https://github.com/geoqiao/geoqiao.github.io/issues/9">what's on my mac</a>。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/17-app-defaults-2023.html"/>
    <published>2023-11-11T09:01:56+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/18-python-bian-ji-qi-wo-de-vscode-pei-zhi.html</id>
    <title>Python编辑器-我的VSCode配置</title>
    <updated>2024-05-26T11:45:08+00:00</updated>
    <content type="html"><![CDATA[<p>VSCode 是一款由微软开发、非常流行的代码编辑器：功能强大、简单易用。</p>
<h2>为什么不是其他编辑器</h2>
<p>可以编辑 Python 的编辑器很多，但是为什么选择 VSCode 呢？</p>
<p><strong>PyCharm</strong>：太重了，并且是付费软件。社区版免费，但无法在 PyCharm 中使用 jupyter notebook。并且实话说，我感觉 PyCharm 的学习曲线相对陡峭(下载过一次，感觉配置起来没有 VSCode 简单)。</p>
<p><strong>jupyter notebook</strong>：在最开始，我使用 notebook 工作，主要写一些处理 excel 的脚本。缺点是写代码聚焦于每个<code>cell</code>，每个<code>cell</code>都很有条理，但是整体看起来很乱。</p>
<p><strong>spyder</strong>：我觉得 spyder 的界面是最适合使用 Python 来进行数据分析类工作的。左边用来写代码，右下角展示输出，右上角展示输出的图片。但是缺点是集成的功能比较弱。</p>
<p><strong>VSCode</strong>：可以配置成 spyder 类似的界面，并且功能更加强大、配置起来也更加简单直观。</p>
<h2>安装 VSCode</h2>
<p>安装 VSCode 非常简单，可以直接在<a href="https://code.visualstudio.com/download">官网</a>安装，跟大多数下载软件一样，直接下载就行。</p>
<p>如果你是 macOS、并且已经安装了 Homebrew，可以通过以下命令安装：</p>
<pre><code class="language-shell">brew install visual-studio-code
</code></pre>
<h2>安装插件</h2>
<p>实际上 VSCode 本身只是一个文本编辑器，使它强大且流行的主要原因是强大的插件系统。通过不同的插件组合，可以把 VSCode 配置成几乎任何想要的集成开发环境。</p>
<p>因为我是一个初学者，并且只会写一些简单的 Python 脚本，这里主要针对 Python 进行 VSCode 配置。</p>
<p>我的插件列表：</p>
<ol>
<li><strong>Python&amp;Pylance</strong>：微软官方开发的 Python 插件，可以提供语法高亮、自动补全、类型检查等强大功能。</li>
<li><strong>Jupyter</strong>：集成 notebook，可以在 VSCode 中编辑执行<code>.ipynb</code>文件，体验不亚于在网页编辑。并且还享受 VSCode 的 Python 插件提供的功能。通过在 setting 中配置，可以在<code>.py</code>文件中通过<code>shift+enter</code>把代码让代码在 Jupyter 中执行。</li>
<li><strong>Rainbow CSV</strong>：通过不同列的颜色高亮，让在 VSCode 里看 CSV 文件时更不费眼睛。</li>
<li><strong>Ayu</strong>：个人最喜欢的 VSCode theme。</li>
<li><strong>Ruff</strong>：Python 的 lint&amp;format 工具，有类型检查个人感觉比 black 好用。需要在本地环境安装<code>ruff</code>。</li>
</ol>
<h2>编辑配置</h2>
<p>在下载好插件之后，插件的有些功能需要在 VSCode 设置中开启，为了方便，我直接把设置的 setting.json 文件放在这里供参考：</p>
<pre><code class="language-json">{

// editor basics

&quot;editor.accessibilitySupport&quot;: &quot;on&quot;,

&quot;editor.fontFamily&quot;: &quot;JetBrains Mono NL, MesloLGS NF&quot;, //字体部分需要下载相关字体

&quot;editor.cursorBlinking&quot;: &quot;solid&quot;,

&quot;editor.defaultFormatter&quot;: &quot;charliermarsh.ruff&quot;, // ruff插件的配置项

&quot;editor.mouseWheelScrollSensitivity&quot;: 1,

&quot;editor.mouseWheelZoom&quot;: true,

&quot;editor.semanticHighlighting.enabled&quot;: true, //语义高亮

&quot;editor.wordWrap&quot;: &quot;on&quot;,

&quot;editor.autoClosingBrackets&quot;: &quot;languageDefined&quot;,



// python

&quot;[python]&quot;: {

&quot;editor.formatOnSave&quot;: true,

&quot;editor.codeActionsOnSave&quot;: {

&quot;source.fixAll&quot;: &quot;explicit&quot;,

&quot;source.organizeImports&quot;: &quot;explicit&quot;

},

&quot;editor.defaultFormatter&quot;: &quot;charliermarsh.ruff&quot;

},

&quot;python.languageServer&quot;: &quot;Pylance&quot;,

&quot;python.analysis.typeCheckingMode&quot;: &quot;basic&quot;, //类型检查



// theme

&quot;workbench.colorTheme&quot;: &quot;Best Themes - Xcode Catalina Bold&quot;,

// audio

&quot;audioCues.chatRequestSent&quot;: &quot;off&quot;,

&quot;audioCues.chatResponseReceived&quot;: &quot;off&quot;,

&quot;audioCues.chatResponsePending&quot;: &quot;off&quot;,

&quot;audioCues.clear&quot;: &quot;off&quot;,

&quot;audioCues.diffLineDeleted&quot;: &quot;off&quot;,

&quot;audioCues.diffLineInserted&quot;: &quot;off&quot;,

&quot;audioCues.diffLineModified&quot;: &quot;off&quot;,

&quot;audioCues.lineHasBreakpoint&quot;: &quot;off&quot;,

&quot;audioCues.lineHasError&quot;: &quot;off&quot;,

&quot;audioCues.lineHasFoldedArea&quot;: &quot;off&quot;,

&quot;audioCues.lineHasInlineSuggestion&quot;: &quot;off&quot;,

&quot;audioCues.noInlayHints&quot;: &quot;off&quot;,

&quot;audioCues.notebookCellCompleted&quot;: &quot;off&quot;,

&quot;audioCues.notebookCellFailed&quot;: &quot;off&quot;,

&quot;audioCues.onDebugBreak&quot;: &quot;off&quot;,

&quot;audioCues.taskCompleted&quot;: &quot;off&quot;,

&quot;audioCues.taskFailed&quot;: &quot;off&quot;,

&quot;audioCues.terminalCommandFailed&quot;: &quot;off&quot;,

&quot;audioCues.terminalQuickFix&quot;: &quot;off&quot;,

&quot;audioCues.volume&quot;: 40,

&quot;workbench.iconTheme&quot;: &quot;material-icon-theme&quot;,

&quot;jupyter.interactiveWindow.textEditor.executeSelection&quot;: true,

&quot;debug.console.fontSize&quot;: 15,

&quot;editor.fontSize&quot;: 15,

&quot;window.zoomLevel&quot;: 1,

}
</code></pre>
]]></content>
    <link href="https://geoqiao.github.io/blog/18-python-bian-ji-qi-wo-de-vscode-pei-zhi.html"/>
    <published>2023-12-10T07:14:08+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/1-rye-hao-yong-de-python-bao-guan-li-gong-ju.html</id>
    <title>rye - 好用的Python包管理工具</title>
    <updated>2024-05-07T15:16:05+00:00</updated>
    <content type="html"><![CDATA[<p><a href="https://github.com/mitsuhiko/rye">rye</a>是一个 Python 的包管理器，可以更轻松的管理 Python 项目和虚拟环境，作者是流行 web 框架 flask 的作者<a href="https://github.com/mitsuhiko">Armin Ronacher</a></p>
<p>作为一个刚开始学习 Python 的新手，它解决了我碰到的两个难题：</p>
<ol>
<li>使用<code>pip</code>安装包时，经常某些包无法在当前 python 版本安装</li>
<li>不会使用 venv 等虚拟环境管理工具</li>
<li>使用<code>conda</code>时，经常社区还没有适配某些最新版本的包</li>
</ol>
<p>这里引出 rye 主要的几个功能：</p>
<ol>
<li>管理全局的 Python 版本</li>
<li>管理虚拟环境中的 Python 版本</li>
<li>以封装<code>pip</code>和<code>virtualenv</code>的方式，让我不必烦恼如何使用他们</li>
</ol>
<h2>安装 rye</h2>
<p>在 macOS 上，直接运行一下命令即可，同时在 rye 的<a href="https://rye-up.com/guide/installation/#installing-rye">文档</a>也给出了其他系统的安装方式。</p>
<p>例如 macOS：</p>
<blockquote>
<p>To install run you can curl a command which will install the right binary for your operating system and CPU architecture and install it:</p>
<pre><code class="language-shell">curl -sSf https://rye-up.com/get | bash
</code></pre>
</blockquote>
<p><strong>补充</strong>：</p>
<pre><code class="language-shell">rye self update # 升级rye
</code></pre>
<pre><code class="language-shell">rye self uninstall # 卸载rye
</code></pre>
<h2>开始一个新项目</h2>
<p>使用  <code>rye init</code>  初始化一个新项目非常容易。在这里，我开始一个名为： <code>&quot;test-rye&quot;</code>的新项目。</p>
<pre><code class="language-shell">mkdir test-rye  #创建项目文件夹
cd test-rye #在终端进入刚才创建的项目文件夹
rye init . #使用rye初始化项目
</code></pre>
<p>执行初始化之后，rye 会帮我们创建一些默认文件：</p>
<pre><code class="language-shell">tree
├── README.md       # 项目的README文件
├── pyproject.toml  # rye用来管理项目的文件
└── src
    └── test_rye
        └── __init__.py
</code></pre>
<p>现在，我们便可以安装自己想安装的包。假设我这个项目想用来做一些数据分析工作：</p>
<pre><code class="language-shell"># 使用rye安装 numpy pandas scikit-learn xgboost
rye add numpy pandas scikit-learn xgboost # 解析包版本，并添加到pyproject.toml文件中
rye sync # 开始下载文件对应的包
</code></pre>
<p>至此，一个由 rye 管理的项目就创建完成了，我们可以使用 VSCode 打开项目文件夹，并开始写代码了。</p>
<pre><code class="language-shell">code .  # 使用VSCode打开项目文件夹
</code></pre>
<p>此时，我们的项目文件夹结构如下：</p>
<pre><code class="language-shell">tree
├── README.md
├── pyproject.toml
├── requirements-dev.lock
├── requirements.lock
└── src
    └── test_rye
        ├── __init__.py
        └── __pycache__
            └── __init__.cpython-311.pyc
</code></pre>
<p><strong>注意事项</strong>：
当我们的项目需要添加新的依赖时，可以使用<code>rye add &lt;package name&gt;</code> 和 <code>rye sync</code>来安装对应的包，或者通过<code>rye romove &lt;package name&gt;</code>和<code>rye sync</code>来移除对应的包。</p>
<p><code>rye add &lt;package name&gt;</code>和<code>rye romove &lt;package name&gt;</code>只修改<code>pyproject.toml</code>文件，<code>rye sync</code>会按照<code>pyproject.toml</code>文件实际对项目的依赖进行操作。</p>
<h2>修改项目的 Python 版本</h2>
<p>rye 当前为我们的项目安装 <a href="mailto:Python@3.11">Python@3.11</a> 版本，但不必担心，rye 为我们提供了修改项目 Python 版本的命令</p>
<pre><code class="language-shell">rye pin 3.9
rye sync # 所有的修改都需要使用sync命令生效
</code></pre>
<p>此时，我们的项目的 Python <a href="%E7%89%88%E6%9C%AC%E5%B0%B1%E5%8F%98%E4%B8%BA%E4%BA%86Python@3.9">版本就变为了<span class="pangu"></span>Python@3.9</a></p>
<h2>全局 Python 脚本</h2>
<p>某些情况下，有些包我们想要全局使用，比如<code>black</code>或者<code>ruff</code>来对我们的代码进行格式化。</p>
<pre><code class="language-shell">rye install ruff
</code></pre>
<p>安装之后，就可以在终端全局使用<code>ruff</code>命令了</p>
<p>卸载也很简单：</p>
<pre><code class="language-shell">rye uninstall ruff
</code></pre>
<h2>最后</h2>
<p>rye 还支持一些常规的操作，比如接管全局 python、升级项目中某个依赖或者所有依赖的版本、构建/发布包等等功能，可以通过<a href="https://rye-up.com/guide/">官方文档</a>查看。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/1-rye-hao-yong-de-python-bao-guan-li-gong-ju.html"/>
    <published>2024-01-06T07:38:36+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/20-ji-yu-fastapi-de-crud-lian-xi-rss-ding-yue-guan-li.html</id>
    <title>基于 fastAPI 的 CRUD 练习- RSS 订阅管理</title>
    <updated>2024-05-15T15:59:15+00:00</updated>
    <content type="html"><![CDATA[<h1>背景</h1>
<p>最近两三年，我逐渐卸载了抖音、微博等社交媒体，主要从<span class="pangu"></span>RSS<span class="pangu"></span>订阅获取信息。卸载部分社交媒体让我有了一点时间做其他事情，比如听播客、学<span class="pangu"></span>Python、阅读......</p>
<p>这个练习是我的<a href="https://cs50.harvard.edu/python/2022/">CS50P</a>final project<span class="pangu"></span>的延续，主要目的是学习一些<span class="pangu"></span>web<span class="pangu"></span>的开发框架、使用<span class="pangu"></span>Python<span class="pangu"></span>操作数据库。</p>
<h2>why fastAPI</h2>
<p>对比了<span class="pangu"></span>Django 还有 Flask：</p>
<ol>
<li>感觉<span class="pangu"></span>Django<span class="pangu"></span>太重了，没有方便的装饰器，不适合新手</li>
<li>Flask<span class="pangu"></span>感觉有点乱，主要命令行我没有弄明白</li>
<li>fastAPI<span class="pangu"></span>对<span class="pangu"></span>type hints<span class="pangu"></span>的支持很好，感觉也更简单</li>
</ol>
<h2>why SQLite</h2>
<p>SQLite<span class="pangu"></span>只有一个文件，操作起来很简单，也不用配置什么环境</p>
<h1>思路</h1>
<p>我想实现对<span class="pangu"></span>RSS<span class="pangu"></span>订阅源的添加、查询、删除功能，所以思路很简单</p>
<ol>
<li>创建一个<span class="pangu"></span>SQLite<span class="pangu"></span>数据库，要包含<code>订阅链接</code>、<code>标题</code>、<code>tag</code>、<code>网址</code>、<code>添加时间</code>等字段</li>
<li>定义<span class="pangu"></span>CRUD<span class="pangu"></span>函数</li>
<li>将函数返回值给到<span class="pangu"></span>fastAPI，并渲染前端页面</li>
</ol>
<h1>上手开干</h1>
<h2>创建数据库</h2>
<p>这里我使用<span class="pangu"></span>SQLAlchemy<span class="pangu"></span>库来实现，搜索中推荐这个库的文章很多，ORM<span class="pangu"></span>支持很不错</p>
<blockquote>
<p>ORM：指的是对象关系映射(Object-Relational Mapping)，主要作用是将数据库中的表结构映射到对象上,使开发者可以使用面向对象的方式来操作数据库,而不需要直接编写<span class="pangu"></span>SQL<span class="pangu"></span>语句。</p>
</blockquote>
<p>使用<span class="pangu"></span>SQLAlchemy<span class="pangu"></span>创建<span class="pangu"></span>SQLite<span class="pangu"></span>数据库，设计<code>feeds</code>表的字段，并为字段添加类型要求</p>
<pre><code class="language-python">class Base(DeclarativeBase):
    pass


class Subscription(Base):
    __tablename__ = &quot;feeds&quot;
    
    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    url: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
    title: Mapped[str] = mapped_column(nullable=False)
    tag: Mapped[Optional[str]]
    link: Mapped[str] = mapped_column(nullable=False)
    updated_at: Mapped[datetime] = mapped_column(nullable=False, default=datetime.now)
    
    def __repr__(self) -&gt; str:
        return f&quot;Feed(id={self.id!r}, url={self.url!r},title={self.title},tag={self.tag!r},link={self.link!r})&quot;
</code></pre>
<h2>定义<span class="pangu"></span>CRUD<span class="pangu"></span>函数</h2>
<p>这里主要学习了<span class="pangu"></span>SQLAlchemy<span class="pangu"></span>的<span class="pangu"></span>ORM<span class="pangu"></span>查询方法。</p>
<p>一开始觉得直接写<span class="pangu"></span>SQL<span class="pangu"></span>语句更好，只用掌握一种<span class="pangu"></span>SQL<span class="pangu"></span>语法就行了；后来查询后，好像直接写<span class="pangu"></span>SQL<span class="pangu"></span>语句有安全风险，比如<span class="pangu"></span>SQL<span class="pangu"></span>注入。</p>
<blockquote>
<p>SQL<span class="pangu"></span>注入：用户前端输入框填写<span class="pangu"></span>SQL<span class="pangu"></span>语句，导致后端数据泄露、篡改等等问题</p>
</blockquote>
<p><strong>ORM<span class="pangu"></span>语法示例</strong>：</p>
<p>以下代码通过数据库中的<span class="pangu"></span>ID<span class="pangu"></span>字段查询对应的订阅链接。我感觉这种写法还能接受，不过还是感觉直接写<span class="pangu"></span>SQL<span class="pangu"></span>语句的话心智负担更小一点，因为可以少学一种语法。</p>
<pre><code class="language-python">def get_feed_by_id(feed_id: int):
    with Session(engine) as session:
        feed = session.query(Subscription).filter(Subscription.id == feed_id).first()
    
    return feed
</code></pre>
<h2>fastAPI<span class="pangu"></span>接口</h2>
<p>其实<span class="pangu"></span>fastAPI<span class="pangu"></span>部分很好写，只要我们获取到返回值，并且传给前端页面就好了</p>
<p>Django<span class="pangu"></span>框架中需要配置的视图函数、URL<span class="pangu"></span>路径等等都不在一个文件中，但是<span class="pangu"></span>fastAPI<span class="pangu"></span>通过一个简单的装饰器将这些工作都做好了</p>
<pre><code class="language-python">@app.get(&quot;/feeds_list&quot;)
async def get_rss_feeds(request: Request):
    feeds = get_all_feeds()
    return template_dir.TemplateResponse(&quot;feeds_list.html&quot;, {&quot;request&quot;: request, &quot;feeds&quot;: feeds})

</code></pre>
<h2>命令行运行程序</h2>
<p>通过命令行运行，在 <a href="http://127.0.0.1:8000">http://127.0.0.1:8000</a> 预览程序</p>
<pre><code class="language-shell">uvicorn main:app --reload 
</code></pre>
<p><a href="https://github.com/geoqiao/RSS_db">项目地址</a></p>
<blockquote>
<p>纯属兴趣驱动，如有不准确的地方欢迎交流</p>
</blockquote>
<p><strong>预览效果如下</strong>
<img width="1336" alt="image" src="https://github.com/geoqiao/geoqiao.github.io/assets/105639506/869f0d88-fdb0-4f7a-911c-6c8e39b260df"></p>
]]></content>
    <link href="https://geoqiao.github.io/blog/20-ji-yu-fastapi-de-crud-lian-xi-rss-ding-yue-guan-li.html"/>
    <published>2024-05-10T15:41:01+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/21-shi-yong-python-he-github-pages-da-jian-ge-ren-bo-ke.html</id>
    <title>使用 Python 和 GitHub Pages 搭建个人博客</title>
    <updated>2024-09-22T09:52:11+00:00</updated>
    <content type="html"><![CDATA[<h1>背景</h1>
<p>我偶尔有写点什么的欲望，加上 yihong 老师 <a href="https://github.com/yihong0618/gitblog">gitblog</a> 项目的激励，于是产生了写一个个人博客页面的想法。</p>
<p>因为工作上数据分析需要，我在 2022 年开始接触 Python。作为一名曾经试图考艺术硕士的商科生，我意外的很喜欢写 Python 的体验。很长一段时间以来，我只使用 Python 做一些数据分析工作。但随着使用时间的增长，我发现自己的 Python 代码代码虽然可以运行，但是很难读、很多代码重复使用率不高、维护起来很费力。</p>
<p>于是我尝试学习 Python 的基本概念，而不仅仅局限于 Pandas 和 sklearn。这个项目便是我目前学习的成果。</p>
<h2>why GitHub Pages</h2>
<ol>
<li>不用买域名</li>
<li>不用买服务器</li>
<li>是一个网页，可以满足分享欲望</li>
</ol>
<h2>why Python</h2>
<p>实际上，GitHub Pages 提供了非常丰富的支持，也许使用 JavaScript 的框架可以更快更好的完成这个项目。但是，我只会写一点基础的 Python，其他语言完全不会。</p>
<h1>思路</h1>
<p>为了满足写博客的需求，我的思路非常简单：</p>
<ol>
<li>可以读取 GitHub Issues</li>
<li>将读取到的 Issues 转换为 HTML</li>
<li>有简单的 HTML 模板，有一个不丑的前端页面</li>
<li>将渲染后的 HTML 上传到 GitHub Pages</li>
<li>整个过程自动化，我只想写 issue，其他的工作全部自动完成</li>
</ol>
<h1>马上开干</h1>
<h2>读取 GitHub Issues</h2>
<p>这个环节非常简单，GitHub 提供了一个非常简单使用的 Python 库：PyGithub。只需要设置好 GitHub Token，便可以很轻易的读取到 issues 的内容</p>
<pre><code class="language-python">def get_all_issues(repo: Repository, me: str) -&gt; PaginatedList[Issue]:
    &quot;&quot;&quot;Get all issues for a given GitHub repository.

    Args:
        github_repo: GitHub repository name in the format &quot;owner/name&quot;.

    Returns:
        List of GitHub issue objects.
    &quot;&quot;&quot;
    issues = repo.get_issues(creator=me)
    return issues
</code></pre>
<p>返回的 issues 是一个包含所有 issue 的列表。通过<code>for循环</code>可以遍历这个列表，可以通过<code>issue.title</code>等方法获取 issue 的标题、创建时间、内容、tag 等信息。比如：</p>
<pre><code class="language-python">issue.title # 获取标题
issue.updated_at # 获取创建时间
issue.body # 获取正文内容
</code></pre>
<h2>将 issue 转换为 HTML</h2>
<p>GitHub 有使用一个官方接口，可以将 markdown 格式的文本转换为 HTML，但是每次转换请求这个 API 的速度很慢，所以我使用了<code>marko</code>库。</p>
<p><code>marko</code> 提供了 GitHub 风格的转换方法，只需要传入我们读取到的 issue.body 即可：</p>
<pre><code class="language-python">from marko.ext.gfm import gfm

def markdown2html(mdstr: str):
    html = gfm.convert(mdstr)
    return html
</code></pre>
<h2>HTML 模板</h2>
<p>我对于 CSS 和 JavaScript 一窍不通，所以这部分内容我是参考了 yihong 老师的 <a href="https://yihong0618.github.io/gitblog/">GitHub Pages</a>，从页面的 HTML 源码中发现了可用的 CSS 和 JavaScript 代码，并且模仿页面的 HTML，这样拼凑出来的一个页面。</p>
<p>这个页面满足了我对于一个不太丑的前端页面的需求，并且因为过程中自己拼凑了模板，对于一些 CSS、JavaScript 的作用也有了一点点理解。</p>
<p>当然，这个模板的搭建过程中 <a href="https://www.perplexity.ai">perplexity</a> 帮了我非常多的忙。<code>perplexity</code>非常强大，可以将我得到的前端代码作为文件上传，ai 帮我解读每个 CSS 和 JavaScript 的作用。免费版本已经足够我的使用，非常推荐！</p>
<h2>GitHub Actions 自动化</h2>
<p>在主体代码全部实现后，接下来就是将整个过程自动化。这一步可以交给强大的 GitHub Actions 完成。它会帮我监控 issue 的变化：一旦有 issue 添加、编辑等动作，actions 会帮我自动执行我的 Python 代码，并将输出的 HTML 文件上传至 GitHub Pages 仓库。</p>
<p>这一步也主要参考 yihong 老师<code>gitblog</code>项目的 action 实现。因为我是用 <a href="https://github.com/astral-sh/rye">rye</a> 管理 Python 项目，但<code>rye</code>并不支持输出<code>requirements.txt</code>，所以我增加了一条将<code>requirements.lock</code>文件转换为<code>requirements.txt</code>的命令：</p>
<pre><code class="language-shell">sed &#x27;/^-e/d&#x27; requirements.lock &gt; requirements.txt
</code></pre>
<h2>总结</h2>
<p>因为白天上班比较忙，所以每天晚上下班都会花一个小时来看这个项目。花了将近一个月的时间，我终于实现了自己搭建博客页面的想法。</p>
<p>现在我已经开始使用自己的项目来写博客，这种体验真的很美妙。</p>
<p>这是我的<a href="https://github.com/geoqiao/github_blog">源代码仓库</a>和<a href="https://geoqiao.github.io/contents/">GitHub Pages</a>页面</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/21-shi-yong-python-he-github-pages-da-jian-ge-ren-bo-ke.html"/>
    <published>2024-05-12T09:14:39+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/22-claim-my-rss-feed-on-follow-a-amazing-rss-reader.html</id>
    <title>Claim my RSS feed on Follow ,a amazing RSS reader</title>
    <updated>2024-09-08T02:01:25+00:00</updated>
    <content type="html"><![CDATA[<p>This message is used to verify that this feed (feedId:53066833315102724) belongs to me (userId:53065838481510400). Join me in enjoying RSS on the next generation information browser <a href="https://follow.is">https://follow.is</a>.</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/22-claim-my-rss-feed-on-follow-a-amazing-rss-reader.html"/>
    <published>2024-09-08T02:01:25+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/23-uv-github-20k-star-de-zhong-ji-python-xiang-mu-guan-li.html</id>
    <title>uv - GitHub 20k star 的终极 Python 项目管理工具</title>
    <updated>2024-09-22T09:38:47+00:00</updated>
    <content type="html"><![CDATA[<h2>uv 是什么</h2>
<p><a href="https://docs.astral.sh/uv/">uv</a> 是一个 Python 项目管理和包管理的工具，由 Astral 开发（他们的另一个明星产品是 <a href="https://docs.astral.sh/ruff/">ruff</a> ）。</p>
<p>在我刚接触 Python 的时候，阻止我动手写代码的问题主要有 2 个：</p>
<h3>1. 怎么安装 Python？</h3>
<p>确实，这是一个很大的问题。对于还不懂命令行的我来说，使用 Homebrew 或者官网下载的方式，都会污染我的电脑环境。以至于搞不清楚每次运行的 Python 到底是哪一个。</p>
<blockquote>
<p>真实教训：因为想把自己安装的杂乱的 Python 都卸载掉，只保留 3.11 版本，导致我不小心删除了系统自带 Python 的某些文件，被迫将电脑送去天才吧维修！</p>
</blockquote>
<h3>2. 怎么安装三方库？</h3>
<p>刚看了一些入门教程后，自以为这个不是问题，直接<code>pip install</code>就行了呗？</p>
<p>其实不然，安装的时候发现好多包安装不上：不适配当前的 Python 版本，或者存在三方库之间的依赖冲突。对初学者来说，又得了解一个新词汇：依赖解析。</p>
<p>再搜一圈教程下来，发现又要用<code>pyenv</code>管理 Python 版本，还得结合<code>pip</code>解决依赖冲突，命令行里面还得随时想着有没有激活虚拟环境！真服了，我可是刚入门的小白！</p>
<h2>uv - Python&amp;依赖&amp;项目管理</h2>
<h3>功能一：管理 Python 版本</h3>
<p>uv 自带管理 Python 版本的功能，可以下载、项目中选用特定 Python 版本、卸载等全套服务，同时命令行操作也非常简洁：</p>
<pre><code class="language-bash">uv python install 3.11.9   # 安装3.11.9版本的Python
uv python uninstall 3.11.9  # 卸载3.11.9版本的Python
uv python pin 3.11.9 # 为当前项目选择特定版本的Python
</code></pre>
<h3>功能二：解决项目依赖</h3>
<p>uv 提供<code>add</code>和 <code>remove</code>命令，可以为项目添加和删除依赖，非常直觉：</p>
<pre><code class="language-bash">uv add pandas # 安装pandas库
uv remove pandas # 移除pandas库
</code></pre>
<h2>为什么不选 conda or pdm</h2>
<p>说实话 pdm 也是一个非常好用的 Python 项目管理工具，并且在最近的版本也可以管理 Python 版本，常用命令和 uv 基本一致。从我个人而言，有两个原因没有使用 pdm：</p>
<ol>
<li>功能太多（是的没错），兼容的标准很多，对我这个初学者而言会比较复杂</li>
<li>无法真正独立于 Python 安装，自从曾经搞乱过系统 Python 环境后，我就再不想使用系统 Python 哪怕一丁点。所以，对我来说 uv 这种可以独立于 Python 安装，并且可以完全不使用系统 Python 建立项目的工具，完美满足我的需求</li>
</ol>
<p>conda 是我第一个接触的 Python 管理工具，对我而言有几个小痛点：</p>
<ol>
<li>社区对于包的最新版本更新较慢：有时无法第一时间尝鲜某个新包的新功能（比如 pandas2.0 的 pyarrow 后端</li>
<li>依赖解析慢且有一些小 bug：慢是显而易见的，bug 我没有仔细研究过，但之前经常碰到 wordcloud 库有时无法安装，有时又可以正常安装的问题（或许跟我刚开始不熟悉所以经常卸载重装有关</li>
</ol>
<h2>最后</h2>
<p>这里只是介绍了 uv 的一些常用功能，对于如何使用大家可以参考<a href="https://geoqiao.github.io/contents/blog/1.html">rye 推荐</a>以及<a href="https://docs.astral.sh/uv/">官方文档</a></p>
<p>如果你也是刚刚接触 Python，或者像我一样刚刚接触代码和命令行，非常推荐使用 uv，可以省去安装 Python 和相关依赖的绝大部分麻烦，直接进入主要的学习代码环节，而不是把时间浪费在环境配置上。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/23-uv-github-20k-star-de-zhong-ji-python-xiang-mu-guan-li.html"/>
    <published>2024-09-08T07:52:02+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/24-wei-github-pages-ge-ren-bo-ke-tian-jia-yaml-pei-zhi-gong.html</id>
    <title>为 GitHub Pages 个人博客添加 YAML 配置功能 - 基于 Python</title>
    <updated>2024-10-03T13:35:19+00:00</updated>
    <content type="html"><![CDATA[<p>好长一段时间了，工作上事情很多，很烦。也很久没有写工作以外的 Python 了。趁着假期和一些其他原因，今天又重新捡起了 <a href="https://geoqiao.github.io/contents/">github_blog</a> 这个项目。</p>
<p>近期主要做了两个改动：</p>
<ol>
<li>
<p>把前端模板部分利用 <code>cursor</code> 重写了一下。和原来的 <a href="https://github.com/ahonn/hexo-theme-even">even</a> 主题相比，现在的虽然看起来比较简陋，但胜在每一行 CSS 和 HTML 都知道是什么意思、有什么作用！</p>
<blockquote>
<pre><code>其实过程特别简单，仅仅在 cursor 中使用了3个 prompt，cursor 太强大，几乎一遍过，所以这个改动真的没啥讲的。
</code></pre>
</blockquote>
</li>
<li>
<p>就是为主题增加配置文件的功能，目的是为了其他人使用（当然，大概率可能也没有其他人用），这也是写这篇 blog 要讲的主题。</p>
</li>
</ol>
<h2>正文</h2>
<p>其实增加配置文件的功能想了很久，因为可以减少别人使用的成本，并且满足自己的虚荣心。</p>
<h2>why YAML？</h2>
<p>其实这部分决策起来很快，主要有 4 个原因：</p>
<ol>
<li>我对与所有配置文件几乎都不熟</li>
<li>记得 <a href="https://www.gohugo.org/doc/overview/configuration/">Hugo</a> 的配置文件就可以用 YAML，GitHub Actions 也使用 YAML</li>
<li>JSON 太不易读了，对于小白来说那么多花括号会搞晕人的</li>
<li>TOML 看起来也挺复杂，而且我不想跟 Python 的<code>pyproject.toml</code>搞混</li>
</ol>
<p>但 YAML 不是没有缺点：对缩进和空格有要求这一点比较麻烦，曾经我就因为这一点在 GitHub Actions 上浪费了一下午 debug。</p>
<p><strong>配置 YAML</strong>：
目前我的配置还比较简单，模板中涉及的变量主要是博客的标题、描述、以及使用者的 GitHub 名称：</p>
<pre><code class="language-yaml"># 博客信息
blog:
	title: GeoQiao&#x27;s Blog
	description: This is a blog powered by pygithub and jinja2.
	url: https://geoqiao.github.io/contents
	author:
		name: geoqiao
		email: geoqiao@example.com

# GitHub 相关配置
github:
	name: geoqiao # GitHub 用户名
	repo: geoqiao/geoqiao.github.io # GitHub 仓库名称
</code></pre>
<p>使用 Python 读取 yaml 文件也很简单：</p>
<pre><code class="language-python">import yaml  # 导入yaml包，需要提前安装`uv add pyyaml`

CONFIG_FILE = &quot;./configs/config.yaml&quot; # 配置文件路径

# 写一个上下文管理器打开就行，这个函数会返回一个配置文件的dict
def load_config():
	with open(CONFIG_FILE, &quot;r&quot;) as file:
		config = yaml.safe_load(file)
	return config

CONFIG = liad_config()
</code></pre>
<p>读取文件之后，只要使用 dict 的方法读取相应的 value 就行，比如读取博客的标题就是：<code>CONFIG[&quot;blog&quot;][&quot;title&quot;]</code>，这样就会输出所对应的 value<code>GeoQiao&#x27;s Blog</code>。</p>
<h2>剩下的</h2>
<p>剩下的就比较简单了，只要 1. 在模板中把相应的变量用符合 Jinja2 的语法写入，2. 并把读取到的配置变量传入给 HTML 模板 即可</p>
<p><strong>写入模板</strong></p>
<p>把原本手写的标题、名字、描述部分全都换为变量格式：比如把 <code>geoqiao</code> 全部替换为<code>{{ github_name }}</code></p>
<p><strong>给模板传入变量的值</strong></p>
<p>这里以渲染<code>index.html</code>为例:</p>
<pre><code class="language-python">def render_blog_index(issues: PaginatedList[Issue]) -&gt; str:
	env = Environment(loader=FileSystemLoader(&quot;templates&quot;))
	template = env.get_template(&quot;index.html&quot;)
	# 通过CONFIG获取相应变量的value（就是字典取值的写法
	blog_title = CONFIG[&quot;blog&quot;][&quot;title&quot;]
	github_name = CONFIG[&quot;github&quot;][&quot;name&quot;]
	meta_description = CONFIG[&quot;blog&quot;][&quot;description&quot;]

	return template.render(
		issues=issues,
		# 把取到的配置文件中的值传给HTML模板
		blog_title=blog_title,
		github_name=github_name,
		meta_description=meta_description,
	)
</code></pre>
<h2>最后</h2>
<p>配置文件功能增加后，使用这个项目搭建 GitHub Pages 博客会变得相对比较简单：</p>
<ol>
<li>新建一个 GitHub Pages 仓库，名字格式为<code>&lt;github_name&gt;.github.io</code></li>
<li>获取 GitHub Token（可以 Google 搜索如何获取</li>
<li>把我的项目仓库中的文件全部复制到创建好的 GitHub Pages 仓库中</li>
<li>修改<code>configs/config.yaml</code>中的配置项，将博客的标题、描述、GitHub 姓名全部改成自己的</li>
<li>修改 GitHub Actions 中的仓库名字</li>
<li>开始写 issue，submit 之后，GitHub Actions 会自动更新部署到页面</li>
<li>到<code>https://&lt;your_github_name&gt;.github.io/contents</code>页面查看自己的文章</li>
</ol>
<p>项目会自动生成 RSS feed，添加到诸如 netnewsfire 或 Follow 中，而且以上只需要配置一次，之后只需要每次写 issue 就好了</p>
<p>PS：当然现在的前端 templates 还比较简陋，我会慢慢更新优化，也欢迎随时 pull request 到<a href="https://github.com/geoqiao/github_blog">项目仓库</a> 或者提交 issue 。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/24-wei-github-pages-ge-ren-bo-ke-tian-jia-yaml-pei-zhi-gong.html"/>
    <published>2024-10-03T11:12:43+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/25-bu-yao-jiu-jie-le-zai-pandas-zhong-shu-ju-shai-xuan-jiu.html</id>
    <title>不要纠结了！在Pandas中数据筛选就用它 - Python</title>
    <updated>2024-10-07T11:36:26+00:00</updated>
    <content type="html"><![CDATA[<h2>TL;DR</h2>
<p>建议使用 <code>DataFrame.loc</code> 方法，支持类似 SQL 中的<code>where</code>条件对<code>rows</code>筛选，也支持对<code>column</code>进行筛选。</p>
<h2>The Zen of Python</h2>
<p>如果在 Python 文件中输入 <code>import this</code>，便可以看到 Python 之禅的全文。其中有一条：</p>
<blockquote>
<p>There should be one-- and preferably only one --obvious way to do it.</p>
</blockquote>
<p>很明显，Pandas 从 2008 年发展到现在，已经跟这些原则没有什么关系了，光是筛选 DataFrame 的方法就有 n 种，我能想到的：</p>
<pre><code class="language-python">df[df[&quot;foo&quot;]&gt;0]
df.loc[df[&quot;foo&quot;]&gt;0,:]
df.iloc[0,1]
df.filter(items=[&#x27;foo&#x27;, &#x27;bar&#x27;])
df.query(&#x27;foo &gt; bar&#x27;)
</code></pre>
<p>刚开始，对于我这个初学者来说，Google 搜到什么就用什么。实际结果就是自己的代码非常乱，一个文件用到的筛选方法非常多，这个代码第一遍写的时候知道是干嘛的，第二遍看的时候真的没人一下子能看懂。</p>
<p><strong>每种筛选方法有什么区别</strong>：大家可以参考<a href="https://www.perplexity.ai/search/df-loche-df-query-de-qu-bie-KTT8Yo9MQRa8qEFB_CmEzw#10">ai 回答</a></p>
<h2>为什么推荐.loc 方法</h2>
<p><strong>首先我们先创建一个测试用数据集</strong>：</p>
<pre><code class="language-python">data = {
	&quot;Name&quot;: [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;, &quot;David&quot;, &quot;Eva&quot;],
	&quot;Age&quot;: [25, 30, 35, 40, 28],
	&quot;Gender&quot;: [&quot;Female&quot;, &quot;Male&quot;, &quot;Male&quot;, &quot;Male&quot;, &quot;Female&quot;],
	&quot;Salary&quot;: [50000, 60000, 70000, 80000, 55000],
	&quot;Country&quot;: [&quot;USA&quot;, &quot;Canada&quot;, &quot;USA&quot;, &quot;UK&quot;, &quot;Canada&quot;],
}

df = pd.DataFrame(data)
</code></pre>
<p><strong>主要理由如下</strong>：</p>
<ol>
<li>支持同时筛选 rows 和 columns，<code>.loc</code>支持以逗号隔开的两个参数：第一个参数对 rows 进行操作，第二参数对 columns 进行操作</li>
</ol>
<pre><code class="language-python">df.loc[:,:] # 取所有行和所有列
df.loc[df[&quot;age&quot;]&gt;30] # 取age &gt; 30 的行 和 所有列
df.loc[df[&quot;age&quot;]&gt;30, [&quot;Name&quot;, &quot;Salary&quot;]] # 取age &gt; 30 的行 和 Name、Salary列
df.loc[df[&quot;age&quot;]&gt;30, [&quot;Name&quot;, &quot;Salary&quot;]]
df.loc[0:3,:] # 取索引为0-3的行 和 所有列
df.loc[(df[&quot;Age&quot;] &gt; 30) &amp; (df[&quot;Gender&quot;] == &quot;Male&quot;), [&quot;Name&quot;,&quot;Salary&quot;]] # 取age &gt; 30且 Gender = Male 的行 和Name、Salary列
</code></pre>
<ol start="2">
<li>支持对 rows 进行复杂条件判断筛选：</li>
</ol>
<pre><code class="language-python">df.loc[(df[&quot;Age&quot;] &gt; 30) &amp; (df[&quot;Gender&quot;] == &quot;Male&quot;), [&quot;Name&quot;,&quot;Salary&quot;]] # 取age &gt; 30且 Gender = Male 的行 和Name、Salary列
</code></pre>
<ol start="3">
<li>对行或列进行<strong>区间</strong>形式的筛选：</li>
</ol>
<pre><code class="language-python">df.loc[0:3,:] # 取索引为0-3的行 和 所有列
df.loc[0:3,&quot;Name&quot;:&quot;Salary&quot;] # 取索引为0-3的行 和 Name - Salary的所有列
</code></pre>
<ol start="4">
<li>再花哨点，把筛选条件作为变量</li>
</ol>
<pre><code class="language-python"># 取age &gt; n且 Gender = Male 的行 和Name、Salary列
n = 30
df.loc[(df[&quot;Age&quot;] &gt; n) &amp; (df[&quot;Gender&quot;] == &quot;Male&quot;), [&quot;Name&quot;,&quot;Salary&quot;]]
</code></pre>
<h2>.loc 的缺点</h2>
<p>这么全面的方法也有缺点：</p>
<ol>
<li>
<p><strong>性能问题</strong>：在处理非常大的 DataFrame 时，<code>.loc</code>可能会比其他方法（如<code>.query</code>或布尔索引）慢，尤其是当涉及复杂条件时。</p>
</li>
<li>
<p><strong>复杂条件可读性差</strong>：当涉及多个复杂条件时，使用布尔索引结合<code>.loc</code>可能导致代码变得冗长且难以阅读。</p>
</li>
</ol>
<h2>结语</h2>
<p>综上，基本上<code>.loc</code>方法基本可以满足日常工作中会碰到的 90%以上的筛选场景，不用纠结，选<code>.loc</code>准没错！</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/25-bu-yao-jiu-jie-le-zai-pandas-zhong-shu-ju-shai-xuan-jiu.html"/>
    <published>2024-10-07T06:42:00+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/26-ru-he-dui-lian-xu-xing-shu-ju-jin-xing-fen-xiang-python.html</id>
    <title>如何对连续型数据进行分箱 - Python</title>
    <updated>2024-10-26T09:03:51+00:00</updated>
    <content type="html"><![CDATA[<p>在做数据分析时，经常要对连续型数据进行分箱。面临的主要问题是：怎么分箱才是最优的？</p>
<p>一个常见的场景是，老板想看用户在不同年龄段的占比以及消费情况，这时如果将所有年龄全部展示出来会话，表格会非常长，不容易阅读。一般情况下，我们会把相近的年龄做一个区间，来展示不同年龄区间数据。这就需要用到分箱，把年龄划分成不同的区间。</p>
<h2>常用的分箱方法</h2>
<ol>
<li>等距分箱：比如数据集的年龄区间为 1-60 岁，以每 10 岁作为一个区间，划分为 6 个区间。</li>
<li>等频分项：比如数据集总共有 100 个客户，按照年龄从小到大排序，每 10 个客户作为一个区间。</li>
</ol>
<p>但是这两种分箱都回答不了老板的另一个灵魂问题：你这样分能看清客户特征吗？是最合理的吗？</p>
<p>确实，以上两种分箱操作起来比较简单，而且 pandas 自带了<code>.cut</code> 方法。然而，要解决最优分箱，以上两种方法都不太合适。</p>
<p>如何进行最优分箱，就要引出今天的主角：<code>optbinning</code></p>
<h2>最优分箱 - optbinning</h2>
<p><code>optbinning</code>是一个由 Python 编写的可以寻找连续型变量最优分箱的库，他的功能十分强大，甚至可以直接用来开发评分卡模型。大家如果感兴趣可以从他的<a href="https://gnpalencia.org/optbinning/index.html">官网</a>了解更多。这里主要介绍他的分箱功能。</p>
<p>简单来说，optbinning 同时支持等频、等距、CART、MDLP 等四种分箱方法。前两种不做赘述：</p>
<ol>
<li><code>CART</code>全称<strong>Classification and Regression Trees</strong>：即分类回归树，使用决策树的分叉方法来寻找信息增益最大的分箱区间</li>
<li><code>MDLP</code>全称<strong>Minimum Description Length Principle</strong>：即最小描述长度原则，考虑模型复杂度与数据拟合度之间的平衡</li>
</ol>
<p>对于详细的底层算法，可以查看一些详细的教程介绍。作为一个资深调包侠，在日常业务场景中，我认为<code>cart</code>适用性更广，也更好解释。（建议可以看一下吴恩达老师对于决策树模型的讲解，很容易懂，用来自己理解或者让业务领导理解都非常好用）</p>
<h2>实操举例</h2>
<p>这里使用 optbinning 官网文档的例子来向大家演示如何实操分箱：</p>
<h3>首先加载数据集</h3>
<pre><code class="language-python">import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer #著名的癌症数据集
from optbinning import OptimalBinning #今天的主角，分箱器

data = load_breast_cancer() #加载数据集
df = pd.DataFrame(data.data, columns=data.feature_names) #转化为pandas可以读取的dataframe
</code></pre>
<p>breast_cancer 简单来说就是通过肿瘤的半径、纹理、光滑度等数据，来预测肿瘤良性或恶性。这里我们主要使用<strong>半径</strong>来分箱。</p>
<h3>获取变量及结果</h3>
<pre><code class="language-python">variable = &quot;mean radius&quot;
x = df[variable].values
y = data.target
</code></pre>
<h3>实例化分箱器并进行训练</h3>
<pre><code class="language-python">optb = OptimalBinning(name=variable, dtype=&quot;numerical&quot;, prebinning_method=&quot;cart&quot;) #实例化分箱器，dtype是指将要分箱的变量的数据类型，这里使用&quot;numerical&quot;，代表变量为数值，prebinning_method是使用的分箱方法，这里使用“cart”

optb.fit(x, y)  #分箱
</code></pre>
<h3>输出分箱结果</h3>
<pre><code class="language-python">binning_result = optb.binning_table.build() #使用build方法会输出为一个dataframe，方便使用pandas读取
</code></pre>
<p>打印<code>binning_result</code>之后会看到一个如下样式的表格：</p>
<img width="628" alt="image" src="https://github.com/user-attachments/assets/a23f875d-f893-4d41-9ecb-ec7ceecb7a05">
<p>其中每一列的含义如下：</p>
<ul>
<li><strong>Bin</strong>: 由最优切分点界定的区间。</li>
<li><strong>Count</strong>: 每个区间内记录的数量。</li>
<li><strong>Count (%)</strong>: 每个区间内记录的百分比。</li>
<li><strong>Non-event</strong>: 每个区间内非事件记录的数量（𝑦=0）。</li>
<li><strong>Event</strong>: 每个区间内事件记录的数量（𝑦=1）。</li>
<li><strong>Event rate</strong>: 每个区间内事件记录的百分比。</li>
<li><strong>WoE</strong>: 每个区间的证据权重（Weight-of-Evidence）。</li>
<li><strong>IV</strong>: 每个区间的信息值（Information Value，也称为杰弗瑞斯散度）。</li>
<li><strong>JS</strong>: 每个区间的詹森-香农散度（Jensen-Shannon divergence）。</li>
</ul>
<p>其中<code>bin</code>列就是找到的最优区间了；<code>IV</code>（Information Value）是我们在进行信用卡数据分析时用到的一个非常重要的指标，反映了特征与目标之间的相关性，后续有机会分箱评分卡模型制作的时候我会再仔细写。</p>
<h2>结语</h2>
<p>是不是非常简单！核心代码其实就三行：实例化分箱器、fit、输出分箱结果。</p>
<p>实际使用中，可以针对自己的业务场景对代码增加判断是否数值型变量、输出到 excel 等操作。</p>
<p>其实<code>optbinning</code>库还提供了很多非常好用的接口，比如只获取分箱区间、将分箱结果映射到原始数据集等等操作，大家可以从<a href="https://gnpalencia.org/optbinning/index.html">文档</a>中看到更多技巧。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/26-ru-he-dui-lian-xu-xing-shu-ju-jin-xing-fen-xiang-python.html"/>
    <published>2024-10-26T09:03:51+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/27-python-huan-jing-pei-zhi-cong-ling-kai-shi-uv-pdm-he.html</id>
    <title>Python 环境配置从零开始： uv、pdm 和 VSCode 的最佳实践</title>
    <updated>2024-11-08T15:50:23+00:00</updated>
    <content type="html"><![CDATA[<h2>前言</h2>
<p>写过好多次 Python 包管理工具和编辑器选择的 issues 了，但是很散，这里集中整合一下，一次性解决学习 Python 的新手一定会碰到的 Python 安装、环境配置、编辑器选择的问题！</p>
<h3>TL;DR</h3>
<p>推荐使用<code>uv</code>或者<code>pdm</code>这样的工具来解决管理 Python 版本、管理虚拟环境及依赖的问题。</p>
<p>编辑器推荐使用 VSCode。</p>
<h2>为什么要写这篇</h2>
<p>我在学习 Python 之初遇到了三大难题：</p>
<h3>1. 怎么下载 Python，用哪个 Python？</h3>
<p>市面上的教程大部分让我们通过 Python 官网下载 Python 解释器，但是这对于新手来说有很多问题：</p>
<ol>
<li>要选择与教程匹配的 Python 版本：为了避免因为 Python 版本不同而出现的问题，但这并不容易，</li>
<li>配置默认路径对新手来说不容易：下载后要配置路径，不然可能无法使用，这需要一些配置路径的知识</li>
<li>如何切换 Python 版本：很多情况下，我们可能已经看了很多教程，电脑上已经安装了 Python，但是版本和当前教程并不一样！</li>
</ol>
<p>我在接触 Python 的时候，经常卡在这第一步出问题，然后陷入找教程、看教程第一节、放弃、找下一个教程的死循环。</p>
<h3>2. 怎么安装三方库，安装到哪里？</h3>
<p>市面上的教程关于安装三方库的时候总是只说一句 <code>pip install</code> ，如果真的这么做了，时间久了之后，本机的 Python 环境一定会很混乱。</p>
<p>我主要学习 Python 来做数据分析工作，你懂的，数据分析的库贼多，而且互相之间大都有依赖关系。然后我有时还会想看些其他方面的教程，比如 Django、fastapi 这些。<strong>我按照教程中不断的往本机环境<code>pip install</code> ，直到把新买的 MacBook 送进天才吧！</strong></p>
<h3>3. 选择哪个编辑器？</h3>
<p>这又是一大难题，好奇心作祟的我，遵循着差生文具多的定律，把几乎所有的主流编辑器都试用了：VSCode、jupyter notebook、PyCharm CE、spyder、zed、Neovim......</p>
<p>结果就是，只顾着看这种编辑器、折腾各种配置了，真正的 Python 代码怎么写是一点没看....</p>
<p>没有完美的编辑器！这里推荐：<strong>VSCode，免费、功能强大、不局限于某个语言、跨平台、配置少、支持 jupyter notebook！</strong></p>
<p>不建议其他编辑器的原因：</p>
<ol>
<li>jupyter notebook：除了在初学或者必要场景，不推荐使用。用 jupyter 写出来的代码结构性很差，会很难学会 Python 中面向对象的概念；如果入门之后切换到其他编辑器，也会增加切换编辑器的学习成本</li>
<li>PyCharm CE：专业版好贵，社区版居然不支持 jupyter notebook，太离谱。而且在我配置的过程中，感觉配置起来也相对麻烦，一直没有搞懂各种教程中对 PyCharm 吹捧的原因是啥</li>
<li>spyder：好喜欢这种左边<code>.py</code>文件，右边类似 jupyter 一样的输出展示！但是真的太慢了，功能界面也很老旧。而且 VSCode 也可以设置为类似 spyder 这样的界面</li>
<li>zed：性能真的好快！但是会陷入到 LSP 的各种配置文档中，不配置的话，甚至 impot 语句到会报错</li>
<li>Neovim：千万不要下载！千万不要下载！千万不要下载！时间一宿一宿的过去，根本不知道干啥了</li>
</ol>
<h2>实操 Python 环境配置-仅需五步进入代码学习</h2>
<h3>1. 安装 Python 项目管理工具</h3>
<p>uv 和 pdm 二选一即可，这里以 macOS 为例：</p>
<pre><code class="language-shell"># 安装uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# or 安装pdm
curl -sSL https://pdm-project.org/install-pdm.py | python3 -
</code></pre>
<h3>2. 安装 Python</h3>
<pre><code class="language-shell">uv python install 3.11 # 使用uv安装Python，我一般会把最近的4个版本都装上，方便折腾，反正也不会把电脑搞坏
</code></pre>
<h3>3. 初始化项目并选择最低 Python 版本</h3>
<p>给每个项目单独创建一个虚拟环境，并把项目文件放在一个文件夹内管理是一个非常好的习惯。比如，我会给我学习的每个教程都单独设置一个项目文件夹。</p>
<pre><code class="language-shell">mkdir my_project # 创建文件夹，mkdir 是 make directory 的缩写
cd my_project # 进入我们创建的项目文件内，cd 是 change directory 的缩写

uv init . --python 3.9  # 使用uv初始化项目文件夹，并选择项目可接受的最低Python版本为3.9
</code></pre>
<h3>4.选择 Python 版本并添加项目依赖</h3>
<pre><code class="language-shell">uv python pin 3.11 # 指定项目的Python版本，这里指定的版本不可以比初始化的最低版本低
uv add pandas # 使用uv安装pandas依赖，这时uv会自动帮我们把pandas安装到当前项目的虚拟环境中，如果我们没有安装3.11版本，uv会帮我们自动安装
uv add numpy scipy # 使用uv同时安装多个依赖
uv remove scipy # 使用uv移除scipy
</code></pre>
<p><code>uv add</code>和<code>uv remove</code>每次运行都会帮我们自动进行依赖解析，安装最合适的三方库版本</p>
<h3>5.VSCode 配置</h3>
<p>这一步最简单，任何方式下载安装好 VSCode 之后，只需要下载 Python 插件，其他插件依据实际个人需求，比如中文界面、主题、csv 美化等等。如果想使用 jupyter 可以下载 jupyter 插件，然后在<code>.ipynb</code>文件中编辑即可</p>
<p>刚开始全部默认配置即可。VSCode 会自动帮我们完成虚拟环境识别、智能补全、错误提示等功能。</p>
<h2>最后</h2>
<p>类似 uv 和 pdm 这样的工具可以帮我们节省很多项目配置的时间，在正式学习 Python 之前先掌握他们的用法非常有必要。最后备注一些可能的疑问：</p>
<ol>
<li>
uv 和 pdm 有什么区别：<ul>
<li>功能上：基本功能完全一样，pdm 有更多的高级功能更加成熟一点</li>
<li>性能：uv 基于 rust，在依赖解析方面更快</li>
</ul>
</li>
<li>
如何生成<code>requirements.txt</code>文件：<ul>
<li>uv：<code>uv export &gt; requirements.txt</code></li>
<li>pdm：<code>pdm export -f requirements &gt; requirements.txt</code></li>
</ul>
</li>
<li>
每个项目一个环境，重复的依赖会不会特别占存储空间？<ul>
<li>不会，uv 和 pdm 都采用的中心化存储缓存，每个版本的包只有在第一次安装的时候存储一份，后续相同的版本会复用第一次安装的缓存</li>
</ul>
</li>
<li>
文档：<ul>
<li>uv：<a href="https://docs.astral.sh/uv/">https://docs.astral.sh/uv/</a></li>
<li>pdm：<a href="https://pdm-project.org/en/latest/">https://pdm-project.org/en/latest/</a></li>
</ul>
</li>
</ol>
<p>最后再提一句，编辑器就用 VSCode 就行了，千万不要瞎折腾！千万不要瞎折腾！千万不要瞎折腾！</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/27-python-huan-jing-pei-zhi-cong-ling-kai-shi-uv-pdm-he.html"/>
    <published>2024-11-03T09:53:26+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/28-pei-zhi-vscode-de-mian-fei-ai-bian-cheng-zhu-shou-ollama.html</id>
    <title>配置 VSCode 的免费 AI 编程助手：Ollama 、Groq和 Continue 扩展</title>
    <updated>2024-11-16T08:53:28+00:00</updated>
    <content type="html"><![CDATA[<p>这篇 issue 展示通过配置 Ollama 和 Continue 扩展，为 VSCode 配置免费、本地的 AI 编程助手。</p>
<p>我在体验了 cursor 之后，立即寻找类似 cursor 的免费解决方案。最终发现使用 Continue 配置自定义的 API 是相对比较简单，且实用的方法。</p>
<blockquote>
<p><strong>Ollama</strong>: 是一个开源框架，专为在本地机器上便捷部署和运行大型语言模型（LLM）而设计。使用 ollama 可以在自己的本地电脑上运行开源大模型。</p>
<p><strong>Groq</strong>: 是一家专注于人工智能芯片研发的公司，目前提供的 API key 是完全免费的</p>
<p><strong>Continue</strong>: 是一个 VSCode 的 AI 助手扩展，提供付费版本、免费但需自定义 API 两种方式配置自己要使用的 AI 模型。</p>
</blockquote>
<h2>方案一：使用 Ollama</h2>
<h3>安装 Ollama</h3>
<p>Ollama 现在支持 Windows、Linux、macOS，是一个真正意义上的跨平台本地大模型解决方案，安装使用起来也比较简单。</p>
<pre><code class="language-markdown">进入 Ollama [官网](https://ollama.com/)，点击 Download，即可完成下载安装
</code></pre>
<h3>安装本地大模型</h3>
<p>因为我的电脑内存为 16G，安装参数比较大的模型运行会比较慢，所以我这边推荐<code>qwen2.5-coder:7b</code> 或者 <code>codeqwen 7b</code>。</p>
<p>这两个模型的编程能力都比较强，并且参数只有 7b，运行在我的本地机器上还算比较流畅。</p>
<p>安装也比较简单，打开终端，每个模型大概不到 5G，运行命令后等待下载成功即可：</p>
<pre><code class="language-bash"># 如果内存吃紧可以仅安装一个
ollama run codeqwen   # 安装 codeqwen
ollama run qwen2.5-coder:7b # 安装 qwen2.5-coder:7b
</code></pre>
<h3>安装 Continue</h3>
<p>在 VSCode 的扩展商店搜索 Continue 并安装。Continue 对新用户提供可免费试用，可以使用 Claude 和 ChatGPT 的最新模型。</p>
<h3>修改 Continue 的配置文件</h3>
<p>将这段 JSON 配置粘贴入 Continue 的 config.json 中，Continue 便会自动检测本地已经安装的大模型</p>
<pre><code class="language-json">{
&quot;title&quot;: &quot;Autodetect&quot;,
&quot;provider&quot;: &quot;ollama&quot;,
&quot;model&quot;: &quot;AUTODETECT&quot;,
&quot;systemMessage&quot;: &quot;You are an expert software developer. You give helpful and concise responses.You will think in English and reply in Chinese&quot;
},
</code></pre>
<h2>方案二：使用 Groq-API</h2>
<h3>生成自己的 API key</h3>
<p>打开官方的<a href="https://console.groq.com/keys">API Keys 生成页面</a>，使用 GitHub 或者 Google 登录，然后直接点击<code>Create API Key</code>即可</p>
<h3>配置 Continue</h3>
<p>将这段 JSON 配置粘贴入 Continue 的 config.json 中，将 apikey 替换为自己的，Continue 便会自动检测 API 可以调用的大模型</p>
<pre><code class="language-json">{
&quot;model&quot;: &quot;AUTODETECT&quot;,
&quot;title&quot;: &quot;Autodetect&quot;,
&quot;apiKey&quot;: &quot;&lt;your API key&gt;&quot;,
&quot;provider&quot;: &quot;groq&quot;,
&quot;systemMessage&quot;: &quot;You are an expert software developer. You give helpful and concise responses.You will think in English and reply in Chinese &quot;
}
</code></pre>
<p>值得一提的是，groq 的生成速度非常快，而且支持调用 70b，甚至更大参数的模型，使用体验要比本地的 ollama 好上不少。</p>
<h2>结论</h2>
<p>现在给自己配置一个免费的编程助手真的不要太简单，虽然能力上还不如 Claude，但是日常使用已经非常够用了</p>
<img width="1988" alt="image" src="https://github.com/user-attachments/assets/b257d01e-3c16-4a38-b75e-413d0ce500f8">
]]></content>
    <link href="https://geoqiao.github.io/blog/28-pei-zhi-vscode-de-mian-fei-ai-bian-cheng-zhu-shou-ollama.html"/>
    <published>2024-11-16T08:53:27+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/29-2024-nian-zhong-zong-jie-kong-zhi-yu-qi-jian-chi-xia-qu.html</id>
    <title>2024年终总结：控制预期，坚持下去</title>
    <updated>2025-12-21T06:58:17+00:00</updated>
    <content type="html"><![CDATA[<p>好久不见!</p>
<p>已经好久没有更新博客了，甚至很久没有优化博客的代码实现。</p>
<p>2024 年发生了很多事情，我很感谢它。</p>
<blockquote>
<p>做一件事情需要有想法、摸索出路径，然后就是控制难度、控制自己的预期、坚持下去。</p>
</blockquote>
<h2>Python</h2>
<p>从打印第一行<code>hello world</code>开始，我断断续续学习 Python 已经 3 年了。前两年看了很多教程，但一直没有实际上手用过。</p>
<p>今年终于写了自己的第一个可以运行的 Python 项目，也就是这个搭建在 GitHub Pages 的博客。</p>
<p>今年终于凭借 Python 找到一个薪资更高的数据分析工作，尽管工作中应用仍然不多，但是学习 Python 的过程确实帮我在面试环节得到不少加分。这也算<strong>重要的是过程，而不是结果</strong>的现实验证吧！</p>
<p>我依然喜欢 Python，也更明确 Python 在我生活中的地位。Python 并不适合探索性的数据分析工作，在这方面 SQL 和 tableau 等 BI 工具的组合明显效率更高也更简单。它更适合处理一些常规的、固定化的脚本工作，更适合作为我的爱好，给我的业余生活增加一点色彩。</p>
<h2>工作</h2>
<p>今年我跳槽了，跳的很犹豫。因为很难遇到一个能看到员工闪光点，并且努力为员工争取利益的领导和没有任何勾心斗角的同事氛围了。</p>
<p>只是最后，我仍然因为薪水原因选择了离开。很难说这个决定是否正确，就留给时间检验吧。</p>
<p>新公司也很不错，大家都很强，氛围也很随和，希望我也会变得更好。</p>
<h2>感情</h2>
<p>这是今年最大的遗憾吧。</p>
<p>在一起三年之后，我们选择了分手。恋爱一旦进入谈婚论嫁阶段，经济问题总是不可避免，<code>门当户对</code>这个成语存在是有原因的。日常生活中的琐事也火上浇油，诸如情侣因为挤牙膏的方式争议而分手的离谱新闻也有其一定的真实性。</p>
<p>没有让我选择继续挽留的原因有两个：一是我没法抛弃我所有的规划去她的家乡从零开始；二是这段感情的最后一年多，我很少感受到支持和正反馈。</p>
<p>祝她好，也祝我好！</p>
<h2>生活</h2>
<p>这个问题分手后我才认真考虑，有一段时间我不知道干什么，大把的时间用来抽烟和刷无聊短视频。</p>
<p>我才发现，在一起的这几年，除了同事，认识的新朋友几乎为零。我很久没有和陌生人聊过天，很久没有和老朋友喝酒谈心。</p>
<p>最近的每个周末，我都不让自己闲下来。同事朋友邀请的饭局积极参加，很久没联系但依然欣赏的老同学也去主动联系。</p>
<p>很幸运，我从这些正向社交里学到好多东西！</p>
<h2>还有好多事情没做</h2>
<ul>
<li><input disabled="" type="checkbox"> 独自旅行一次，独自规划，独自出行</li>
<li><input disabled="" type="checkbox"> 继续学习 Python，我要继续维护这个 Python 博客，让搭建更加简单！</li>
<li><input disabled="" type="checkbox"> 继续学习英语，最近发现一个免费的口语交流网站，很不错，要坚持练习。国外出差机会之前要可以基本的口语交流</li>
<li><input disabled="" type="checkbox"> 工作也要积极向上，很多同事都有可以学习的点。要主动沟通，主动同步想法。</li>
<li><input checked="" disabled="" type="checkbox"> 要对自己更加坦诚，要对朋友真诚。就像局外人中的一个句子，人生在世，永远不要弄虚作假。</li>
<li><input checked="" disabled="" type="checkbox"> 带妈妈出去走走</li>
<li><input checked="" disabled="" type="checkbox"> 要回去看看姥姥，我很想她，但我不能经常想</li>
</ul>
]]></content>
    <link href="https://geoqiao.github.io/blog/29-2024-nian-zhong-zong-jie-kong-zhi-yu-qi-jian-chi-xia-qu.html"/>
    <published>2024-12-31T15:42:13+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/30-wo-xi-huan-dong-tian-de-xia-wu-zou-lu-qu-cheng-du-de-cha.html</id>
    <title>我喜欢冬天的下午走路去成都的茶馆喝茶</title>
    <updated>2025-02-05T12:39:28+00:00</updated>
    <content type="html"><![CDATA[<h2>记录一下</h2>
<p>今年的计划完成了一大项：带妈妈出去走走。</p>
<p>正好赶上春节期间表妹结婚，要去成都，所以回家也待不了几天，于是邀请妈妈来上海。</p>
<p>去了杭州、苏州，也再次逛了一下上海，最后去成都。</p>
<h2>收获</h2>
<p>玩的过程其实也没啥好讲的，但是有很多收获</p>
<h3>1. 我也可以旅游规划</h3>
<p>我是一个喜欢懒散的人，不想把每天的行程安排太满。这次完全按照自己的节奏规划，很轻松也很快乐！当然也离不开老妈的情绪支持，她也没有怨言去的地方太少。</p>
<p>相信接下来一个人旅行的时候也可以很快乐，这件事给了我很多自信。</p>
<h3>2. 很喜欢成都的喝茶文化</h3>
<p>加上婚礼在成都待了<span class="pangu"></span>4<span class="pangu"></span>天，其中<span class="pangu"></span>3<span class="pangu"></span>天下午都在茶馆喝茶。成都真的没什么好逛的，ifs、春熙路、天府广场、人民公园、宽窄巷子、锦里都几乎在一条路上，前后不过几公里。哪里都是饭馆、哪里都是人，其实挺千篇一律的。</p>
<p>喝茶就不一样了，便宜点<span class="pangu"></span>10<span class="pangu"></span>块钱就能坐一下午，几乎每个茶馆都做满了人。下棋的人沉默不语，看棋的人面红耳赤，真的太有意思了。我不会打麻将，感觉还有一些快乐没有体会到，但也不遗憾，我没办法从麻将里面体验到快乐。</p>
<p>成都冬天的气温也非常加分，昼夜温差很小，白天坐在室外的茶馆也不觉得冷。</p>
<h3>3. 相比历史文化景点，我更喜欢自然景点</h3>
<p>虽然历史文化有其独特魅力，但自然景观带来的宁静与放松让我感到更加舒适。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/30-wo-xi-huan-dong-tian-de-xia-wu-zou-lu-qu-cheng-du-de-cha.html"/>
    <published>2025-02-05T12:39:28+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/31-2025-nian-zhong-zong-jie-guan-zhu-zi-ji.html</id>
    <title>2025年终总结：关注自己</title>
    <updated>2026-02-23T02:33:41+00:00</updated>
    <content type="html"><![CDATA[<p>是时候回顾一下了。26<span class="pangu"></span>年已经到来，祝有缘读到这篇的朋友新年快乐！</p>
<h2>25<span class="pangu"></span>年待办进度</h2>
<p>25<span class="pangu"></span>年的待办事项基本完成</p>
<ul>
<li><input checked="" disabled="" type="checkbox"> 独自旅行一次，独自规划，独自出行</li>
</ul>
<blockquote>
<p>新加坡 citywalk 一日游</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 继续学习 Python，我要继续维护这个 Python 博客，让搭建更加简单！</li>
</ul>
<blockquote>
<p>说来惭愧，这一年没怎么维护，blog 也写的很少</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 继续学习英语，最近发现一个免费的口语交流网站，很不错，要坚持练习。国外出差机会之前要可以基本的口语交流</li>
</ul>
<blockquote>
<p>得益于工作的关系，这一年还是有不少锻炼口语的机会</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 工作也要积极向上，很多同事都有可以学习的点。要主动沟通，主动同步想法。</li>
</ul>
<blockquote>
<p>今年工作很充实，获得一个小升职，感谢领导同事的支持和帮助</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 要对自己更加坦诚，要对朋友真诚。就像局外人中的一个句子，人生在世，永远不要弄虚作假。</li>
</ul>
<blockquote>
<p>主观感觉做到了</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 带妈妈出去走走</li>
</ul>
<blockquote>
<p>上海 - 杭州 - 苏州 - 成都</p>
</blockquote>
<ul>
<li><input checked="" disabled="" type="checkbox"> 要回去看看姥姥，我很想她，但我不能经常想</li>
</ul>
<blockquote>
<p>回去了，姥爷今年也去世了</p>
</blockquote>
<h2>一些待办以外的事情</h2>
<h3>工作</h3>
<p>不得不说，目前所在的公司人才密度很高。和老板、同事们合作很开心，但压力也很大。</p>
<p>这一年也暴露出一些问题，自己经常关注于解决某个具体问题，而忽略全局视野。在做决策的时候也总是担心做的不够好，导致拖延。</p>
<h3>生活</h3>
<p>今年最大的改变就是姥爷去世了。姥姥和姥爷操劳一生，没有什么财产。最后的遗物除了一张以前农村的地契，就是我们小时候的照片了。</p>
<p>在一个从我小时候就一直使用的衣柜里面，一个盒子包着一个盒子，再打开用一张硬纸包裹着的照片。</p>
<p>关于我的部分停留在高中时代。想起来自从读大学开始，就很少回家，也很少拍照片，应该多拍点照片多回家看看的。</p>
<h3>兴趣爱好</h3>
<p>我是一个比较宅的人，前年体检又有了一点脂肪肝，今年尝试找点爱好。</p>
<p>健身：年初报了<span class="pangu"></span>3<span class="pangu"></span>个月的私教课，前期做有氧减脂，后期做一点力量训练。我很喜欢有氧的部分，但有些动作在家里做容易扰民。现在有机会也还会去跑步机慢跑<span class="pangu"></span>1<span class="pangu"></span>小时出出汗。</p>
<p>骑自行车：下半年搬家，房租更便宜一点的同时，到地铁站的距离也远了。于是购入一辆二手自行车，我很喜欢他的名字——<code>Escape</code>。好想逃跑啊！奋斗打工绝对不是人生的意义。缺点是早上出门总想左拐直接去公司，导致到公司一身汗，只有晚上到家才能洗个澡。</p>
<h3>理财</h3>
<p>是的，今年发现每个月可以剩下一点钱，于是想理财一下子。</p>
<p>从<span class="pangu"></span>2<span class="pangu"></span>月份到<span class="pangu"></span>26<span class="pangu"></span>年<span class="pangu"></span>1<span class="pangu"></span>月份：</p>
<p>A<span class="pangu"></span>股盈利<span class="pangu"></span>3.6%，估计扣掉手续费啥的，只有<span class="pangu"></span>2%左右，勉强比存银行多一点。</p>
<p>纳斯达克<span class="pangu"></span>ETF<span class="pangu"></span>盈利<span class="pangu"></span>14%(现在<span class="pangu"></span>2<span class="pangu"></span>月份只有<span class="pangu"></span>1%了)，最近一个月美股一直在横盘往下走，但还是一直在定投，当作一个长期储蓄吧。</p>
<h3>阅读</h3>
<p>今年读的书不多，在高铁上读完了《克莱因壶》，有一次在<span class="pangu"></span>yihong<span class="pangu"></span>大佬的<span class="pangu"></span>Twitter<span class="pangu"></span>上看到，于是就读了。还不错，什么是真的，什么是假的？</p>
<p>看了一些理财入门书：《穷爸爸富爸爸》、《跟银行螺丝钉玩定投》、《穷查理宝典》、《如何选择成长股》、《经济学原理》读了一半。学到的东西有限，更多的是种下了资产和消费的观念、定投的习惯。现在买股票还停留在感觉、觉得价格合适就买、觉得不合适就卖。幸运的是整体上没有亏损，但是其中有几笔交易，买了之后一直亏，越加越亏。</p>
<h3>一些其他</h3>
<p>发现自己在做事情的时候，还是很在意别人的看法，总是得等到自己觉得完美才敢做。这样其实很不好。我想再次告诉自己，完美主义害人害己，一定要开始做。</p>
<h2>26 年待办</h2>
<ul>
<li><input disabled="" type="checkbox"> 理财：熟悉常看的一些技术指标、学会看公司财报，26<span class="pangu"></span>年收益率<span class="pangu"></span>4%+</li>
<li><input disabled="" type="checkbox"> 健康：坚持骑自行车和偶尔慢跑</li>
<li><input disabled="" type="checkbox"> 社交：与为数不多的朋友多见面，上海的同事一年<span class="pangu"></span>3<span class="pangu"></span>次以上、杭州的好友一年<span class="pangu"></span>4<span class="pangu"></span>次以上、老家的发小至少一年<span class="pangu"></span>1<span class="pangu"></span>次</li>
<li><input disabled="" type="checkbox"> 阅读：读更多的理财相关书籍，偏向技术指标学习</li>
<li><input disabled="" type="checkbox"> 旅游：一次<span class="pangu"></span>3<span class="pangu"></span>天以上的一人行</li>
<li><input disabled="" type="checkbox"> 学习：尝试报一个线上硕士课程或者读一个非全日制硕士</li>
<li><input disabled="" type="checkbox"> 多拍照片，制作一个实体相册</li>
</ul>
<h2>总结</h2>
<p>2025<span class="pangu"></span>年过去了，30<span class="pangu"></span>岁到了，很多事情都已发生。愿我可以永远策马扬鞭、坦诚对待自己。</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/31-2025-nian-zhong-zong-jie-guan-zhu-zi-ji.html"/>
    <published>2026-02-21T14:35:26+00:00</published>
  </entry>
  <entry>
    <id>https://geoqiao.github.io/blog/32-vibe-coding-shi-zhan-hou-gan-github-blog-with-trae.html</id>
    <title>Vibe Coding 实战后感 - github_blog with Trae</title>
    <updated>2026-03-21T10:02:38+00:00</updated>
    <content type="html"><![CDATA[<h2>TL:DR</h2>
<p>我使用 Trae IDE 对我的 github_blog 项目做了一些迭代。与之前不同的是，这次完全<code>vibe coding</code>，没有手写一行代码。</p>
<blockquote>
<p>也许以后真的只需要自然语言编程，设置好明确的准出条件，剩下的就完全交给 AI 去做就好了。</p>
</blockquote>
<h2>为什么要迭代</h2>
<p>正如项目<code>README.md</code>中所写：想要一个更好看的前端</p>
<h3>一些背景</h3>
<p>这个博客搭建在 GitHub Pages 上，由 Python、GitHub Actions 实现自动更新。</p>
<p>逻辑很简单：</p>
<ol>
<li>写 issue</li>
<li>GitHub Actions 捕捉每一次 issue 变更运行 python 脚本</li>
<li>python 读取 issues，并将 issue 渲染为 HTML(Jinja2)</li>
</ol>
<p>但是有一个痛点：我不会写 JS 和 CSS。</p>
<p>所以第一版前端界面长这样：</p>
<img width="1280" height="747" alt="Image" src="https://github.com/user-attachments/assets/6ad6413e-d305-4f91-a279-626be0fc9cb5" />
<p>我当然很不满意呀！</p>
<h2>怎么做</h2>
<p>当然是让 AI 来帮我写前端！</p>
<h3>Why Trae ?</h3>
<ol>
<li>GitHub Copilot：我日常工作中 GitHub Copilot 基本可以满足需求，但是免费版额度不够</li>
<li>Cursor：相当明星的产品，但是我只试用过，没有付费</li>
<li><strong>价格</strong>：刷到 Trae 的一些博客，性价比很高，只要 7.5$一个月</li>
<li>至于其他比如 Claude Code：我确实不是职业开发，感觉价格很高，但是我很难物尽其用</li>
</ol>
<h3>过程</h3>
<p>整个过程其实很简单，<strong>给 Trae 一张图，然后让 Trae 自己改</strong>，我只需要每次点击确认。当然我不希望它随意改动我的主体 python 代码，担心它搞砸主体逻辑。</p>
<ol>
<li>10min 不到，整体的模板框架已经出来了，</li>
<li>然后就是字体、颜色、暗黑模式、目录悬浮、缩进等等一些小需求的顶点优化</li>
<li>回头一看，不到 2 个小时，前端就变成了下面这样，大呼牛逼 👍</li>
</ol>
<img width="3024" height="1964" alt="Image" src="https://github.com/user-attachments/assets/731f4455-f8d2-477e-8b12-fd0ec02acd46" />
<h2>回顾</h2>
<h3>自己确实落伍了</h3>
<p>Trae 只是一个普通的 AI 编程工具而已，看风评远没有 Claude Code、Codex 等产品优秀。然而已经可以理解本地项目，并写一个符合项目规范的前端模板。</p>
<h3>核心永远是：上下文和提示词</h3>
<blockquote>
<p>纯主观感受，不一定对</p>
</blockquote>
<p>不管是 system prompt、还是 skills，本质上都是提示词工程，只不过在实现工程上变得更有巧思。让大模型可以读取特定的提示词，提升某方面的能力。</p>
<p>MCP 和 web search 可以通过工具调用的方式增加特定方面的上下文，让模型做的选择更加符合现状，而不是瞎猜。</p>
<h3>痛点在回滚和环境隔离</h3>
<p>虽然 Trae 已经有 sand-box 隔离，但是一旦它搞错，或者自己想回滚的时候，一些实际发生的命令是不可逆的。比如创建、删除文件。刚开始没有提醒它用<code>uv</code>，结果在系统 python 环境下，用<code>PIP</code>装了一堆乱七八糟的库.</p>
<p>这些终端命令实打实的运行在自己的系统上，风险真是很大。也许后面会演变出一个专门隔离 agent 的系统，直到项目完全符合准出才应用到生产环境？</p>
]]></content>
    <link href="https://geoqiao.github.io/blog/32-vibe-coding-shi-zhan-hou-gan-github-blog-with-trae.html"/>
    <published>2026-03-21T09:54:26+00:00</published>
  </entry>
</feed>
