<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python on Margrop Blog</title>
    <link>https://blog.margrop.net/en/tag/python/</link>
    <description>Recent content in Python on Margrop Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <lastBuildDate>Sat, 11 Jul 2026 08:30:00 +0800</lastBuildDate>
    <atom:link href="https://blog.margrop.net/en/tag/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Password Was Right—So Why Did Synology Reject It? Rebuilding DSM’s RSA &#43; AES WebAPI Login</title>
      <link>https://blog.margrop.net/en/post/synology-webapi-login-encryption-deep-dive/</link>
      <pubDate>Sat, 11 Jul 2026 08:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/synology-webapi-login-encryption-deep-dive/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The short version&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Some Synology WebAPI clients do more than post &lt;code&gt;account&lt;/code&gt; and &lt;code&gt;passwd&lt;/code&gt; to &lt;code&gt;auth.cgi&lt;/code&gt;. The implementation preserved in OpenStack Cinder first calls &lt;code&gt;SYNO.API.Encryption.getinfo&lt;/code&gt;, receives an RSA public modulus, server time, and two dynamic field names, then generates a one-use passphrase. RSA PKCS#1 v1.5 encrypts that passphrase; an OpenSSL-compatible AES-256-CBC envelope encrypts the URL-encoded login parameters; both Base64 values are finally placed inside the server-provided &lt;code&gt;cipherkey&lt;/code&gt; field.&lt;/p&gt;&#xA;&lt;p&gt;This is an authorized WebAPI compatibility technique—not a password bypass. A SID for &lt;code&gt;session=DSM&lt;/code&gt; is also not automatically the same thing as a complete browser UI login state. Parameter encryption does not replace HTTPS, because TLS still authenticates the server and protects integrity against an active intermediary.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Original cover: an RSA outer envelope and AES inner envelope protect a NAS login&#34; src=&#34;https://blog.margrop.net/post-images/synology-webapi-login-encryption-deep-dive/00-cover-original.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ubuntu shutdown stuck for 90 seconds? A Python asyncio service that won&#39;t honour SIGTERM, and how to fix it</title>
      <link>https://blog.margrop.net/en/post/ubuntu-shutdown-stuck/</link>
      <pubDate>Fri, 19 Jun 2026 10:58:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/ubuntu-shutdown-stuck/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;After upgrading my home proxy box to Ubuntu 24.04, &lt;code&gt;systemctl reboot&lt;/code&gt; stopped being fast: SSH would hang on for &lt;strong&gt;90 seconds&lt;/strong&gt; before the box actually shut down. &lt;code&gt;journalctl&lt;/code&gt; made it obvious: &lt;code&gt;smart-proxy.service: State &#39;stop-sigterm&#39; timed out. Killing.&lt;/code&gt; — systemd sent SIGTERM, waited 90 seconds, nobody reacted, and SIGKILL was the only option left.&lt;/p&gt;&#xA;&lt;p&gt;The root cause is not systemd&amp;rsquo;s fault and not Ubuntu&amp;rsquo;s fault. It is &lt;strong&gt;Python&amp;rsquo;s asyncio runtime not actually ending its child tasks when SIGTERM arrives&lt;/strong&gt; — it is parked on a &lt;code&gt;socket.recv&lt;/code&gt; and never voluntarily looks at the signal queue.&lt;/p&gt;&#xA;&lt;p&gt;The fix has two halves, both required: &lt;strong&gt;(1)&lt;/strong&gt; a systemd drop-in that lowers &lt;code&gt;TimeoutStopSec&lt;/code&gt; from the default 90s down to 20s on the affected Python units; &lt;strong&gt;(2)&lt;/strong&gt; inside the Python service itself, walk &lt;code&gt;asyncio.all_tasks()&lt;/code&gt;, &lt;code&gt;.cancel()&lt;/code&gt; the in-flight connection handlers on SIGTERM, and wrap &lt;code&gt;self.stop()&lt;/code&gt; in &lt;code&gt;asyncio.wait_for(..., timeout=10)&lt;/code&gt; as a safety net. After both halves, the same &lt;code&gt;reboot&lt;/code&gt; drops from 90 seconds to one second.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Python App in macOS LaunchAgent Can&#39;t Reach the Internet? Here&#39;s the httpx Proxy Trap You Need to Know</title>
      <link>https://blog.margrop.net/en/post/macos-launchagent-python-httpx-proxy-no-route-to-host/</link>
      <pubDate>Sat, 30 May 2026 09:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/macos-launchagent-python-httpx-proxy-no-route-to-host/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;When a Python application using httpx with &lt;code&gt;trust_env=True&lt;/code&gt; runs inside a macOS LaunchAgent, it silently picks up the system proxy settings from &lt;code&gt;scutil --proxy&lt;/code&gt;. But the LaunchAgent process may not be able to reach that proxy server at all — resulting in &lt;code&gt;All connection attempts failed&lt;/code&gt; or &lt;code&gt;No route to host&lt;/code&gt; errors.&lt;/p&gt;&#xA;&lt;p&gt;The fix is one line: add &lt;code&gt;NO_PROXY=*&lt;/code&gt; to the LaunchAgent&amp;rsquo;s plist &lt;code&gt;EnvironmentVariables&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This article documents the full debugging journey: from discovering that my AI Agent&amp;rsquo;s WeChat Enterprise (WeCom) messages weren&amp;rsquo;t being replied to, through methodical proxy troubleshooting, to finally pinning down the root cause — macOS system proxy + LaunchAgent network isolation. We&amp;rsquo;ll dive deep into Python httpx source code, macOS proxy architecture, and the many gotchas of LaunchAgent runtime environments.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>The Complete AI Agent Migration Guide: A Real-World Journey from Scratch with 9 Pitfalls and Fixes</title>
      <link>https://blog.margrop.net/en/post/ai-agent-complete-migration-guide-from-scratch/</link>
      <pubDate>Sat, 30 May 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/ai-agent-complete-migration-guide-from-scratch/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Migrating from one AI Agent platform to another sounds like a &amp;ldquo;copy and paste&amp;rdquo; job. In reality, it&amp;rsquo;s a systems engineering challenge involving data migration, channel integration, scheduled tasks, auto-start configuration, proxy settings, and module compatibility.&lt;/p&gt;&#xA;&lt;p&gt;This article documents my complete migration journey: from installing the new platform, migrating memories and skills, configuring messaging channels, debugging mysterious failures, to achieving fully automated operation. 9 pitfalls encountered, 9 solutions found — all shared here.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Clawd Code Quick Architecture Read: One Page to Understand the Python-First Rewrite Workspace</title>
      <link>https://blog.margrop.net/en/post/clawd-code-architecture-quick-read/</link>
      <pubDate>Tue, 31 Mar 2026 21:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/clawd-code-architecture-quick-read/</guid>
      <description>&lt;p&gt;The latest &lt;code&gt;margrop/clawd-code&lt;/code&gt; codebase is no longer just a preserved source archive. It is now a very explicit &lt;strong&gt;Python-first porting workspace&lt;/strong&gt;: &lt;code&gt;src/&lt;/code&gt; is the active implementation surface, &lt;code&gt;tests/&lt;/code&gt; is the verification layer, &lt;code&gt;archive/claude_code_ts_snapshot/&lt;/code&gt; is an optional local archive, and &lt;code&gt;src/reference_data/&lt;/code&gt; is the source of mirrored command and tool inventories.&lt;/p&gt;&#xA;&lt;p&gt;This short post answers one question only: &lt;strong&gt;how is the workspace organized right now?&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog.margrop.net/post-images/clawd-code-quick-overview.svg&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Clawd Code Latest Code Analysis: How a Python-First Claude Code Rewrite Organizes Commands, Tools, Sessions, and Audit</title>
      <link>https://blog.margrop.net/en/post/claude-code-daofa-tishu-source-code-analysis/</link>
      <pubDate>Tue, 31 Mar 2026 20:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/claude-code-daofa-tishu-source-code-analysis/</guid>
      <description>&lt;p&gt;After reading the latest code in &lt;code&gt;margrop/clawd-code&lt;/code&gt;, the main change is obvious: this repository is no longer just an archive of the leaked Claude Code tree. It is now a &lt;strong&gt;Python-first porting workspace&lt;/strong&gt;. The tracked tree centers on &lt;code&gt;src/&lt;/code&gt; as active implementation, &lt;code&gt;tests/&lt;/code&gt; as verification, &lt;code&gt;archive/claude_code_ts_snapshot/&lt;/code&gt; as an optional local archive, and &lt;code&gt;src/reference_data/&lt;/code&gt; as the mirrored data source for commands, tools, and surface coverage.&lt;/p&gt;&#xA;&lt;p&gt;That changes the question. We are no longer asking only “what did the original source look like?” We are asking:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;can the old system be reorganized into a maintainable Python workspace?&lt;/li&gt;&#xA;&lt;li&gt;can commands, tools, sessions, permissions, and startup order be modeled explicitly?&lt;/li&gt;&#xA;&lt;li&gt;how much of the original surface is mirrored today?&lt;/li&gt;&#xA;&lt;li&gt;which parts are already runnable, and which parts are still skeletal?&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;That is why I rewrote this post. The previous version still revolved around the leaked snapshot itself. This version needs to talk about the &lt;strong&gt;new engineering object&lt;/strong&gt;: the rewrite workspace.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog.margrop.net/post-images/clawd-code-architecture-2026.svg&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Python-based way to keep China Telecom Cloud PC awake</title>
      <link>https://blog.margrop.net/en/post/automating-connections-to-ctyun-desktop-using-python/</link>
      <pubDate>Tue, 18 Jun 2024 17:41:35 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/automating-connections-to-ctyun-desktop-using-python/</guid>
      <description>&lt;h4 id=&#34;principle-regularly-connect-to-china-telecom-cloud-desktop-interval-must-be-less-than-1-hour&#34;&gt;Principle: Regularly connect to China Telecom Cloud Desktop (interval must be less than 1 hour)&lt;/h4&gt;&#xA;&lt;h5 id=&#34;step-1-obtain-request-data&#34;&gt;Step 1: Obtain Request Data&lt;/h5&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Open Chrome browser&amp;rsquo;s Developer Tools&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;In Chrome browser, press &lt;code&gt;F12&lt;/code&gt; or right-click and select &lt;code&gt;Inspect&lt;/code&gt; to open Developer Tools.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Visit and log in to China Telecom Cloud Desktop&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Visit &lt;code&gt;https://pc.ctyun.cn&lt;/code&gt; and log in to Cloud PC with your account.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Copy the curl command for the connect request&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;In Developer Tools, select the &lt;code&gt;Network&lt;/code&gt; tab, find and click on the request named &lt;code&gt;connect&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Right-click on this request and select &lt;code&gt;Copy as cURL (cmd)&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Obtain authData from localStorage&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;In Developer Tools, select the &lt;code&gt;Application&lt;/code&gt; tab.&lt;/li&gt;&#xA;&lt;li&gt;In the left sidebar, find &lt;code&gt;Local Storage&lt;/code&gt; and select &lt;code&gt;https://pc.ctyun.cn&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Find the &lt;code&gt;authData&lt;/code&gt; key and copy its corresponding value.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;</description>
    </item>
    <item>
      <title>Issue where pip becomes unusable after pip install --upgrade pip on CentOS 7: ImportError: No module named typing</title>
      <link>https://blog.margrop.net/en/post/centos-7-no-module-named-typing-after-upgrade-pip/</link>
      <pubDate>Wed, 16 Jun 2021 11:13:46 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/centos-7-no-module-named-typing-after-upgrade-pip/</guid>
      <description>&lt;h1 id=&#34;problem-description&#34;&gt;Problem Description&lt;/h1&gt;&#xA;&lt;p&gt;pip安装某第三方 SDK，提示升级 pip，按提示升级 pip 后报错&lt;/p&gt;&#xA;&lt;h2 id=&#34;pip-upgrade-command-that-causes-the-error&#34;&gt;pip Upgrade Command that Causes the Error&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install --upgrade pip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;pip-error-message&#34;&gt;pip Error Message&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Traceback &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;most recent call last&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/bin/pip&amp;#34;&lt;/span&gt;, line 9, in &amp;lt;module&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_entry_point&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;pip==21.1.2&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;console_scripts&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;pip&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/lib/python2.7/site-packages/pkg_resources.py&amp;#34;&lt;/span&gt;, line 378, in load_entry_point&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; get_distribution&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;dist&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;.load_entry_point&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;group, name&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/lib/python2.7/site-packages/pkg_resources.py&amp;#34;&lt;/span&gt;, line 2566, in load_entry_point&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ep.load&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/lib/python2.7/site-packages/pkg_resources.py&amp;#34;&lt;/span&gt;, line 2260, in load&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    entry &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; __import__&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;self.module_name, globals&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;,globals&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;__name__&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/lib/python2.7/site-packages/pip/__init__.py&amp;#34;&lt;/span&gt;, line 1, in &amp;lt;module&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    from typing import List, Optional&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ImportError: No module named typing&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Python3 object-oriented programming</title>
      <link>https://blog.margrop.net/en/post/python3-oop/</link>
      <pubDate>Thu, 04 Mar 2021 22:23:55 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-oop/</guid>
      <description>Object-oriented programming Access restrictions Private variables start with __ class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print(&amp;#39;%s: %s&amp;#39; % (self.name, self.score)) Inheritance and polymorphism Inheritance: Dog inherits from Animal class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print(&amp;#39;%s: %s&amp;#39; % (self.__name, self.__score)) Get object information Basic object types Object type of a function or class Type checking Reflection: use dir() to get all properties and methods of an object Reflection: getattr(), setattr(), and hasattr() Interfaces and duck typing class Animal(object): def run(self): print(&amp;#39;Animal is running.</description>
    </item>
    <item>
      <title>Python 3 I/O Programming</title>
      <link>https://blog.margrop.net/en/post/python3-io-programming/</link>
      <pubDate>Fri, 26 Feb 2021 10:29:31 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-io-programming/</guid>
      <description>&lt;h1 id=&#34;file-reading-and-writing&#34;&gt;File Reading and Writing&lt;/h1&gt;&#xA;&lt;h2 id=&#34;read-reads-the-entire-file-at-once&#34;&gt;&lt;code&gt;read()&lt;/code&gt;: reads the entire file at once&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;with&lt;/code&gt; is similar to &lt;code&gt;try...catch&lt;/code&gt;, but simpler, and it automatically calls &lt;code&gt;close&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/path/to/file&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>How to Run Multiple Python Scripts on Mac with One Command</title>
      <link>https://blog.margrop.net/en/post/one-command-in-mac-execute-mulit-python-scripts/</link>
      <pubDate>Thu, 25 Feb 2021 15:52:15 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/one-command-in-mac-execute-mulit-python-scripts/</guid>
      <description>&lt;p&gt;There are currently 4 Python scripts, and I want to execute all 4 scripts with a single command. How can I do that?&#xA;My current approach is rather crude. I used 5 shell scripts to achieve it, but I don&amp;rsquo;t know whether there is a better way.&lt;/p&gt;&#xA;&lt;h1 id=&#34;shell-script-runallsh&#34;&gt;shell script &lt;code&gt;runAll.sh&lt;/code&gt;&lt;/h1&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;ls&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;open -a Terminal.app run17688821.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;open -a Terminal.app run49763693.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;open -a Terminal.app run857413.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;open -a Terminal.app run856853.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Python3 regular expressions</title>
      <link>https://blog.margrop.net/en/post/python3-zheng-ze-biao-da-shi/</link>
      <pubDate>Wed, 24 Feb 2021 08:38:22 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-zheng-ze-biao-da-shi/</guid>
      <description>re module s = r&amp;#39;ABC\-001&amp;#39; # Python的字符串 # 对应的正则表达式字符串不变： # &amp;#39;ABC\-001&amp;#39; Determine whether a regular expression matches &amp;gt;&amp;gt;&amp;gt; import re &amp;gt;&amp;gt;&amp;gt; re.match(r&amp;#39;^\d{3}\-\d{3,8}$&amp;#39;, &amp;#39;010-12345&amp;#39;) &amp;lt;_sre.SRE_Match object; span=(0, 9), match=&amp;#39;010-12345&amp;#39;&amp;gt; &amp;gt;&amp;gt;&amp;gt; re.match(r&amp;#39;^\d{3}\-\d{3,8}$&amp;#39;, &amp;#39;010 12345&amp;#39;) &amp;gt;&amp;gt;&amp;gt; Split a string Group &amp;gt;&amp;gt;&amp;gt; &amp;#39;a b c&amp;#39;.split(&amp;#39; &amp;#39;) [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;c&amp;#39;] Greedy matching &amp;gt;&amp;gt;&amp;gt; m = re.match(r&amp;#39;^(\d{3})-(\d{3,8})$&amp;#39;, &amp;#39;010-12345&amp;#39;) &amp;gt;&amp;gt;&amp;gt; m &amp;lt;_sre.SRE_Match object; span=(0, 9), match=&amp;#39;010-12345&amp;#39;&amp;gt; &amp;gt;&amp;gt;&amp;gt; m.group(0) &amp;#39;010-12345&amp;#39; &amp;gt;&amp;gt;&amp;gt; m.group(1) &amp;#39;010&amp;#39; &amp;gt;&amp;gt;&amp;gt; m.group(2) &amp;#39;12345&amp;#39; Compile a regular expression &amp;gt;&amp;gt;&amp;gt; re.</description>
    </item>
    <item>
      <title>Python 3 Built-in Module: HTMLParser</title>
      <link>https://blog.margrop.net/en/post/python3-htmlparser/</link>
      <pubDate>Mon, 15 Feb 2021 11:07:02 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-htmlparser/</guid>
      <description>&lt;h1 id=&#34;htmlparser&#34;&gt;HTMLParser&lt;/h1&gt;</description>
    </item>
    <item>
      <title>Python3 common string operations</title>
      <link>https://blog.margrop.net/en/post/python-string-opeation/</link>
      <pubDate>Sun, 14 Feb 2021 22:33:22 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python-string-opeation/</guid>
      <description>&lt;h1 id=&#34;python-print&#34;&gt;python print&lt;/h1&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;No line breaks (add, end=&amp;rsquo;&amp;rsquo; at the end)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;print(string,end=&amp;#39;&amp;#39;) &#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Python3 basics</title>
      <link>https://blog.margrop.net/en/post/python3-basic-learning/</link>
      <pubDate>Fri, 12 Feb 2021 14:28:13 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-basic-learning/</guid>
      <description>Python3 tutorial Python download Python3 built-in functions Base Use indentation instead of {} The end of the statement is not required; list=[&amp;hellip;] method len()/append()/insert() tuple=() immutable list map={key:value,key:value&amp;hellip;} method key in map/get(key,defaultValue)/pop(key) set=set([&amp;hellip;]) method add(key)/remove(key) function Data type: int(v), float(v), str(v), bool(v) Empty statement: pass Immutable object: None Variable parameters: *args, receives 1 tuple Keyword parameter: **kw, receives 1 dict </description>
    </item>
    <item>
      <title>Python3 web environment, including third-party and self-built</title>
      <link>https://blog.margrop.net/en/post/python3-web-runtime-environment/</link>
      <pubDate>Sun, 24 Jan 2021 13:07:30 +0800</pubDate>
      <guid>https://blog.margrop.net/en/post/python3-web-runtime-environment/</guid>
      <description>I needed to use the Python3 Web environment because of some family matters, so I collected them. The environment of the third-party website is very simple to use, but the shortcomings are also obvious. The last Python code cannot be saved.&#xA;Python3 environment provided by third-party websites So I built an environment myself, and after struggling for a long time, I finally used Docker to build it, and it was done in just a few lines of code.</description>
    </item>
  </channel>
</rss>
