<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>从冰上的水 - 软件使用</title><link href="https://zqw.ink/" rel="alternate"/><link href="https://zqw.ink/feeds/Ruan-Jian-Shi-Yong.atom.xml" rel="self"/><id>https://zqw.ink/</id><updated>2024-10-26T00:00:00+08:00</updated><entry><title>在博客中嵌入 JavaScript 之 Plotly.js</title><link href="https://zqw.ink/2024-10-26-coding-plotlyjs.html" rel="alternate"/><published>2024-10-26T00:00:00+08:00</published><updated>2024-10-26T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2024-10-26:/2024-10-26-coding-plotlyjs.html</id><summary type="html">&lt;script src="https://unpkg.com/mathjs@13.2.0/lib/browser/math.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.35.0/plotly.min.js"&gt;&lt;/script&gt;
&lt;form id="form", class="img-like"&gt;
  &lt;label for="eq"&gt;Enter an equation: f(x)=&lt;/label&gt;
  &lt;input type="text" id="eq" value="sin(x)" /&gt;
  &lt;input type="submit" value="Draw" /&gt;
&lt;/form&gt;
&lt;div id="plot" class="img-like"&gt;&lt;/div&gt;
&lt;script&gt;

        window.MathJax.loader = { load: ['output/svg'] };
        window.MathJax.startup = {
            ready() {
                MathJax.startup.defaultReady();
                draw("plot");
            }
        }

async function draw(idToPlot) {
    try {
        // compile the expression once
        const expression = document.getElementById('eq').value;
        const expr = math.compile(expression);

        // evaluate the expression repeatedly for different values of x
        const …&lt;/script&gt;</summary><content type="html">&lt;script src="https://unpkg.com/mathjs@13.2.0/lib/browser/math.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.35.0/plotly.min.js"&gt;&lt;/script&gt;
&lt;form id="form", class="img-like"&gt;
  &lt;label for="eq"&gt;Enter an equation: f(x)=&lt;/label&gt;
  &lt;input type="text" id="eq" value="sin(x)" /&gt;
  &lt;input type="submit" value="Draw" /&gt;
&lt;/form&gt;
&lt;div id="plot" class="img-like"&gt;&lt;/div&gt;
&lt;script&gt;

        window.MathJax.loader = { load: ['output/svg'] };
        window.MathJax.startup = {
            ready() {
                MathJax.startup.defaultReady();
                draw("plot");
            }
        }

async function draw(idToPlot) {
    try {
        // compile the expression once
        const expression = document.getElementById('eq').value;
        const expr = math.compile(expression);

        // evaluate the expression repeatedly for different values of x
        const xValues = math.range(-10, 10, 0.1).toArray();
        const yValues = xValues.map(function (x) {
            return expr.evaluate({ x: x })
        });

        // render the plot using plotly
        const trace1 = {
            x: xValues,
            y: yValues,
            type: 'scatter'
        };
        const layout = {
            title: 'Plot Example',
            xaxis: {title: {text: '$x$'},
			        showgrid: false,
					// linecolor: 'blue',
					// zerolinecolor: 'red'
					},
            yaxis: {title: {text: '$f(x)$'}, showgrid: false},
			paper_bgcolor: "rgba(255, 200, 200, 0)",
			plot_bgcolor: "rgba(200, 200, 255, 0)",
			gridcolor:"rgba(0, 0, 255, 1)",
			autosize: true
        };
        const config = {
            responsive: false,
        };

		await Plotly.newPlot(idToPlot, [trace1], layout, config);
        MathJax.typesetPromise();
    }
    catch (err) {
        console.error(err)
        alert(err)
    }
};

document.getElementById('form').onsubmit = function (event) {
    event.preventDefault()
    draw("plot")
};
&lt;/script&gt;
&lt;h2 id="javascript-code"&gt;JavaScript Code&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;
        window.MathJax.loader = { load: ['output/svg'] };
        window.MathJax.startup = {
            ready() {
                MathJax.startup.defaultReady();
                draw(&amp;quot;plot&amp;quot;);
            }
        }

async function draw(idToPlot) {
    try {
        // compile the expression once
        const expression = document.getElementById('eq').value;
        const expr = math.compile(expression);

        // evaluate the expression repeatedly for different values of x
        const xValues = math.range(-10, 10, 0.1).toArray();
        const yValues = xValues.map(function (x) {
            return expr.evaluate({ x: x })
        });

        // render the plot using plotly
        const trace1 = {
            x: xValues,
            y: yValues,
            type: 'scatter'
        };
        const layout = {
            title: 'Plot Example',
            xaxis: {title: {text: '$x$'},
			        showgrid: false,
					// linecolor: 'blue',
					// zerolinecolor: 'red'
					},
            yaxis: {title: {text: '$f(x)$'}, showgrid: false},
			paper_bgcolor: &amp;quot;rgba(255, 200, 200, 0)&amp;quot;,
			plot_bgcolor: &amp;quot;rgba(200, 200, 255, 0)&amp;quot;,
			gridcolor:&amp;quot;rgba(0, 0, 255, 1)&amp;quot;,
			autosize: true
        };
        const config = {
            responsive: false,
        };

		await Plotly.newPlot(idToPlot, [trace1], layout, config);
        MathJax.typesetPromise();
    }
    catch (err) {
        console.error(err)
        alert(err)
    }
};

document.getElementById('form').onsubmit = function (event) {
    event.preventDefault()
    draw(&amp;quot;plot&amp;quot;)
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mathjs.org/examples/browser/plot.html.html"&gt;https://mathjs.org/examples/browser/plot.html.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/plotly/plotly.js/pull/6073"&gt;https://github.com/plotly/plotly.js/pull/6073&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ChatGPT 4o&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="javascript"/><category term="plotly"/></entry><entry><title>博客第二次改版的说明及一些笔记</title><link href="https://zqw.ink/2024-10-24-pelican_blog.html" rel="alternate"/><published>2024-10-24T00:00:00+08:00</published><updated>2024-10-24T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2024-10-24:/2024-10-24-pelican_blog.html</id><summary type="html">
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E5%8D%87%E7%BA%A7%E8%AF%B4%E6%98%8E"&gt;升级说明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E5%8D%87%E7%BA%A7%E5%8D%9A%E5%AE%A2%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E7%AC%94%E8%AE%B0%E7%94%B1-chatgpt-%E7%94%9F%E6%88%90"&gt;升级博客过程中的笔记(由 ChatGPT 生成)&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3"&gt;类型注解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#itertoolschain"&gt;&lt;code&gt;itertools.chain&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8-%EF%B8%8F-multiprocessingqueue-%E5%AE%9E%E7%8E%B0%E7%94%9F%E4%BA%A7%E8%80%85-%E6%B6%88%E8%B4%B9"&gt;示例代码：使用 🛠️ multiprocessing.Queue 实现生产者-消费&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8--while-true-%E5%AE%9E%E7%8E%B0%E6%97%A0%E9%99%90%E5%BE%AA%E7%8E%AF%E7%9A%84%E5%BA%94%E7%94%A8"&gt;示例代码：使用 🔄 while True 实现无 …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E5%8D%87%E7%BA%A7%E8%AF%B4%E6%98%8E"&gt;升级说明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E5%8D%87%E7%BA%A7%E5%8D%9A%E5%AE%A2%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E7%AC%94%E8%AE%B0%E7%94%B1-chatgpt-%E7%94%9F%E6%88%90"&gt;升级博客过程中的笔记(由 ChatGPT 生成)&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3"&gt;类型注解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#itertoolschain"&gt;&lt;code&gt;itertools.chain&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8-%EF%B8%8F-multiprocessingqueue-%E5%AE%9E%E7%8E%B0%E7%94%9F%E4%BA%A7%E8%80%85-%E6%B6%88%E8%B4%B9"&gt;示例代码：使用 🛠️ multiprocessing.Queue 实现生产者-消费&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8--while-true-%E5%AE%9E%E7%8E%B0%E6%97%A0%E9%99%90%E5%BE%AA%E7%8E%AF%E7%9A%84%E5%BA%94%E7%94%A8"&gt;示例代码：使用 🔄 while True 实现无限循环的应用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#1-%E5%AE%9E%E7%8E%B0%E7%94%A8%E6%88%B7%E8%BE%93%E5%85%A5%E9%AA%8C%E8%AF%81"&gt;1. 实现用户输入验证&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9B%91%E5%90%AC-%EF%B8%8F"&gt;2. 服务器监听 🖥️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E5%A4%9A%E8%BF%9B%E7%A8%8B%E7%9A%84%E4%BB%BB%E5%8A%A1%E5%88%86%E9%85%8D-"&gt;3. 多进程的任务分配 👥🔄&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E5%8A%A8%E6%80%81%E5%AF%BC%E5%85%A5%E7%9A%84%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF"&gt;动态导入的使用场景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#getattr-%E7%9A%84%E7%94%A8%E6%B3%95"&gt;&lt;code&gt;getattr()&lt;/code&gt; 的用法&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81"&gt;示例代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9"&gt;注意事项&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E4%BD%BF%E7%94%A8%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9-%EF%B8%8F"&gt;使用注意事项 ⚠️&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#acknowledge"&gt;Acknowledge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="升级说明"&gt;升级说明&lt;/h2&gt;
&lt;p&gt;最近终于能抽出一些时间, 打算把博客升级一下, 修复之前的一些 bug.
但是发现之前写的程序很乱. 而且当时水平不如现在, 程序思路很乱.
这次过了两年多, 决定使用 &lt;a href="https://getpelican.com/"&gt;&lt;code&gt;Pelican&lt;/code&gt;&lt;/a&gt; 生成, 然后再使用一些插件, 自己写一些插件, 把原来的主题移植过来. 就成为了现在呈现的版本.&lt;/p&gt;
&lt;p&gt;之前自己写静态博客生成器原因是:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本站的需求比较简单&lt;/li&gt;
&lt;li&gt;想要练习写程序&lt;/li&gt;
&lt;li&gt;Hexo 等, 更新之后有时会产生一些兼容问题&lt;/li&gt;
&lt;li&gt;难以随心所欲的修改博客的样式, 添加一些新的页面, 组件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在使用 &lt;a href="https://getpelican.com/"&gt;&lt;code&gt;Pelican&lt;/code&gt;&lt;/a&gt; 的原因是&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;练习写程序. 由于博客源文件中有一些格式比较特别, 所有要自己设置一下. 这个过程中了解了 &lt;a href="https://getpelican.com/"&gt;&lt;code&gt;Pelican&lt;/code&gt;&lt;/a&gt; 的插件机制, 学些到了&lt;a href="#%E5%8D%87%E7%BA%A7%E5%8D%9A%E5%AE%A2%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E7%AC%94%E8%AE%B0%E7%94%B1-chatgpt-%E7%94%9F%E6%88%90"&gt;许多知识&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;由于现在会自己写插件, 所以兼容行问题可以自己解决了. 同时也学会了自己写主题, 可以随心所欲的修改博客的样式.&lt;/li&gt;
&lt;li&gt;之前的需求都实现了,同时还可用获得 &lt;a href="https://getpelican.com/"&gt;&lt;code&gt;Pelican&lt;/code&gt;&lt;/a&gt; 的好处. 比如: 许许多多的主题, 丰富的插件(自己写也很方便).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="升级博客过程中的笔记由-chatgpt-生成"&gt;升级博客过程中的笔记(由 ChatGPT 生成)&lt;/h2&gt;
&lt;h3 id="类型注解"&gt;类型注解&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Tuple[str, ...]：&lt;/code&gt; 这是类型注解，表示 &lt;code&gt;mandatory_properties&lt;/code&gt; 的类型是一个字符串元组（tuple），并且元组中的元素类型是字符串（str）。... 表示元组的长度是可变的，可以包含任意数量的字符串。&lt;/p&gt;
&lt;h3 id="itertoolschain"&gt;&lt;code&gt;itertools.chain&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;itertools.chain&lt;/code&gt; 是 🐍 &lt;code&gt;Python&lt;/code&gt; 标准库 &lt;code&gt;itertools&lt;/code&gt; 模块中的一个函数，用于将多个可迭代对象🔗连接在一起，生成一个连续的单个迭代器。它可以接受任意数量的可迭代对象，并依次迭代每个可迭代对象的元素，就像将它们“链接”成一个整体。&lt;/p&gt;
&lt;h3 id="示例代码使用--multiprocessingqueue-实现生产者-消费"&gt;示例代码：使用 🛠️ multiprocessing.Queue 实现生产者-消费&lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import multiprocessing  # 🛠️ 导入多进程模块
import time  # ⏳ 导入时间模块

def producer(queue):  # 🏭 生产者函数
    for i in range(5):
        print(f&amp;quot;Producing item {i}&amp;quot;)  # 🛠️ 生产物品
        queue.put(i)  # 📥 将物品放入队列
        time.sleep(1)  # ⏱️ 延时 1 秒

def consumer(queue):  # 🛍️ 消费者函数
    while True:
        item = queue.get()  # 取出队列中的一个元素 📤
        if item is None:  # 接收到 None 表示生产者已结束 🚫
            break
        print(f&amp;quot;Consuming item {item}&amp;quot;)  # 🛠️ 消费物品

if __name__ == &amp;quot;__main__&amp;quot;:
    queue = multiprocessing.Queue()  # 📦 创建队列

    # 创建生产者进程和消费者进程 👥
    producer_process = multiprocessing.Process(target=producer, args=(queue,))
    consumer_process = multiprocessing.Process(target=consumer, args=(queue,))

    # 启动生产者和消费者进程 ▶️
    producer_process.start()
    consumer_process.start()

    # 等待生产者完成 ⏳
    producer_process.join()

    # 生产者结束后，向队列中放入一个 None，通知消费者退出 🚫
    queue.put(None)

    # 等待消费者完成 ⏳
    consumer_process.join()

    print(&amp;quot;Main process is finishing.&amp;quot;)  # 🎬 主进程结束
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="示例代码使用--while-true-实现无限循环的应用"&gt;示例代码：使用 🔄 while True 实现无限循环的应用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;while True:&lt;/code&gt; 是一个常见的无限循环结构，广泛应用于需要持续运行、持续监听或者重复执行某项任务的场景中。以下是几个使用 &lt;code&gt;while True:&lt;/code&gt; 的实际例子：&lt;/p&gt;
&lt;h4 id="1-实现用户输入验证"&gt;1. 实现用户输入验证&lt;/h4&gt;
&lt;p&gt;在用户输入中，我们可以用 &lt;code&gt;while True:&lt;/code&gt; 来不断请求用户输入，直到输入满足条件为止：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;while True:  # 🔄 无限循环请求用户输入
    user_input = input(&amp;quot;Enter a number (q to quit): &amp;quot;)  # 📥 用户输入
    if user_input == &amp;quot;q&amp;quot;:
        print(&amp;quot;Quitting...&amp;quot;)  # 🚪 退出程序
        break
    try:
        number = int(user_input)
        print(f&amp;quot;You entered: {number}&amp;quot;)
    except ValueError:
        print(&amp;quot;Invalid input, please enter a number.&amp;quot;)  # ⚠️ 输入无效
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="2-服务器监听-"&gt;2. 服务器监听 🖥️&lt;/h4&gt;
&lt;p&gt;在服务器应用程序中，我们可以用 &lt;code&gt;while True:&lt;/code&gt; 来持续监听请求，例如一个简单的 TCP 服务器：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import socket  # 🌐 导入套接字模块

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建服务器套接字
server_socket.bind(('localhost', 8080))  # 绑定地址和端口
server_socket.listen(5)  # 监听连接
print(&amp;quot;Server is listening on port 8080...&amp;quot;)  # 🖥️ 服务器监听

while True:  # 🔄 持续监听客户端连接
    client_socket, address = server_socket.accept()  # 接受客户端连接
    print(f&amp;quot;Connection from {address} has been established.&amp;quot;)  # 🤝 连接建立
    client_socket.send(bytes(&amp;quot;Welcome to the server!&amp;quot;, &amp;quot;utf-8&amp;quot;))  # 发送欢迎消息
    client_socket.close()  # 关闭客户端连接
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="3-多进程的任务分配-"&gt;3. 多进程的任务分配 👥🔄&lt;/h4&gt;
&lt;p&gt;在某些场景下，可以使用 &lt;code&gt;while True:&lt;/code&gt; 来持续从队列中取任务并进行处理，如生产者-消费者模型：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import multiprocessing
import time

def worker(queue):  # 工作者函数
    while True:
        task = queue.get()  # 从队列中取任务 📤
        if task is None:  # 任务队列结束标志 🚫
            break
        print(f&amp;quot;Processing task: {task}&amp;quot;)  # 🔧 处理任务
        time.sleep(1)  # ⏱️ 模拟处理时间

if __name__ == &amp;quot;__main__&amp;quot;:
    task_queue = multiprocessing.Queue()  # 📦 创建任务队列

    # 添加任务 📋
    for i in range(5):
        task_queue.put(f&amp;quot;Task {i}&amp;quot;)

    # 添加结束标志 🚫
    task_queue.put(None)

    # 启动工作进程 ▶️
    process = multiprocessing.Process(target=worker, args=(task_queue,))
    process.start()

    # 等待进程完成 ⏳
    process.join()

    print(&amp;quot;All tasks are completed.&amp;quot;)  # 🎬 所有任务完成
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="动态导入的使用场景"&gt;动态导入的使用场景&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;__import__()&lt;/code&gt; 是 Python 中用于动态导入模块的内置函数，通常用于模块名在运行时才确定的情况，提供了一种灵活的导入机制。它在以下场景中非常有用：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;插件系统&lt;/strong&gt;：可以根据用户需求或配置文件选择性地导入某些模块。例如，某些插件可能需要在运行时按需加载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;模块管理&lt;/strong&gt;：当模块的名称是动态生成或用户输入的，使用 &lt;code&gt;__import__()&lt;/code&gt; 可以让程序根据名字导入相应的模块。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;示例代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;module_name = &amp;quot;math&amp;quot;  # 模块名可能从用户输入或配置文件中获取
module = __import__(module_name)  # 动态导入模块

# 使用导入的模块
print(module.sqrt(16))  # 输出: 4.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="getattr-的用法"&gt;&lt;code&gt;getattr()&lt;/code&gt; 的用法&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cls = getattr(module, cls_name)&lt;/code&gt; 是 Python 中一种动态获取属性的方式，用于从模块或对象中获取名称为 &lt;code&gt;cls_name&lt;/code&gt; 的属性。这里 &lt;code&gt;getattr()&lt;/code&gt; 函数被用来从 &lt;code&gt;module&lt;/code&gt; 中获取名为 &lt;code&gt;cls_name&lt;/code&gt; 的类，变量 &lt;code&gt;cls&lt;/code&gt; 最终会指向该类。&lt;/p&gt;
&lt;h4 id="示例代码"&gt;示例代码&lt;/h4&gt;
&lt;p&gt;假设你有一个模块 &lt;code&gt;shapes&lt;/code&gt;，其中定义了两个类 &lt;code&gt;Circle&lt;/code&gt; 和 &lt;code&gt;Square&lt;/code&gt;。你可以通过字符串名称动态地从模块中获取类。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;shapes.py&lt;/code&gt; 模块：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;# shapes.py
class Circle:
    def draw(self):
        print(&amp;quot;Drawing a Circle&amp;quot;)

class Square:
    def draw(self):
        print(&amp;quot;Drawing a Square&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;主代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import shapes

# 动态获取类名
cls_name = &amp;quot;Circle&amp;quot;
cls = getattr(shapes, cls_name)

# cls 现在指向 Circle 类，可以创建其实例
shape = cls()
shape.draw()  # 输出: Drawing a Circle
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="注意事项"&gt;注意事项&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;属性不存在时引发异常&lt;/strong&gt;：如果 &lt;code&gt;name&lt;/code&gt; 不存在且未提供 &lt;code&gt;default&lt;/code&gt; 参数，&lt;code&gt;getattr()&lt;/code&gt; 会引发 &lt;code&gt;AttributeError&lt;/code&gt;。为避免异常，可以传递一个默认值。&lt;pre&gt;&lt;code class="language-python"&gt;cls = getattr(module, &amp;quot;NonExistentClass&amp;quot;, None)
if cls is None:
    print(&amp;quot;Class not found&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全性问题&lt;/strong&gt;：使用 &lt;code&gt;getattr()&lt;/code&gt; 获取属性需要特别小心，因为它可以动态地访问任意属性或方法，可能会带来安全性风险。如果用户能够控制传递给 &lt;code&gt;getattr()&lt;/code&gt; 的字符串，他们可以试图访问不应暴露的内部类或方法。因此，在使用时要确保输入是可信的或经过适当的验证。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用注意事项-"&gt;使用注意事项 ⚠️&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;break&lt;/code&gt; 退出&lt;/strong&gt;：&lt;code&gt;while True:&lt;/code&gt; 是无限循环，所以为了避免程序一直运行下去，通常需要使用 &lt;code&gt;break&lt;/code&gt; 来在合适的条件下跳出循环。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能问题 🖥️&lt;/strong&gt;：在某些情况下，使用 &lt;code&gt;while True:&lt;/code&gt; 可能会导致程序占用大量 CPU 资源，因此在循环中应该使用适当的延时（如 &lt;code&gt;time.sleep()&lt;/code&gt; ⏱️) 或等待机制来减少 CPU 的占用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结束条件 🚪&lt;/strong&gt;：务必为循环设置合理的结束条件，避免程序进入死循环导致资源浪费。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;while True:&lt;/code&gt; 是一种简单但非常强大的循环结构，广泛应用于需要不断重复某些操作的场景，如输入验证、监听服务器、生产者-消费者模型等。它可以确保程序不断运行，直到某个条件触发 &lt;code&gt;break&lt;/code&gt; 退出循环，从而灵活地控制程序的执行流程。&lt;/p&gt;
&lt;h2 id="acknowledge"&gt;Acknowledge&lt;/h2&gt;
&lt;p&gt;ChatGPT&lt;/p&gt;
</content><category term="软件使用"/><category term="blog"/><category term="python"/><category term="pelican"/></entry><entry><title>旧版“关于”存档（存档于2026-01-03）</title><link href="https://zqw.ink/2024-10-23-coding-about_page_archive.html" rel="alternate"/><published>2024-10-23T00:00:00+08:00</published><updated>2024-10-23T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2024-10-23:/2024-10-23-coding-about_page_archive.html</id><summary type="html">
&lt;p&gt;本博客于 2025-12-31 进行第三次升级升级。此为升级前的一些存档。&lt;/p&gt;
&lt;h2 id="关于我"&gt;关于我&lt;/h2&gt;
&lt;h3 id="联系"&gt;联系&lt;/h3&gt;
&lt;p&gt;请 E-mail: zeqing6688@126.com&lt;/p&gt;
&lt;h2 id="关于本站"&gt;关于本站&lt;/h2&gt;
&lt;p&gt;本站内容为: 只对自己负责的 …&lt;/p&gt;</summary><content type="html">
&lt;p&gt;本博客于 2025-12-31 进行第三次升级升级。此为升级前的一些存档。&lt;/p&gt;
&lt;h2 id="关于我"&gt;关于我&lt;/h2&gt;
&lt;h3 id="联系"&gt;联系&lt;/h3&gt;
&lt;p&gt;请 E-mail: zeqing6688@126.com&lt;/p&gt;
&lt;h2 id="关于本站"&gt;关于本站&lt;/h2&gt;
&lt;p&gt;本站内容为: 只对自己负责的学习笔记, 以及生活的牢骚.&lt;/p&gt;
&lt;p&gt;本站是由 &lt;a href="https://getpelican.com/"&gt;Pelican&lt;/a&gt; 生成的静态博客, 托管于
&lt;a href="https://github.com/phyer219/phyer219.github.io"&gt;GithubPages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;文章的源格式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;org-mode 的格式, 由 &lt;a href="https://github.com/phyer219/phyer219.github.io.2.0/tree/main/zqwblog/renderer"&gt;zqwblog/renderer&lt;/a&gt; 渲染成 html. 由于是自己的写的包, 还有很多不完善的地方. 重复造轮子的目的是练习写程序.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;markdown, 由包 &lt;a href="https://python-markdown.github.io/"&gt;python-markdown&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;文章中的公式由 &lt;a href="https://www.mathjax.org/"&gt;MathJax&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;p&gt;文章中的代码块由 &lt;a href="https://highlightjs.org/"&gt;highlight.js&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;h2 id="readme-存档"&gt;README 存档&lt;/h2&gt;
&lt;p&gt;Generate by &lt;a href="https://getpelican.com/"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Use Plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pelican-plugins/sitemap"&gt;sitemap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use package:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/pallets/jinja/"&gt;jinja2&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://python-markdown.github.io/"&gt;Python-Markdown&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/sgryjp/markdown_math_escape"&gt;markdown_math_escape&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter/nbformat"&gt;nbformat&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="blog"/><category term="about"/><category term="archive"/></entry><entry><title>Arch安装deb包：为 deb 包编写 PKGBUILD 文件</title><link href="https://zqw.ink/2023-11-16-coding-makepkg-copy.html" rel="alternate"/><published>2023-11-16T00:00:00+08:00</published><updated>2023-11-16T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2023-11-16:/2023-11-16-coding-makepkg-copy.html</id><summary type="html">
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E5%89%8D%E8%A8%80"&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#makepkg-%E7%AE%80%E4%BB%8B"&gt;&lt;code&gt;makepkg&lt;/code&gt; 简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E4%B8%80%E4%B8%AA%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84-pkgbuild-%E6%96%87%E4%BB%B6"&gt;一个最简单的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E6%89%93%E5%8C%85%E6%B5%81%E7%A8%8B%E4%B8%80%E4%B8%AA%E4%B8%8D-trivial-%E7%9A%84%E6%B5%8B%E8%AF%95"&gt;打包流程（一个不 trivial 的测试）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#deb-%E5%8C%85%E7%A4%BA%E4%BE%8Bwps-office"&gt;deb 包示例：wps-office&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;使用 Arch, 或者基于 Arch 的 Manjaro 时，有些软件官方仓 …&lt;/p&gt;</summary><content type="html">
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%E5%89%8D%E8%A8%80"&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#makepkg-%E7%AE%80%E4%BB%8B"&gt;&lt;code&gt;makepkg&lt;/code&gt; 简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E4%B8%80%E4%B8%AA%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84-pkgbuild-%E6%96%87%E4%BB%B6"&gt;一个最简单的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%E6%89%93%E5%8C%85%E6%B5%81%E7%A8%8B%E4%B8%80%E4%B8%AA%E4%B8%8D-trivial-%E7%9A%84%E6%B5%8B%E8%AF%95"&gt;打包流程（一个不 trivial 的测试）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#deb-%E5%8C%85%E7%A4%BA%E4%BE%8Bwps-office"&gt;deb 包示例：wps-office&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;使用 Arch, 或者基于 Arch 的 Manjaro 时，有些软件官方仓库里没有，而网上又可以下载到编译好的二进制文件，deb包，或者rpm包。二进制文件可以直接运行，deb或者rpm包解压后，找到对应的二进制文件，也可以直接运行。&lt;/p&gt;
&lt;p&gt;但时，它们不被 &lt;code&gt;pacman&lt;/code&gt; 包管理器管理，也不能从 app lancher 里面便捷的运行。&lt;/p&gt;
&lt;p&gt;对于 deb 包，AUR库里有一个 &lt;code&gt;debtap&lt;/code&gt; 脚本，可以将 deb 包转换成 &lt;code&gt;pacman -U&lt;/code&gt; 可以直接安装的 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 格式。这个脚本非常方便，但是由于这个脚本考虑非常全面，注意普适性，这就导致有时候转换后的 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 包会出现一些问题，安装不上。&lt;/p&gt;
&lt;p&gt;用 &lt;code&gt;makepkg&lt;/code&gt; 打包软件是非常简单的事情，只是如果一点也不了解的话，会生怵。但是只要知道了它的运行机理，就会觉得非常简单，而且很多问题也就不存在了。&lt;/p&gt;
&lt;h2 id="makepkg-简介"&gt;&lt;code&gt;makepkg&lt;/code&gt; 简介&lt;/h2&gt;
&lt;p&gt;详细地介绍在 ArchWiki 里面都有介绍。在此按我的理解梳理一下。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;makepkg&lt;/code&gt; 是 Arch 系统中的一个软件，它的作用是将写好的程序源代码编译好，并且打包成 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 格式，然后发布。大家就可以下载打包好的 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 文件在 Arch 上直接安装。&lt;/p&gt;
&lt;p&gt;要想用 &lt;code&gt;makepkg&lt;/code&gt; 打包一个程序，必须先写一个 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件。系统中有一些示例文件，比如 &lt;code&gt;/usr/share/pacman/PKGBUILD.proto&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;写好了 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件，就可以直接在  &lt;code&gt;PKGBUILD&lt;/code&gt; 文件所在的目录直接运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;makepkg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就生成了 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 格式的软件包，然后 &lt;code&gt;pacman -U&lt;/code&gt; 安装就可以了。&lt;/p&gt;
&lt;h2 id="一个最简单的-pkgbuild-文件"&gt;一个最简单的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;PKGBUILD&lt;/code&gt; 文件使用的是 &lt;code&gt;shell&lt;/code&gt; 语言。最简单的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pkgname=hello-makepkg
pkgver=1.0
pkgrel=1
arch=('x86_64')

package() {
	echo &amp;quot;packaging...&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前四行定义了四个变量，是软件的名字，版本，以及运行架构。最后三行定义了一个函数，输出一行字 packaging...。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pkgname&lt;/code&gt; 、 &lt;code&gt;pkgver&lt;/code&gt; 、 &lt;code&gt;pkgrel&lt;/code&gt; 、 &lt;code&gt;arch&lt;/code&gt; 四个变量必须定义。名为 &lt;code&gt;package()&lt;/code&gt; 的函数会被 &lt;code&gt;makepkg&lt;/code&gt; 自动执行。&lt;/p&gt;
&lt;p&gt;这个最简单的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件是 trivial 的，因为它什么也没干，只是走了个过场。&lt;/p&gt;
&lt;h2 id="打包流程一个不-trivial-的测试"&gt;打包流程（一个不 trivial 的测试）&lt;/h2&gt;
&lt;p&gt;下面写一个不 trivial 的 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件。如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;# This is an example PKGBUILD file. Use this as a start to creating your own,
# and remove these comments. For more information, see 'man PKGBUILD'.
# NOTE: Please fill out the license field for your package! If it is unknown,
# then please put 'unknown'.

# Maintainer: Your Name &amp;lt;youremail@domain.com&amp;gt;
pkgname=zqwtest
pkgver=1.0
pkgrel=1
arch=('x86_64')
source=(&amp;quot;m.vsix&amp;quot;)
md5sums=('541126551a459a74e740ac6a82875d24')


prepare() {
	echo &amp;quot;prepare...&amp;quot;
}

build() {
	echo &amp;quot;building...&amp;quot;
#	pwd
#	cd ${srcdir}
#	pwd
#	mkdir diraa
}

check() {
	echo &amp;quot;checking...&amp;quot;
}

package() {
	echo &amp;quot;packaging...&amp;quot;
	mkdir ${pkgdir}/home
	cp m.vsix ${pkgdir}/home/m.vsix
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;PKGBUILD&lt;/code&gt; 文件所在的目录结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;.
├── m.vsix
└── PKGBUILD
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与之前相比，多定义了两个变量，&lt;code&gt;source&lt;/code&gt; 和 &lt;code&gt;md5sums&lt;/code&gt; 。这两个变量有什么用处呢？那应该先说一下 &lt;code&gt;makepkg&lt;/code&gt; 具体都做了什么。&lt;/p&gt;
&lt;p&gt;首先，它们通过我们定义的变量，得到软件包的名字，版本号等信息。&lt;code&gt;source&lt;/code&gt; 变量是告诉 &lt;code&gt;makepkg&lt;/code&gt; 我们打包过程中所需要的文件，它可以是一个本地文件，也可以是一个文件网址。 &lt;code&gt;makepkg&lt;/code&gt; 会获取这个文件，验证它的 md5，然后将它放在（链接）目录 &lt;code&gt;src&lt;/code&gt; 下。 &lt;code&gt;src&lt;/code&gt; 目录是 &lt;code&gt;makepkg&lt;/code&gt; 进行一些处理，比如编译，时的工作目录。&lt;/p&gt;
&lt;p&gt;接下来， &lt;code&gt;makepkg&lt;/code&gt; 依次执行四个函数 &lt;code&gt;prepare()&lt;/code&gt; 、 &lt;code&gt;build()&lt;/code&gt; 、 &lt;code&gt;check()&lt;/code&gt; 、 &lt;code&gt;package()&lt;/code&gt; 。 &lt;code&gt;prepare()&lt;/code&gt; 一般做编译前的处理，比如解压文件。 &lt;code&gt;build()&lt;/code&gt; 进行编译。&lt;code&gt;check()&lt;/code&gt; 检查编译结果。最后 &lt;code&gt;package()&lt;/code&gt; 进行打包。我们这里的 &lt;code&gt;prepare()&lt;/code&gt; 、 &lt;code&gt;build()&lt;/code&gt; 、 &lt;code&gt;check()&lt;/code&gt; 不进行操作，只输出一行文字提示。&lt;/p&gt;
&lt;p&gt;最后，我在函数 &lt;code&gt;package()&lt;/code&gt; 中，先新建了一个目录 &lt;code&gt;${pkgdir}/home&lt;/code&gt; 。这里先说明一下，  &lt;code&gt;makepkg&lt;/code&gt; 会默认定义两个变量：&lt;code&gt;${srcdir}&lt;/code&gt; 是前面提到的工作路径 &lt;code&gt;src&lt;/code&gt;；另一个 &lt;code&gt;${pkgdir}&lt;/code&gt; 是软件包的目录 &lt;code&gt;pkg/${pkgname}&lt;/code&gt; 。 &lt;code&gt;${pkgdir}&lt;/code&gt; 目录就是最终打包成 &lt;code&gt;.pkg.tar.zst&lt;/code&gt; 的目录。在安装包时，&lt;code&gt;${pkgdir}&lt;/code&gt; 会被安装对应的目录中。比如我们在这个例子中，将文件 &lt;code&gt;m.vsix&lt;/code&gt; 放在 &lt;code&gt;${pkgdir}/home/m.vsix&lt;/code&gt; ，那么我们用 &lt;code&gt;pacman -U&lt;/code&gt; 安装时，就会把 &lt;code&gt;m.vsix&lt;/code&gt; 复制到 &lt;code&gt;/home/m.vsix&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;makepkg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后，目录结构如下&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;.
├── m.vsix
├── pkg
│   └── zqwtest
├── PKGBUILD
├── src
│   ├── [Content_Types].xml
│   ├── extension
│   ├── extension.vsixmanifest
│   └── m.vsix -&amp;gt; /home/zqw/pkgtest/m.vsix
└── zqwtest-1.0-1-x86_64.pkg.tar.zst
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -U zqwtest-1.0-1-x86_64.pkg.tar.zst
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装一下，就可以看到，如我们所预期，&lt;code&gt;/home&lt;/code&gt; 目录下多了文件 &lt;code&gt;m.vsix&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;/home
├── m.vsix
└── zqw
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -R zqwtest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除软件包，就发现&lt;code&gt;/home&lt;/code&gt; 目录下的 &lt;code&gt;m.vsix&lt;/code&gt; 被删除了：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;/home
└── zqw
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更加多的例子可以去 AUR 仓库里随便找一些看。比如 &lt;a href="https://aur.archlinux.org/packages/quickapp-ide"&gt;quickapp-ide&lt;/a&gt; ，可以直接 clone 下来学习。&lt;/p&gt;
&lt;h2 id="deb-包示例wps-office"&gt;deb 包示例：wps-office&lt;/h2&gt;
&lt;p&gt;我们提前准备好 wps-office 的 deb 格式安装包，并和 &lt;code&gt;PKGBUILD&lt;/code&gt; 文件放在一起：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;.
├── PKGBUILD
└── wps-office_11.1.0.11698.XA_amd64.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;PKGBUILD&lt;/code&gt; 文件如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;# This is an example PKGBUILD file. Use this as a start to creating your own,
# and remove these comments. For more information, see 'man PKGBUILD'.
# NOTE: Please fill out the license field for your package! If it is unknown,
# then please put 'unknown'.

# Maintainer: Your Name &amp;lt;youremail@domain.com&amp;gt;
pkgname=wps-office
pkgver=11.1.0.11698
pkgrel=1
arch=('x86_64')
source=(&amp;quot;wps-office_11.1.0.11698.XA_amd64.deb&amp;quot;)
md5sums=('c80a2b32604cb2a8eb0de456a062fe30')


prepare() {
	mv wps-office_11.1.0.11698.XA_amd64.deb ${pkgver}_${pkgver}.deb
 	ar -x ${pkgver}_${pkgver}.deb
  	mkdir ${pkgname}-${pkgver}
	tar -xf data.tar.xz --directory=&amp;quot;${pkgname}-${pkgver}&amp;quot;
}


package() {
  cd &amp;quot;$pkgname-$pkgver&amp;quot;
  cp -r ./ ${pkgdir}/
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里说明一下， &lt;code&gt;deb&lt;/code&gt; 包全部解压后会有两个文件夹，&lt;code&gt;control&lt;/code&gt; 和 &lt;code&gt;data&lt;/code&gt; 。&lt;code&gt;control&lt;/code&gt; 类似于我们的  &lt;code&gt;PKGBUILD&lt;/code&gt; ，包含了软件的信息和安装过程中进行的一些操作。 &lt;code&gt;data&lt;/code&gt; 类似于 &lt;code&gt;{pkgdir}&lt;/code&gt; ，包含了需要安装的所有文件。因此我们要做的就是把 &lt;code&gt;deb&lt;/code&gt; 全部解压，然后将 &lt;code&gt;data&lt;/code&gt; 目录打包。&lt;/p&gt;
</content><category term="软件使用"/><category term="Arch"/><category term="manjaro"/><category term="makepkg"/><category term="PKGBUILD"/></entry><entry><title>matplotlib 科研作图总结</title><link href="https://zqw.ink/2023-10-12-coding-matplotlib.html" rel="alternate"/><published>2023-10-12T00:00:00+08:00</published><updated>2023-10-12T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2023-10-12:/2023-10-12-coding-matplotlib.html</id><summary type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;p&gt;结合近几年的经验，把&lt;code&gt;matplotlib&lt;/code&gt;作图常用的脚本集合在此。这包含了之前一些关于&lt;code&gt;matplotlib&lt;/code&gt;作图的博文。&lt;/p&gt;
&lt;h1 id="作图风格"&gt;作图风格&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from matplotlib import rc
def prettify_plot():
    &amp;quot;&amp;quot;&amp;quot;
    change the plot …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;p&gt;结合近几年的经验，把&lt;code&gt;matplotlib&lt;/code&gt;作图常用的脚本集合在此。这包含了之前一些关于&lt;code&gt;matplotlib&lt;/code&gt;作图的博文。&lt;/p&gt;
&lt;h1 id="作图风格"&gt;作图风格&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from matplotlib import rc
def prettify_plot():
    &amp;quot;&amp;quot;&amp;quot;
    change the plot matplotlibrc file

    To use it, please run it before plotting.

    https://matplotlib.org/stable/tutorials/introductory/customizing.html#customizing-with-matplotlibrc-files
    &amp;quot;&amp;quot;&amp;quot;
    rc('text', usetex=True)
    rc('font', family='serif', serif='Computer Modern Roman', size=8)
    # rc('legend', fontsize=10)
    # rc('mathtext', fontset='cm')
    rc('xtick', direction='in')
    rc('ytick', direction='in')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用于调整作图的字体，风格。&lt;/p&gt;
&lt;h1 id="作图尺寸布局"&gt;作图尺寸，布局&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import matplotlib.pyplot as plt
fig = plt.figure(figsize=(3.375, 3.5))# 单栏图宽度固定3.375， 双栏图宽度固定 6.75

gs = fig.add_gridspec(nrows=2, ncols=2,
                      left=.08, bottom=.1, right=.99, top=.94,
                      wspace=1, hspace=1,
                      width_ratios=[1, 2],
                      height_ratios=[1, 0.1])
ax_a = fig.add_subplot(gs[0, 0])
ax_b = fig.add_subplot(gs[0, 1])
ax_c = fig.add_subplot(gs[1, :])
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="彩图及colorbar"&gt;彩图及colorbar&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;gs = fig.add_gridspec(nrows=2, ncols=2,
                      left=.08, bottom=.1, right=.99, top=.94,
                      wspace=1, hspace=1,
                      width_ratios=[1, 2],
                      height_ratios=[1, 0.1])
ax_a = fig.add_subplot(gs[0, 0])
ax_b = fig.add_subplot(gs[0, 1])
ax_c = fig.add_subplot(gs[1, :])
ima = ax_a.imshow(np.random.randn(20, 20))
fig.colorbar(ima, cax=ax_c, orientation='horizontal')
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="自定义color-map"&gt;自定义color map&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import matplotlib as mpl


def newcmap(old):
    old_map = mpl.colormaps[old]
    cut1 = old_map(np.linspace(0, 0.5, 50))
    cut2 = old_map(np.linspace(0.5, 1, 500))
#     cut3 = old_map(np.linspace(0.6, 1, 10))
    cutall = np.concatenate([cut1, cut2])
    return ListedColormap(cutall)


print(newcmap('jet'))
plt.imshow(np.random.randn(100, 100), cmap=newcmap('jet'))
plt.colorbar()
plt.savefig('newcmap.png', transparent=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="2023-10-12-coding-matplotlib/newcmap.png" alt="image-newcamp" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="2023-10-12-coding-matplotlib/newcmap.py"&gt;newcmap.py&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="在每个子图插入-colorbar"&gt;在每个子图插入 colorbar&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np


fig = plt.figure(figsize=[8, 4])
ax_1 = fig.add_subplot(1, 2, 1)
ax_2 = fig.add_subplot(1, 2, 2)

divider1 = make_axes_locatable(ax_1)
ax_cb1 = divider1.new_horizontal(size='5%', pad=.05)
fig.add_axes(ax_cb1)

divider2 = make_axes_locatable(ax_2)
ax_cb2 = divider2.new_horizontal(size='5%', pad=.05)
fig.add_axes(ax_cb2)

im1 = ax_1.imshow(np.random.randn(100, 100), origin='lower', cmap='rainbow')
im2 = ax_2.imshow(100*np.random.randn(100, 100), origin='lower', cmap='rainbow')
fig.colorbar(im1, ax_cb1)
fig.colorbar(im2, ax_cb2)
fig.savefig('divider.png', transparent=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="2023-10-12-coding-matplotlib/divider.py"&gt;divider.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="2023-10-12-coding-matplotlib/divider.png" alt="divider" /&gt;&lt;/p&gt;
&lt;h1 id="双重坐标轴"&gt;双重坐标轴&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax00 = fig.add_subplot(1, 2, 1)
ax00twin = ax00.twiny()
ax01 = fig.add_subplot(1, 2, 2)

x = np.linspace(0, 6, 100)
xtwin = np.linspace(0, 60, 100)
ax00.plot(x, np.sin(x), 'b-')
# ax00twin.plot(xtwin, np.cos(0.1*xtwin), 'r--')
ax00twin.set_xticks([0, 100, 200])
ax00.set_xlim(0, 6)
ax00twin.set_xlim(0, 200)

ax01.plot(x, np.cos(x))
ax01.secondary_xaxis(location='top', functions=(lambda x: 2*x, lambda x: 2*x))
fig.savefig('double_ax.png', transparent=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="2023-10-12-coding-matplotlib/double_ax.png" alt="image-double_ax" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="2023-10-12-coding-matplotlib/double_ax.py"&gt;double_ax.py&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="示例-phys-rev-b-108-054313-2023-fig1"&gt;示例 Phys. Rev. B 108, 054313 (2023) fig1&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import matplotlib.pyplot as plt
from matplotlib import rc
import numpy as np
import json
import os
from types import SimpleNamespace


def get_file_name(path):
    fn = os.path.basename(path)
    fn, _ = os.path.splitext(fn)
    return fn


def prettify_plot():
    &amp;quot;&amp;quot;&amp;quot;
    change the plot matplotlibrc file

    To use it, please run it before plotting.

    https://matplotlib.org/stable/tutorials/introductory/customizing.html#customizing-with-matplotlibrc-files
    &amp;quot;&amp;quot;&amp;quot;
    rc('text', usetex=True)
    rc('font', family='serif', serif='Computer Modern Roman', size=8)
    # rc('legend', fontsize=10)
    # rc('mathtext', fontset='cm')
    rc('xtick', direction='in')
    rc('ytick', direction='in')


class FigureData:
    &amp;quot;&amp;quot;&amp;quot;
    A dict which figure data save in.
    For example:
        save:
            x1 = [1, 2, 3]
            y1 = [1, 2, 3]
            x2 = [2, 3, 4]
            y2 = [2, 3, 4]
            fd = FigureData()
            fd.add_data('x1', x1)
            fd.add_data('y1', y1)
            fd.add_data('x2', x2)
            fd.add_data('y2', y2)
            fd.save_data('mydata')
        load:
            fd = FigureData()
            fd.load_data('mydata')
            x1 = fd.d.x1
            y1 = fd.d.y1
            x2 = fd.d.x2
            y2 = fd.d.y2
    &amp;quot;&amp;quot;&amp;quot;
    def __init__(self):
        self.data = {}

    def add_data(self, name, data):
        self.data[name] = data

    def save_data(self, file_name):
        with open(file_name + '.json', 'w') as f:
            json.dump(self.data, f)

    def load_data(self, file_name):
        with open(file_name + '.json', 'r') as f:
            self.data = json.load(f)
        self.d = SimpleNamespace(**self.data)


arrowprops = {&amp;quot;color&amp;quot;: 'tab:pink',
              &amp;quot;shrink&amp;quot;: 0.05,
              &amp;quot;width&amp;quot;: 1,
              &amp;quot;headwidth&amp;quot;: 4,
              &amp;quot;headlength&amp;quot;: 7}
gap_arrowprops = {&amp;quot;color&amp;quot;: 'black',
                  &amp;quot;arrowstyle&amp;quot;: '&amp;lt;|-|&amp;gt;',
                  'shrinkA': 0,
                  'shrinkB': 0}

fd = FigureData()
fd.load_data(get_file_name(__file__)[:-4])

prettify_plot()



fig = plt.figure(figsize=(6.75, 3.5))

gs = fig.add_gridspec(nrows=100, ncols=100,
                      left=.08, bottom=.1, right=.99, top=.94,
                      wspace=1, hspace=1)

ax_a = fig.add_subplot(gs[0:40, 0:30])
ax_a_ins = ax_a.inset_axes([.12, .15, .39, .2])
ax_b = fig.add_subplot(gs[0:40, 35:65])
ax_b_ins = ax_b.inset_axes([.1, .13, .34, .23])
ax_c = fig.add_subplot(gs[0:40, 70:])
ax_c_ins = ax_c.inset_axes([.3, .65, .4, .27])
ax_d = fig.add_subplot(gs[55:, 0:20])
ax_e = fig.add_subplot(gs[55:, 23:43])
ax_f = fig.add_subplot(gs[55:, 46:66])
ax_g = fig.add_subplot(gs[55:, 69:89])
ax_cbar = fig.add_subplot(gs[56:-1, 90:92])

ax_a.plot(fd.d.on_hop_val_real, fd.d.on_hop_val_imag,
          marker='o', ms=2, lw=0, mec='none')
ax_a.set_ylabel(r'Im$[\lambda]$')
ax_a.set_xlabel(r'Re$[\lambda]$')
ax_a.xaxis.set_label_coords(.5, -.2)
ax_a.yaxis.set_label_coords(-.2, .5)
ax_a.text(-.2, .83, '(a)', transform=ax_a.transAxes)
vec_i = [-1, -2, 100, 0]
vmax = 1
vmin = 0
ax_a.annotate('(iii)', [fd.d.on_hop_val_real[vec_i[2]],
                        fd.d.on_hop_val_imag[vec_i[2]]],
              [.85, .85], arrowprops=arrowprops, textcoords='axes fraction')
ax_a.annotate('(iv)', [fd.d.on_hop_val_real[vec_i[3]],
                       fd.d.on_hop_val_imag[vec_i[3]]],
              [.1, .8], arrowprops=arrowprops, textcoords='axes fraction')
ax_a_ins.annotate('(i)', [fd.d.on_hop_val_real[vec_i[0]],
                          fd.d.on_hop_val_imag[vec_i[0]]],
                  [.6, 3.5], arrowprops=arrowprops,
                  textcoords='axes fraction')
ax_a_ins.annotate('(ii)', [fd.d.on_hop_val_real[vec_i[1]],
                           fd.d.on_hop_val_imag[vec_i[1]]],
                  [.3, 3], arrowprops=arrowprops,
                  textcoords='axes fraction')

ax_a_ins.plot(fd.d.on_hop_val_real, fd.d.on_hop_val_imag,
              marker='o', ms=3, lw=0, mec='none')
ax_a_ins.annotate('', [0, 0],
                  [-70, 10], arrowprops=gap_arrowprops)
ax_a_ins.text(-55, -1.8e6, r'$\Delta$')

ax_a_ins.set_xlim(-300, 50)
ax_a_ins.set_ylim(-2e6, 2e6)
_, connector_lines_a = ax_a.indicate_inset_zoom(ax_a_ins, edgecolor=&amp;quot;black&amp;quot;,
                                                alpha=1, lw=.7)
for cl in connector_lines_a:
    cl.set(lw=.7)

ax_b.plot(fd.d.on_no_hop_val_real, fd.d.on_no_hop_val_imag,
          marker='o', ms=3, lw=0, mec='none')
ax_b_ins.plot(fd.d.on_no_hop_val_real, fd.d.on_no_hop_val_imag,
              marker='o', ms=3, lw=0, mec='none')
ax_b_ins.set_xlim(-30, 5)
ax_b_ins.set_ylim(-1e6, 1e6)
ax_b_ins.annotate('', [0, 0],
                  [-11, 0], arrowprops=gap_arrowprops)
ax_b_ins.text(-8, 3e5, r'$\Delta$')

_, connector_lines_b = ax_b.indicate_inset_zoom(ax_b_ins, edgecolor=&amp;quot;black&amp;quot;,
                                                alpha=1, lw=.7)
for cl in connector_lines_b:
    cl.set(lw=.7)

# ax_b.set_yticks([])
ax_b.text(-.1, .83, '(b)', transform=ax_b.transAxes)
ax_b.set_xlabel(r'Re$[\lambda]$')
ax_b.xaxis.set_label_coords(.5, -.2)

ax_c.plot(fd.d.no_on_hop_val_real, fd.d.no_on_hop_val_imag,
          marker='o', ms=3, lw=0, mec='none')
ax_c.set_ylim(-1, 1)
ax_c.text(-.13, .83, '(c)', transform=ax_c.transAxes)
ax_c.set_xlabel(r'Re$[\lambda]$')
ax_c.xaxis.set_label_coords(.5, -.2)
ax_c_ins.plot(fd.d.no_on_hop_val_real, fd.d.no_on_hop_val_imag,
              marker='o', ms=3, lw=0, mec='none')
ax_c_ins.set_xlim(-200, 100)
ax_c_ins.set_ylim(-.1, .1)
ax_c_ins.annotate('', [0, 0],
                  [-65, 0], arrowprops=gap_arrowprops)
ax_c_ins.text(-55, .02, r'$\Delta$')

_, connector_lines_c = ax_c.indicate_inset_zoom(ax_c_ins, edgecolor=&amp;quot;black&amp;quot;,
                                                alpha=1, lw=.7)
for cl in connector_lines_c:
    cl.set(lw=.7)

# ax_e.plot([5], [15],
#           'gx', ms=2)
# ax_d.plot([5], [15],
#           'rx', ms=2)
# ax_f.plot([5], [15],
#           'bx', ms=2)
# ax_g.plot([5], [15],
#           color='orange', marker='x', ms=2)

im_d = ax_d.imshow(fd.d.on_hop_vecs_abs[vec_i[0]],
                   cmap='jet', origin='lower', vmax=vmax, vmin=vmin)
ax_d.text(-.3, .9, '(d)', transform=ax_d.transAxes)
ax_d.set_xlabel(r'$m$')
ax_d.set_ylabel(r'$n$')
ax_d.xaxis.set_label_coords(.5, -.2)
ax_d.yaxis.set_label_coords(-.3, .5)
ax_d.set_title('(i)')

ax_e.imshow(fd.d.on_hop_vecs_abs[vec_i[1]],
            cmap='jet', origin='lower', vmax=vmax, vmin=vmin)
ax_e.set_yticks([])
ax_e.set_xlabel(r'$m$')
ax_e.xaxis.set_label_coords(.5, -.2)
ax_e.set_title('(ii)')

ax_f.imshow(fd.d.on_hop_vecs_abs[vec_i[2]],
            cmap='jet', origin='lower', vmax=vmax, vmin=vmin)
ax_f.set_yticks([])
ax_f.set_xlabel(r'$m$')
ax_f.xaxis.set_label_coords(.5, -.2)
ax_f.set_title('(iii)')

ax_g.imshow(fd.d.on_hop_vecs_abs[vec_i[3]],
            cmap='jet', origin='lower', vmax=vmax, vmin=vmin)
ax_g.set_yticks([])
ax_g.set_xlabel(r'$m$')
ax_g.xaxis.set_label_coords(.5, -.2)
ax_g.set_title('(iv)')

ax_cbar.tick_params(size=0)
ax_cbar.set_title(r'$\rho_{nm}$')
fig.colorbar(im_d, cax=ax_cbar)
fig.savefig(get_file_name(__file__)[:-4] + '.pdf', dpi=200)
fig.savefig(get_file_name(__file__)[:-4] + '.png', dpi=200, transparent=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;画图数据：&lt;a href="2023-10-12-coding-matplotlib/fig2/fig2.json"&gt;fig2.json&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="2023-10-12-coding-matplotlib/fig2/fig2.png" alt="image-fig2" /&gt;&lt;/p&gt;
&lt;h1 id="参考资料"&gt;参考资料&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://matplotlib.org/stable/"&gt;https://matplotlib.org/stable/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><category term="软件使用"/><category term="python"/><category term="matplotlib"/></entry><entry><title>Intel AI Analytics Toolkit 加速 numpy, scipy</title><link href="https://zqw.ink/2023-04-23-coding-intel_python.html" rel="alternate"/><published>2023-04-23T00:00:00+08:00</published><updated>2023-04-23T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2023-04-23:/2023-04-23-coding-intel_python.html</id><summary type="html">
&lt;h2&gt;MATLAB&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-matlab"&gt;clear all;
clc;

a = rand(1220,1220);
tic;
for i=1:10
    fprintf("%i", i)
    eig(a);
end
toc;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;返回结果如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-matlab"&gt;12345678910Elapsed time is 6.629721 seconds.&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Python&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from scipy.linalg import eig
from time import perf_counter
import sys

a = np …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;MATLAB&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-matlab"&gt;clear all;
clc;

a = rand(1220,1220);
tic;
for i=1:10
    fprintf("%i", i)
    eig(a);
end
toc;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;返回结果如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-matlab"&gt;12345678910Elapsed time is 6.629721 seconds.&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Python&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from scipy.linalg import eig
from time import perf_counter
import sys

a = np.random.randn(1220, 1220)

tic = perf_counter()
for i in range(10):
    print(i, end='\r')
    np.linalg.eig(a)
toc = perf_counter()
print("Elapsed time is ", toc-tic)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;返回结果如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;Elapsed time is  93.00676925900007&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Intel Python&lt;/h2&gt;

&lt;p&gt;与上面相同的程序，返回结果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;Elapsed time is  7.760291491999851&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;与 MATLAB 相近的水平。&lt;/p&gt;

&lt;h2&gt;总结&lt;/h2&gt;

&lt;p&gt;Intel 优化编译版本的 python ，在底层与 MATLAB 相似，会调用多个核。
除此以外 &lt;code&gt;scipy.linalg&lt;/code&gt; 需要手动根据不同的矩阵选择不同的方法。比如对于实对称矩阵，
选择 &lt;code&gt;eigh&lt;/code&gt; 会大大提升效率。而 MATLAB 则不需要手动选择。&lt;/p&gt;

&lt;p&gt;重要的是想法，而选择什么方法，只是一种手段。&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://www.intel.com/content/www/us/en/developer/tools/oneapi/ai-analytics-toolkit.html#gs.w44gqo'&gt;Intel® AI Analytics Toolkit (AI Kit)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://www.intel.com/content/www/us/en/developer/tools/oneapi/distribution-for-python.html#gs.w44b4p'&gt;Intel® Distribution for Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="python"/><category term="intel python"/></entry><entry><title>博客2.0版本的介绍存档</title><link href="https://zqw.ink/2022-09-20-coding-blog20.html" rel="alternate"/><published>2022-09-20T00:00:00+08:00</published><updated>2022-09-20T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2022-09-20:/2022-09-20-coding-blog20.html</id><summary type="html">
&lt;h1 id="关于我"&gt;关于我&lt;/h1&gt;
&lt;p&gt;AMO PhD student&lt;/p&gt;
&lt;p&gt;研究课题: RF spectrum of strongly interacting Bose gases across d-wave resonance&lt;/p&gt;
&lt;p&gt;热爱生活, 热爱物理.&lt;/p&gt;
&lt;p&gt;业余爱好列表, 排名不分先后:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;书法: 始于初中语文课本 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">
&lt;h1 id="关于我"&gt;关于我&lt;/h1&gt;
&lt;p&gt;AMO PhD student&lt;/p&gt;
&lt;p&gt;研究课题: RF spectrum of strongly interacting Bose gases across d-wave resonance&lt;/p&gt;
&lt;p&gt;热爱生活, 热爱物理.&lt;/p&gt;
&lt;p&gt;业余爱好列表, 排名不分先后:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;书法: 始于初中语文课本最后一页的兰亭集序, 发展于本科时的书画协会.&lt;/li&gt;
&lt;li&gt;口琴: 始于高中时, 发展比较平缓, 研三在家终于调琴超吹成功.&lt;/li&gt;
&lt;li&gt;吉他: 始于高中同学拿到宿舍的一把蓝色破吉他. 研四暑假从零开始.&lt;/li&gt;
&lt;li&gt;乒乓球: 始于小学水泥台子, 发展于本科时选修的乒乓球体育课&lt;/li&gt;
&lt;li&gt;羽毛球: 始于研二时舒哥的指引, 在北园食堂上面打.&lt;/li&gt;
&lt;li&gt;植物: 蓬勃的生命!&lt;/li&gt;
&lt;li&gt;Linux: 始于研二的 deepin, 发展于 Manjaro.&lt;/li&gt;
&lt;li&gt;写程序: 始于研二, python, c, html...&lt;/li&gt;
&lt;li&gt;Latex: 必备技能.&lt;/li&gt;
&lt;li&gt;折腾: 生命!&lt;/li&gt;
&lt;li&gt;看动漫: 始于研一, 第一部是 《超时空要塞 $\Delta$ 》. 每天睡觉看一集, 研一支撑我过来的精神支柱. 睡前看的习惯持续至今, 不觉已有四年.&lt;/li&gt;
&lt;li&gt;打邦邦: BanG Dream!  始于研三因疫情在家的那个夏天, 让我体会到音乐带来的快感!&lt;/li&gt;
&lt;li&gt;跑跑卡丁车: 始于初中时时候家里刚给买了电脑, 从那就一直玩. 周五放学回家最开心的时光!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;联系请 E-mail: zeqing6688@126.com&lt;/p&gt;
&lt;p&gt;本站内容为: 只对自己负责的学习笔记, 以及生活的牢骚.&lt;/p&gt;
&lt;h1 id="关于本站"&gt;关于本站&lt;/h1&gt;
&lt;p&gt;本站是由 python 生成的静态博客, 托管于
&lt;a href="https://github.com/phyer219/phyer219.github.io.2.0"&gt;GithubPages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;文章的源格式大多采用 org-mode 的格式, 由
&lt;a href="https://github.com/phyer219/phyer219.github.io.2.0/tree/main/zqwblog/renderer"&gt;zqwblog/renderer&lt;/a&gt;
渲染成 html . 由于是自己的写的包, 还有很多不完善的地方. 重复造轮子的目的是练习写
程序.&lt;/p&gt;
&lt;p&gt;还有一部分文章的源格式是 markdown, 由包
&lt;a href="https://python-markdown.github.io/"&gt;python-markdown&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;p&gt;文章中的公式由 &lt;a href="https://www.mathjax.org/"&gt;MathJax&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;p&gt;文章中的代码块由 &lt;a href="https://highlightjs.org/"&gt;highlight.js&lt;/a&gt; 渲染.&lt;/p&gt;
&lt;p&gt;有许多现有的静态博客生成器, 如 Hexo, Jekyll, Pelican 等, 都非常优秀. 但本站还是
自己写了一个简陋的版本, 原因在于:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本站的需求比较简单&lt;/li&gt;
&lt;li&gt;想要练习写程序&lt;/li&gt;
&lt;li&gt;Hexo 等, 更新之后有时会产生一些兼容问题&lt;/li&gt;
&lt;li&gt;难以随心所欲的修改博客的样式, 添加一些新的页面, 组件&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="blog"/><category term="archive"/></entry><entry><title>最简单的调用网站api的程序</title><link href="https://zqw.ink/2022-07-31-coding-py_api.html" rel="alternate"/><published>2022-07-31T00:00:00+08:00</published><updated>2022-07-31T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2022-07-31:/2022-07-31-coding-py_api.html</id><summary type="html">
&lt;p&gt;在 themoviedb 上注册账号，申请自己的应用，获得一个 api 。之后就可以利用网站的资源进行开发了。下面是一个最简短的例子。（如果长 …&lt;/p&gt;</summary><content type="html">
&lt;p&gt;在 themoviedb 上注册账号，申请自己的应用，获得一个 api 。之后就可以利用网站的资源进行开发了。下面是一个最简短的例子。（如果长时间没有反应，那就是
api.themoviedb.org 被污染了，可以手动找到 ip，然后修改 host 文件）&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import requests
v3auth = '?api_key=你的api_key'
q = '&amp;query=' + 'lycoris'
r = requests.get('https://api.themoviedb.org/3/search/tv'+v3auth+q)
print(r.status_code)
for i in r.json()['results']:
    print(i)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;返回结果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;200
{'backdrop_path': '/cPqA1G5odxY7uVJ0i81z5E2tSSW.jpg', 'first_air_date': '2022-07-02', 'genre_ids': [16, 10759, 35], 'id': 154494, 'name': 'Lycoris Recoil', 'origin_country': ['JP'], 'original_language': 'ja', 'original_name': 'リコリス・リコイル', 'overview': "For these peaceful days――there’s a secret behind it all. A secret organization that prevents crimes: “DA - Direct Attack”. And their group of all-girl agents: “Lycoris”. This peaceful everyday life is all thanks to these young girls. The elite Chisato Nishikigi is the strongest Lycoris agent of all time. Alongside is Takina Inoue, the talented but mysterious Lycoris. They work together at one of its branches–Café LycoReco. Here, the orders this café takes range from coffee and sweets to childcare, shopping, teaching Japanese to foreign students, etc. It's mostly tasks unbefitting of Lycoris. The free-spirited and optimistic pacifist, Chisato. And the cool-headed and efficient Takina. The chaotic everyday lives of this mismatched duo begin!", 'popularity': 112.401, 'poster_path': '/dfGf0Ti3BEKpBpVCVtEXKTjQjNR.jpg', 'vote_average': 7.7, 'vote_count': 10}&lt;/code&gt;&lt;/pre&gt;
</content><category term="软件使用"/><category term="python"/><category term="api"/></entry><entry><title>scipy 数值求解微分方程, 方程组, 复微分方程组</title><link href="https://zqw.ink/2021-12-09-coding-py_ode.html" rel="alternate"/><published>2021-12-09T00:00:00+08:00</published><updated>2021-12-09T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-12-09:/2021-12-09-coding-py_ode.html</id><summary type="html">
&lt;p&gt;Some examples&lt;/p&gt;

&lt;h2&gt;1D Real&lt;/h2&gt;


$$\begin{align}
\frac{\mathrm{d}}{\mathrm{d}t}y(t) = 2 t y(t)
\end{align}$$

&lt;p&gt;exact solution is&lt;/p&gt;

$$\begin{align}
y(t) = e^{t^2}y(0)
\end{align}$$


&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint


def dy_dt …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;p&gt;Some examples&lt;/p&gt;

&lt;h2&gt;1D Real&lt;/h2&gt;


$$\begin{align}
\frac{\mathrm{d}}{\mathrm{d}t}y(t) = 2 t y(t)
\end{align}$$

&lt;p&gt;exact solution is&lt;/p&gt;

$$\begin{align}
y(t) = e^{t^2}y(0)
\end{align}$$


&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint


def dy_dt(y, t):
    return 2*t*y


ts = np.linspace(0, 1, 40)
y0 = 1
ys = odeint(dy_dt, y0, ts)

plt.plot(ts, ys, 'o', label='numerical')
plt.plot(ts, np.exp(ts**2)*y0, label='analytical')
plt.legend()
plt.xlabel('t')
plt.ylabel('y(t)')
plt.savefig('1d.png')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href='2021-12-09-coding-py_ode/1d-real.py'&gt;2021-12-09-coding-py_ode/1d-real.py&lt;/a&gt;
&lt;p&gt;&lt;img src='2021-12-09-coding-py_ode/1d-real.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;1D Complex&lt;/h2&gt;


$$\begin{align}
\frac{d}{\mathrm{d}t}\psi = f(t) \psi
\end{align}$$

&lt;p&gt;Write as&lt;/p&gt;

$$\begin{align}
\frac{\mathrm{d}}{\mathrm{d}t}
    \begin{pmatrix}
     \mathrm{Re}\psi(t) \\ \mathrm{Im}\psi(t)
    \end{pmatrix}
      =
    \begin{pmatrix}
       \mathrm{Re} f(t) &amp; -\mathrm{Im} f(t)\\
       \mathrm{Im} f(t) &amp; \mathrm{Re} f(t)
    \end{pmatrix}
    \begin{pmatrix}
     \mathrm{Re}\psi(t) \\ \mathrm{Im}\psi(t)
    \end{pmatrix}
\end{align}$$

&lt;p&gt;For example&lt;/p&gt;

$$\begin{align}
\frac{d}{\mathrm{d}t}\psi = \mathrm{i}\omega \psi
\end{align}$$

&lt;p&gt;exact solution is&lt;/p&gt;

$$\begin{align}
\psi = e^{\mathrm{i}(\omega t + \phi_0)}
\end{align}$$




&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint


omega = 1


def dPsi_dt(Psi, t, omega=omega):
    re = 0
    im = omega
    m = [[re, -im], [im, re]]
    return np.dot(m, Psi)


ts = np.linspace(0, 10, 51)
phi0 = 1
Psi0 = [np.cos(phi0), np.sin(phi0)]
Psis = odeint(dPsi_dt, Psi0, ts)

plt.plot(ts, Psis[:, 0], 'o', label=r'numerical  $\mathrm{Re}\psi(t)$')
plt.plot(ts, Psis[:, 1], 'o', label=r'numerical  $\mathrm{Im}\psi(t)$')
plt.plot(ts, np.cos(omega*ts + phi0), '-',
         label=r'analytical  $\mathrm{Re}\psi(t)$')
plt.plot(ts, np.sin(omega*ts + phi0), '-',
         label=r'analytical  $\mathrm{Im}\psi(t)$')
plt.xlabel('t')
plt.legend()
plt.savefig('1d-complex.png')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href='2021-12-09-coding-py_ode/1d-complex.py'&gt;2021-12-09-coding-py_ode/1d-complex.py&lt;/a&gt;
&lt;p&gt;&lt;img src='2021-12-09-coding-py_ode/1d-complex.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;


&lt;h2&gt;2D Real&lt;/h2&gt;

&lt;p&gt;A Van der Pol oscillator&lt;/p&gt;

$$\begin{align}
\frac{\mathrm{d}^2}{\mathrm{d}t^2}x(t)
  - \mu\left[1 - x(t)^2\right] \frac{\mathrm{d}}{\mathrm{d}t}x(t) + x(t) =0
\end{align}$$

&lt;p&gt;Can write as&lt;/p&gt;

$$\begin{align}
\frac{\mathrm{d}}{\mathrm{d}t}
   \begin{pmatrix}
    x(t) \\ x'(t)
   \end{pmatrix}
     =
   \begin{pmatrix}
    x'(t) \\
    \mu\left[1 - x(t)^2\right] x'(t) - x(t)
   \end{pmatrix}
\end{align}$$


&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from scipy.integrate import odeint


def dX_dt(X, t, mu=5):
    return [X[1], mu*(1 - X[0]**2)*X[1] - X[0]]


ts = np.linspace(0, 30, 1000)
X0 = [0, 0.1]
Xs = odeint(dX_dt, X0, ts)


fig, ax = plt.subplots()
line1, = ax.plot(Xs[0, 0], Xs[0, 1], 'o')
line2, = ax.plot(Xs[0, 0], Xs[0, 1], '-')
time_tags = ax.text(-1.5, 4, r'$t = 0$', fontsize=20)


def ani(i):
    line1.set_data(Xs[i, 0], Xs[i, 1])
    line2.set_data(Xs[:i, 0], Xs[:i, 1])
    time_tags.set_text(r'$t=$' + f'{i:n}')
    return None


ax.set_xlim(min(Xs[:, 0]), max(Xs[:, 0]))
ax.set_ylim(min(Xs[:, 1]), max(Xs[:, 1]))
plt.xlabel(r'$x(t)$')
plt.ylabel(r'$x\prime(t)$')
anifig = animation.FuncAnimation(fig=fig, func=ani, frames=len(Xs),
                                 interval=.1)
ax.grid()
anifig.save('2d-real.gif', writer='imagemagick')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href='2021-12-09-coding-py_ode/2d-real.py'&gt;2021-12-09-coding-py_ode/2d-real.py&lt;/a&gt;
&lt;p&gt;&lt;img src='2021-12-09-coding-py_ode/2d-real.gif' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;2D Complex&lt;/h2&gt;

&lt;p&gt;Rabi oscillation(ref: another post)&lt;/p&gt;

$$\begin{align*}
  \mathrm{i}\hbar\dot{c}_1 =&amp;
       \gamma e^{\mathrm{i}(\omega-\omega_{21})t} c_2 \tag{1}\\
    \mathrm{i}\hbar\dot{c}_2 =&amp;\gamma e^{-\mathrm{i}(\omega-\omega_{21})t}  c_1\tag{2}
\end{align*}$$

&lt;p&gt;exact solution is&lt;/p&gt;

$$\begin{align}
  |c_2(t)|^2 = \frac{1}{1+\frac{\hbar^2(\omega-\omega_{21})^2}{4\gamma^2}}\sin^2\left(
  \Omega t \right)
\end{align}$$

&lt;p&gt;where&lt;/p&gt;

$$\begin{align}
  \Omega = \sqrt{\frac{(\omega-\omega_{21})^2}{4}+\frac{\gamma^2}{\hbar^2}}
\end{align}$$


&lt;p&gt;In numerical calculation, we set $\hbar = 1, \gamma = 1, \Delta\omega = \omega - \omega_{21}$ , then&lt;/p&gt;

$$\begin{align}
\frac{\mathrm{d}}{\mathrm{d}t}
   \begin{pmatrix}
     \mathrm{Re} c_1 \\  \mathrm{Im} c_1 \\ \mathrm{Re}c_2 \\ \mathrm{Im}c_2
   \end{pmatrix}
      =
   \begin{pmatrix}
      0 &amp; 0 &amp; \sin\Delta\omega t &amp; \cos\Delta\omega t \\
      0 &amp; 0 &amp; -\cos\Delta\omega t &amp; \sin\Delta\omega t \\
      -\sin\Delta\omega t &amp; \cos\Delta\omega t  &amp; 0 &amp; 0 \\
      -\cos\Delta\omega t &amp; -\sin\Delta\omega t &amp; 0 &amp; 0 \\
   \end{pmatrix}
   \begin{pmatrix}
     \mathrm{Re} c_1 \\  \mathrm{Im} c_1 \\ \mathrm{Re}c_2 \\ \mathrm{Im}c_2
   \end{pmatrix}
\end{align}$$


&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint


domega = 1


def dC_dt(C, t, domega=domega):
    '''C = [Re c1, Im c1, Re c2, Im c2]'''
    s = np.sin(domega*t)
    c = np.cos(domega*t)
    m = [[0, 0, s, c],
         [0, 0, -c, s],
         [-s, c, 0, 0],
         [-c, -s, 0, 0]]
    return np.dot(m, C)


ts = np.linspace(0, 5, 51)
C0 = [1, 0, 0, 0]
Cs = odeint(dC_dt, C0, ts)


plt.plot(ts, Cs[:, 0]**2+Cs[:, 1]**2, 'o', label=r'numerical $|c_1(t)|^2$')
plt.plot(ts, Cs[:, 2]**2+Cs[:, 3]**2, 'o', label=r'numerical $|c_2(t)|^2$')

plt.plot(ts, np.sin(np.sqrt(domega**2/4 + 1)*ts)**2 / (1 + domega**2/4),
         label=r'analytical $|c_2(t)|^2$')
plt.ylim(0, 1.3)
plt.legend()
plt.xlabel(r'$t$')
plt.savefig('2d-complex.png')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;file:2021-12-09-coding-py_ode/2d-complex.py
&lt;p&gt;&lt;img src='2021-12-09-coding-py_ode/2d-complex.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html'&gt;scipy.integrate.odeint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Van_der_Pol_oscillator'&gt;wikipedia: Van der Pol oscillator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="python"/><category term="ode"/><category term="Rabi"/><category term="Van der Pol oscillator"/></entry><entry><title>python matplotlib 画图小技巧: 自定义字体</title><link href="https://zqw.ink/2021-11-10-coding-matplot_fonts.html" rel="alternate"/><published>2021-11-10T00:00:00+08:00</published><updated>2021-11-10T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-11-10:/2021-11-10-coding-matplot_fonts.html</id><summary type="html">
&lt;h2&gt;问题&lt;/h2&gt;

&lt;p&gt;在用 &lt;code&gt;matplotlib&lt;/code&gt; 画图时, 使用自定义字体. 比如从一个下载好的 &lt;code&gt;.ttf&lt;/code&gt; 字体文件加载,
或者在程序无法找到系统中的字体时, 指定字 …&lt;/p&gt;</summary><content type="html">
&lt;h2&gt;问题&lt;/h2&gt;

&lt;p&gt;在用 &lt;code&gt;matplotlib&lt;/code&gt; 画图时, 使用自定义字体. 比如从一个下载好的 &lt;code&gt;.ttf&lt;/code&gt; 字体文件加载,
或者在程序无法找到系统中的字体时, 指定字体文件的位置.&lt;/p&gt;

&lt;h2&gt;Method 1&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager

fe = font_manager.FontEntry(fname='/usr/share/fonts/TTF/Times.TTF', name='tnr')
font_manager.fontManager.ttflist.append(fe)

plt.rcParams['font.family'] = fe.name
plt.rcParams['mathtext.fontset'] = 'cm'

x = np.linspace(0, 6, 51)
plt.plot(x, np.sin(x))
plt.title(r'Sin Function - Method 1')
plt.xlabel(r'$\theta$')
plt.ylabel(r'$\sin\theta$')
plt.savefig('method1.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-11-10-coding-matplot_fonts/method1.py'&gt;method1.py&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Method 2&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager

font_path = '/usr/share/fonts/TTF/Times.TTF'  # Your font path goes here
font_manager.fontManager.addfont(font_path)
prop = font_manager.FontProperties(fname=font_path)

plt.rcParams['font.family'] = prop.get_name()
plt.rcParams['mathtext.fontset'] = 'cm'  # 'cm' (Computer Modern)

x = np.linspace(0, 6, 51)
plt.plot(x, np.sin(x))
plt.title(r'Sin Function - Method 2')
plt.xlabel(r'$\theta$')
plt.ylabel(r'$\sin\theta$')
plt.savefig('method2.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-11-10-coding-matplot_fonts/method2.py'&gt;method2.py&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Result&lt;/h2&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-11-10-coding-matplot_fonts/method1.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;


&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://stackoverflow.com/questions/35668219/how-to-set-up-a-custom-font-with-custom-path-to-matplotlib-global-font'&gt;https://stackoverflow.com/questions/35668219/how-to-set-up-a-custom-font-with-custom-path-to-matplotlib-global-font&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://matplotlib.org/stable/tutorials/introductory/customizing.html#customizing-with-matplotlibrc-files'&gt;Matplotlib Documentation: A sample matplotlibrc file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://matplotlib.org/stable/users/dflt_style_changes.html?highlight=math%20font#math-text'&gt;Matplotlib Documentation: Math text&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="python"/><category term="matplotlib"/><category term="font_manager"/><category term="mathtext"/></entry><entry><title>python matplotlib 画图小技巧: 虚线的圆与虚线的五角星</title><link href="https://zqw.ink/2021-10-21-coding-dash_circle.html" rel="alternate"/><published>2021-10-21T00:00:00+08:00</published><updated>2021-10-21T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-10-21:/2021-10-21-coding-dash_circle.html</id><summary type="html">
&lt;h2&gt;问题一:&lt;/h2&gt;

&lt;p&gt;在散点图上, 用一个虚线的圆圈标出某个数据点&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath

x = np.linspace(0, 6, 20)
y = np.sin(x)
plt.plot(x …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;问题一:&lt;/h2&gt;

&lt;p&gt;在散点图上, 用一个虚线的圆圈标出某个数据点&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath

x = np.linspace(0, 6, 20)
y = np.sin(x)
plt.plot(x, y, ls='none', marker='o', mfc='none')

plt.plot(x[10], y[10], marker='o', mfc='none', ms=20)
plt.plot(x[10], y[10], marker=mpath.Path.unit_regular_star(20),
         ms=25, mfc='none', mec='white')
plt.savefig('./fig1.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-10-21-coding-dash_circle/code1.py'&gt;code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-10-21-coding-dash_circle/fig1.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;问题二:&lt;/h2&gt;

&lt;p&gt;画一个金色的的虚线边框的五角星&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import matplotlib.pyplot as plt

plt.plot([1], [1], marker=(5, 1, 0), markersize=30, mfc='none', mec='k', mew=1)

for i in range(4):
    plt.plot([1], [1], marker='o', markersize=30-5*i,
             mfc='none', mec='w', mew=1)

plt.plot([1], [1], marker=(5, 1, 0), markersize=30, mfc='gold', mec='k', mew=0)
plt.savefig('fig2.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-10-21-coding-dash_circle/code2.py'&gt;code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-10-21-coding-dash_circle/fig2.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;YK Yang 的讨论&lt;/li&gt;
&lt;li&gt;&lt;a href='https://stackoverflow.com/questions/38316746/how-to-draw-a-marker-with-dashed-dotted-edge-in-matplotlib/69658923#69658923'&gt;https://stackoverflow.com/questions/38316746/how-to-draw-a-marker-with-dashed-dotted-edge-in-matplotlib/69658923#69658923&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://matplotlib.org/stable/gallery/shapes_and_collections/marker_path.html'&gt;Marker Path&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="python"/><category term="matplotlib"/><category term="marker"/><category term="dashed"/></entry><entry><title>scipy.integrate.quad 是如何取点的, 以及记录所计算的点(update 4/April/2023)</title><link href="https://zqw.ink/2021-09-16-physics-scipy_integrate.html" rel="alternate"/><published>2021-09-16T00:00:00+08:00</published><updated>2021-09-16T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-09-16:/2021-09-16-physics-scipy_integrate.html</id><summary type="html">
&lt;h2&gt;探究 &lt;code&gt;scipy.integrate.quad&lt;/code&gt; 取点的方式&lt;/h2&gt;

&lt;p&gt;&lt;a href='2021-09-16-physics-scipy_integrate/code.py'&gt;code.py&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt

nodes = []


def foo(x):
    nodes.append(x)
    return np.exp(x) + np.sin(10*x)**2 + np.exp(x)**100


result = integrate.quad(foo, -1 …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;探究 &lt;code&gt;scipy.integrate.quad&lt;/code&gt; 取点的方式&lt;/h2&gt;

&lt;p&gt;&lt;a href='2021-09-16-physics-scipy_integrate/code.py'&gt;code.py&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt

nodes = []


def foo(x):
    nodes.append(x)
    return np.exp(x) + np.sin(10*x)**2 + np.exp(x)**100


result = integrate.quad(foo, -1, 1, epsrel=1e-125, limit=2, full_output=1)
n = np.linspace(1, len(nodes), len(nodes))
print(len(nodes))
print(len(nodes)/21)
print(result[2]['neval'])
plt.plot(n, nodes, '*')
plt.grid()
plt.title('limit = 2')
plt.xlabel(r"$i$")
plt.ylabel("position of $i$th node")
plt.savefig('fig.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-09-16-physics-scipy_integrate/fig.png' alt='fig' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;记录所计算的值&lt;/h2&gt;

&lt;p&gt;利用列表的性质，实现记录积分的过程中所计算的函数值。&lt;/p&gt;

&lt;p&gt;&lt;a href='2021-09-16-physics-scipy_integrate/code.py'&gt;quad_recorded.py&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import quad


def quad_recorded(func, *args, **kwargs):
    """
    use scipy.integrate.quad, but return the results with additional
    information "nc" and "vc".

    Returns:
        inte_res: the return of scipy.integrate.quad
              nc: the points calculated
              vc: the calculated functiona values
    """
    def func_recorded(x, node_container, value_container):
        res = func(x)
        node_container.append(x)
        value_container.append(res)
        return res
    nc = []
    vc = []
    inte_res = quad(lambda x: func_recorded(x, node_container=nc,
                                            value_container=vc),
                    *args, **kwargs)
    idx = np.argsort(np.array(nc))
    nc = np.array(nc)[idx].tolist()
    vc = np.array(vc)[idx].tolist()
    return inte_res, nc, vc


res, nc, vc = quad_recorded(np.sin, 0, np.pi, points=[.5])
plt.plot(nc, vc, '*')
print(res)
plt.savefig('quad_recorded.png', transparent=True)&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;&amp;gt;&amp;gt;&amp;gt; (1.9999999999999998, 2.2204460492503128e-14)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-09-16-physics-scipy_integrate/quad_recorded.png' alt='quad_recorded' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;可以看出，正如所预期的，在 $0.5$ 处切开了。此函数可以用于保存计算较慢的积分，查
看被积函数是否光滑，是否真的收敛。&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://docs.scipy.org/doc/scipy/reference/reference/generated/scipy.integrate.quad.html#scipy.integrate.quad'&gt;scipy.integrate.quad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/QUADPACK'&gt;wikipedia: QUADPACK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Adaptive_quadrature'&gt;wikipedia: Adaptive quadrature&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="python"/><category term="quadrature"/></entry><entry><title>beamer 笔记</title><link href="https://zqw.ink/2021-06-24-coding-beamer_note.html" rel="alternate"/><published>2021-06-24T00:00:00+08:00</published><updated>2021-06-24T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-06-24:/2021-06-24-coding-beamer_note.html</id><content type="html">
&lt;p&gt;[[file:./2021-06-24-coding-beamer_note/beamer_note.pdf][PDF version]]
[[file:./2021-06-24-coding-beamer_note/beamer_note.tex][source file]]&lt;/p&gt;
</content><category term="软件使用"/><category term="latex"/><category term="beamer"/></entry><entry><title>round-off error, unstable method, mpmath(update 15/Mar/2022)</title><link href="https://zqw.ink/2021-05-15-coding-unstable_method.html" rel="alternate"/><published>2021-05-15T00:00:00+08:00</published><updated>2021-05-15T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-05-15:/2021-05-15-coding-unstable_method.html</id><summary type="html">

&lt;h2&gt;Round-off error&lt;/h2&gt;

&lt;p&gt;Round-off error 的原因是数值计算的过程中, 机器的精度是有限的. &lt;a href='https://en.wikipedia.org/wiki/Round-off_error'&gt;wikipedia: Round-off error&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Unstable method&lt;/h2&gt;

&lt;p&gt;计算 Goledn Mean&lt;/p&gt;

$$\begin{align}
\phi = \frac{\sqrt{5} - 1}{2} \approx 0.61803398
\end{align}$$

&lt;p&gt;的 $n$ 次 …&lt;/p&gt;</summary><content type="html">

&lt;h2&gt;Round-off error&lt;/h2&gt;

&lt;p&gt;Round-off error 的原因是数值计算的过程中, 机器的精度是有限的. &lt;a href='https://en.wikipedia.org/wiki/Round-off_error'&gt;wikipedia: Round-off error&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Unstable method&lt;/h2&gt;

&lt;p&gt;计算 Goledn Mean&lt;/p&gt;

$$\begin{align}
\phi = \frac{\sqrt{5} - 1}{2} \approx 0.61803398
\end{align}$$

&lt;p&gt;的 $n$ 次幂 $\phi^n$ . 可以证明它满足递推关系&lt;/p&gt;

$$\begin{align}
\phi^{n + 1} = \phi^{n - 1} - \phi^n
\end{align}$$

&lt;p&gt;使用此递推关系, 可以由原来的乘法变成减法, 会节约计算资源. 但是此递推关系还有另一
个解&lt;/p&gt;

$$\begin{align}
- \frac{1}{2}(\sqrt{5} + 1)
\end{align}$$

&lt;p&gt;因为它的绝对值是大于 $1$ 的. 所以混入任何 round-off error 都会指数发散. 因此这个
递推算法是一个 unstable method.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt


def unstable(n: int) -&amp;gt; float:
    p = []
    p.append(1)
    p.append((np.sqrt(5) - 1) / 2)
    for i in range(n-1):
        i += 1
        p.append(p[i-1] - p[i])
    return p[-1]


def stable(n: int) -&amp;gt; float:
    return ((np.sqrt(5) - 1) / 2)**n


n = 80
x = []
y_unstable = []
y_stable = []
for i in range(n):
    i += 1
    x.append(i)
    y_unstable.append(unstable(i))
    y_stable.append(stable(i))

plt.plot(x, y_unstable, '-x', label="unstable")
plt.plot(x, y_stable, label="stable")
plt.xlabel(r'$n$')
plt.ylabel(r'$\left(\frac{\sqrt{5} - 1}{2}\right)^n$')
plt.legend()
plt.savefig('unstable_method.png')&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-05-15-coding-unstable_method/unstable_method.py'&gt;2021-05-15-coding-unstable_method/unstable_method.py&lt;/a&gt;
&lt;p&gt;&lt;img src='2021-05-15-coding-unstable_method/unstable_method.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;解决方法&lt;/h2&gt;

&lt;p&gt;解决方法之一是使用更高精度的数值类型. 虽然此法在效率上的代价是巨大的.
Mathematica 中设置 WorkingPrecision 即为此方法.&lt;/p&gt;

&lt;p&gt;在 python, &lt;code&gt;mpmath&lt;/code&gt; 包提供了类似的处理方法&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;  import numpy as np
  from mpmath import mp
  import matplotlib.pyplot as plt


  mp.dps = 20
  print(mp)


  def unstable(n: int) -&amp;gt; float:
      p = []
      p.append(1)
      p.append((mp.sqrt(5) - 1) / 2)
      for i in range(n-1):
          i += 1
          p.append(p[i-1] - p[i])
      return p[-1]


  def stable(n: int) -&amp;gt; float:
      return ((np.sqrt(5) - 1) / 2)**n


  n = 80
  x = []
  y_unstable = []
  y_stable = []
  for i in range(n):
      i += 1
      x.append(i)
      y_unstable.append(unstable(i))
      y_stable.append(stable(i))

  plt.plot(x, y_unstable, '-x', label="unstable method with mpmath")
  plt.plot(x, y_stable, label="stable")
  plt.xlabel(r'$n$')
  plt.ylabel(r'$\left(\frac{\sqrt{5} - 1}{2}\right)^n$')
  plt.legend()
  plt.savefig('unstable_method_with_mpmath.png')


    &amp;gt;&amp;gt;&amp;gt;
    Mpmath settings:
      mp.prec = 70                [default: 53]
      mp.dps = 20                 [default: 15]
      mp.trap_complex = False     [default: False]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;file:2021-05-15-coding-unstable_method/unstable_method_with_mpmath.py
&lt;p&gt;&lt;img src='2021-05-15-coding-unstable_method/unstable_method_with_mpmath.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;可以看出, 将求根的计算精度由 &lt;code&gt;numpy.float64&lt;/code&gt; (53个二进制位表示一个浮点数) 提高到
70 个二进制位表示一个浮点数, 在 $n\le 80$ 的范围内, round-off error 被压住了.&lt;/p&gt;

&lt;p&gt;[[eww:https://mpmath.org/doc/1.2.0/basics.html][二进制位与十进制数有效数字个数的关系大致是 &lt;code&gt;prec = 3.33*dps&lt;/code&gt;]]&lt;/p&gt;

&lt;h2&gt;另一种出现 round-off error 的情况&lt;/h2&gt;


$$\begin{align}
\int_0^{\infty } \mathrm{d}k\cdot \left[\sqrt{5 k^4+4 \sqrt{k^4+1} k^2+4}-3 k^2\right]
  \approx 2.4720995697351625579
\end{align}$$

&lt;p&gt;从解析上可以得到, 被积函数在 $k\to \infty$ 时的行为是 $\sim 1/k^2$ . 根号中的第一项和第二
项 $-3k^2$ 在 $k\to \infty$ 时各自是发散的, 但是相加之后是收敛的.&lt;/p&gt;

&lt;p&gt;但是数值计算上, 当 $k$ 很大时, 在保留的有效数字个数有限的情况下, 相加得到的结果
可能在有效数字之外了, 因此相加的结果是 round-off error. 反映在结果上就是本来应该
$\sim 1/k^2\to 0$ 的, 却出现抖动.&lt;/p&gt;

&lt;p&gt;这时也可以用 mpmath 提高精度.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;  import numpy as np
  import matplotlib.pyplot as plt
  from mpmath import mp
  from scipy.integrate import quad


  mp.dps = 18
  print(mp)


  def func(k):
      res = np.sqrt(k**4 + 1)
      res *= 4*k**2
      res += 5*k**4 + 4
      res = np.sqrt(res)
      res += -3*k**2
      return res


  def mpmath_func(k_float):
      k_mpmath = mp.mpmathify(k_float)
      return func(k_mpmath)


  ks = np.linspace(1000, 1001, 100)
  fs = func(ks)
  mp_math_fs = [mpmath_func(k) for k in ks]

  plt.plot(ks, fs, '-x', label="numpy float64 type")
  plt.plot(ks, mp_math_fs, label="mpmath mpf type")
  plt.title('mpmath example')
  plt.xlabel(r'$x$')
  plt.ylabel(r'$f(x)$')
  plt.legend()
  plt.savefig('mpmath_example.png')

  print('result of numpy float64 type:', quad(mpmath_func, 0, np.inf))
  print('result of mpmath mpf type:', quad(func, 0, np.inf))


&amp;gt;&amp;gt;&amp;gt;
Mpmath settings:
  mp.prec = 63                [default: 53]
  mp.dps = 18                 [default: 15]
  mp.trap_complex = False     [default: False]
result of numpy float64 type: (2.472099569305563, 1.412300021975624e-10)
/..../mpmath_expample.py:38: IntegrationWarning: The algorithm does not converge.  Roundoff error is detected
  in the extrapolation table.  It is assumed that the requested tolerance
  cannot be achieved, and that the returned result (if full_output = 1) is
  the best which can be obtained.
  print('result of mpmath mpf type:', quad(func, 0, np.inf))
result of mpmath mpf type: (2.472099451021771, 7.496323446432029e-07)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='2021-05-15-coding-unstable_method/mpmath_example.py'&gt;2021-05-15-coding-unstable_method/mpmath_example.py&lt;/a&gt;
&lt;p&gt;&lt;img src='2021-05-15-coding-unstable_method/mpmath_example.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;可以看出如果用 &lt;code&gt;numpy.float64&lt;/code&gt; 计算会提示 round-off error. &lt;/p&gt;


&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Round-off_error'&gt;wikipedia: Round-off error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Winkler, J. R. Numerical recipes in C: The art of scientific computing, second edition. Endeavour 17, 201 (1993). Chap 1.3&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Numerical_stability'&gt;wikipedia: Numerical stability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Double-precision_floating-point_format'&gt;wikipedia: Double-precision floating-point format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://mpmath.org/doc/1.2.0/index.html'&gt;mpmath's documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://scicomp.stackexchange.com/questions/21483/how-to-avoid-the-round-off-errors-in-the-larger-calculations'&gt;https://scicomp.stackexchange.com/questions/21483/how-to-avoid-the-round-off-errors-in-the-larger-calculations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fan Yang 的讨论&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="numerical stability"/><category term="unstable method"/><category term="round-off error"/><category term="mpmath"/><category term="integral"/></entry><entry><title>C 中的指针与动态内存分配</title><link href="https://zqw.ink/2021-05-14-coding-C_pointer_malloc.html" rel="alternate"/><published>2021-05-14T00:00:00+08:00</published><updated>2021-05-14T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-05-14:/2021-05-14-coding-C_pointer_malloc.html</id><summary type="html">
&lt;p&gt;主要是为 Reference 存个书签.&lt;/p&gt;

&lt;h2&gt;Pointers&lt;/h2&gt;

&lt;p&gt;在写程序的过程中, array 是相当有用的. 但是 array 是静态的, 也就是它的大小不能改
变. 此时指针就派上 …&lt;/p&gt;</summary><content type="html">
&lt;p&gt;主要是为 Reference 存个书签.&lt;/p&gt;

&lt;h2&gt;Pointers&lt;/h2&gt;

&lt;p&gt;在写程序的过程中, array 是相当有用的. 但是 array 是静态的, 也就是它的大小不能改
变. 此时指针就派上用场.&lt;/p&gt;

&lt;p&gt;在 C 中, pointer 表示一个 data 的内存地址. 如果一个 pointer 为 0, 那它叫做 null
pointer, 也叫 NULL , "nil" .&lt;/p&gt;

&lt;h2&gt;Declarations&lt;/h2&gt;

&lt;p&gt;指针声明的方式是, 在一个已经存在的数据类型前加一个 &lt;code&gt;*&lt;/code&gt;. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;int *ip;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;声明了一个名为 &lt;code&gt;ip&lt;/code&gt; 的 pointer 指向一个整数.&lt;/p&gt;

&lt;p&gt;创建一个指针的方法是用算符 &lt;code&gt;&amp;&lt;/code&gt; (address-of) . 顾名思义, 它作用到一个变量后, 得到它
的地址. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;int *ip;
int x;
x = 42;
ip = &amp;x;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将 &lt;code&gt;42&lt;/code&gt; 赋值给 &lt;code&gt;x&lt;/code&gt;, 将 &lt;code&gt;x&lt;/code&gt; 的地址赋值给 &lt;code&gt;ip&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Using a pointer&lt;/h2&gt;

&lt;p&gt;使用 pointer 的方法是使用算符 &lt;code&gt;*&lt;/code&gt; , 它叫做 dereference operator. 它作用在一个指针
上, 得到的结果是它指向的内存地址中的值.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;printf("%d %d\n", x, *ip);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;会输出 &lt;code&gt;42 42&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;也可以&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;*ip = 37;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时, 这块内存中的值就变成了 &lt;code&gt;37&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;Memory allocation and deallocation&lt;/h2&gt;


&lt;p&gt;一般来讲, 把一个指针指向一个已经声明的变量, 没什么用. 真正有用的是用它来分配一块
没有使用的内存. 这使得程序能够处理大量的内存.&lt;/p&gt;

&lt;p&gt;基本的内存分配函数是&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;(void *) malloc(size_t numbytes);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;它的意思是分出一定数量的内存空间, 并返回一个指向它的指针. 由于  malloc 不知道你
想要什么类型的指针, 它返回的是 pointer to void, 也就是指向一块数据类型不明的区域.&lt;/p&gt;

&lt;p&gt;常用的是把它和内置算符 &lt;code&gt;sizeof()&lt;/code&gt; 放在一起用. &lt;code&gt;sizeof()&lt;/code&gt; 返回特定数据类型的比特
数. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;int *ip;
ip = (int *) malloc(sizeof(int));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这将分配出 1 个 &lt;code&gt;int&lt;/code&gt; 大小的内存, 将其指针给 &lt;code&gt;ip&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;Pointers and arrays&lt;/h2&gt;

&lt;p&gt;分配单个整型大小的内存没什么用, 有用的是 allocate arrays. 实际上, 指针可以当作一
个 array 用. 如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;int *ip;
ip = (int *) malloc( sizeof(int)*10 ); // allocate 10 ints
ip[6] = 42; // set the 7th element to 42
ip[10] = 99; // WRONG: array only has 10 elements
(this would corrupted memory!)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Freeing memory, and memory leaks&lt;/h2&gt;

&lt;p&gt;如果有以下 code&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;int *ip;
ip = (int *) malloc( sizeof(int)*10 ); // allocate 10 ints
... (use the array, etc.)
ip = (int *) malloc( sizeof(int)*100 ); // allocate 100 ints
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;它没有金鼓齐鸣. 可以给一个指针重新赋值. 但是重新赋值之后, 之前分出的那 10 ints
的内存呢? 答案是它永远地消失了, 直到程序结束. 这叫内存(memory leak). 虽然这 10
ints 内存是被分配的, 但程序再也无法使用这些内存了.&lt;/p&gt;

&lt;p&gt;解决方法是, 在 C 或者 C++ 中, 当被分配的内存用完后, 可以通过 &lt;code&gt;free()&lt;/code&gt; 来释放内存.
如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c    int *ip;"&gt;ip = (int *) malloc( sizeof(int)*10 ); // allocate 10 ints
... (use the array, etc.)
free(ip); // de-allocate old array
ip = (int *) malloc( sizeof(int)*100 ); // allocate 100 ints
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上面的 code 就不会发生内存泄漏. 有一些语言 (如 Java) 会自动清理分配的内存, 这叫
automatic garbage collection , 但是 C 和 C++ 没有这种机制. 所以你在用完后, 应该
负责释放掉它们.&lt;/p&gt;

&lt;h2&gt;Pointers and arrays&lt;/h2&gt;

&lt;p&gt;pointers 可以用 array 的指标, 或者说, 一个数组的名字本质上就是一个 constant
pointer.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;int *p;
int a[10];
p = (int*) malloc(sizeof(int)*20);
p[2] = 100; // set 3rd element in alloc'd array to 100
*(p+2) = 100; // same thing
a[2] = 200; // set 3rd element in regulary array to 200
*(a+2) = 200; // same thing&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;指针和数组是不同的, 但是当指针被用来 access 一块区域时, 用法是一样的. 但是&lt;/p&gt;

&lt;blockquote&gt;- the array declares a block of some datatype while a pointer only declares
  space for itself (the data area needs malloc'd)

  数组会声明一块特定数据类型的区域, 而指针只会声明这块空间本身.

- The address of the array (i.e., a pointer to it) is not stored anywhere; the
    compiler figures it out while it is compiling your program, so when you use
    the array name as a pointer, you are essentially using a constant number as
    an address.

  数组的地址没有存在任何地方, 编译器编译的时候才搞清它. 所以将数组的名字当作指针
  使用的时候, 本质上是将一个常数当作地址使用.&lt;/blockquote&gt;

&lt;h2&gt;Pointers and arrays as arguments&lt;/h2&gt;

&lt;p&gt;有一个地方,指针和数组几乎是完全相同的, 那就是 当它们作为一个函数的参数的时候. 这
是因为 agruments pass only the address of the array to the function. 也就是说数
组作为指针传递.&lt;/p&gt;

&lt;p&gt;在 C 中, 大部分值的传递方法是 call-by-value, 函数得到的是值的一个副本, 函数不会
改变原来的值. 但数组的传递方法是 call-by-reference, 传递的是指针, 而不是数组本
身.&lt;/p&gt;

&lt;p&gt;如果传递数组时, 传递一个副本的话, 当数组非常大时, 那是非常浪费的. 所以数值的传递
方法是 call-by-reference. 这也意味着函数中对数组的修改, 会直接修改原来的数组.&lt;/p&gt;

&lt;p&gt;因此, 下面的声明是等价的&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;int func(int A[]);
int func(int *A);&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;How to dynamically allocate a 2D array in C?&lt;/h2&gt;

&lt;p&gt;有四种方法能够动态的给一个二维数组赋值. 比如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;  1  2  3  4
  5  6  7  8
  9  10 11 12&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;1. Using a single pointer&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main()
{
    int r = 3, c = 4;
    int *arr = (int *)malloc(r * c * sizeof(int));

    int i, j, count = 0;
    for (i = 0; i &amp;lt;  r; i++)
      for (j = 0; j &amp;lt; c; j++)
         *(arr + i*c + j) = ++count;

    for (i = 0; i &amp;lt;  r; i++)
      for (j = 0; j &amp;lt; c; j++)
         printf("%d ", *(arr + i*c + j));

   /* Code for further processing and free the
      dynamically allocated memory */

   return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;2. Using an array of pointers&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main()
{
	int r = 3, c = 4, i, j, count;

	int *arr[r];
	for (i=0; i&amp;lt;r; i++)
		arr[i] = (int *)malloc(c * sizeof(int));

	// Note that arr[i][j] is same as *(*(arr+i)+j)
	count = 0;
	for (i = 0; i &amp;lt; r; i++)
	for (j = 0; j &amp;lt; c; j++)
		arr[i][j] = ++count; // Or *(*(arr+i)+j) = ++count

	for (i = 0; i &amp;lt; r; i++)
	for (j = 0; j &amp;lt; c; j++)
		printf("%d ", arr[i][j]);

	/* Code for further processing and free the
	dynamically allocated memory */

return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;3. Using pointer to a pointer&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main()
{
	int r = 3, c = 4, i, j, count;

	int **arr = (int **)malloc(r * sizeof(int *));
	for (i=0; i&amp;lt;r; i++)
		arr[i] = (int *)malloc(c * sizeof(int));

	// Note that arr[i][j] is same as *(*(arr+i)+j)
	count = 0;
	for (i = 0; i &amp;lt; r; i++)
	for (j = 0; j &amp;lt; c; j++)
		arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

	for (i = 0; i &amp;lt; r; i++)
	for (j = 0; j &amp;lt; c; j++)
		printf("%d ", arr[i][j]);

/* Code for further processing and free the
	dynamically allocated memory */

return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;4. Using double pointer and one malloc call&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-c"&gt;#include&amp;lt;stdio.h&amp;gt;
#include&amp;lt;stdlib.h&amp;gt;

int main()
{
	int r=3, c=4, len=0;
	int *ptr, **arr;
	int count = 0,i,j;

	len = sizeof(int *) * r + sizeof(int) * c * r;
	arr = (int **)malloc(len);

	// ptr is now pointing to the first element in of 2D array
	ptr = (int *)(arr + r);

	// for loop to point rows pointer to appropriate location in 2D array
	for(i = 0; i &amp;lt; r; i++)
		arr[i] = (ptr + c * i);

	for (i = 0; i &amp;lt; r; i++)
		for (j = 0; j &amp;lt; c; j++)
			arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

	for (i = 0; i &amp;lt; r; i++)
		for (j = 0; j &amp;lt; c; j++)
			printf("%d ", arr[i][j]);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Memory leak&lt;/h2&gt;

&lt;p&gt;下面的 code 可以演示内存泄漏&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;include &amp;lt;stdio.h&amp;gt;
 #include &amp;lt;stdlib.h&amp;gt;

 void f(void)
 {
     void* s;
     s = malloc(50); /* 申请内存空间 */
     return;  /* 内在泄漏 - 参见以下资料 */
     /*
      * s 指向新分配的堆空间。
      * 当此函数返回，离开局部变量s的作用域后将无法得知s的值，
      * 分配的内存空间不能被释放。
      *
      * 如要「修复」这个问题，必须想办法释放分配的堆空间，
      * 也可以用alloca(3)代替malloc(3)。
      * （注意：alloca(3)既不是ANSI函数也不是POSIX函数）
      */
 }
 int main(void)
 {
     /* 该函数是一个死循环函数 */
     while (1) f(); /* Malloc函数迟早会由于内存泄漏而返回NULL*/
     return 0;
 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;结果是几秒后内存就满了. 但是系统会有保护机制? 直接杀掉了进程([[file:2021-05-14-coding-C_pointer_malloc/memory_leak.c][memory_leak.c]] [[file:2021-05-14-coding-C_pointer_malloc/makefile][makefile]]):&lt;/p&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='2021-05-14-coding-C_pointer_malloc/memory_leak_res.png' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;https://www.cs.nmsu.edu/~rth/cs/cs271/notes/Pointers.html&lt;/li&gt;
&lt;li&gt;https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/&lt;/li&gt;
&lt;li&gt;&lt;a href='https://zh.wikipedia.org/zh-cn/%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F'&gt;wikipedia: 内存泄漏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://en.wikipedia.org/wiki/Dereference_operator'&gt;wikipeida: Dereference operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="C"/><category term="array"/><category term="malloc"/><category term="memory leak"/></entry><entry><title>记一次折腾上头经历: lsp-pyright vs. flycheck &amp; flake8</title><link href="https://zqw.ink/2021-03-19-coding-lsp_flycheck.html" rel="alternate"/><published>2021-03-19T00:00:00+08:00</published><updated>2021-03-19T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-03-19:/2021-03-19-coding-lsp_flycheck.html</id><summary type="html">
&lt;p&gt;起因于昨天下午.&lt;/p&gt;

&lt;p&gt;在科研课题久久没有进展之后, 突然有了一些想法. 遂写程序.&lt;/p&gt;

&lt;p&gt;在寒假配置的 Emacs 个人新版配置终于有了用 …&lt;/p&gt;</summary><content type="html">
&lt;p&gt;起因于昨天下午.&lt;/p&gt;

&lt;p&gt;在科研课题久久没有进展之后, 突然有了一些想法. 遂写程序.&lt;/p&gt;

&lt;p&gt;在寒假配置的 Emacs 个人新版配置终于有了用武之地, 甚是高兴.&lt;/p&gt;

&lt;p&gt;可随后而来的却是一次折腾上头.&lt;/p&gt;

&lt;p&gt;之前在 Emacs 里加了 lsp-pyright, 可以提示程序中一些不规范的细节. 比如给一行注释
的话要在 &lt;code&gt;#&lt;/code&gt; 后面加至少两个空格, 诸如此类的根据 PEP8 给出的提示.&lt;/p&gt;

&lt;p&gt;可是很奇怪, 它在笔记本上可以, 在台式上不行. 开始以为是设置工程前可以显示, 设置工
程路径后就不显示了. 这也很奇怪. 搞来搞去不行, emacs 的插件删了又重下, 好多次, 就
是不行. 基本断定不是 emacs 配置的原因. 想着放弃吧, 现在没那么多多余的时间搞这些
了. 于是昨天搞了一晚上后回宿舍睡觉了.&lt;/p&gt;

&lt;p&gt;第二天上自习, 还是忍不住, 又搞了起来, 发现并不是设置工程路径的原因. 各种查 lsp,
原理, 配置...&lt;/p&gt;

&lt;p&gt;未果.&lt;/p&gt;

&lt;p&gt;越来越上头了. 今天下午为了做对照, 新建了用户, 发现和用户也没关系, 看来也不是 lsp
设置的原因.&lt;/p&gt;

&lt;p&gt;最后, 尝试安装 KDE 版本的 manjaro. 一开始想试一下直接 arch, 但想想还是算了. 没想
到装 manjaro 也是出了问题, 第一次装完, 莫名其妙地少了 libc.so , 连 pacman 都打不
开了. 想了个笨方法 chroot 直接复制 libc.so 文件直接过去, 结果连 kernel 也进不去
了.&lt;/p&gt;

&lt;p&gt;那就再装一次吧, 我已经无法回头了. 期间还出现了少见的办公室断网, 这运气...&lt;/p&gt;

&lt;p&gt;第二次终于好了, 验证了没有显示 PEP8 提示的原因是少装了什么软件.&lt;/p&gt;

&lt;p&gt;最后终于发现是 flycheck 调用 pylint 给的提示, 和 lsp 没一点关系! 安上 flake8 就
好了.&lt;/p&gt;

&lt;p&gt;太上头了. 自己本来就是外行程序员, 还这么喜欢搞这些, 下场就是一天半的时间没了...&lt;/p&gt;

&lt;p&gt;不过也有收获. 那就是现在台式上以前丢失的引导在装了 KED manjaro 之后全部都找回来
了. 现在开机有五个系统可选.&lt;/p&gt;

&lt;p&gt;本来想尝试 KDE 的, 可以就这一下午就出了致命和不致命的问题, 还是算了吧! 等我真正
闲的时候再尝试吧.&lt;/p&gt;

&lt;p&gt;不过这次折腾有一个好的结果, 不是放弃了, 而是解决了. 问题解决了, 心情是真的舒畅,
真的爽!!!&lt;/p&gt;

&lt;p&gt;这一切都不是因为问题有多复杂, 只是看问题缺乏知识, 流于表面. 或许科研也是这样, 大
家都这样, 就习以为常了.&lt;/p&gt;
</content><category term="软件使用"/><category term="emacs"/><category term="lsp"/><category term="pyright"/><category term="flycheck"/><category term="flake8"/></entry><entry><title>欢迎来到 Emacs 主义至上教室(lisp note -_-)</title><link href="https://zqw.ink/2021-01-20-coding-lisp.html" rel="alternate"/><published>2021-01-20T00:00:00+08:00</published><updated>2021-01-20T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-01-20:/2021-01-20-coding-lisp.html</id><summary type="html">
&lt;h2&gt;Intro&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;Intro&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49.93+ (2018-02-18) &amp;lt;http://clisp.org/&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;交互式的(类似 ipython), 在 terminal 中输入 &lt;code&gt;ecl&lt;/code&gt; (Embeddable Common Lisp) . 没有
的话则需要安装. 也可以用 &lt;code&gt;clisp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;此为快速入门笔记.&lt;/p&gt;

&lt;h2&gt;Common Lisp Syntax&lt;/h2&gt;

&lt;h3&gt;Form&lt;/h3&gt;

&lt;p&gt;lisp 的语法比较特别, 表达式用括号括起来, 括号中第一部分是函数, 剩余部分是函数的
参数. 当然也可以直接是一个 data. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; 1

1
&amp;gt; (+ 2 3)

5
&amp;gt; (+ 2 3 4)

9
&amp;gt; (+)

0
&amp;gt; (/ (- 7 1) (- 4 2))

3&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Evaluation &lt;/h3&gt;

&lt;p&gt;lisp 默认对 &lt;code&gt;(+ 1 1)&lt;/code&gt; 是要求值的. 如果要避免求值, 可以用 &lt;code&gt;quote&lt;/code&gt; .&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (quote (+ 3 5))

(+ 3 5)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;'&lt;/code&gt; 为 &lt;code&gt;quote&lt;/code&gt; 的简写&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; '(+ 3 5)

(+ 3 5)&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Data&lt;/h3&gt;

&lt;h4&gt;integer, string&lt;/h4&gt;

&lt;p&gt;在其它语言中常见.&lt;/p&gt;

&lt;h4&gt;symbol&lt;/h4&gt;

&lt;p&gt;无论怎输入, 都会被转换成大写. symbol 不对自身求值, 一般加 &lt;code&gt;'&lt;/code&gt; 引用&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; 'Good

GOOD&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;list&lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (list 'hello (+ 3 6) "good")

(HELLO 9 "good")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;list&lt;/code&gt; 函数来创建列表. build lists&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (list '(+ 1 1) (+ 1 1))

((+ 1 1) 2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;空列表有两种表示方式&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; ()

NIL
&amp;gt; nil

NIL &lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;List Operations &lt;/h3&gt;

&lt;p&gt;&lt;code&gt;cons&lt;/code&gt; build lists&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (cons 'a '(b c d))

(A B C D)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述例子第二个实参是一个 list . &lt;/p&gt;

&lt;p&gt;list 是将几个元素加到 &lt;code&gt;nil&lt;/code&gt; 空表的快捷方式, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (cons 'a (cons 'b nil))

(A B)
&amp;gt; (list 'a 'b)

(A B)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;car&lt;/code&gt; 返回 list 的第一个元素, &lt;code&gt;cdr&lt;/code&gt; 返回第一个元素之后的所有元素, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (car '(a b c))

A
&amp;gt; (cdr '(a b c))

(B C)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;取第三个元素有两种方法, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (car (cdr (cdr '(a b c d))))

C
&amp;gt; (third '(a b c d))

C&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Truth &lt;/h3&gt;

&lt;h4&gt;True and False&lt;/h4&gt;
&lt;p&gt;symbol &lt;code&gt;t&lt;/code&gt; 表示逻辑真的默认值. 它是一个 symbol, 因此它会自身求值. 逻辑假由 &lt;code&gt;nil&lt;/code&gt;
来表示.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;listp&lt;/code&gt; returns true if its argument is a list:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (listp '(a b c))

T
&amp;gt; (listp 2)

NIL&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;像 &lt;code&gt;listp&lt;/code&gt; 这样返回结果为真或假的函数, 称为 predicate, 这类函数通常以 p 结尾.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;null&lt;/code&gt; returns true of the empty list. The function &lt;code&gt;not&lt;/code&gt; returns
true if its argument is false. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (null nil)

T
&amp;gt; (not nil)

T&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述例子中, 第一个 &lt;code&gt;nil&lt;/code&gt; 表示 empty list, 因此返回 True. 第二个 &lt;code&gt;nil&lt;/code&gt; 表示逻辑假,
因此返回 True. 但由于 &lt;code&gt;nil&lt;/code&gt; 既可表示 empty list, 也可表示逻辑假, 因此上述两个表
达式在功能上等价的. &lt;/p&gt;

&lt;h4&gt;if &lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (if (listp '(a b c))
      (+ 1 2)
      (+ 5 6))

3
&amp;gt; (if (listp 2)
      (+ 1 2)
      (+ 5 6))

11&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;if 函数的第一个参量是 test 表达式, 即要判断真假的对象. 第二个 then 表达式. 第三
个是 else 表达式, 是可选参数, 默认是 &lt;code&gt;nil&lt;/code&gt; . 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (if (listp 27)
      (+ 1 2))

NIL&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;除了 &lt;code&gt;nil&lt;/code&gt; 以外的所有东西, 都视为 True, 如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (if 27 1 2)

1&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;AND and OR&lt;/h4&gt;

&lt;p&gt;逻辑与, 或. &lt;code&gt;and&lt;/code&gt; , 求到第一个为 False 后, 就不对后面的表达式求值了, 直接返回
&lt;code&gt;nil&lt;/code&gt; 如果所有值为真, 那么它就会返回最后一个参数(而不是返回 True). 也就是说它比
较懒, 知道结果了, 就不继续求值了. 
. or 运算时, 有一个 False 后, 就不对后面的表达式求值了.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (and t (+ 1 2))

3&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Functions&lt;/h3&gt;

&lt;p&gt;定义 function, 第一个实参是函数名字, 第二个是用列表表示的参数, 第三个是一个或多
个组成函数体的表达式. 如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (and t (+ 1 2))

3
&amp;gt; (defun our-third (x)
   (car (cdr (cdr x))))

OUR-THIRD
&amp;gt; (our-third '(a b c d e f))

C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;又如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun sum-greater (x y z)
   (&amp;gt; (+ x y) z))

SUM-GREATER
&amp;gt; (sum-greater 1 4 3)

T
&amp;gt; (sum-greater 2 5 9)

NIL&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Recursion&lt;/h3&gt;

&lt;p&gt;下面的函数是递归的一个例子&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun our-member (obj lst)
   (if (null lst)
       nil
   (if (eql (car lst) obj)
       lst
       (our-member obj (cdr lst)))))

OUR-MEMBER
&amp;gt; (our-member 'b '(a b c))

(B C)
&amp;gt; (our-member 'z '(a b c))

NIL&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;函数 &lt;code&gt;our-member&lt;/code&gt; 用来判断 &lt;code&gt;obj&lt;/code&gt; 是否是列表 &lt;code&gt;lst&lt;/code&gt; 中的成员.&lt;/p&gt;

&lt;p&gt;首先判断 &lt;code&gt;lst&lt;/code&gt; 是否为空, 如果为空, 那当然就返回 &lt;code&gt;nil&lt;/code&gt; . 如果不空, 那么就用函数
&lt;code&gt;eql&lt;/code&gt; 判断 &lt;code&gt;lst&lt;/code&gt; 的第一个成员是否与 &lt;code&gt;obj&lt;/code&gt; 相同, 相同的话输出当前的 &lt;code&gt;lst&lt;/code&gt; , 如果
不同, 只有当 &lt;code&gt;obj&lt;/code&gt; 是其它列表成员时, 它才可能是 &lt;code&gt;lst&lt;/code&gt; 的成员, 于是就就递归调用,
并把除掉第一个成员后的 &lt;code&gt;lst&lt;/code&gt; 传递给递归调用的自己. &lt;/p&gt;

&lt;h3&gt;Input and Output&lt;/h3&gt;

&lt;h4&gt;output&lt;/h4&gt;

&lt;p&gt;common lisp 最普遍的输出函数是 &lt;code&gt;format&lt;/code&gt; . 第一个实参是输出到哪里, &lt;code&gt;t&lt;/code&gt; 表示默认的
的地方. 第二个实参是字符模板, 剩下的实参是要插入到模板的对象. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (format t "~A plus ~A equals ~A. ~%" 2 3 (+ 2 3))
2 plus 3 equals 5. 
NIL&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;~A&lt;/code&gt; 表示被填入的位置, &lt;code&gt;~%&lt;/code&gt; 表示换行.&lt;/p&gt;

&lt;h4&gt;input&lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun askem (string)
   (format t "~A" string)
   (read))

ASKEM
&amp;gt; (askem "How old are you?")
How old are you?15

15&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个函数首先输出参量 &lt;code&gt;string&lt;/code&gt; , 返回通过 &lt;code&gt;read&lt;/code&gt; 输入得到的值. 当函数 &lt;code&gt;read&lt;/code&gt; 没有
实参时, 它会读取默认的位置. 函数 &lt;code&gt;askem&lt;/code&gt; 有两个表达式, 它会返回最后一个表达式的
值. &lt;/p&gt;

&lt;h3&gt;Variables&lt;/h3&gt;

&lt;h4&gt;local variable&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;let&lt;/code&gt; 可以引入局部变量, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (let ((x 1) (y 2))
     (+ x y))

3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述例子分别把 &lt;code&gt;1&lt;/code&gt; 和 &lt;code&gt;2&lt;/code&gt; 赋值给 &lt;code&gt;x&lt;/code&gt; 和 &lt;code&gt;y&lt;/code&gt; , 赋值只在 &lt;code&gt;let&lt;/code&gt; 函数值内有效. 之后
是表达式, 求值的结果作为 &lt;code&gt;let&lt;/code&gt; 的返回值.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt;  (defun ask-number ()
   (format t "Please enter a number. ")
   (let ((val (read)))
     (if (numberp val)
         val
          (ask-number))))

ASK-NUMBER
&amp;gt; (ask-number)
Please enter a number. a
Please enter a number. (ho hum)
Please enter a number. 19&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;numberp&lt;/code&gt; 是一个 predicate, 判断是否是一个数. 这也是递归调用的一个例子.&lt;/p&gt;

&lt;h4&gt;global variable&lt;/h4&gt;

&lt;p&gt;由 &lt;code&gt;defparameter&lt;/code&gt; 来定义全局变量, 由 &lt;code&gt;defconstant&lt;/code&gt; 定义全局常量, 由 &lt;code&gt;boundp&lt;/code&gt; 判
断某个符号是否为一个全局变量或常量. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defparameter *glob* 99)

*GLOB*
&amp;gt; (defconstant limit (+ *glob* 1))

LIMIT
&amp;gt; (boundp '*glob*)

T&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Assignment &lt;/h3&gt;

&lt;p&gt;&lt;code&gt;setf&lt;/code&gt; 来给变量赋值. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf *glob* 98)

98
&amp;gt; (let ((n 10))
    (setf n 2)
    n)

2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果一个 symbol 不是局部变量的名字, 那么 &lt;code&gt;setf&lt;/code&gt; 把这个 symbol 设置为全局变量. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf x (list 'a 'b 'c))

(A B C)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;也就是说 &lt;code&gt;setf&lt;/code&gt; 也可以用来创建全局变量, 不过还是推荐用 &lt;code&gt;defparameter&lt;/code&gt; 来创建, 这
样比较明确.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;setf&lt;/code&gt; 还有一个用法. 第一个实参可以是表达式, 这样第二个实参直接传给表达式中. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf (car x) 'n)

N
&amp;gt; x

(N B C)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以下两种表达方式是等价的&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf a 'b
        c 'd
        e 'f)

F
&amp;gt; a

B
&amp;gt; c

D
&amp;gt; e

F&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf a 'b)

B
&amp;gt; (setf c 'd)

D
&amp;gt; (setf e 'f)

F&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Functional Programming&lt;/h3&gt;

&lt;p&gt;Lisp 的主流范式是函数式编程. 中心思想是: 执行一个函数是得到它的返回值. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf lst '(c a r a t))

(C A R A T)
&amp;gt; (remove 'a lst)

(C R T)
&amp;gt; lst

(C A R A T)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;remove&lt;/code&gt; 函数是移除列表中的指定元素. 但只是返回移除之后的结果, 原来的列表还是原
来的列表. 如果真的想要移除, 可以如下操作&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (setf lst (remove 'a lst))

(C R T)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;函数式编程意味着避免使用如 &lt;code&gt;setf&lt;/code&gt; 一样的函数. 它的优点之一是允许 interactive
testing. &lt;/p&gt;

&lt;h3&gt;Iteration&lt;/h3&gt;

&lt;p&gt;如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun show-squares (start end)
    (do ((i start (+ i 1)))
        ((&amp;gt; i end) 'done)
      (format t "~A ~A~%" i (* i i)))) 

SHOW-SQUARES
&amp;gt; (show-squares 2 5)
2 4
3 9
4 16
5 25
DONE&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;do&lt;/code&gt; 的第一个表达式是 &lt;code&gt;(variable initial update)&lt;/code&gt; , 标明变量 &lt;code&gt;i&lt;/code&gt; , 初值, 更新规
则. 第二个表达式是结束的条件. 剩下的是循环体.&lt;/p&gt;

&lt;p&gt;上述函数也可以用递归来写, 但是不太自然&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun show-squares (i end)
     (if (&amp;gt; i end)
       'done
       (progn
         (format t "~A ~A~%" i (* i i))
         (show-squares (+ i 1) end))))

SHOW-SQUARES
&amp;gt; (show-squares 2 5)
2 4
3 9
4 16
5 25
DONE&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;新的函数 &lt;code&gt;progn&lt;/code&gt; 接受任意数量的表达式, 依次求值, 并返回最后一个表达式的值.&lt;/p&gt;

&lt;p&gt;用 &lt;code&gt;dolist&lt;/code&gt; 来遍历列表元素会更加简单&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun our-length (lst)
    (let ((len 0))
      (dolist (obj lst)
        (setf len (+ len 1)))
     len))

OUR-LENGTH
&amp;gt; (our-length (list 'a 'b 'c))

3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述例子的递归版本为&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (defun our-length (lst)
    (if (null lst)
        0
        (+ (our-length (cdr lst)) 1)))

OUR-LENGTH
&amp;gt; (our-length (list 'a 'b 'c 'd))

4
&amp;gt; (our-length 'nil)

0
&amp;gt; (our-length '(a b c))          

3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;它更容易理解, 但由于不是 tail-recursive 的形式, 效率不是那么高.&lt;/p&gt;

&lt;h3&gt;Functions as Objects&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;function&lt;/code&gt; 是一个特殊的操作符号, 如果把函数的名字传给function, 它会返回相关关联
的对象, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (function +)

#&amp;lt;compiled-function + 0x55e01ee95b10&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;#'&lt;/code&gt; (sharp-quote)作为 function 的缩写, 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; #' +

#&amp;lt;compiled-function + 0x55e01ee95b10&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;apply&lt;/code&gt; 可以接受函数作为第一个实参, 第二个列表作为函数的实参. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (apply #'+ '(1 2 3))

6&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;funcall&lt;/code&gt; 做相同的事情, 但不需要把实参包装成列表&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (funcall #'+ 1 2 3)

6&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;lambda&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;lambda&lt;/code&gt; 不是一个操作符, 而只是一个符号. 早期由于函数在内部是用列表表示的, 因此
将函数的第一个元素标记为 &lt;code&gt;lambda&lt;/code&gt; 加以区分. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (lambda (x) (+ x 100))

#&amp;lt;bytecompiled-function 0x55726dfbe0f0&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(书上说现在可以省略 &lt;code&gt;lambda&lt;/code&gt; , 但是我这里省略了会报错, 或许我的版本不够新?)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lambda&lt;/code&gt; 表达式是一个列表, 包含符号 &lt;code&gt;lambda&lt;/code&gt; , 接着是形参列表, 以及由零个或多个
表达式所组成的函数体. 如&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (lambda (x y))

#&amp;lt;bytecompiled-function 0x5652ca53c0f0&amp;gt;
&amp;gt; (lambda (x y)
    (+ x y))

#&amp;lt;bytecompiled-function 0x5652ca53c050&amp;gt;
&amp;gt; ((lambda (x) (+ x 100)) 1)

101
&amp;gt; (funcall #'(lambda (x) (+ x 100)) 
          1) 

101&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Types&lt;/h3&gt;

&lt;p&gt;变量没有类型, 数值才有类型, 且可有多个类型. 如 &lt;code&gt;27&lt;/code&gt; 的类型, 依普遍性增加顺序为
&lt;code&gt;fixnum&lt;/code&gt; , &lt;code&gt;integer&lt;/code&gt; , &lt;code&gt;rational&lt;/code&gt; , &lt;code&gt;real&lt;/code&gt; , &lt;code&gt;number&lt;/code&gt; , &lt;code&gt;atom&lt;/code&gt; , &lt;code&gt;t&lt;/code&gt; . &lt;code&gt;t&lt;/code&gt; 是所
有类型的 supertype, 所以每个对象都属于 &lt;code&gt;t&lt;/code&gt; 类型. 如用 &lt;code&gt;typep&lt;/code&gt; 来判断某个数值是否
为某个类型&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-lisp"&gt;&amp;gt; (typep 27 'integer)

T
&amp;gt; (typep 27 't)

T
&amp;gt; (typep 27 'rational)

T
&amp;gt; (typep 27 'fixnum)

T&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;...&lt;/h2&gt;

&lt;p&gt;赶在因疫情突然决定明天回家之前整理完此篇. 不禁感叹世事无常, 还是要好好珍惜眼前的
人和事啊! &lt;/p&gt;

&lt;h2&gt;Elisp&lt;/h2&gt;

&lt;h3&gt;Hello wolrd&lt;/h3&gt;

&lt;p&gt;elisp 要在 emacs 中执行. 一个 hello world 的例子. 在 emacs 中 &lt;code&gt;M-x&lt;/code&gt;
&lt;code&gt;lisp-interaction-mode&lt;/code&gt; 切换到 lisp 交互主模式, 写入 &lt;/p&gt;

&lt;pre&gt;&lt;code class="language-elisp"&gt;(message "hello world")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;光标切到行尾, &lt;code&gt;C-j&lt;/code&gt; 即可运行. 另外也可以在 &lt;code&gt;org-mode&lt;/code&gt; 中, 插入 &lt;code&gt;elisp&lt;/code&gt; 代码块,
然后 &lt;code&gt;C-c&lt;/code&gt; &lt;code&gt;C-c&lt;/code&gt; 运行. (原 org 文件可以显示结果, hexo 不渲染执行结果) .&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-elisp"&gt;(message "hello world")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;#+RESULTS:
: hello world&lt;/p&gt;

&lt;h3&gt;Doc string&lt;/h3&gt;

&lt;p&gt;函数可以加 doc string, 将光标移到函数上, 用 &lt;code&gt;C-h&lt;/code&gt; &lt;code&gt;f&lt;/code&gt; 查看. 如 &lt;/p&gt;

&lt;pre&gt;&lt;code class="language-elisp"&gt;(defun hello-world (name)
"Say hello to user whose name is NAME"
(message "Hello, %s!" name))

(hello-world 'Emacser)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;#+RESULTS:
: Hello, Emacser!&lt;/p&gt;

&lt;p&gt;变量也可以加 doc string, 可用 &lt;code&gt;C-h&lt;/code&gt;  &lt;code&gt;v&lt;/code&gt; 查看. 如声明变量&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-elisp"&gt;(defvar foo "I'm foo!"
  "A demo variable")
foo&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;#+RESULTS:
: I'm foo&lt;/p&gt;

&lt;h3&gt;Some functions&lt;/h3&gt;

&lt;p&gt;函数 &lt;code&gt;eq&lt;/code&gt; 用来判断变量是否为某个值. 如( &lt;code&gt;elisp&lt;/code&gt; 和 &lt;code&gt;lisp&lt;/code&gt; 语法还是有些不同, 如
&lt;code&gt;format&lt;/code&gt; ) &lt;/p&gt;

&lt;pre&gt;&lt;code class="language-elisp"&gt;(defun eq-example()
  "A demo for function eq"
  (let ((a 1) (b 'x)) 
   (format "%s, %s, %s, %s" 
    (eq a 1) (eq a 2) (eq b 'x) (eq b 'y))))

(eq-example)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;#+RESULTS:
: t, nil, t, nil&lt;/p&gt;


&lt;pre&gt;&lt;code class="language-elisp"&gt;system-type&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;#+RESULTS:
: gnu/linux&lt;/p&gt;



&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Book: ANSI Common LISP by Paul Graham (z-lib.org)&lt;/li&gt;
&lt;li&gt;https://acl.readthedocs.io/en/latest/zhCN/ch2-cn.html&lt;/li&gt;
&lt;li&gt;http://smacs.github.io/elisp/01-hello-world.html&lt;/li&gt;
&lt;li&gt;https://www.emacswiki.org/emacs/&lt;/li&gt;
&lt;/ul&gt;
</content><category term="软件使用"/><category term="lisp"/><category term="emacs"/></entry><entry><title>python 并行的简单例子</title><link href="https://zqw.ink/2021-01-13-coding-multiprocessor.html" rel="alternate"/><published>2021-01-13T00:00:00+08:00</published><updated>2021-01-13T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-01-13:/2021-01-13-coding-multiprocessor.html</id><summary type="html">

&lt;pre&gt;&lt;code class="language-python"&gt;import multiprocessing as mp
import time
import functools
import numpy as np
import matplotlib.pyplot as plt

def timer(func):
    """
    Print the runtime of the decorated function.
    参考自: https://realpython.com/primer-on-python-decorators/
    """
    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">

&lt;pre&gt;&lt;code class="language-python"&gt;import multiprocessing as mp
import time
import functools
import numpy as np
import matplotlib.pyplot as plt

def timer(func):
    """
    Print the runtime of the decorated function.
    参考自: https://realpython.com/primer-on-python-decorators/
    """
    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f"Finished {func.__name__!r} in {run_time:.14f} secs")
        return value
    return wrapper_timer


def foo(x):
    '''
    测试函数, 简单地计算 sin(x), 重复 1e5 次
    '''
    for i in range(int(1e5)):
        a = np.sin(x)    
    a = np.sin(x)
    return a

n = int(96)
x = np.linspace(0, 10, n)

@timer
def loop_single_processing(x, n):
    y_l_s_p = np.zeros(n)
    for i in range(n):
        # 单核运行 n 次 foo(x) 函数
        y_l_s_p[i] = foo(x[i])
    y_l_s_p = foo(x)
    return y_l_s_p

@timer
def loop_multi_processing(x, n):
    pool = mp.Pool()
    y_m_s_p = pool.map(foo, x)
    pool.close()
    pool.join()
    return np.array(y_m_s_p)
    

lsp = loop_single_processing(x, n)
lmp = loop_multi_processing(x, n)

plt.plot(x, lsp, '.', label='loop single processing')
plt.plot(x, lmp+1, '.', label='loop multi processing')
plt.legend()
plt.savefig('fig.png')
plt.show()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;结果
file:./2021-01-13-coding-multiprocessor/fig.png&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;Finished 'loop_single_processing' in 9.28632830292918 secs
Finished 'loop_multi_processing' in 3.00595757691190 secs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;code: &lt;a href='./2021-01-13-coding-multiprocessor/mp.py'&gt;./2021-01-13-coding-multiprocessor/mp.py&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;从结果上看, 串行与并行当然给出相同的结果. 电脑上有 8 核, 但速度只提升了约 3 倍,
而不是 8 倍, 是核之间的任务分配与数据交换耗时还是我的程序有问题, 目前并不清楚.&lt;/p&gt;
</content><category term="软件使用"/><category term="python"/></entry><entry><title>如何将 python 程序打包成一个 package</title><link href="https://zqw.ink/2021-01-13-coding-setup_tools.html" rel="alternate"/><published>2021-01-13T00:00:00+08:00</published><updated>2021-01-13T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2021-01-13:/2021-01-13-coding-setup_tools.html</id><summary type="html">
&lt;h2&gt;示例&lt;/h2&gt;
&lt;p&gt;一个简单的示例. 比如写了一个名为 saudade 的包. 目录结构为(用 tree 生成, 不错的程
序, 之前没用过)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;.
├── demo
│   └── __init__.py
├── saudade
│   ├── coding_func.py
│   ├── __init__.py
│   └── physics_func.py
└── setup …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;示例&lt;/h2&gt;
&lt;p&gt;一个简单的示例. 比如写了一个名为 saudade 的包. 目录结构为(用 tree 生成, 不错的程
序, 之前没用过)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;.
├── demo
│   └── __init__.py
├── saudade
│   ├── coding_func.py
│   ├── __init__.py
│   └── physics_func.py
└── setup.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接执行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;python setup.py install --user&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可安装完成. &lt;code&gt;--user&lt;/code&gt; 安装给当前用户, 直接就放在 &lt;code&gt;~/.local/lib/python_xx&lt;/code&gt; 目录下
了, 不影响其它用户, 也不需要管理员权限.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;pip uninstall saudade&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可卸载.
当然也可以传到 github, 直接从 github 上安装.&lt;/p&gt;

&lt;h2&gt;结果&lt;/h2&gt;

&lt;p&gt;安装完以后就可以调用了. 如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;&amp;gt;&amp;gt;&amp;gt; import saudade as sau
&amp;gt;&amp;gt;&amp;gt; @sau.timer
... def foo(x):
...     return x**2
... 
&amp;gt;&amp;gt;&amp;gt; foo(3)
Finished 'foo' in 0.0000 secs
9
&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看出, 可以调用包的中计时器了.&lt;/p&gt;

&lt;p&gt;而 &lt;code&gt;demo&lt;/code&gt; 目录下的函数, 调用时要调用 demo , 如&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;&amp;gt;&amp;gt;&amp;gt; import demo
&amp;gt;&amp;gt;&amp;gt; demo.hello()
hello
&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;源码说明&lt;/h2&gt;

&lt;h3&gt;file:./2021-01-13-coding-setup_tools/setup.py&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;from setuptools import setup, find_packages
setup(
    name = 'saudade',
    version ='0.1',
    packages = find_packages(),
    description = "This is ZQW's first python package",
    author = 'ZQW',
    author_email = "zeqing6688@126.com",
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此文件最重要, 它说明这个目录是一个包, 可以安装.&lt;/p&gt;

&lt;h3&gt;demo/file:./2021-01-13-coding-setup_tools/demo/__init__.py&lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;def hello():
    print('hello')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一个测试函数&lt;/p&gt;

&lt;h3&gt;saudade/file:./2021-01-13-coding-setup_tools/saudade/coding_func.py&lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
#import matplotlib.pyplot as plt
import functools
import time

def timer(func):
    """
    Print the runtime of the decorated function.
    参考自: https://realpython.com/primer-on-python-decorators/
    """
    @functools.wraps(func)
    def wrapper_timer(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
        return value
    return wrapper_timer

@timer
def get_data(parameters, func, x):
    '''
    计算画图所需要的点, 并将参数和结果保存到文件.
    由于自己写的这些函数不能输入数组然后输出数组, 所以只能用循环一个一个算
    '''
    num_points = len(x)
    y = []
    pm = parameters.get_parameters()

    # 计算每一个数据点
    for i in range(num_points):
        print(f"正在计算第 {i+1:d}/{num_points:d}个点...")
        yi = func(x[i])
        y.append(yi)

    # 保存数据和参数到文件
    np.savetxt('./data/x.csv', x, delimiter=',')
    np.savetxt('./data/y.csv', y, delimiter=',')
    np.savetxt('./data/paramaters.csv', pm, delimiter=',')
    return x, y, pm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;saudade&lt;/code&gt; 目录的名字与包的名字相同, 包含了包的主要内容. 此文件是包中的一些函数&lt;/p&gt;

&lt;h3&gt;saudade/&lt;a href='./2021-01-13-coding-setup_tools/saudade/__init__.py'&gt;./2021-01-13-coding-setup_tools/saudade/__init__.py&lt;/a&gt; &lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from .coding_func import *
from .physics_func import *&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整个包的初始化位置.&lt;/p&gt;

&lt;h3&gt;saudade/&lt;a href='./2021-01-13-coding-setup_tools/saudade/physics_func.py'&gt;./2021-01-13-coding-setup_tools/saudade/physics_func.py&lt;/a&gt; &lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np

def ts(f, a, b, n=51):
    """Tanh-sinh quadrature 方法. 适用于端点发散的情况."""
    up = 4
    h = 2*up / (n-1)
    t = np.linspace(-up, up, n, endpoint=True)
    x = np.tanh(1/2*np.pi*np.sinh(t))
    w = 1/2*h*np.pi*np.cosh(t)
    w = w/(np.cosh(1/2*np.pi*np.sinh(t))**2)
    gc = 0
    for i in range(n):
        p = (x[i]*(b-a) + a + b)/2
        gc = gc + f(p)*w[i]
    err = 0
    gc = gc * (b-a)/2
    return gc, err

def bose(beta, energy):
    """Bose 分布函数"""
    x = -beta * energy
    return np.exp(x) / (1 - np.exp(x))

def cos_theta_kq(theta_k, phi_k, theta_q, phi_q):
    """k, q 夹角的余弦值"""
    x = (np.sin(theta_k)*np.sin(theta_q) * np.cos(phi_k - phi_q) 
            + np.cos(theta_k)*np.cos(theta_q))
    return x

class PrincipalValueInt():
    """分母带有无穷小的那种积分"""
    def __init__(self, numerator, coeff, down_bound, upbound):
        """初始化, numerator 都是函数. 分母为 a*x**2 + b*x + c"""
        self.numerator = numerator
        self.down_bound = down_bound
        self.upbound = upbound
        self.coeff = coeff
        a = coeff[0]
        b = coeff[1]
        c = coeff[2]
        self.delta = b**2 - 4*a*c

    def get_imag(self):
        """计算积分的虚部."""
        root_exist = self.delta &amp;gt; 0

        if root_exist:
            # 如果根存在, 计算两根
            root1 = (-self.coeff[1] - np.sqrt(self.delta)) / (2 * self.coeff[0])
            root2 = (-self.coeff[1] + np.sqrt(self.delta)) / (2 * self.coeff[0])

            # 判断两根是否位于积分区间内
            root1_in = self.down_bound &amp;lt; root1 and root1 &amp;lt; self.upbound
            root2_in = self.down_bound &amp;lt; root2 and root2 &amp;lt; self.upbound

            # 计算积分结果
            imag = (root1_in) * self.numerator(root1) 
            imag += (root2_in) * self.numerator(root2) 
            imag *= -np.pi / np.abs(root2 - root1)
        else:
            # 根不存在, 虚部为 0
            imag = 0 
        imag *= 1/self.coeff[0] # bug No.2 分子要除以 a 才行.
        return imag&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;包中的另一些函数.&lt;/p&gt;
</content><category term="软件使用"/><category term="python"/></entry><entry><title>SSD 备忘与趣事</title><link href="https://zqw.ink/2020-11-29-coding-newSSD.html" rel="alternate"/><published>2020-11-29T00:00:00+08:00</published><updated>2020-11-29T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2020-11-29:/2020-11-29-coding-newSSD.html</id><summary type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h1 id="引言"&gt;引言&lt;/h1&gt;
&lt;p&gt;办公室电脑原来的机械硬盘实在有点不行了, 换了一块新的 SSD.&lt;/p&gt;
&lt;p&gt;本来想买个再好一点的, 但是主板有只有 sata 接口. 虽说 …&lt;/p&gt;</summary><content type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h1 id="引言"&gt;引言&lt;/h1&gt;
&lt;p&gt;办公室电脑原来的机械硬盘实在有点不行了, 换了一块新的 SSD.&lt;/p&gt;
&lt;p&gt;本来想买个再好一点的, 但是主板有只有 sata 接口. 虽说再折腾一下也可以换更高级的 SSD, 但是也没(有)那(点)么(懒)多(啊)时(啊)间.&lt;/p&gt;
&lt;p&gt;我发现 11 月份没有写新的博客. 就这样水?一篇吧! 其实这个可以合在之前那篇 manjaro 装机 note 里的的.&lt;/p&gt;
&lt;h1 id="买-ssd"&gt;买 SSD&lt;/h1&gt;
&lt;p&gt;我之前只知道 SSD 分好几种, 具体也没怎么研究过. 要自己买当然要拆开看看主板上有什么接口. 哎, 自己看了半天也不知道哪个是 SSD接口. 把图片发给店家, 立马知道要买什么样的了!&lt;/p&gt;
&lt;p&gt;原来主板上有空的 sata 接口, 而且之前我也没有意识到 SSD 是用线与主板相连的, 还以为是像内存一样直接插上的, 怪不得没有找到插口.&lt;/p&gt;
&lt;p&gt;在卖家的帮忙下(吐嘈一下, 东芝改名叫铠侠, 觉得不如原来好听) , 买了 SSD 和 sata 线.&lt;/p&gt;
&lt;h1 id="装-ssd"&gt;装 SSD&lt;/h1&gt;
&lt;p&gt;很快啊, 新的 SSD 第二天就来了. 一拿的感觉是: 轻!&lt;/p&gt;
&lt;p&gt;直接插上 sata 线连上, 开机! 竟然没有识别. 思考为什么会这样的时候, 瞟了一眼说明说: SSD 还需要接电源的! 看来&amp;quot;不用读系列&amp;quot;有时候还是要看的. 我说这硬盘上怎么有两块呲出来的.&lt;/p&gt;
&lt;p&gt;可是我并没有买电源线. 就在我一边责怪卖家没有告诉我, 一边又想又得再等一天快递了, 一边又想从哪个废旧电脑上拆一根时, 突然又想到光驱也是 sata 线连到主板上的, 应该也有电源线. 机智如我, 直接拔下来接到了 SSD 上. 开机, 开不了机了, 原来那里接的是机械硬盘. 又一次偶然发现, 这根电源线中间还伸出一个头. 不错, 接上, 完美解决!&lt;/p&gt;
&lt;h1 id="安装-ssd-manjaro"&gt;安装 SSD manjaro&lt;/h1&gt;
&lt;p&gt;记录一下注意的点. Bootloader 选到 KIOXIA (新 SSD ) 上, BIOS select device 也先 KIOXIA.&lt;/p&gt;
&lt;h1 id="幽灵般的网络"&gt;幽灵般的网络&lt;/h1&gt;
&lt;p&gt;在 SSD 上装 win10 和 manjaro 很顺利. 但接下来有一件事我至今不明白是为什么.&lt;/p&gt;
&lt;p&gt;win10 是有网的. 然后装 manjaro, 打开之后没网. 心想是网络配置不对. 然后打开机械硬盘上的 manjaro 对一下配置. 再重启进 SSD manjaro, 突然有网了. 虽然奇怪, 但问题自己好了.&lt;/p&gt;
&lt;p&gt;在 SSD manjaro 上进行了一些设置后, 重启, 又没网了, 啊! 再重启进机械硬盘 manjaro, 啊, 机械 manjaro 也没网了, 很奇怪啊, 之前 机械 manjaro 用了很久, 也没有出现连不上网的情况. 怀疑是办公室的网络出问题了, 进 SSD win10, 也没网, 更加断定我的判断.&lt;/p&gt;
&lt;p&gt;问了一下别人, 有网?&lt;/p&gt;
&lt;p&gt;那是我这根线上的路由器被我搞冲突了? 但是 yf 的还有网, 而且又边了它的网线, 也连不上网, 它的电脑却能连上. 那就是我电脑的问题了.&lt;/p&gt;
&lt;p&gt;应该也不是软件的问题, 因为无论新旧, 四个系统每个都边不上网.&lt;/p&gt;
&lt;p&gt;硬件问题, 难道是我装 SSD 的时候碰到了什么? 不应该啊! 有点迷惑!&lt;/p&gt;
&lt;p&gt;在 yf 提醒下, 将 SSD 拆下来, 进机械 win10, 进不去了... 进机械 manjaro, 啊, 竟然能连上, 真的太奇怪了! 难道接上 SSD 导致其它部分供电不足?&lt;/p&gt;
&lt;p&gt;又把 SSD 装回去, 又能连上了...&lt;/p&gt;
&lt;p&gt;从 SSD manjaro 重启再进 SSD manjaro 又边不上了.&lt;/p&gt;
&lt;p&gt;再从 SSD manjaro 重启进 SSD win10 可以.&lt;/p&gt;
&lt;p&gt;再从 SSD win10 进 SSD manjaro, 又可以了.&lt;/p&gt;
&lt;p&gt;从 SSD manjaro 重启再进 SSD manjaro 又边不上了.&lt;/p&gt;
&lt;p&gt;再从 SSD manjaro 重启进 SSD win10 可以.&lt;/p&gt;
&lt;p&gt;再从 SSD win10 进 SSD manjaro, 又可以了.&lt;/p&gt;
&lt;p&gt;看来 SSD manjaro 的网络需要 SSD win10 的唤醒...&lt;/p&gt;
&lt;p&gt;又想起之前对机械和 SSD manjaro 配置的时候网上驱动不太一样, 但是重启后好了, 没有在意. 现在又边不上了. 这就把驱动弄地一样. 好了&lt;/p&gt;
&lt;p&gt;一切都好了, 是网卡驱动的问题. 之前 cy 机械硬盘 manjaro 连不上网估计也是这个问题.&lt;/p&gt;
&lt;p&gt;但是!!! 之前四个系统都连不上的原因我依然不知道, 我能想到的就只能是... 想不到是为什么 . 太奇怪了!&lt;/p&gt;
&lt;p&gt;附网上安装: 右键安装&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-11-29-coding-newSSD/image-20201128212856147.png" alt="fig" /&gt;&lt;/p&gt;
&lt;h1 id="wayland-换-xorg"&gt;wayland 换 xorg&lt;/h1&gt;
&lt;p&gt;奇怪的网络问题让我对了机械和 SSD 的 gnome 版本, 发现新的 manjaro 包默认是 wayland. 我突然意识到之前给 cy 的机械硬盘装 manjaro 后闪屏的问题, 很有可能也是用了 wayland.&lt;/p&gt;
&lt;p&gt;换回 Xorg 直接安装 Xorg 包就好了&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -S xorg 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;登陆选 xorg 的 gnome 即可.&lt;/p&gt;
&lt;h1 id="输入法"&gt;输入法&lt;/h1&gt;
&lt;p&gt;arch wiki 关于中文输入法的部分升级了, 存放环境变量的文件有了变化, 详见: https://wiki.archlinux.org/index.php/Fcitx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E5.AE.89.E8.A3.85&lt;/p&gt;
&lt;p&gt;还是比较习惯之前的快捷键设置, 截图记录.&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-11-29-coding-newSSD/image-20201128215138108.png" alt="image-20201128215138108" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-11-29-coding-newSSD/image-20201128215200197.png" alt="image-20201128215200197" /&gt;&lt;/p&gt;
&lt;h1 id="evince-中文问题"&gt;evince 中文问题&lt;/h1&gt;
&lt;p&gt;之前装 xpdf 就好了, 可这次不好使了. 这样, 也促使我找到了问题的原因: https://blog.csdn.net/nevasun/article/details/7303529 okular, epdfview, evince的pdf功能均由xpdf的分支poppler提供，poppler从fontconfig的配置文件中读取字体取代pdf里的字体。&lt;/p&gt;
&lt;p&gt;这次安装 &lt;code&gt;poppler-data&lt;/code&gt; 就好了&lt;/p&gt;
&lt;h1 id="emacs-开启卡顿"&gt;emacs 开启卡顿&lt;/h1&gt;
&lt;p&gt;看卡顿的时间, 卡顿完字体变大, 推测是 cnfonts 的问题, 注释掉就好了&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;;; 字体设置
;;(require 'cnfonts)
;; 让 cnfonts 随着 Emacs 自动生效。
;;(cnfonts-enable)
;; 让 spacemacs mode-line 中的 Unicode 图标正确显示。
;;(cnfonts-set-spacemacs-fallback-fonts)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="修改默认-shell"&gt;修改默认 shell&lt;/h1&gt;
&lt;p&gt;新的 manjaro 包默认的 shell 也改成了 zsh. 不过我还是习惯原来的 bash. 改下面的文件就可以:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo emacs /etc/passwd 
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="grub-theme"&gt;GRUB theme&lt;/h1&gt;
&lt;p&gt;新的 manjaro 包里也没有了 GRUB theme, 有点不好看, 可以直接 &lt;code&gt;yaourt grub theme&lt;/code&gt; 找到 manjaro 的 grub theme 安装就好.&lt;/p&gt;
&lt;h1 id="开机挂载"&gt;开机挂载&lt;/h1&gt;
&lt;p&gt;旧的机械硬盘可以设置开机自动挂到某个目录, 方法是修改 &lt;code&gt;/etc/fstab&lt;/code&gt; , 比如增加记录&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;/dev/sda5				  /docu		 ntfs	 defaults		    0 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="对-manjaro-版本时用到的命令"&gt;对 manjaro 版本时用到的命令&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;lsb_release -a
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="对-hexo"&gt;对 hexo&lt;/h1&gt;
&lt;p&gt;hexo 貌似对新版的 node 支持不友好, 需要将 node 进行版本回退才可以正常 deploy.&lt;/p&gt;
&lt;p&gt;用 &lt;code&gt;n&lt;/code&gt; 来管理和切换 node 版本.&lt;/p&gt;
&lt;p&gt;查看 node 版本&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;node -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;npm install -g n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下载 hexo 可用的 node 版本 13.14.0&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo n 13.14.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;切换版本是与上面相同的命令&lt;/p&gt;
&lt;p&gt;或许有一天, 我该把 blog 换到 pelican 上面, 毕竟比较熟悉语言.&lt;/p&gt;
&lt;h1 id="virtualbox"&gt;VirtualBox&lt;/h1&gt;
&lt;p&gt;不仅需要安装 virtualbox, 还需要安装宿主机对应内核的 host modules. &lt;code&gt;umane -a&lt;/code&gt; 查看 Linux 内核版本, 比如我的结果是 5.8.18, 所以还要安装 &lt;code&gt;linux58-virtualbox-host-modules&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;两个安装好之后, 还要激活模块(这个在安装 virtualbox 时有过一行提示)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo modprobe vboxdrv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后即可正常使用&lt;/p&gt;
</content><category term="软件使用"/><category term="SSD"/><category term="manjaro"/></entry><entry><title>matplotlib.animation 制作动图</title><link href="https://zqw.ink/2020-09-18-coding-animation_plot.html" rel="alternate"/><published>2020-09-18T00:00:00+08:00</published><updated>2020-09-18T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2020-09-18:/2020-09-18-coding-animation_plot.html</id><summary type="html">
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani

fig, ax = plt.subplots()

# 横坐标取值
m, n = 100, 20
x = np.linspace(0, 4*np.pi, n)

y = np.zeros((m, n))
for i in range(m):
    y[i] = np.sin(x …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani

fig, ax = plt.subplots()

# 横坐标取值
m, n = 100, 20
x = np.linspace(0, 4*np.pi, n)

y = np.zeros((m, n))
for i in range(m):
    y[i] = np.sin(x+2*np.pi*i/m)

# 在画纸上画出零时刻第一条线 ln
ln, = ax.plot(x, y[0], 'ro')

def init():
    """FuncAnimation 所需要的动画初始设置, 返回值为零时刻的线 ln"""
    ax.set_xlim(0, 4*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(i):
    """
    FuncAnimation 所需要的更新函数, 对于第 i 帧, 修改纵轴数据为 y 的第 i 行
    返回值为更新后的第 i 帧对应的线
    """
    ln.set_data(x, y[i])
    return ln,

# 进行绘制. FuncAnimation 的函数文档: https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation
my_ani = ani.FuncAnimation(fig=fig, func=update, frames=m, interval=1,
                            init_func=init, blit=False)

# Set up formatting for the movie files (3.7.3 报错, 3.8.5 可以)
writer = ani.FFMpegFileWriter(fps=60, metadata=dict(artist='Me'), bitrate=180)
# 保存图片
# my_ani.save('Harmonic.gif',writer=writer)

plt.show()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='./2020-09-18-coding-animation_plot/Harmonic.gif' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;
</content><category term="软件使用"/><category term="python"/></entry><entry><title>坎坷的 wakatime-mode</title><link href="https://zqw.ink/2020-07-28-coding-wakatime.html" rel="alternate"/><published>2020-07-28T00:00:00+08:00</published><updated>2020-07-28T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2020-07-28:/2020-07-28-coding-wakatime.html</id><summary type="html">
&lt;p&gt;(许久没有更新折腾类的了.)&lt;/p&gt;

&lt;h2&gt;ailien invasion&lt;/h2&gt;

&lt;p&gt;最近按照 《Python编程：从入门到实践 - 2016》 一书重复了 ailien invasion 这一
project (见 https://github.com/phyer219/alien_invasion ) ! 本身是个写游戏的项 …&lt;/p&gt;</summary><content type="html">
&lt;p&gt;(许久没有更新折腾类的了.)&lt;/p&gt;

&lt;h2&gt;ailien invasion&lt;/h2&gt;

&lt;p&gt;最近按照 《Python编程：从入门到实践 - 2016》 一书重复了 ailien invasion 这一
project (见 https://github.com/phyer219/alien_invasion ) ! 本身是个写游戏的项目.
但是很多方法都可以借鉴到其它的 project 中. 对于我这种没有正经地学过写程序的人来
说(我不想回忆本科时上的那门程序设计课...), 收获还是颇丰的!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;对类的应用&lt;/li&gt;
&lt;li&gt;要给每个函数写 docstring&lt;/li&gt;
&lt;li&gt;把不同功能的函数放到不同的文件里&lt;/li&gt;
&lt;li&gt;写一些程序后, 要进行重构(Refactoring), 降低一些函数的长度. 使程序的结构清晰.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;感谢这本书的作者和翻译者. 这样完整且标准的去重复这样的 project 的机会真的难得!&lt;/p&gt;

&lt;p&gt;得益于 ailien invasion , 又用了一天的时间把正在做的课题用 python 重新算了一遍.
经过修改一些 bug 后, 和之前的 fortran 符合得很好, 我终于能够对自己写的 fortran
程序的正确性很有信心了!&lt;/p&gt;

&lt;h2&gt;VS Code &lt;/h2&gt;

&lt;p&gt;就我目前所处的 emacs 学习曲线的阶段来说, 还是 VS Code / Atom 这类的编辑器写这种
project 比较合适. 它的特点是 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;程序分散在不同的文件里, 要频繁来回切换, 反复修改.&lt;/li&gt;
&lt;li&gt;总的代码量并不大.&lt;/li&gt;
&lt;li&gt;要时常查看函数的 docstring .&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;VS Code 新插件 Pylance 真的方便. (期间遇到问题, 才知道 VS Code 有好多分支, code,
vscodium ...)&lt;/p&gt;

&lt;p&gt;但写 tex , emacs + auctex 的效率还是无敌的! &lt;/p&gt;

&lt;h2&gt;wakatime-mode&lt;/h2&gt;

&lt;p&gt;用了 VS Code, 不免要看看有哪些好玩的插件. 于是就发现了 wakatime. 统计你在不同去
的 project, 不同的时间段, 不同的编辑器上花费的时间的插件. 好玩! 好玩在展示统计结
果的界面, 真好看! 我此时认为统计的主要魅力就在于那些漂亮的图表!&lt;/p&gt;

&lt;p&gt;昨天发现 wakatime 还有 emacs 的插件, 那岂不美哉! &lt;/p&gt;

&lt;p&gt;但是无论怎么搞, 它都会报错&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;error "WakaTime Error 104 Invalid API Key. Set your api key with: (custom-set-variables '(wakatime-api-key \"XXXX\")) &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;几个小时没有解决(折腾这种事容易上头, 这还是近几个月来少见地上头了) . 回头一看 VS
code 竟然也 Invalid API Key 了, 在 atom 也是 Invalid API Key . 然后换了系统, 换
了账号, 都是 Invalid API Key . 而其它类似的插件是可以正常连接的. 此时, 我已基本
断定, 这个报错的原因极有可能是服务器出了问题. 于是没有再理.&lt;/p&gt;

&lt;p&gt;今天早上一看, 昨天果是它们的服务器的问题, VS Code 和 atom 都正常了. emacs 仍然是
Invalid API Key. 我打开 dashboard 一看, 让我震惊的是 dashboard 上竟然显示了我昨
天在 atom 和 emacs 上的活动! 也就是说, 虽然 wakatime-mode 报错 Invalid API Key,
但是实际是 dashboard 已经收到信号了. 这是谎报的!&lt;/p&gt;

&lt;p&gt;经过一波测试, 断定是 emacs 的 wakatime-mode 插件的 bug! 于是找到插件对应的
wakatime-mode.elc , 定位到 Error 104 对应的语句&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;    (set-process-sentinel process
      `(lambda (process signal)
         (when (memq (process-status process) '(exit signal))
           (kill-buffer (process-buffer process))
           (let ((exit-status (process-exit-status process)))
             (when (and (not (= 0 exit-status)) (not (= 102 exit-status)))
               (cond
                 ((= exit-status 103) (error "WakaTime Error (%s) Config file parse error. Check your ~/.wakatime.cfg file." exit-status))
                 ((= exit-status 104) (error "WakaTime Error (%s) Invalid API Key. Set your api key with: (custom-set-variables '(wakatime-api-key \"XXXX\"))" exit-status))
                 ((= exit-status 105) (error "WakaTime Error (%s) Unknown wakatime-cli error. Please check your ~/.wakatime.log file and open a new issue at https://github.com/wakatime/wakatime-mode" exit-status))
                 ((= exit-status 106) (error "WakaTime Error (%s) Malformed heartbeat error. Please check your ~/.wakatime.log file and open a new issue at https://github.com/wakatime/wakatime-mode" exit-status))
                 (t (error "WakaTime Error (%s) Make sure this command runs in a Terminal: %s" exit-status (wakatime-client-command nil)))
               )
             )
           )
         )
      )
    )&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;果断删除了&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt; ((= exit-status 104) (error "WakaTime Error (%s) Invalid API Key. Set your api key with: (custom-set-variables '(wakatime-api-key \"XXXX\"))" exit-status))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再测试一波, dashboard 能统计到 emacs 的活动, emacs 的 wakatime-mode 也不再报错.
完美解决.&lt;/p&gt;

&lt;p&gt;对我来说是解决了, 如果有能力的话, 还是把这个 bug 报给开发都比较好. 我还是算了...&lt;/p&gt;
</content><category term="软件使用"/><category term="emacs"/><category term="wakatime"/></entry><entry><title>Django 笔记：CentOS+Apache+Mariadb+mod_wsgi+Django</title><link href="https://zqw.ink/2020-02-03-physics-Django.html" rel="alternate"/><published>2020-02-03T00:00:00+08:00</published><updated>2020-02-03T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2020-02-03:/2020-02-03-physics-Django.html</id><summary type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h1 id="写在前面的声明"&gt;写在前面的声明&lt;/h1&gt;
&lt;p&gt;本人非专业人士，对于写程序只是业余爱好。以下内容仅供参考，我一个业余人士也不能保证内容的准确 …&lt;/p&gt;</summary><content type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h1 id="写在前面的声明"&gt;写在前面的声明&lt;/h1&gt;
&lt;p&gt;本人非专业人士，对于写程序只是业余爱好。以下内容仅供参考，我一个业余人士也不能保证内容的准确性，对一些命令的解释也只是为了便于记忆和理解，更加专业准确的知识还请查询如官方文档这样的资料。&lt;/p&gt;
&lt;h1 id="引言"&gt;引言&lt;/h1&gt;
&lt;h2 id="思路"&gt;思路&lt;/h2&gt;
&lt;p&gt;寒假在家，又不能出门，闲来无事，又不太想学习，就尝试了用在华为云上买的学生价服务器，在 CentOS 上用 Apache+Mariadb+Django 来搭建一个网站，目标是能够显示内容即可，而对安全性，实用性，美观性不做要求。&lt;/p&gt;
&lt;p&gt;网站内容是显示《诗经》的所有内容。数据来自于 github 上的诗词数据库 https://github.com/chinese-poetry/chinese-poetry ，在此感谢此项目中的贡献者表示感谢！&lt;/p&gt;
&lt;p&gt;大体思路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在服务器上开放所需要的端口，安装所需要的 Apache, Mariadb, Python3。&lt;/li&gt;
&lt;li&gt;建立一个虚拟环境，在虚拟环境中用 pip 安装 Django, pymysql, mod_wsgi。&lt;/li&gt;
&lt;li&gt;修改各种设置，使 Django 能够和 Apache, Mariadb 正常连接。&lt;/li&gt;
&lt;li&gt;写一个程序，把诗经的数据从 json 文件中复制到数据库中&lt;/li&gt;
&lt;li&gt;编写 Django 中的文件，使其从数据库中读取诗经的数据，并在网页上展示。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;写这篇笔记的目的，首先是记录过程为自己作备忘。其次，是想将一些过程的目的说出来，便于和我一样在尝试搭建的人理解为什么要这样做。&lt;/p&gt;
&lt;h2 id="云服务器的对比"&gt;云服务器的对比&lt;/h2&gt;
&lt;p&gt;我先后买过腾讯云，阿里云，华为云提供的学生价服务器，最便宜的配置大概都在10元／月不到。真的很棒，感谢他们！&lt;/p&gt;
&lt;p&gt;这三家的配置大致差不多，不过三家中只有阿里云，在学生期间可以，不限次数不限期限地以学生价续费。其它两家都对期限以及续费的次数有所限制。目前我在腾讯云买的已经到期了，华为云上刚刚买的，阿里云上的可以一直用。&lt;/p&gt;
&lt;h1 id="系统环境"&gt;系统环境&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;操作系统：CentOS Linux release 7.7.1908 (Core)&lt;/li&gt;
&lt;li&gt;Mariadb 版本：mysql  Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64) using readline 5.1&lt;/li&gt;
&lt;li&gt;Apache 版本：Apache/2.4.6 (CentOS)&lt;/li&gt;
&lt;li&gt;Python 版本：Python 3.7.3&lt;/li&gt;
&lt;li&gt;确保端口开放&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="记号说明"&gt;记号说明&lt;/h1&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;表示在本地运行的命令。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud] $
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;表示在云服务器上以 root 用户运行命令。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;表示在在云服务器的虚拟环境 .sabafun 中以 root 用户运行命令。&lt;/p&gt;
&lt;h1 id="安装-apache-mariadb-python3"&gt;安装 Apache, Mariadb, Python3&lt;/h1&gt;
&lt;p&gt;升级软件包，安装 apache（在 yum 库中名字叫 httpd）, mariadb, emacs(文本编辑器，个人偏好，可选)，并开启，然后设置开机自启。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ yum upgrade

[root@cloud]$ yum install httpd httpd-devel
[root@cloud]$ yum systemctl start httpd
[root@cloud]$ yum systemctl enable httpd

[root@cloud]$ yum install mariadb mariadb-server
[root@cloud]$ yum systemctl start mariadb
[root@cloud]$ yum systemctl enable mariadb

[root@cloud]$ yum install emacs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 CentOS 上，用 yum 命令来安装，升级，删除软件。yum upgrade 升级软件包，yum install 安装某个软件。systemctl 用来对服务进行开启，关闭，重启等操作。常用的有：systemctl start 开启服务，systemctl stop 停止服务，systemctl restart 重启服务，systemctl enable 让服务开机自启。&lt;/p&gt;
&lt;p&gt;通过安装 Anaconda 来安装 Python3.7，（yum 库中是Python3.6，版本有点低，会报错）。从 Anaconda 官网下载安装包后，进入到安装包所在的目录进行安装&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ bash ./Anaconda3-2019.07-Linux-x86_64.sh 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;./ 表示当前路径。&lt;/p&gt;
&lt;h1 id="安装虚拟环境-virtualenv"&gt;安装虚拟环境 virtualenv&lt;/h1&gt;
&lt;p&gt;安装完 Anaconda 后，并没有自动将 python3.7 添加到环境变量中，因此直接把路径完整地打出来，来运行 pip&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ /root/anaconda3/bin/pip install virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pip 是 Python 的包管理工具，安装一些 Python 包都可以用 pip install 来安装。&lt;/p&gt;
&lt;p&gt;安装 virtualenv 是为了给 Django 建立一个独立的 Python 环境，下面可以看出这样做的好处。&lt;/p&gt;
&lt;h1 id="创建虚拟环境"&gt;创建虚拟环境&lt;/h1&gt;
&lt;p&gt;安装好 virtualenv 后，进入到想要进行工作的目录，通过 virtualenv 创建一个虚拟环境，用来进行后续的活动&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ virtualenv .sabafun --python=/root/anaconda3/bin/python3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;-- 后面的参数表示：以指定的 Python 版本创建虚拟环境，这里指定的是我们安装的 Anaconda 中的 Python 3。不加这个参数，就会以系统默认的 Python2.7。创建的虚拟环境名字叫做 .sabafun 前面的点是为了将存放虚拟环境的文件夹隐藏，也可以不加 点。&lt;/p&gt;
&lt;p&gt;进入虚拟环境，此时可以再确认一下 Python 版本&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ source .sabafun/bin/activate
(.sabafun)[root@cloud]$ python --version
Python 3.7.3
(.sabafun)[root@cloud]$ pip --version
pip 20.0.2 from /root/sabafun/.sabafun/lib/python3.7/site-packages/pip (python 3.7)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入虚拟环境中，在命令的开头会出现 (.sabafun) ，表示在虚拟环境中。可以看出，在虚拟环境中直接运行 Python 就是我们创建虚拟环境时指定的 Python 版本。这样就和系统的环境隔离来，以避免一些冲突，因为如果将系统的 Python 绑定到 Python3.7 会导致系统中一些依赖 Python2 的程序无法正常运行。&lt;/p&gt;
&lt;p&gt;source 命令是让某些文件中的设置立即生效，这里是使虚拟环境中的设置生效。source 还用于当我们修改配置文件中的环境变量后，source 一下配置文件，就可以使配置马上生效，而不需要重启设备。&lt;/p&gt;
&lt;p&gt;要停止使用虚拟环境,可执行命令 deactivate&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ deactivate 
[root@cloud]$ 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行后，前面的 (.sabafun) 就消失了，表示退出了虚拟环境。如果想要删除虚拟环境，直接将保存虚拟环境的文件夹删除就行。&lt;/p&gt;
&lt;h1 id="安装-django创建项目"&gt;安装 Django，创建项目&lt;/h1&gt;
&lt;p&gt;在虚拟环境中，用 pip 安装 Django，然后新建一个项目，名字叫作 sabafun&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install django
(.sabafun)[root@cloud]$ django-admin startproject sabafun .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意不要漏掉最后的点'.'。这个命令末尾的句点让新项目使用合适的目录结构。如果漏了，就把这个项目的文件夹删除，再重新创建一次。&lt;/p&gt;
&lt;h1 id="启动用于开发的-web-服务器"&gt;启动用于开发的 web 服务器&lt;/h1&gt;
&lt;p&gt;在启动 web 服务器测试之前，需要做一些准备工作。&lt;/p&gt;
&lt;p&gt;首先，将服务器的 IP 加到项目的设置文件 sabafun/settings.py 中，即将 ALLOWED_HOSTS 项修改为&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;ALLOWED_HOSTS = [‘服务器IP地址’]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后启动 Django 自带的用于测试的 web 服务器&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对项目的一些操作都保存在 mange.py 文件中。出现关于数据库的提示可以忽略。Django 默认用 SQLite 作数据库。而我们不用它，而是用 Mariadb。&lt;/p&gt;
&lt;p&gt;此时从本地访问 http://你的服务器IP:8000 ，出现如下小火箭界面，表示成功&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204125926942.png" alt="image-20200204125926942" /&gt;&lt;/p&gt;
&lt;p&gt;如果无法访问，可以查看一下服务器的 8000 端口是否开放。一般都可以从云服务器的管理页面中找到安全组设置。&lt;/p&gt;
&lt;h1 id="django-的大致工作流程"&gt;Django 的大致工作流程&lt;/h1&gt;
&lt;p&gt;比较业余的理解，Django 是一个用 Python 写网站的框架。我们可以用 Python 语言写一些函数来实现想要的功能。web 服务器，如 Apache，负责将我们设计好的功能提供给浏览器。而 mod_wsgi 负责将我们用 Python 写的功能翻译给 Apache。网站的数据，如我们用于展示的《诗经》就存储在 Mariadb 数据库中。&lt;/p&gt;
&lt;p&gt;所以我们通过网址访问网站，Apache 接收到我们的请求，wsgi 将请求翻译给 Django，Django 从数据库中读取到数据，然后再通过 wsgi 这位翻译发送给 Apache，Apache 将数据发送给我们的浏览器，我们就看到了我们想要的东西。&lt;/p&gt;
&lt;h1 id="通过-mod_wsgi-连接-apache"&gt;通过 mod_wsgi 连接 Apache&lt;/h1&gt;
&lt;p&gt;我们上面看到的小火箭的页面，所用的 web 服务器不是 Apache ，而是 Django 自带的用于开发测试的 web 服务器，真正运行网站时，就要连接像 Apache, Nginx 这样的 web服务器。&lt;/p&gt;
&lt;p&gt;下面就设置一下，让 Apache 作为 web 服务器。&lt;/p&gt;
&lt;p&gt;首先安装负责 Apache 和 Python3 之间进行通信的 mod_wsgi 模块&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install mod_wsgi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;wsgi 是 Web Server Gateway Interface 的缩写。参考 Django 的官方文档 https://docs.djangoproject.com/zh-hans/3.0/howto/deployment/wsgi/modwsgi/ 和 https://modwsgi.readthedocs.io/en/develop/ 进行设置。&lt;/p&gt;
&lt;p&gt;安装好 mod_wsgi 后，查看 wsgi 和 Apache 的接头暗号&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ mod_wsgi-express module-config
LoadModule wsgi_module &amp;quot;/root/sabafun/.sabafun/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so&amp;quot;
WSGIPythonHome &amp;quot;/root/sabafun/.sabafun&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一行是告诉 Apache 在哪里能够找到 wsgi 。第二行是告诉 Apache ，Django 所使用的 Python在哪里。&lt;/p&gt;
&lt;p&gt;然后将接头暗号写入 Apache 的配置文件 /etc/httpd/conf/httpd.conf ，在其末尾添加以下内容&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;#　加载模块
LoadModule wsgi_module &amp;quot;/root/sabafun/.sabafun/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so&amp;quot;

WSGIScriptAlias / /root/sabafun/sabafun/wsgi.py
WSGIPythonHome /root/sabafun/.sabafun
WSGIPythonPath /root/sabafun

&amp;lt;Directory /root/sabafun/sabafun&amp;gt;
&amp;lt;Files wsgi.py&amp;gt;
Require all granted
&amp;lt;/Files&amp;gt;
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WSGIPythonPath 是告诉 Apache 项目所在的地方。WSGIScriptAlias 是说 wsgi.py 文件在哪。wsgi.py 文件 Django 已经写好了，我们不用动，里面包含了 Apache 如何与 Django 交流的方法 。&lt;/p&gt;
&lt;p&gt;同样是 Apache 的配置文件 /etc/httpd/conf/httpd.conf ，修改 ServerName 项为&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;ServerName 你的服务器IP:80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改项目的权限，以便 Apache 有权限读取我们创建的项目&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ chmod 755 -R /root/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;chmod 是 change mode单词前缀的组合，用来修改文件的权限。755 是用八进制表示的权限，7 就是最高权限，三个数字分别表示文件所有者，用户组以及其它用户的权限，具体参考 https://zh.wikipedia.org/wiki/Chmod 。&lt;/p&gt;
&lt;p&gt;然后重启 Apache 服务&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接访问 IP ，出现了小火箭，这时的小火箭是通过 Apache 给我们的，说明 Django 能够和 Apache 交流了。&lt;/p&gt;
&lt;h1 id="设置-mariadb-数据库"&gt;设置 Mariadb 数据库&lt;/h1&gt;
&lt;p&gt;首先初始化数据库&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会让我们设置数据库的 root 用户密码等。&lt;/p&gt;
&lt;p&gt;用 root 用户登陆数据库&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参数 -u 表示 user，后面跟用户名，参数 -p 表示 password。&lt;/p&gt;
&lt;p&gt;登陆数据库后，为 Django 创建一个用户，然后再为我们的项目创建一个数据库，并设置权限&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;MariaDB [(none)]&amp;gt; create user django@localhost identified by '密码';
MariaDB [(none)]&amp;gt; create database sabafun character set utf8mb4 collateutf8mb4_unicode_ci;
MariaDB [(none)]&amp;gt; grant all on sabafun.* to django@localhost;
MariaDB [(none)]&amp;gt; exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;django@localhost 是说用户名是 django，localhost 表示是本地用户。sabafun 是数据库的名字。character 之后的内容是设置编码。一定注意设置编码！要不然可能没法导入中文！注意不要漏掉每条命令后的分号。命令不区分大小写。&lt;/p&gt;
&lt;p&gt;grant 是设置数据库的权限。all 表示权限的种类是所有权限， sabafun.* 表示要设置权限的数据库是 sabafun，* 表示这个数据库中所有的表，to 后面是将权限所赋予的用户。&lt;/p&gt;
&lt;p&gt;创建一个数据库就好像创建一个 Excel 文件，一个数据库中有好多表，不同的表就像 Excel 文件中的 sheet1, sheet2...，而每一个表中有好多行和列存储具体的数据。只不过数据库中的数据可能关系要复杂一些。&lt;/p&gt;
&lt;p&gt;创建用户后，可以查看已有的数据库，来确认刚刚创建的数据库确实已经存在&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MariaDB [(none)]&amp;gt; show databases;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然也可以不创建新用户，而是让 Django 直接用 root 用户。创建新用户是出于便于管理和考虑安全性。&lt;/p&gt;
&lt;h1 id="连接-mariadb"&gt;连接 Mariadb&lt;/h1&gt;
&lt;p&gt;首先安装 pymysql&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install pymysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它使 Python3 能够读取 Mariadb 中的数据。&lt;/p&gt;
&lt;p&gt;修改项目中关于数据库的设置。参考 https://docs.djangoproject.com/zh-hans/3.0/ref/settings/#std:setting-DATABASES 。&lt;/p&gt;
&lt;p&gt;修改文件&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt; __init__.py 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个文件中的设置对整个项目都有效。修改为&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;import pymysql
pymysql.version_info = (1, 3, 13, &amp;quot;final&amp;quot;, 0)
pymysql.install_as_MySQLdb()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它的意思是导入 pymysql 模块。第二行是为了解决一个 bug , 是个坑不加的话就会提示数据库的版本过低。第三行如字面意思。&lt;/p&gt;
&lt;p&gt;然后修改设置文件 sabafun/settings.py 中的 DATABASES 项：&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'sabafun',
        'USER': 'django',
        'PASSWORD': '密码',
        'HOST': 'localhost',
        'PORT': '3306',
        'CHARSET': 'utf8',
        'COLLATION':  'utf8_general_ci',
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;里面都如字面意思，告诉 Django 怎么访问数据库。让它用 django 用户名访问我们创建好的 sabafun 数据库。&lt;/p&gt;
&lt;h1 id="创建超级用户"&gt;创建超级用户&lt;/h1&gt;
&lt;p&gt;接下来为项目创建一个超级用户，它能够方便地查看和修改项目的一些信息。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后迁移数据库，将我们创建和超级用户的相关信息存入我们之前设置好的数据库&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py makemigrations
No changes detected
(.sabafun)[root@cloud]$ python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果出现一串 'OK' ，没有报错，则连接 Mariadb 数据库成功！&lt;/p&gt;
&lt;p&gt;之后启动 Django 用于开发测试的 web 服务器&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之所以不用 Apache，是因为 Django 用于开发的服务器在需要的情况下会对每一次的访问请求重新载入一遍 Python 代码。而用 Apache 的话，每次修改都要重启 Apache 服务。Django 的文档中说&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;会自动重新加载的服务器 &lt;a href="https://docs.djangoproject.com/zh-hans/3.0/ref/django-admin/#django-admin-runserver"&gt;&lt;code&gt;runserver&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用于开发的服务器在需要的情况下会对每一次的访问请求重新载入一遍 Python 代码。所以你不需要为了让修改的代码生效而频繁的重新启动服务器。然而，一些动作，比如添加新文件，将不会触发自动重新加载，这时你得自己手动重启服务器。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="创建-poetry-应用"&gt;创建 poetry 应用&lt;/h1&gt;
&lt;p&gt;Django项目由一系列应用程序组成，它们协同工作，让项目成为一个整体。我们创建一个 poetry 应用，来实现网站展示一些古诗词的功能&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py startapp poetry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建应用后，在项目文件夹中会出现相应的文件夹。&lt;/p&gt;
&lt;h1 id="创建-poetryurlspy文件"&gt;创建 poetry/urls.py　文件&lt;/h1&gt;
&lt;p&gt;这个文件用来说明 poetry 应用对应的网址是什么样的&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from django.urls import path

from . import views

urlpatterns = [
    path('', views.poetry, name='poetry'),
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="修改-sabafunurlspy-文件"&gt;修改 sabafun/urls.py 文件&lt;/h1&gt;
&lt;p&gt;这个文件是整个项目的网址管理&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs sabafun/urls.py 

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('poetry/', include('poetry.urls')),
    path('admin/', admin.site.urls),
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="创建-shijing-models"&gt;创建 Shijing Models&lt;/h1&gt;
&lt;p&gt;修改文件 poetry/models.py&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from django.db import models

# Create your models here.                                                    

class Shijing(models.Model):
    &amp;quot;&amp;quot;&amp;quot;诗经&amp;quot;&amp;quot;&amp;quot;
    fixed_id = models.IntegerField(default=0)
    title = models.CharField(max_length=32, default='')
    chapter = models.CharField(max_length=32, default='')
    section = models.CharField(max_length=32, default='')
    content = models.TextField(max_length=8000, default='')

    def __str__(self):
        &amp;quot;&amp;quot;&amp;quot;返回模型的字符串表示&amp;quot;&amp;quot;&amp;quot;
        return self.title
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个 Shijing 类就对应于数据库中的一个表，一个实例就对应于表中的一条记录，也就是一行。fixed_id, title, chapter... 这些对应于一条记录包含的属性。&lt;/p&gt;
&lt;h1 id="注册-poetry-应用"&gt;注册 poetry 应用&lt;/h1&gt;
&lt;p&gt;修改 sabafun/settings.py 文件，告诉 Django ，我们创建了一个新的应用&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # My apps                                                             
    'poetry'，
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="迁移数据库"&gt;迁移数据库&lt;/h1&gt;
&lt;p&gt;修改 poetry/admin.py ，将创建的 Shijing 添加到管理页面中&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from django.contrib import admin

# Register your models here.                                                  

from .models import Shijing

admin.site.register(Shijing)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后迁移数据库&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py makemigrations
(.sabafun)[root@cloud]$ python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这时，Django 就在数据库中为 Shijing 类中创建了一个表，但是还没有任何记录，是一个空表。&lt;/p&gt;
&lt;p&gt;启动 Django 用于开发测试的 web 服务器&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在本地通过浏览器访问 IP::8000/admin/ 就会看到 Shijing&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204153009618.png" alt="image-20200204153009618" /&gt;&lt;/p&gt;
&lt;h1 id="迁入-json-数据"&gt;迁入 json 数据&lt;/h1&gt;
&lt;p&gt;然后将 github 上的诗词数据库 https://github.com/chinese-poetry/chinese-poetry 中的 shijing.json 传到服务器上，并在同一目录下编写文件 json_to_database.py&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs json_to_database.py

# -*- coding: &amp;lt;encoding name&amp;gt; -*-                                             
'''将 json 转换到数据库'''
# https://shockerli.net/post/python3-pymysql/                                 

import json
import pymysql

import os
print(os.getcwd())

# 连接数据库。假设数据库中已经建好了名为 poetry 的空数据库。                  
poetry = pymysql.connect(host='localhost',
                         port=3306,
                         user='django',
                         password='*********',
                         db='sabafun',
                         charset='utf8')
cursor = poetry.cursor()




# 转存《诗经》。                                                              
# 读取 shijing.json 到变量 shijing 中。                                       
with open('./shijing.json', 'r', encoding='UTF-8') as f:
    shijing = json.load(f)

# 查看 shijing.json 中有哪些 key                                              
# for k in shijing[0].keys():                                                 
#     print(k)    
# 为 shijing 创建一个表。                                                     
# cursor.execute('''                                                          
#                create table shijing(id int not null auto_increment,         
#                                     title varchar(32) not null,             
#                                     chapter varchar(32) not null,           
#                                     section varchar(32) not null,           
#                                     content varchar(8000) not null,         
#                                     primary key (id)                        
#                                    )                                        
#                ''')                                                         


# 将数组写入数据库。                                                          
shijing_sql = ('insert into poetry_shijing (title, chapter, section, content,\
 fixed_id)'
               + 'values (%s, %s, %s, %s, %s)')
shijing_values = [list(v.values()) for v in shijing]  # 将字典转换为数组      
i = 0
for v in shijing_values:                              #                       
    v[3] = '\n'.join(v[3])                            # 将数组转换为字符串    
    i += 1                                            # 添加 fixed_id 字段    
    v.append(i)

cursor.executemany(shijing_sql, shijing_values[:])  # 写入数据库              
poetry.commit()                                      # 提交更改               
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后运行它&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python json_to_database.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就把 305 首诗经导入到数据库中了！&lt;/p&gt;
&lt;p&gt;进入管理界面，看到 305 个导入的数据&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204165427906.png" alt="image-20200204165427906" /&gt;&lt;/p&gt;
&lt;p&gt;成功！&lt;/p&gt;
&lt;h1 id="修改-poetryviewspy-文件"&gt;修改 poetry/views.py 文件&lt;/h1&gt;
&lt;p&gt;至此为止，我们只能够在管理页面中看到诗经，下面让它在网页上显示。&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;from django.shortcuts import render

# Create your views here.                                                     

from django.http import HttpResponse

from .models import Shijing

def poetry(request):
    context = {'shijing_list': Shijing.objects.all()}
    return render(request, 'poetry/poetry.html', context)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;poetry 函数将一个字典 context 传递给渲染函数 render()&lt;/p&gt;
&lt;h1 id="编写网页模板"&gt;编写网页模板&lt;/h1&gt;
&lt;p&gt;新建一个用于存放 html 模板的地方&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud sabafun]# cd poetry/
(.sabafun)[root@cloud poetry]# mkdir templates
(.sabafun)[root@cloud poetry]# cd templates/
(.sabafun)[root@cloud templates]# mkdir poetry
(.sabafun)[root@cloud templates]# ls
poetry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编写模板文件 poetry/templates/poetry/poetry.html&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;body&amp;gt;                                                                        
{% for item in shijing_list %}                                                
&amp;lt;center&amp;gt;                                                                      
第{{ item.fixed_id }}篇：                                                     
&amp;lt;h1&amp;gt;                                                                          
  {{ item.chapter }}·{{ item.section }}·{{ item.title }}                      
&amp;lt;/h1&amp;gt;                                                                         
&amp;lt;h2&amp;gt;{{ item.content }}&amp;lt;/h2&amp;gt;                                                   
{% endfor %}                                                                  
&amp;lt;/center&amp;gt;                                                                     
&amp;lt;/body&amp;gt;                                                                       
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;shijing_list 就是通过 render() 函数传递过来的字典的键。重启 httpd 从本地访问 IP/poetry，就看到如下界面了！&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204210647475.png" alt="image-20200204210647475" /&gt;&lt;/p&gt;
&lt;h1 id="后续操作"&gt;后续操作&lt;/h1&gt;
&lt;p&gt;Apache 配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 连接 Django                                                                 
LoadModule wsgi_module &amp;quot;/root/sabafun/.sabafun/lib/python3.7/site-packages/mo\
d_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so&amp;quot;

WSGIScriptAlias / /root/sabafun/sabafun/wsgi.py
WSGIPythonHome /root/sabafun/.sabafun
WSGIPythonPath /root/sabafun

&amp;lt;Directory /root/sabafun/sabafun&amp;gt;
&amp;lt;Files wsgi.py&amp;gt;
Require all granted
&amp;lt;/Files&amp;gt;
&amp;lt;/Directory&amp;gt;


# 文件服务, 如果不配置, 当关闭 Debug 时, 会无法访问静态文件. 具体方法参考 Django 官方文档中的说明
#Alias /robots.txt /path/to/mysite.com/static/robots.txt                      
#Alias /favicon.ico /path/to/mysite.com/static/favicon.ico                    

#Alias /media/ /path/to/mysite.com/media/                                     

Alias /static /root/sabafun/static_cdn/
#Alias /static/ /path/to/mysite.com/static/                                   

&amp;lt;Directory /root/sabafun/static_cdn/&amp;gt;
Require all granted
&amp;lt;/Directory&amp;gt;

# &amp;lt;Directory /path/to/mysite.com/media&amp;gt;                                       
# Require all granted                                                         
# &amp;lt;/Directory&amp;gt;                                                                

# WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py                        

# &amp;lt;Directory /path/to/mysite.com/mysite&amp;gt;                                      
# &amp;lt;Files wsgi.py&amp;gt;                                                             
# Require all granted                                                         
# &amp;lt;/Files&amp;gt;                                                                    
# &amp;lt;/Directory&amp;gt;                                                                
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;settings.py 中关于静态文件的配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Static files (CSS, JavaScript, Images)                                      
# https://docs.djangoproject.com/en/3.0/howto/static-files/                   

# 会在每个 app_name/static/app_name 及总的 mysite/static 下找静态文件
STATIC_URL = '/static/'

# collectstatic 时存放静态文件的地方, 这个路径提供给 Apache
STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn')

# 总的 mysite/static 下找静态文件
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="具体操作过程仅供参考"&gt;具体操作过程（仅供参考）&lt;/h1&gt;
&lt;h2 id="配置-ssh-登陆"&gt;配置 ssh 登陆&lt;/h2&gt;
&lt;p&gt;在本地连接云端&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;$ ssh root@h.saba.fun
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入密码，确认云端可以登录。&lt;/p&gt;
&lt;p&gt;为了不用每次连接都输入密码，以后采用密钥的方式登录。进入云端的 .ssh 目录，进行查看&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ cd .ssh/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入 .ssh 目录后，确认目录下的文件&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ ls
authorized_keys
[root@cloud]$ pwd
/root/.ssh
[root@cloud]$ logout
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将本地的公钥传到云端&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;$ scp ~/.ssh/xps13.pub root@h.saba.fun:/root/.ssh
xps13.pub                                   100%  744     6.8KB/s   00:00 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再回到云端&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;$ ssh root@h.saba.fun
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加入公钥&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ cat .ssh/xps13.pub &amp;gt;&amp;gt; .ssh/authorized_keys 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时从本地登陆云端就不需要输入密码了。&lt;/p&gt;
&lt;h2 id="配置环境"&gt;配置环境&lt;/h2&gt;
&lt;p&gt;在云端进行升级&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ yum upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看 Python 版本&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ python --version
Python 2.7.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;是 Python2 。Django 需要 Python3 因此安装&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ yum install python3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装后查看确认&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$  python3 --version
Python 3.6.8
[root@cloud]$ pip3 --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装 Apache&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ yum install httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ systemctl start httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从本机登录 IP 会看到测试界面&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204114524492.png" alt="image-20200204114524492" /&gt;&lt;/p&gt;
&lt;p&gt;让 Apache 开机自动运行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ systemctl enable httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装 Mariadb&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ yum install mariadb
[root@cloud]$ yum install mariadb-server
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="配置并测试-django"&gt;配置并测试 Django&lt;/h2&gt;
&lt;p&gt;新建一个存放项目的文件夹并进入&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ mkdir saba
[root@cloud]$ cd saba
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用 Pip3 安装虚拟环境&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ pip3 install virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建虚拟环境&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ virtualenv .sabaenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;激活虚拟环境&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ source .sabaenv/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功后在终端的前面会出现&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时环境中就是 Python3 了&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ pip --version
pip 20.0.2 from /root/saba/.sabaenv/lib/python3.6/site-packages/pip (python 3.6)
(.sabaenv)[root@cloud]$ python --version 
Python 3.6.8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装 Django&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ pip install django
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建项目&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ django-admin startproject sabafun
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看确认&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(.sabaenv)# ls -alh
total 16K
drwxr-xr-x  4 root root 4.0K Feb  4 11:59 .
dr-xr-x---. 7 root root 4.0K Feb  4 11:47 ..
drwxr-xr-x  5 root root 4.0K Feb  4 11:52 .sabaenv
drwxr-xr-x  3 root root 4.0K Feb  4 11:59 sabafun

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ cd sabafun/
(.sabaenv)[root@cloud]$ ls
manage.py  sabafun
(.sabaenv)[root@cloud]$ ls sabafun/
asgi.py  __init__.py  settings.py  urls.py  wsgi.py

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File &amp;quot;/usr/lib64/python3.6/threading.py&amp;quot;, line 916, in _bootstrap_inner
    self.run()
  File &amp;quot;/usr/lib64/python3.6/threading.py&amp;quot;, line 864, in run
    self._target(*self._args, **self._kwargs)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/utils/autoreload.py&amp;quot;, line 53, in wrapper
    fn(*args, **kwargs)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/core/management/commands/runserver.py&amp;quot;, line 109, in inner_run
    autoreload.raise_last_exception()
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/utils/autoreload.py&amp;quot;, line 76, in raise_last_exception
    raise _exception[1]
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/core/management/__init__.py&amp;quot;, line 357, in execute
    autoreload.check_errors(django.setup)()
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/utils/autoreload.py&amp;quot;, line 53, in wrapper
    fn(*args, **kwargs)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/__init__.py&amp;quot;, line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/apps/registry.py&amp;quot;, line 114, in populate
    app_config.import_models()
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/apps/config.py&amp;quot;, line 211, in import_models
    self.models_module = import_module(models_module_name)
  File &amp;quot;/root/saba/.sabaenv/lib64/python3.6/importlib/__init__.py&amp;quot;, line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File &amp;quot;&amp;lt;frozen importlib._bootstrap&amp;gt;&amp;quot;, line 994, in _gcd_import
  File &amp;quot;&amp;lt;frozen importlib._bootstrap&amp;gt;&amp;quot;, line 971, in _find_and_load
  File &amp;quot;&amp;lt;frozen importlib._bootstrap&amp;gt;&amp;quot;, line 955, in _find_and_load_unlocked
  File &amp;quot;&amp;lt;frozen importlib._bootstrap&amp;gt;&amp;quot;, line 665, in _load_unlocked
  File &amp;quot;&amp;lt;frozen importlib._bootstrap_external&amp;gt;&amp;quot;, line 678, in exec_module
  File &amp;quot;&amp;lt;frozen importlib._bootstrap&amp;gt;&amp;quot;, line 219, in _call_with_frames_removed
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/contrib/auth/models.py&amp;quot;, line 2, in &amp;lt;module&amp;gt;
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/contrib/auth/base_user.py&amp;quot;, line 47, in &amp;lt;module&amp;gt;
    class AbstractBaseUser(models.Model):
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/models/base.py&amp;quot;, line 121, in __new__
    new_class.add_to_class('_meta', Options(meta, app_label))
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/models/base.py&amp;quot;, line 325, in add_to_class
    value.contribute_to_class(cls, name)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/models/options.py&amp;quot;, line 208, in contribute_to_class
    self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/__init__.py&amp;quot;, line 28, in __getattr__
    return getattr(connections[DEFAULT_DB_ALIAS], item)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/utils.py&amp;quot;, line 207, in __getitem__
    backend = load_backend(db['ENGINE'])
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/utils.py&amp;quot;, line 111, in load_backend
    return import_module('%s.base' % backend_name)
  File &amp;quot;/root/saba/.sabaenv/lib64/python3.6/importlib/__init__.py&amp;quot;, line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py&amp;quot;, line 68, in &amp;lt;module&amp;gt;
    check_sqlite_version()
  File &amp;quot;/root/saba/.sabaenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py&amp;quot;, line 65, in check_sqlite_version
    raise ImproperlyConfigured('SQLite 3.8.3 or later is required (found %s).' % Database.sqlite_version)
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
(.sabaenv) [root@ecs-sn3-medium-2-linux-20200114152809 sabafun]# pip install SQLite
ERROR: Could not find a version that satisfies the requirement SQLite (from versions: none)
ERROR: No matching distribution found for SQLite
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ pip install db-sqlite3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还是不行。重新安装 Python 吧。&lt;/p&gt;
&lt;p&gt;安装 Anaconda 。它的 Python 版本比较新&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabaenv)[root@cloud]$ deactivate
[root@cloud]$ bash ./Anaconda3-2019.07-Linux-x86_64.sh 
[root@cloud]$ /root/anaconda3/bin/python3 --version
Python 3.7.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重新来&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-bash"&gt;[root@cloud]$ rm -rf saba/
[root@cloud]$ mkdir sabafun
[root@cloud]$ cd sabafun
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ virtualenv .sabafun --python=/root/anaconda3/bin/python3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入虚拟环境&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;[root@cloud]$ source .sabafun/bin/activate
(.sabafun)[root@cloud]$ python --version
Python 3.7.3
(.sabafun)[root@cloud]$ pip --version
pip 20.0.2 from /root/sabafun/.sabafun/lib/python3.7/site-packages/pip (python 3.7)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这时的版本应该没问题了。&lt;/p&gt;
&lt;p&gt;接下来再把之前的工作重复一遍&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install django
Collecting django
  Using cached Django-3.0.3-py3-none-any.whl (7.5 MB)
Collecting asgiref~=3.2
  Using cached asgiref-3.2.3-py2.py3-none-any.whl (18 kB)
Collecting pytz
  Using cached pytz-2019.3-py2.py3-none-any.whl (509 kB)
Collecting sqlparse&amp;gt;=0.2.2
  Using cached sqlparse-0.3.0-py2.py3-none-any.whl (39 kB)
Installing collected packages: asgiref, pytz, sqlparse, django
Successfully installed asgiref-3.2.3 django-3.0.3 pytz-2019.3 sqlparse-0.3.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一定记得加末尾的点&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ django-admin startproject sabafun .
(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

February 04, 2020 - 04:50:05
Django version 3.0.3, using settings 'sabafun.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一次试运行不成功提示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;You may need to add '***.***.***.***' to ALLOWED_HOSTS.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装我 熟悉的 emacs 编辑器&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ yum install emacs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将服务器的 IP 加到设置中&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ emacs sabafun/settings.py 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将  IP 加入&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;ALLOWED_HOSTS = [‘你的IP’]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存，退出。再运行（无视数据库提示，因为不用这个）&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

February 04, 2020 - 04:57:45
Django version 3.0.3, using settings 'sabafun.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时从本地访问 8000 端口，终于出现了小火箭界面&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204125926942.png" alt="image-20200204125926942" /&gt;&lt;/p&gt;
&lt;p&gt;参考官方文档连接 Apache https://docs.djangoproject.com/zh-hans/3.0/howto/deployment/wsgi/modwsgi/&lt;/p&gt;
&lt;h2 id="连接-mod_wsgi"&gt;连接 mod_wsgi&lt;/h2&gt;
&lt;p&gt;首先安装 mod_wsgi&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install mod_wsgi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参考官方文档连接 Apache https://docs.djangoproject.com/zh-hans/3.0/howto/deployment/wsgi/modwsgi/&lt;/p&gt;
&lt;p&gt;根据　https://modwsgi.readthedocs.io/en/develop/　的提示，查看所需要的路径&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ mod_wsgi-express module-config
LoadModule wsgi_module &amp;quot;/root/sabafun/.sabafun/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so&amp;quot;
WSGIPythonHome &amp;quot;/root/sabafun/.sabafun&amp;quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ ls
asgi.py      __pycache__  settings.py~  wsgi.py
__init__.py  settings.py  urls.py
(.sabafun)[root@cloud]$ pwd
/root/sabafun/sabafun
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ emacs /etc/httpd/conf/httpd.conf 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;#　加载模块
LoadModule wsgi_module &amp;quot;/root/sabafun/.sabafun/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so&amp;quot;

WSGIScriptAlias / /root/sabafun/sabafun/wsgi.py
WSGIPythonHome /root/sabafun/.sabafun
WSGIPythonPath /root/sabafun

&amp;lt;Directory /root/sabafun/sabafun&amp;gt;
&amp;lt;Files wsgi.py&amp;gt;
Require all granted
&amp;lt;/Files&amp;gt;
&amp;lt;/Directory&amp;gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启后访问服务器 IP 没有反应。因此去查看 Apache 的 error log&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ emacs /etc/httpd/logs/error_log 
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress t\
his message
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;ServerName 121.36.10.39:80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还是不行，再次查看 error log&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;Current thread 0x00007fca65324880 (most recent call first):
[Tue Feb 04 13:31:57.815061 2020] [wsgi:warn] [pid 5238] (13)Permission denied: mod_wsgi (pid=5238): Unable to stat Python ho\
me /root/sabafun/.sabafun. Python interpreter may not be able to be initialized correctly. Verify the supplied path and acces\
s permissions for whole of the path.
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'

Current thread 0x00007fca65324880 (most recent call first):
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说是不能访问环境。但是环境的路径没有错，可能是权限问题。经过几次尝试并参考　http://www.jeepxie.net/article/565984.html　后&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ chmod 755 -R /root/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再重启 httpd 。直接访问 IP ，出现了小火箭。&lt;/p&gt;
&lt;h2 id="配置-mariadb"&gt;配置 Mariadb&lt;/h2&gt;
&lt;p&gt;启动服务（之前忘记安装 mariadb-server，就找不到服务）&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ systemctl start mariadb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;登陆&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;MariaDB [(none)]&amp;gt; create user django@localhost identified by '*********';

一定注意设置编码！要不然没法导入中文
MariaDB [(none)]&amp;gt; create database sabafun character set utf8mb4 collate utf8mb4_unicode_ci;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]&amp;gt; grant all on sabafun.* to django@localhost;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]&amp;gt; flush privileges;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]&amp;gt;　exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用新用户登陆&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;(.sabafun)[root@cloud]$ mysql -u django -p


MariaDB [(none)]&amp;gt; use sabafun;
Database changed

MariaDB [sabafun]&amp;gt; show tables;
Empty set (0.00 sec)

MariaDB [sabafun]&amp;gt; exit

Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="连接mariadb"&gt;连接　mariadb&lt;/h2&gt;
&lt;p&gt;修改项目中的　settings.py 中关于数据库的设置 https://docs.djangoproject.com/zh-hans/3.0/ref/settings/#std:setting-DATABASES&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;MariaDB [(none)]&amp;gt; show variables like 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ pip install pymysql
Collecting pymysql
  Downloading PyMySQL-0.9.3-py2.py3-none-any.whl (47 kB)
     |████████████████████████████████| 47 kB 13 kB/s 
Installing collected packages: pymysql
Successfully installed pymysql-0.9.3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;__init.py__:

import pymysql
pymysql.version_info = (1, 3, 13, &amp;quot;final&amp;quot;, 0)
pymysql.install_as_MySQLdb()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'sabafun',
        'USER': 'django',
        'PASSWORD': '*********',
        'HOST': 'localhost',
        'PORT': '3306',
        'CHARSET': 'utf8',
        'COLLATION':  'utf8_general_ci',
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试一下&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py makemigrations
No changes detected
(.sabafun)[root@cloud]$ python manage.py migrate
System check identified some issues:

WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
	HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.com/en/3.0/ref/databases/#mysql-sql-mode
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;没有报错，连接成功！&lt;/p&gt;
&lt;h2 id="开始写-django-页面"&gt;开始写 Django 页面&lt;/h2&gt;
&lt;p&gt;创建管理页面&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;时候要重启　httpd　才能进入　IP/admin　。而且好像有些问题。因此，在编写项目的过程中用　django　自带的开发服务器，它有一些好处，比如官方文档中说的&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;会自动重新加载的服务器 &lt;a href="https://docs.djangoproject.com/zh-hans/3.0/ref/django-admin/#django-admin-runserver"&gt;&lt;code&gt;runserver&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用于开发的服务器在需要的情况下会对每一次的访问请求重新载入一遍 Python 代码。所以你不需要为了让修改的代码生效而频繁的重新启动服务器。然而，一些动作，比如添加新文件，将不会触发自动重新加载，这时你得自己手动重启服务器。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;新开一个终端，进入虚拟环境，打开　django　开发服务器&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;$ ssh root@h.saba.fun
[root@cloud]$ cd /root/sabafun/
[root@cloud]$ source .sabafun/bin/activate
(.sabafun)[root@cloud]$ python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
February 04, 2020 - 06:53:48
Django version 3.0.3, using settings 'sabafun.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="创建-poetry-应用-1"&gt;创建 poetry 应用&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py startapp poetry
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs poetry/views.py 


from django.shortcuts import render

# Create your views here.                                                     

from django.http import	HttpResponse

def poetry(request):
    return HttpResponse(&amp;quot;Hello, poetry!&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs poetry/urls.py
                                   
from django.urls import path

from . import views

urlpatterns = [
    path('', views.poetry, name='poetry'),
]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs sabafun/urls.py 

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('poetry/', include('poetry.urls')),
    path('admin/', admin.site.urls),
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看　IP:8000/poetry/&lt;/p&gt;
&lt;p&gt;出现　Hello, poetry!&lt;/p&gt;
&lt;p&gt;成功！&lt;/p&gt;
&lt;h2 id="创建-shijing-models-1"&gt;创建 Shijing Models&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs poetry/models.py 


from django.db import models

# Create your models here.                                                    

class Shijing(models.Model):
    &amp;quot;&amp;quot;&amp;quot;诗经&amp;quot;&amp;quot;&amp;quot;
    fixed_id = models.IntegerField(default=0)
    title = models.CharField(max_length=32, default='')
    chapter = models.CharField(max_length=32, default='')
    section = models.CharField(max_length=32, default='')
    content = models.TextField(max_length=8000, default='')

    def __str__(self):
        &amp;quot;&amp;quot;&amp;quot;返回模型的字符串表示&amp;quot;&amp;quot;&amp;quot;
        return self.title
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加　poetry　应用&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs sabafun/settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # My apps                                                             
    'poetry'，
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;迁移&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python manage.py makemigrations
Migrations for 'poetry':
  poetry/migrations/0001_initial.py
    - Create model Shijing
(.sabafun)[root@cloud]$ python manage.py migrate
System check identified some issues:

WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
	HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.com/en/3.0/ref/databases/#mysql-sql-mode
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, poetry, sessions
Running migrations:
  Applying poetry.0001_initial... OK
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs poetry/admin.py 


from django.contrib import admin

# Register your models here.                                                  

from .models import Shijing

admin.site.register(Shijing)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这时 IP::8000/admin/　就会看到 Shijing&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204153009618.png" alt="image-20200204153009618" /&gt;&lt;/p&gt;
&lt;h2 id="迁入-json-数据-1"&gt;迁入 json 数据&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-mysql"&gt;删除表中所有条目
truncate table poetry_shijing;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;传入 shijing.json 并编写文件&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud]$ emacs json_to_database.py

# -*- coding: &amp;lt;encoding name&amp;gt; -*-                                             
'''将 json 转换到数据库'''
# https://shockerli.net/post/python3-pymysql/                                 

import json
import pymysql

import os
print(os.getcwd())

# 连接数据库。假设数据库中已经建好了名为 poetry 的空数据库。                  
poetry = pymysql.connect(host='localhost',
                         port=3306,
                         user='django',
                         password='*********',
                         db='sabafun',
                         charset='utf8')
cursor = poetry.cursor()




# 转存《诗经》。                                                              
# 读取 shijing.json 到变量 shijing 中。                                       
with open('./shijing.json', 'r', encoding='UTF-8') as f:
    shijing = json.load(f)

# 查看 shijing.json 中有哪些 key                                              
# for k in shijing[0].keys():                                                 
#     print(k)    
# 为 shijing 创建一个表。                                                     
# cursor.execute('''                                                          
#                create table shijing(id int not null auto_increment,         
#                                     title varchar(32) not null,             
#                                     chapter varchar(32) not null,           
#                                     section varchar(32) not null,           
#                                     content varchar(8000) not null,         
#                                     primary key (id)                        
#                                    )                                        
#                ''')                                                         


# 将数组写入数据库。                                                          
shijing_sql = ('insert into poetry_shijing (title, chapter, section, content,\
 fixed_id)'
               + 'values (%s, %s, %s, %s, %s)')
shijing_values = [list(v.values()) for v in shijing]  # 将字典转换为数组      
i = 0
for v in shijing_values:                              #                       
    v[3] = '\n'.join(v[3])                            # 将数组转换为字符串    
    i += 1                                            # 添加 fixed_id 字段    
    v.append(i)

cursor.executemany(shijing_sql, shijing_values[:])  # 写入数据库              
poetry.commit()                                      # 提交更改               




&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后运行导入&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud]$ python json_to_database.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入管理界面，看到 305 个导入的数据&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204165427906.png" alt="image-20200204165427906" /&gt;&lt;/p&gt;
&lt;p&gt;成功！&lt;/p&gt;
&lt;h2 id="编写网页来显示"&gt;编写网页，来显示&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;(.sabafun)[root@cloud sabafun]# cd poetry/
(.sabafun)[root@cloud poetry]# mkdir templates
(.sabafun)[root@cloud poetry]# cd templates/
(.sabafun)[root@cloud templates]# mkdir poetry
(.sabafun)[root@cloud templates]# ls
poetry
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;(.sabafun)[root@cloud sabafun]# emacs poetry/templates/poetry/poetry.html

                                                                              
                                                                              
&amp;lt;body&amp;gt;                                                                        
{% for item in shijing_list %}                                                
                                                                              
                                                                              
&amp;lt;center&amp;gt;                                                                      
第{{ item.fixed_id }}篇：                                                     
&amp;lt;h1&amp;gt;                                                                          
  {{ item.chapter }}·{{ item.section }}·{{ item.title }}                      
&amp;lt;/h1&amp;gt;                                                                         
&amp;lt;h2&amp;gt;{{ item.content }}&amp;lt;/h2&amp;gt;                                                   
{% endfor %}                                                                  
&amp;lt;/center&amp;gt;                                                                     
&amp;lt;/body&amp;gt;                                                                       
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;(.sabafun)[root@cloud sabafun]# emacs poetry/views.py


from django.shortcuts import render

# Create your views here.                                                     

from django.http import HttpResponse

from .models import Shijing

def poetry(request):
    context = {'shijing_list': Shijing.objects.all()}
    return render(request, 'poetry/poetry.html', context)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启 httpd 从本地访问 IP/poetry，就看到界面了&lt;/p&gt;
&lt;p&gt;&lt;img src="./2020-02-03-physics-Django/image-20200204210647475.png" alt="image-20200204210647475" /&gt;&lt;/p&gt;
&lt;h1 id="参考资料"&gt;参考资料&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;Eric Matthes 著，袁国忠 译, Python 编程从入门到实践，中国工信出版集团，2016，人民邮电出版社&lt;/li&gt;
&lt;li&gt;https://docs.djangoproject.com/zh-hans/3.0/intro/tutorial01/&lt;/li&gt;
&lt;li&gt;www.google.com&lt;/li&gt;
&lt;/ol&gt;
</content><category term="软件使用"/><category term="Django"/><category term="Mariadb"/><category term="Python"/><category term="mod_wsgi"/><category term="Apache"/></entry><entry><title>面向对象, 花式作图</title><link href="https://zqw.ink/2019-10-25-coding-objectPlot.html" rel="alternate"/><published>2019-10-25T00:00:00+08:00</published><updated>2019-10-25T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2019-10-25:/2019-10-25-coding-objectPlot.html</id><summary type="html">
&lt;h2&gt;面向对象&lt;/h2&gt;

&lt;p&gt;面向对象写程序, 是一直在对一些对象作一些操作.&lt;/p&gt;

&lt;p&gt;总的来说, Figure 类相当于画板, Axes 相当于画纸&lt;/p&gt;

&lt;blockquote&gt;figure : Figure
The Figure instance returned will also …&lt;/blockquote&gt;</summary><content type="html">
&lt;h2&gt;面向对象&lt;/h2&gt;

&lt;p&gt;面向对象写程序, 是一直在对一些对象作一些操作.&lt;/p&gt;

&lt;p&gt;总的来说, Figure 类相当于画板, Axes 相当于画纸&lt;/p&gt;

&lt;blockquote&gt;figure : Figure
The Figure instance returned will also be passed to new_figure_manager in the backends, which allows to hook custom Figure classes into the pyplot interface. Additional kwargs will be passed to the Figure init function.&lt;/blockquote&gt;

&lt;p&gt;plt.figure()返回一个 matplotlib.figure.Figure, 它是一个类, &lt;/p&gt;
&lt;blockquote&gt;The top level container for all the plot elements.
它是所有 plot 元素的最上级容器&lt;/blockquote&gt;

&lt;p&gt;plt.subplot() 返回一个 Axes 类&lt;/p&gt;
&lt;blockquote&gt;The Axes contains most of the figure elements: Axis, Tick, Line2D, Text, Polygon, etc., and sets the coordinate system.
Axes 包含大部分 figure 元素, 比如 Axis, Tick, Line2D, Text, Polygon, 等等, 以及 sets the coordinate system.&lt;/blockquote&gt;

&lt;h2&gt;示例&lt;/h2&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import numpy as np
from matplotlib import pyplot as plt

# 创建一个画板(画板是一个 Figure 类), 给它取名为 myFigure
myFigure = plt.figure(facecolor='pink')

# 对 myFigure 进行操作, 它可以进行的操作, 可以查看画板(Figure) 这个类的官方文档:
# https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure
# 这里对它进行一个 add_subplot 的操作. 这个操作(或者函数)的返回值是一张画纸(Axes
# 类), 给它取名为 myAxesTom. 
# 具体的返回值为 axes : axes.SubplotBase, or another subclass of Axes
myAxesTom = myFigure.add_subplot(4, 3, 10)

# 再放一张叫 myAxesBob 的画线到画板上. 现在 myFigure 上有了 myAxesTom 和
# myAxesBob 两张画纸. 
myAxesBob = myFigure.add_subplot(4, 3, 12)

# 对 myFigure 进行另一个操作 add_axes. 
# 它的返回值是 axes : Axes (or a subclass of Axes), 是另一种类型的画纸.
# 用这种方法添加画纸, 位置和大小比较灵活
# 括号中的参数是 rect 的值, 是必须给的, 没有默认值. 四个参数分别是 [left,
# bottom, width, height] 
# 有了画板, 和画纸, 接下来就是在画纸上画画, 对画纸有哪些操作可以查阅官方文档:
# https://matplotlib.org/3.1.1/api/axes_api.html#matplotlib.axes.Axes
# 这些画纸上可以放 Axis, Tick, Line2D, Text, Polygon 等等
myAxesAlice = myFigure.add_axes([.2, .5, .5, .4]) 
myAxesAlice.grid()              # 再加上网格


# 最基本的是画函数图像, 这个操作就是 plot. 比如在 myAxesAlice 上画一个正弦函数和
# 余弦函数. 
x = np.linspace(0, 1, 100)
y1 = np.sin(2*np.pi*x)
y2 = np.cos(2*np.pi*x)

# plot 操作的返回值是一系列 Line2D 类组成的数组. 是我们在画纸上画的许多二维线.
# 它也是一个对象, 可以进行一系列操作:
# https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D
# print("Color is", sinFun[1].get_color()) # 对 2D 线进行操作 get_color, 得到它
# 的颜色 
sinFun = myAxesAlice.plot(x, y1, x, y2) 
sinFun[0].set_color('y')         # 对 2D 线进行操作, 设置它的颜色为我们想要的颜
                                 # 色. 
sinFun[0].set_label(r'$sin(x)$') # 为 2D 线添加图例.
sinFun[1].set_label(r'$cos(x)$')
# 还可以对这条线做许多的操作, 需要什么就直接查文档了.

# 然后在画纸上做一些其它操作. 实际上, 画纸上已经默认有 x 轴, y轴了. 现在可以对这
# 两个部件来修改. 
myAxesAlice.set_xlabel(r'$x$')
myAxesAlice.set_ylabel(r'$f(x)$')

# 添加标题和图例
myAxesAlice.set_title(r'sin and cos function')
myAxesAlice.legend()

# 在纸上写字
Alice = myAxesAlice.text(.5, .5, "Alice", fontsize=20)
Tom = myAxesTom.text(.2, .5, "Tom", fontsize=20)
Bob = myAxesBob.text(.2, .5, "Bob", fontsize=20)

# text 返回的是一个 text 类. 也可以修改它的属性
Tom.set_backgroundcolor('r')
Bob.set_color('y')

# 还可以修改字体
# 用这两句查询已有的字体
#from matplotlib.font_manager import fontManager
#fontManager.ttflist
from matplotlib.font_manager import FontProperties
font0=FontProperties()
font0.set_size('20')
font0.set_family('Constantia')
font0.set_style('normal')
font0.set_variant('normal')
font0.set_stretch('normal')
Alice.set_fontproperties(font0)

myFigure.show()
# 保存图片有一些问题, 在画板上设置的 facecolor 要重新设置才能保存下来.
# 没有 bbox_inches = 'tight' 可能会保存不全图片
myFigure.savefig('myFigure.jpg', bbox_inches = 'tight', facecolor='pink')&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Results&lt;/h2&gt;

&lt;p&gt;&lt;p&gt;&lt;img src='./2019-10-25-coding-objectPlot/myFigure.jpg' alt='figalt' max-width:100%&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;p&gt;&lt;a href='./2019-10-25-coding-objectPlot/objectPlot.py'&gt;./2019-10-25-coding-objectPlot/objectPlot.py&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Reference: &lt;/h2&gt;

&lt;p&gt;https://www.zhihu.com/question/51745620&lt;/p&gt;

&lt;p&gt;https://zhuanlan.zhihu.com/p/35983270&lt;/p&gt;
</content><category term="软件使用"/><category term="python"/><category term="matplotlib"/></entry><entry><title>Git 使用备忘</title><link href="https://zqw.ink/2019-04-18-coding-Git-Shi-Yong-Bei-Wang.html" rel="alternate"/><published>2019-04-18T00:00:00+08:00</published><updated>2019-04-18T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2019-04-18:/2019-04-18-coding-Git-Shi-Yong-Bei-Wang.html</id><summary type="html">
&lt;h2&gt;基本命令&lt;/h2&gt;

&lt;h3&gt;本地&lt;/h3&gt;

&lt;h4&gt;必备操作&lt;/h4&gt;

&lt;h5&gt;基本&lt;/h5&gt;

&lt;p&gt;初始化 repository&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加变动到 stage&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git add &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;提交变动&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git commit -m "some comment ..."&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;分支&lt;/h5&gt;

&lt;p&gt;查看分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git branch&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git branch …&lt;/code&gt;&lt;/pre&gt;</summary><content type="html">
&lt;h2&gt;基本命令&lt;/h2&gt;

&lt;h3&gt;本地&lt;/h3&gt;

&lt;h4&gt;必备操作&lt;/h4&gt;

&lt;h5&gt;基本&lt;/h5&gt;

&lt;p&gt;初始化 repository&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加变动到 stage&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git add &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;提交变动&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git commit -m "some comment ..."&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;分支&lt;/h5&gt;

&lt;p&gt;查看分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git branch&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git branch &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;切换分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git checkout &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建+切换分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git checkout -b &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;合并某分支到当前分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git merge &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git branch -d &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;


&lt;h4&gt;辅助操作&lt;/h4&gt;

&lt;p&gt;查看当前仓库的状态&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看文件的不同&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-"&gt;git diff &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;回到哪个版本&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git reset --hard commit_id&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看提交历史(图形化), 以便确定退回到哪个版本&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git log --graph&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重返未来&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git reflog&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把文件在工作区的修改全部撤销&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git checkout -- &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;git reset HEAD &lt;filename&gt;
删除&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git rm&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;高级操作&lt;/h4&gt;

&lt;p&gt;工作现场&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git stash&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git stash pop&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;分叉的历史整理成直线&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git rebase&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;标签操作&lt;/h4&gt;

&lt;h5&gt;基本操作&lt;/h5&gt;

&lt;p&gt;新建一个标签, 默认为 &lt;HEAD&gt; , 也可以指定一个 commit ID&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git tag &amp;lt;tagename&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tag 时指定标签名, 指定描述&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git tag -a &amp;lt;tagname&amp;gt; -m "describ ..."&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看所有标签&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git tag&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;高级操作&lt;/h5&gt;

&lt;p&gt;推送一个本地标签&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git push origin &amp;lt;tagname&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;推送全部未推送过的本地标签&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git push origin --tags&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除一个本地标签&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git tag -d &amp;lt;tagname&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除一个远程标签&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git push origin :refs/tags/&amp;lt;tagname&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;远程操作&lt;/h3&gt;

&lt;p&gt;关联一个远程库&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git remote add origin git$server-name:path/repo-name.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;推送 (我们第一次推送master分支时，加上了-u参数，Git不但会把本地的
master分支内容推送的远程新的 master 分支，还会把本地的 master 分支和远
程的 master 分支关联起来，在以后的推送或者拉取时就可以简化命令)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git push -u origin master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;克隆&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git clone&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;实践一: 博客备份&lt;/h2&gt;

&lt;h3&gt;本地操作&lt;/h3&gt;

&lt;p&gt;进入到博客的根目录, 一定要记得先删除主题文件夹下的 .git/ 文件夹, 不然就会产生 submodules ,
从而导致无法 commit 主题. 比如要备件 next 主题&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;rm -r themes/next/.git/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这时就可以初始化 git了&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后添加所有的文件到 stage&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git add .&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;检察有没有问题&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;结果一片绿就没有问题了!&lt;/p&gt;

&lt;p&gt;接下来提交备份&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git commit -m "first backup"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;想备份到和 githubpages 一个 repository , 所以要另外建一个分支, 名为 backup&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git checkout -b backup&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;备份到 github&lt;/h3&gt;

&lt;p&gt;与 github 关联&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git remote add origin git@github.com:phyer219/phyer219.github.io.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将本地的 backup 分支推到 github&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git push origin backup&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;备份完成!&lt;/p&gt;

&lt;p&gt;以后每次备份都直接&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git add .
git commit -m "new blog ..."
git push origin backup&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可完成备份!&lt;/p&gt;

&lt;h3&gt;恢复&lt;/h3&gt;

&lt;p&gt;备份好以后, 如果在另一台设备上(已经安装好 hexo)恢复, 首先到一个要恢复的文件夹, 然后
clone 下来 backup 分支&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git clone -b backup git@github.com:phyer219/phyer219.github.io.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;npm install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后本地测试是否备份成功&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;hexo s&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以后每次从 back up 中更新直接&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;git pull&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可!&lt;/p&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;p&gt;&lt;a href='https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000'&gt;https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000&lt;/a&gt;&lt;/p&gt;
</content><category term="软件使用"/><category term="hexo"/><category term="git"/></entry><entry><title>Manjaro-18-Gnome 装机备忘</title><link href="https://zqw.ink/2018-11-11-coding-Manjaro-18-Gnome-Zhuang-Ji-Bei-Wang.html" rel="alternate"/><published>2018-11-11T00:00:00+08:00</published><updated>2018-11-11T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2018-11-11:/2018-11-11-coding-Manjaro-18-Gnome-Zhuang-Ji-Bei-Wang.html</id><summary type="html">
&lt;h2&gt;基本安装&lt;/h2&gt;

&lt;h3&gt;刻盘&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用ultroiso，刻录方式应选择raw&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;配置安装源&lt;/h3&gt;

&lt;h4&gt;添加中国镜像&lt;/h4&gt;

&lt;p&gt;生成可用中国镜像站列表:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman-mirrors -i -c China -m rank&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;出现镜像 …&lt;/p&gt;</summary><content type="html">
&lt;h2&gt;基本安装&lt;/h2&gt;

&lt;h3&gt;刻盘&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用ultroiso，刻录方式应选择raw&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;配置安装源&lt;/h3&gt;

&lt;h4&gt;添加中国镜像&lt;/h4&gt;

&lt;p&gt;生成可用中国镜像站列表:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman-mirrors -i -c China -m rank&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;出现镜像列表后勾选所需要的镜像.&lt;/p&gt;

&lt;p&gt;然后刷新缓存:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -Syy&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;参见: &lt;a href='http://mirrors.ustc.edu.cn/help/manjaro.html'&gt;http://mirrors.ustc.edu.cn/help/manjaro.html&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;添加 archlinuxcn 仓库&lt;/h4&gt;

&lt;p&gt;在 `/etc/pacman.conf` 文件末尾添加两行：&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;[archlinuxcn]
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;刷新&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -Syy&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;之后安装 archlinuxcn-keyring 包导入 GPG key.&lt;/p&gt;


&lt;p&gt;参见: &lt;a href='https://mirror.tuna.tsinghua.edu.cn/help/archlinuxcn'&gt;https://mirror.tuna.tsinghua.edu.cn/help/archlinuxcn&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;yaourt 配置&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;安装 yaourt&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -S yaourt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装 base-devel&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -S base-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;参见: &lt;a href='https://wiki.archlinux.org/index.php/Arch_User_Repository_(%25E7%25AE%2580%25E4%25BD%2593%25E4%25B8%25AD%25E6%2596%2587)'&gt;https://wiki.archlinux.org/index.php/Arch_User_Repository_(%25E7%25AE%2580%25E4%25BD%2593%25E4%25B8%25AD%25E6%2596%2587)&lt;/a&gt;&lt;/p&gt;


&lt;h4&gt;snap&lt;/h4&gt;

&lt;h5&gt;连不上网&lt;/h5&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;systemctl start snapd.service&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;中文输入法&lt;/h3&gt;

&lt;h4&gt;安装&lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo pacman -S fcitx
sudo pacman -S fcitx -configtool   ----配置工具
sudo pacman -S fcitx-sogoupinyin    ----可选安装，fcitx默认已有中文输入&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;配置文件&lt;/h4&gt;

&lt;p&gt;在 &lt;code&gt;~/.xprofile&lt;/code&gt; 中添加以下内容&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;参见: &lt;a href='https://wiki.archlinux.org/index.php/Fcitx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E5.AE.89.E8.A3.85'&gt;https://wiki.archlinux.org/index.php/Fcitx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E5.AE.89.E8.A3.85&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;软件安装&lt;/h2&gt;

&lt;h3&gt;tex&lt;/h3&gt;

&lt;p&gt;安装以下三个包, 中文编写应该没有问题.&lt;/p&gt;

&lt;p&gt;texlive-most&lt;/p&gt;

&lt;p&gt;texlive-lang&lt;/p&gt;

&lt;p&gt;texlive-latexextra&lt;/p&gt;

&lt;h3&gt;evince 中文&lt;/h3&gt;

&lt;p&gt;evince 可能中文显示不好. 安装 xpdf 后会解决&lt;/p&gt;

&lt;h3&gt;hexo&lt;/h3&gt;

&lt;h4&gt;安装 Hexo&lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo npm install -g hexo-cli&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;复制旧的文件过来&lt;/h4&gt;

&lt;h4&gt;添加site map&lt;/h4&gt;

&lt;h5&gt;执行命令安装sitemap&lt;/h5&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;npm install hexo-generator-sitemap --save&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;在Hexo站点配置文件 _config.yml 中加入 sitemap 插件&lt;/h5&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;# Extensions
plugins: hexo-generator-sitemap&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;执行命令生成sitemap文件&lt;/h5&gt;

&lt;pre&gt;&lt;code class="language-"&gt;hexo clean
hexo g&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;emacs&lt;/h3&gt;

&lt;h4&gt;右alt不能当meta&lt;/h4&gt;

&lt;p&gt;搜索：优化-键盘和鼠标-其它布局选项&lt;/p&gt;

&lt;h3&gt;坚果云&lt;/h3&gt;

&lt;h4&gt;无托盘图标：&lt;/h4&gt;

&lt;p&gt;搜索：优化-扩展-topicons plus（没有的话安装gnome-shell-extension-topicons-plus-git）&lt;/p&gt;

&lt;h3&gt;teamviewer&lt;/h3&gt;

&lt;h4&gt;不能连网：&lt;/h4&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;sudo teamviewer --daemon start
teamviewer&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;问题合集&lt;/h2&gt;
&lt;h3&gt;shadowsocks-qt5连上, 但是浏览器连不上&lt;/h3&gt;

&lt;p&gt;原来是 ss-qt5 里边没改端口. 汗...&lt;/p&gt;


&lt;h2&gt;注&lt;/h2&gt;
&lt;p&gt;善用 arch 的 wiki , 一般问题都可以得到解决.&lt;/p&gt;
</content><category term="软件使用"/><category term="manjaro"/><category term="linux"/></entry><entry><title>Emacs使用笔记</title><link href="https://zqw.ink/2018-09-07-coding-emacs_note.html" rel="alternate"/><published>2018-09-07T00:00:00+08:00</published><updated>2018-09-07T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2018-09-07:/2018-09-07-coding-emacs_note.html</id><summary type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h3 id="修改配色"&gt;修改配色&lt;/h3&gt;
&lt;p&gt;打开Emacs的配置文件。配置文件在~/.emacs。增加：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(set-background-color &amp;quot;black&amp;quot;) ;; 使用黑色背景
(set-foreground-color &amp;quot;white&amp;quot;) ;; 使用白色前景
(set-face-foreground 'region &amp;quot;green&amp;quot;)  ;; 区域前景颜色设为绿色
(set-face-background 'region &amp;quot;blue&amp;quot;) ;; 区域背 …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h3 id="修改配色"&gt;修改配色&lt;/h3&gt;
&lt;p&gt;打开Emacs的配置文件。配置文件在~/.emacs。增加：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(set-background-color &amp;quot;black&amp;quot;) ;; 使用黑色背景
(set-foreground-color &amp;quot;white&amp;quot;) ;; 使用白色前景
(set-face-foreground 'region &amp;quot;green&amp;quot;)  ;; 区域前景颜色设为绿色
(set-face-background 'region &amp;quot;blue&amp;quot;) ;; 区域背景色设为蓝色&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;尽管可以重启Emacs使配置生效，但更快捷的方式是在打开~/.emacs的时候执行命令M-x eval-buffer，就可以使配置文件立即生效。&lt;/p&gt;
&lt;h3 id="快捷键"&gt;快捷键&lt;/h3&gt;
&lt;p&gt;中文帮助：&lt;code&gt;C-h t&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;撤消：&lt;code&gt;C-x u&lt;/code&gt; &lt;code&gt;C-/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;启动自动折行模式：&lt;code&gt;M-x auto-fill-mode &amp;lt;Return&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;相关命令搜索（Command Apropos）：&lt;code&gt;C-h a&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Emacs 使用手册（manual）：&lt;code&gt;C-h r&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;自动补全：&lt;code&gt;M-/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在另一个窗口打开缓冲：&lt;code&gt;C-x 4 b&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;复制：&lt;code&gt;M-w&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;把当前进程放到后台（之后可用''fg''命令回到前台）： &lt;code&gt;Ctrl Z&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;清屏：&lt;code&gt;ctrl L&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="打开"&gt;打开&lt;/h3&gt;
&lt;p&gt;终端模式：&lt;code&gt;emacs -nw&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="配置备份"&gt;配置备份&lt;/h3&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;;;用xetex编译,以支持中文
(setq-default TeX-engine 'xetex)
;;默认输出pdf
(setq-default TeX-PDF-mode t)

;;ELPA (Emacs Lisp Package Archive)扩展插件管理,用命令`package-list-packages`调用.
;;主题网站https://emacsthemes.com/ 
(require 'package)
(add-to-list 'package-archives 
             '(&amp;quot;melpa&amp;quot; . &amp;quot;http://melpa.org/packages/&amp;quot;))
(package-initialize)

;;加载主题
(load-theme 'light-blue t)
;;auctex插件
(load &amp;quot;auctex.el&amp;quot; nil t t)
(load &amp;quot;preview-latex.el&amp;quot; nil t t)
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)

;;在 LaTeX mode 中，默认开启 PDF mode，即默认使用 xelatex 直接生成 pdf 文 件，而不用每次用 'C-c C-t C-p' 进行切换。设置 'Tex-show-compilation' 为 t，在另一个窗口显示编译信息，对于错误的排除很方便。另外，编译时默认直接 保存文件，绑定补全符号到 TAB 键。
(add-hook 'LaTeX-mode-hook
          (lambda ()
            (setq TeX-auto-untabify t     ; remove all tabs before saving
                  TeX-engine 'xetex       ; use xelatex default
                  TeX-show-compilation t) ; display compilation windows
            (TeX-global-PDF-mode t)       ; PDF mode enable, not plain
            (setq TeX-save-query nil)
            (imenu-add-menubar-index)
            (define-key LaTeX-mode-map (kbd &amp;quot;TAB&amp;quot;) 'TeX-complete-symbol)))


;;自动换行，数学公式，reftex，显示号
(mapc (lambda (mode)
      (add-hook 'LaTeX-mode-hook mode))
      (list 'auto-fill-mode
            'LaTeX-math-mode
            'turn-on-reftex
            'linum-mode))
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-selected-packages (quote (pyim nord-theme))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

(elpy-use-ipython)

; python-mode
(setq py-install-directory &amp;quot;~/.emacs.d/python-mode-6.0.11&amp;quot;)
(add-to-list 'load-path py-install-directory)
(require 'python-mode)

; use IPython
(setq-default py-shell-name &amp;quot;ipython&amp;quot;)
(setq-default py-which-bufname &amp;quot;IPython&amp;quot;)
; use the wx backend, for both mayavi and matplotlib
(setq py-python-command-args
  '(&amp;quot;--gui=wx&amp;quot; &amp;quot;--pylab=wx&amp;quot; &amp;quot;-colors&amp;quot; &amp;quot;Linux&amp;quot;))
(setq py-force-py-shell-name-p t)

; switch to the interpreter after executing code
(setq py-shell-switch-buffers-on-execute-p t)
(setq py-switch-buffers-on-execute-p t)
; don't split windows
(setq py-split-windows-on-execute-p nil)
; try to automagically figure out indentation
(setq py-smart-indentation t)


(setq TeX-view-program-list
      '((&amp;quot;SumatraPDF&amp;quot; &amp;quot;SumatraPDF.exe %o&amp;quot;)
        (&amp;quot;Gsview&amp;quot; &amp;quot;gsview32.exe %o&amp;quot;)
        (&amp;quot;Okular&amp;quot; &amp;quot;okular --unique %o&amp;quot;)
        (&amp;quot;Evince&amp;quot; &amp;quot;evince %o&amp;quot;)
        (&amp;quot;Firefox&amp;quot; &amp;quot;firefox %o&amp;quot;)))
 ((eq system-type 'gnu/linux)
  (add-hook 'LaTeX-mode-hook
            (lambda ()
              (setq TeX-view-program-selection '((output-pdf &amp;quot;Okular&amp;quot;)
                                                 (output-dvi &amp;quot;Okular&amp;quot;)))))))


(add-to-list 'load-path &amp;quot;/home/dx/Downloads/neotree&amp;quot;)
(require 'neotree)
(global-set-key [f8] 'neotree-toggle)

(require 'sr-speedbar)

&lt;/code&gt;&lt;/pre&gt;
</content><category term="软件使用"/><category term="Emacs"/><category term="快捷键"/></entry><entry><title>Typora使用笔记</title><link href="https://zqw.ink/2018-09-07-coding-typora_note.html" rel="alternate"/><published>2018-09-07T00:00:00+08:00</published><updated>2018-09-07T00:00:00+08:00</updated><author><name>ZQW</name></author><id>tag:zqw.ink,2018-09-07:/2018-09-07-coding-typora_note.html</id><summary type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h2 id="标题"&gt;标题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;“#” 一级标题&lt;/li&gt;
&lt;li&gt;“##” 二级标题&lt;/li&gt;
&lt;li&gt;以此类推直至“######” 表示六级标题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="列表"&gt;列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;无序号列表：“- ”列表内容。注意&amp;quot;- &amp;quot;后有空格&lt;/li&gt;
&lt;li&gt;有序号列表：“1. ”列表内容&lt;/li&gt;
&lt;li&gt;任 …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;!-- toc --&gt;
&lt;!-- more --&gt;
&lt;h2 id="标题"&gt;标题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;“#” 一级标题&lt;/li&gt;
&lt;li&gt;“##” 二级标题&lt;/li&gt;
&lt;li&gt;以此类推直至“######” 表示六级标题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="列表"&gt;列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;无序号列表：“- ”列表内容。注意&amp;quot;- &amp;quot;后有空格&lt;/li&gt;
&lt;li&gt;有序号列表：“1. ”列表内容&lt;/li&gt;
&lt;li&gt;任务列表：“- [ ]”列表内容&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="居中"&gt;居中&lt;/h2&gt;
&lt;p&gt;&amp;quot;&amp;lt;center&amp;gt;&amp;quot;跟居中的内容&lt;/p&gt;
&lt;h2 id="引用与代码"&gt;引用与代码&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;引用文字：“&amp;gt; ”引用内容&lt;/li&gt;
&lt;li&gt;引用网址：&amp;quot;&amp;lt;&amp;quot;网址&amp;quot;&amp;gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;单行代码：&amp;quot;`&amp;quot;代码内容&amp;quot;`&amp;quot;&lt;/li&gt;
&lt;li&gt;多行代码：&amp;quot;```&amp;quot;代码内容&amp;quot;```&amp;quot;&lt;/li&gt;
&lt;li&gt;注释：“[^注释内容]”&lt;/li&gt;
&lt;li&gt;&lt;a href="./2018-09-07-coding-emacs_note.html"&gt;引用博客&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="字体设置"&gt;字体设置&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;斜体：&amp;quot;*&amp;quot;斜体内容&amp;quot;*&amp;quot;&lt;/li&gt;
&lt;li&gt;加粗：&amp;quot;**&amp;quot;加粗内容&amp;quot;**&amp;quot;&lt;/li&gt;
&lt;li&gt;下划线：&amp;quot;&amp;lt;u&amp;gt;&amp;quot;下划线内容“&amp;lt;/u&amp;gt;”&lt;/li&gt;
&lt;li&gt;删除线：&amp;quot;~~&amp;quot;删除内容&amp;quot;~~&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="分割线"&gt;分割线&lt;/h2&gt;
&lt;p&gt;&amp;quot;---&amp;quot;&lt;/p&gt;
&lt;h2 id="转义"&gt;转义&lt;/h2&gt;
&lt;p&gt;\ 转义符号&lt;/p&gt;
&lt;h2 id="插入"&gt;插入&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;图片：直接拖入&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;表格：&lt;/p&gt;
&lt;p&gt;|表	|格	|&lt;/p&gt;
&lt;p&gt;|内	|容	|&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;行内公式：&amp;quot;$&amp;quot;公式内容&amp;quot;$&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;单独成行的公式：&amp;quot;$$&amp;quot;公式内容&amp;quot;$$&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;表情：&amp;quot;:&amp;quot;表情内容&amp;quot;:&amp;quot;。表情内容见附录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;目录：&amp;quot;[toc]&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="附录表情列表"&gt;附录：表情列表&lt;/h2&gt;
&lt;h3 id="symbols"&gt;Symbols&lt;/h3&gt;
&lt;p&gt;2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟 🔢 0️⃣ #️⃣ 🔣 ◀️ ⬇️ ▶️ ⬅️ 🔠 🔡 🔤 ↙️ ↘️ ➡️ ⬆️ ↖️ ↗️ ⏬ ⏫ 🔽 ⤵️ ⤴️ ↩️ ↪️ ↔️ ↕️ 🔼 🔃 🔄 ⏪ ⏩ ℹ️ 🆗 🔀 🔁 🔂 🆕 🔝 🆙 🆒 🆓 🆖 🎦 🈁 📶 :u5272: :u5408: :u55b6: :u6307: :u6708: :u6709: 🈵 :u7121: :u7533: :u7a7a: :u7981: 🈂️ 🚻 🚹 🚺 🚼 🚭 🅿️ ♿️ 🚇 🛄 🉑 🚾 🚰 🚮 ㊙️ ㊗️ Ⓜ️ 🛂 🛅 🛃 🉐 🆑 🆘 🆔 🚫 🔞 📵 🚯 🚱 🚳 🚷 🚸 ⛔️ ✳️ ❇️ ✴️ 💟 🆚 📳 📴 💹 💱 ♈️ ♉️ ♊️ ♋️ ♌️ ♍️ ♎️ ♏️ ♐️ ♑️ ♒️ ♓️ ⛎ 🔯 ❎ 🅰️ 🅱️ 🆎 🅾️ 💠 ♻️ 🔚 🔙 🔛 🔜 🕐 🕜 🕙 🕥 🕚 🕦 🕛 🕧 🕑 🕝 🕒 🕞 🕓 🕟 🕔 🕠 🕕 🕡 🕖 🕢 🕗 🕣 🕘 🕤 💲 ©️ ®️ ™️ ❌ ❗️ ‼️ ⁉️ ⭕️ ✖️ ➕ ➖ ➗ 💮 💯 ✔️ ☑️ 🔘 🔗 ➰ 〰️ 〽️ 🔱 ▪️ ▫️ ◾️ ◽️ ◼️ ◻️ ⬛️ ⬜️ ✅ 🔲 🔳 ⚫️ ⚪️ 🔴 🔵 🔷 🔶 🔹 🔸 🔺 🔻 :shipit:&lt;/p&gt;
&lt;h3 id="places"&gt;Places&lt;/h3&gt;
&lt;p&gt;🏠 🏡 🏫 🏢 🏣 🏥 🏦 🏪 🏩 🏨 💒 ⛪️ 🏬 🏤 🌇 🌆 🏯 🏰 ⛺️ 🏭 🗼 🗾 🗻 🌄 🌅 🌠 🗽 🌉 🎠 🌈 🎡 ⛲️ 🎢 🚢 🚤 ⛵️ ⛵️ 🚣 ⚓️ 🚀 ✈️ 🚁 🚂 🚊 🚞 🚲 🚡 🚟 🚠 🚜 🚙 🚘 🚗 🚗 🚕 🚖 🚛 🚌 🚍 🚨 🚓 🚔 🚒 🚑 🚐 🚚 🚋 🚉 🚆 🚅 🚄 🚈 🚝 🚃 🚎 🎫 ⛽️ 🚦 🚥 ⚠️ 🚧 🔰 🏧 🎰 🚏 💈 ♨️ 🏁 🎌 🏮 🗿 🎪 🎭 📍 🚩 🇯🇵 🇰🇷 🇨🇳 🇺🇸 🇫🇷 🇪🇸 🇮🇹 🇷🇺 🇬🇧 🇬🇧 🇩🇪&lt;/p&gt;
&lt;h3 id="people"&gt;People&lt;/h3&gt;
&lt;p&gt;:bowtie: 😄 :simple_smile: 😆 😊 😃 ☺️ 😏 😍 😘 😚 😳 😌 😆 😁 😉 😜 😝 😀 😗 😙 😛 😴 😟 😦 😧 😮 😬 😕 😯 😑 😒 😅 😓 😥 😩 😔 😞 😖 😨 😰 😣 😢 😭 😂 😲 😱 :neckbeard: 😫 😠 😡 😤 😪 😋 😷 😎 😵 👿 😈 😐 😶 😇 👽 💛 💙 💜 ❤️ 💚 💔 💓 💗 💕 💞 💘 💖 ✨ ⭐️ 🌟 💫 💥 💥 💢 ❗️ ❓ ❕ ❔ 💤 💨 💦 🎶 🎵 🔥 💩 💩 💩 👍 👍 👎 👎 👌 👊 👊 ✊ ✌️ 👋 ✋ ✋ 👐 ☝️ 👇 👈 👉 🙌 🙏 👆 👏 💪 🤘 🖕 🏃 🏃 👫 👪 👬 👭 💃 👯 🙆 🙅 💁 🙋 👰 🙎 🙍 🙇 :couplekiss: 💑 💆 💇 💅 👦 👧 👩 👨 👶 👵 👴 👱 👲 👳 👷 👮 👼 👸 😺 😸 😻 😽 😼 🙀 😿 😹 😾 👹 👺 🙈 🙉 🙊 💂 💀 🐾 👄 💋 💧 👂 👀 👃 👅 💌 👤 👥 💬 💭 :feelsgood: :finnadie: :goberserk: :godmode: :hurtrealbad: :rage1: :rage2: :rage3: :rage4: :suspect: :trollface:&lt;/p&gt;
&lt;h3 id="nature"&gt;Nature&lt;/h3&gt;
&lt;p&gt;☀️ ☔️ ☁️ ❄️ ⛄️ ⚡️ 🌀 🌁 🌊 🐱 🐶 🐭 🐹 🐰 🐺 🐸 🐯 🐨 🐻 🐷 🐽 🐮 🐗 🐵 🐒 🐴 🐎 🐫 🐑 🐘 🐼 🐍 🐦 🐤 🐥 🐣 🐔 🐧 🐢 🐛 🐝 🐜 🐞 🐌 🐙 🐠 🐟 🐳 🐋 🐬 🐄 🐏 🐀 🐃 🐅 🐇 🐉 🐐 🐓 🐕 🐖 🐁 🐂 🐲 🐡 🐊 🐪 🐆 🐈 🐩 🐾 💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄 🌵 🌴 🌲 🌳 🌰 🌱 🌼 🌾 🐚 🌐 🌞 🌝 🌚 🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 🌜 🌛 🌙 🌍 🌎 🌏 🌋 🌌 ⛅️ :octocat: :squirrel: Objects 🎍 💝 🎎 🎒 🎓 🎏 🎆 🎇 🎐 🎑 🎃 👻 🎅 🎄 🎁 🔔 🔕 🎋 🎉 🎊 🎈 🔮 💿 📀 💾 📷 📹 🎥 💻 📺 📱 ☎️ ☎️ 📞 📟 📠 💽 📼 🔉 🔈 🔇 📢 📣 ⌛️ ⏳ ⏰ ⌚️ 📻 📡 ➿ 🔍 🔎 🔓 🔒 🔏 🔐 🔑 💡 🔦 🔆 🔅 🔌 🔋 📲 ✉️ 📫 📮 🛀 🛁 🚿 🚽 🔧 🔩 🔨 💺 💰 💴 💵 💷 💶 💳 💸 📧 📥 📤 ✉️ 📨 📯 📪 📬 📭 📦 🚪 🚬 💣 🔫 🔪 💊 💉 📄 📃 📑 📊 📈 📉 📜 📋 📆 📅 📇 📁 📂 ✂️ 📌 📎 ✒️ ✏️ 📏 📐 📕 📗 📘 📙 📓 📔 📒 📚 🔖 📛 🔬 🔭 📰 🏈 🏀 ⚽️ ⚾️ 🎾 🎱 🏉 🎳 ⛳️ 🚵 🚴 🏇 🏂 🏊 🏄 🎿 ♠️ ♥️ ♣️ ♦️ 💎 💍 🏆 🎼 🎹 🎻 👾 🎮 🃏 🎴 🎲 🎯 🀄️ 🎬 📝 📝 📖 🎨 🎤 🎧 🎺 🎷 🎸 👞 👡 👠 💄 👢 👕 👕 👔 👚 👗 🎽 👖 👘 👙 🎀 🎩 👑 👒 👞 🌂 💼 👜 👝 👛 👓 🎣 ☕️ 🍵 🍶 🍼 🍺 🍻 🍸 🍹 🍷 🍴 🍕 🍔 🍟 🍗 🍖 🍝 🍛 🍤 🍱 🍣 🍥 🍙 🍘 🍚 🍜 🍲 🍢 🍡 🥚 🍞 🍩 🍮 🍦 🍨 🍧 🎂 🍰 🍪 🍫 🍬 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 🍠 🍆 🍅 🌽&lt;/p&gt;
</content><category term="软件使用"/><category term="Typora"/></entry></feed>