<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Blog of science and life</title><link href="https://doanhtu.com/" rel="alternate"></link><link href="https://doanhtu.com/atom" rel="self"></link><id>https://doanhtu.com/</id><updated>2023-10-19T11:21:00+07:00</updated><subtitle>Learn forever</subtitle><entry><title>Backup Sqlite3 with Litestream - Tutorial</title><link href="https://doanhtu.com/article/backup-sqlite3-with-litestream-tutorial/" rel="alternate"></link><published>2023-10-19T11:21:00+07:00</published><updated>2023-10-19T11:21:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2023-10-19:/article/backup-sqlite3-with-litestream-tutorial/</id><summary type="html">&lt;h1&gt;What is backup and restore?&lt;/h1&gt;
&lt;p&gt;Backup: Imagine on a Sunday morning, your hard drive dies. You can't access anything. Your bitcoin wallet's private key is the only copy, and it's on that hard drive. Sounds horrifying, right? That's when a backup comes in handy and saves the day (and maybe your life too).&lt;/p&gt;
&lt;p&gt;Restore: Backups are amazing, but if done incorrectly, you're screwed. So every time you make a backup, make sure to try restoring it, even just once is more than enough. You'll thank yourself later. You'll feel like a god, being able to see the future and prevent disasters.&lt;/p&gt;
&lt;p&gt;In this era of information, it's crucial to have a snapshot of your important data somewhere else. Having three copies will do the trick. More is even better.&lt;/p&gt;
&lt;h1&gt;What is Sqlite3?&lt;/h1&gt;
&lt;p&gt;Sqlite3 is an amazing database; you don't need to run any processes for your database anymore. Just write …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;What is backup and restore?&lt;/h1&gt;
&lt;p&gt;Backup: Imagine on a Sunday morning, your hard drive dies. You can't access anything. Your bitcoin wallet's private key is the only copy, and it's on that hard drive. Sounds horrifying, right? That's when a backup comes in handy and saves the day (and maybe your life too).&lt;/p&gt;
&lt;p&gt;Restore: Backups are amazing, but if done incorrectly, you're screwed. So every time you make a backup, make sure to try restoring it, even just once is more than enough. You'll thank yourself later. You'll feel like a god, being able to see the future and prevent disasters.&lt;/p&gt;
&lt;p&gt;In this era of information, it's crucial to have a snapshot of your important data somewhere else. Having three copies will do the trick. More is even better.&lt;/p&gt;
&lt;h1&gt;What is Sqlite3?&lt;/h1&gt;
&lt;p&gt;Sqlite3 is an amazing database; you don't need to run any processes for your database anymore. Just write to a single database file &lt;code&gt;db.sqlite3&lt;/code&gt; and you will have more than enough for 90% of whatever you want to build. And if you only have one file, backing up and restoring it is very simple, if you use Litestream.&lt;/p&gt;
&lt;h1&gt;What is Litestream?&lt;/h1&gt;
&lt;p&gt;You can read more about Litestream &lt;a href="https://litestream.io/how-it-works/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Litestream is a streaming replication tool for SQLite databases. It runs as a separate background process and continuously copies write-ahead log pages from disk to one or more replicas. This asynchronous replication provides disaster recovery similar to what is available with database servers like Postgres or MySQL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Summary: it's a backup tool for Sqlite3. And it's only write the changes, so it's very fast and space-efficient.&lt;/p&gt;
&lt;h1&gt;Tutorial&lt;/h1&gt;
&lt;p&gt;Imagine you have a Django project, and you want to backup your Sqlite3 database. Here is how you do it.&lt;/p&gt;
&lt;p&gt;Given that your database file is in &lt;code&gt;./db.sqlite3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Install Litestream (For ubuntu users)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://github.com/benbjohnson/litestream/releases/download/v0.3.11/litestream-v0.3.11-linux-amd64.deb&amp;#39;&lt;/span&gt;

sudo&lt;span class="w"&gt; &lt;/span&gt;dpkg&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;litestream-v0.3.11-linux-amd64.deb

rm&lt;span class="w"&gt; &lt;/span&gt;litestream-v0.3.11-linux-amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First you need to set some ENVs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-aws-secret&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-aws-key&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;REPLICA_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;s3://backup/your-project&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Backup&lt;/h3&gt;
&lt;p&gt;For example, you have a bucket on S3 named &lt;code&gt;backup&lt;/code&gt;, and you want to backup your database to that bucket.&lt;/p&gt;
&lt;p&gt;You can run this command to start backing up:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;litestream&lt;span class="w"&gt; &lt;/span&gt;replicate&lt;span class="w"&gt; &lt;/span&gt;./db.sqlite3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPLICA_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it. You can run this command in a screen/tmux session, or use systemd to run it as a service. Now your database is backed up every time you write to it.
The interval is 1 second.&lt;/p&gt;
&lt;h3&gt;Restore&lt;/h3&gt;
&lt;p&gt;To restore (on other location), all you need to do is&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;litestream&lt;span class="w"&gt; &lt;/span&gt;restore&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;-if-replica-exists&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;./db.sqlite3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPLICA_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Awesome, right?&lt;/p&gt;</content><category term="Programming"></category><category term="litestream"></category><category term="sqlite3"></category><category term="backup"></category></entry><entry><title>How to choose a good CPU?</title><link href="https://doanhtu.com/article/how-to-choose-a-good-cpu/" rel="alternate"></link><published>2023-03-30T09:09:00+07:00</published><updated>2023-03-30T09:09:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2023-03-30:/article/how-to-choose-a-good-cpu/</id><summary type="html">&lt;p&gt;Tired of not understanding all of the jargon in CPUs name, in this post I will write down what I've researched.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/god_cpus.png" /&gt;&lt;/p&gt;
&lt;p&gt;There are 2 major players in this field (consumer view): Intel and AMD&lt;/p&gt;
&lt;h2&gt;Intel&lt;/h2&gt;
&lt;h3&gt;Basic&lt;/h3&gt;
&lt;p&gt;So you’ll notice after the i5 it might have some thing like 9600 or 12600, for the i7 you’d see 12700 or 9700. 
The number before the hundredths digit is the generation. 
So a current gen (12th) i5 would be better than a much older i7 8700 (8th gen) for example. 
There’s a 4 generation difference in technology and everything else that goes into them&lt;/p&gt;
&lt;h3&gt;What’s the deal with 11th gen Intel? Are you saying it wasn’t much of an improvement over 10th gen?&lt;/h3&gt;
&lt;p&gt;That is exactly the case.&lt;/p&gt;
&lt;p&gt;In some ways (10900K -&amp;gt; 11900K) it was even the opposite of improvement.&lt;/p&gt;
&lt;p&gt;Every new generation of processors is faster than …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Tired of not understanding all of the jargon in CPUs name, in this post I will write down what I've researched.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/god_cpus.png" /&gt;&lt;/p&gt;
&lt;p&gt;There are 2 major players in this field (consumer view): Intel and AMD&lt;/p&gt;
&lt;h2&gt;Intel&lt;/h2&gt;
&lt;h3&gt;Basic&lt;/h3&gt;
&lt;p&gt;So you’ll notice after the i5 it might have some thing like 9600 or 12600, for the i7 you’d see 12700 or 9700. 
The number before the hundredths digit is the generation. 
So a current gen (12th) i5 would be better than a much older i7 8700 (8th gen) for example. 
There’s a 4 generation difference in technology and everything else that goes into them&lt;/p&gt;
&lt;h3&gt;What’s the deal with 11th gen Intel? Are you saying it wasn’t much of an improvement over 10th gen?&lt;/h3&gt;
&lt;p&gt;That is exactly the case.&lt;/p&gt;
&lt;p&gt;In some ways (10900K -&amp;gt; 11900K) it was even the opposite of improvement.&lt;/p&gt;
&lt;p&gt;Every new generation of processors is faster than the previous, so you end up in a situation (for example) where an i3-10100 from 2020 is equal in performance to an i7-7700 from 2017&lt;/p&gt;
&lt;h3&gt;People recommending i5 over i7, what's the reason for this?&lt;/h3&gt;
&lt;p&gt;Price. And value, when comparing CPUs for gaming, if the i5 gets you 95% there compared to the i7, but the i7 costs 50% more, then the i7, while a better CPU, is a worse value.&lt;/p&gt;
&lt;p&gt;i5, i3, i7, that name doesn't matter. You need the actual product name, 12900k, 10400, etc.&lt;/p&gt;
&lt;h3&gt;Can I tell anything about the threads etc. off of the 600, 600kf 900k 700k, etc. alone like the gen?&lt;/h3&gt;
&lt;p&gt;There is no formula, gotta look at the specs of each processor&lt;/p&gt;
&lt;p&gt;Only constants are "k" and "f"&lt;/p&gt;
&lt;p&gt;k = overclockable&lt;/p&gt;
&lt;p&gt;f = no igpu&lt;/p&gt;
&lt;p&gt;X = HEDT, usually has a different socket/mobo from the rest of the generation&lt;/p&gt;
&lt;p&gt;KS = factory overclocked&lt;/p&gt;
&lt;p&gt;There's also other letters that signify different things that are more common outside of the DIY desktop PC space, like "T" for low TDP, and the "U" and "H" variants for low/high power laptops.&lt;/p&gt;
&lt;h3&gt;Core? Thread?&lt;/h3&gt;
&lt;p&gt;Max processing power is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Clock (in GHz) x IPC x Number of Cores/Threads.&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clock is readily advertised. Boost clocks are another matter but you may be able to ignore that for the moment.This is essentially how many "cycles" it does per second.  &lt;/li&gt;
&lt;li&gt;IPC = Instructions Per Clock. You can read up about this, but this is the LEAST exposed one. Generally it improves with newer generations, sometimes significantly. Also it is generally somewhat consistent within generation. This is why an older 4-core, 3.0 GHz chip can be significantly slower than a newer 4-core 2.7 GHz chip. This is how much work is done per cycle.  &lt;/li&gt;
&lt;li&gt;Number/threads. Easily checked via specs. However not all programs utilize core efficiently. On one end of the spectrum are programs that DO NOT utilize multiple cores well. So regardless of specs you might as well consider this =1. Ont he other side are programs that utilize all core well, for these going from a 4 core to an 8 core (even if it is the same clock and IPC) can double performance. A lot of simulation/math packages are tuned for many cores, so you will probably want more cores.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Family of Intel&lt;/h3&gt;
&lt;p&gt;XE - Highest end workstation unlocked for oc&lt;/p&gt;
&lt;p&gt;X - Extreme edition / workstation unlocked for oc&lt;/p&gt;
&lt;p&gt;K - Unlocked for overclocking&lt;/p&gt;
&lt;p&gt;F - No igpu&lt;/p&gt;
&lt;p&gt;T - Low power desktop&lt;/p&gt;
&lt;p&gt;G - Highest preformance mobile with built in Vega M graphics with 2GB GDDR5 (equivilant to a GTX 1050)&lt;/p&gt;
&lt;p&gt;Gx - Nothing to see here, this is just Intel's weird 10nm naming scheme, the number after the G indicates graphics preformance and power level. Basically the same as U and Y series.&lt;/p&gt;
&lt;p&gt;M - Mobile Xeon / Old PGA socketed mobile Core series.&lt;/p&gt;
&lt;p&gt;H - High preformance mobile (with desktop x30 graphics)&lt;/p&gt;
&lt;p&gt;U - Low power mobile (with x20 graphics)&lt;/p&gt;
&lt;p&gt;Y - Ultra low power mobile (x1x and x0x graphics)&lt;/p&gt;
&lt;p&gt;Xeon - Server / Professional desktop and mobile workstation with ECC support&lt;/p&gt;
&lt;p&gt;Core i9-x9xx - Prosumer / Desktop workstation with no ECC support / Highest end mobile.&lt;/p&gt;
&lt;p&gt;Core i7-x7xx - High end desktop (not hedt) / Old HEDT workstation with no ECC support / High end mobile&lt;/p&gt;
&lt;p&gt;Core i5-xxxx - Mid range desktop / potato HEDT / Mid range mobile&lt;/p&gt;
&lt;p&gt;Core i3-xxxx - Low end desktop / mobile&lt;/p&gt;
&lt;p&gt;Pentium - Slightly bellow Core i3&lt;/p&gt;
&lt;p&gt;Celeron - Entry level potatoes for web browsing
20&lt;/p&gt;</content><category term="Hack"></category><category term="cpu"></category><category term="intel"></category><category term="amd"></category><category term="knowledge"></category></entry><entry><title>Làm thế nào để giải quyết vấn đề?</title><link href="https://doanhtu.com/article/lam-the-nao-de-giai-quyet-van-de/" rel="alternate"></link><published>2023-03-16T09:34:00+07:00</published><updated>2023-03-16T09:34:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2023-03-16:/article/lam-the-nao-de-giai-quyet-van-de/</id><summary type="html">&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/man_thinking.png" /&gt;&lt;/p&gt;
&lt;p&gt;Trước mỗi khi bạn làm việc gì đó, thứ bạn nên làm đầu tiên là suy nghĩ. Nhưng suy nghĩ gì thì không ai hướng dẫn.&lt;/p&gt;
&lt;p&gt;Vì thế mình sẽ chia sẻ một ít thứ mà mình nghĩ trước khi giải quyết một vấn đề gì đó.&lt;/p&gt;
&lt;h2&gt;1. Mong muốn/mục tiêu?&lt;/h2&gt;
&lt;p&gt;Câu hỏi chí mạng nhất mà các newbie chả bao giờ hỏi trước khi xông xáo vào vẽ ra phương án rồi mục tiêu abc xyz.&lt;/p&gt;
&lt;p&gt;Con người ta bị một thói là hay nói bóng gió, ít khi để lộ ý định thực của mình. Hay còn gọi là vòng vo. Nên bạn cần 
phải tỉnh táo và cố tìm ra nguyên nhân ẩn sau những thứ mà họ (khách, sếp, bạn bè ...) nghĩ là họ muốn. Cứ thoải mái hỏi 
đến khi nào ra nhẽ thì thôi.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;... Chúa tha thứ cho mày, vì chính mày cũng …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/man_thinking.png" /&gt;&lt;/p&gt;
&lt;p&gt;Trước mỗi khi bạn làm việc gì đó, thứ bạn nên làm đầu tiên là suy nghĩ. Nhưng suy nghĩ gì thì không ai hướng dẫn.&lt;/p&gt;
&lt;p&gt;Vì thế mình sẽ chia sẻ một ít thứ mà mình nghĩ trước khi giải quyết một vấn đề gì đó.&lt;/p&gt;
&lt;h2&gt;1. Mong muốn/mục tiêu?&lt;/h2&gt;
&lt;p&gt;Câu hỏi chí mạng nhất mà các newbie chả bao giờ hỏi trước khi xông xáo vào vẽ ra phương án rồi mục tiêu abc xyz.&lt;/p&gt;
&lt;p&gt;Con người ta bị một thói là hay nói bóng gió, ít khi để lộ ý định thực của mình. Hay còn gọi là vòng vo. Nên bạn cần 
phải tỉnh táo và cố tìm ra nguyên nhân ẩn sau những thứ mà họ (khách, sếp, bạn bè ...) nghĩ là họ muốn. Cứ thoải mái hỏi 
đến khi nào ra nhẽ thì thôi.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;... Chúa tha thứ cho mày, vì chính mày cũng còn không biết mày đang muốn gì (DSK)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;2. Phương án&lt;/h2&gt;
&lt;p&gt;Vì sau khi hỏi cho ra nhẽ, đôi lúc phương pháp giải quyết lại cực kì đơn giản và &lt;strong&gt;rất&lt;/strong&gt; có khả năng là đã có người 
đi trước giải quyết xong rồi. Việc của bạn lúc này là tìm ra những người đi trước và học tập theo. Dừng cố tự mình 
giải quyết trước. Tìm hiểu đã.&lt;/p&gt;
&lt;h2&gt;3. Thử nghiệm&lt;/h2&gt;
&lt;p&gt;Thử nghiệm, nhưng theo thứ tự &lt;em&gt;đơn giản nhất&lt;/em&gt; cho đến phức tạp nhất. Keep it simple stupid.&lt;/p&gt;
&lt;h2&gt;4. Vấn đề khó hơn bạn nghĩ?&lt;/h2&gt;
&lt;p&gt;Thì một là khả năng là bạn đang tìm sai phương hướng. Vì nếu đúng ra thì phương án giải quyết sẽ phải rất đơn giản. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dao cạo Ockham (tiếng Anh: Ockham's Razor) là một lý thuyết triết học nổi tiếng của nhà triết học người Anh William xứ Ockham. Nó được ông đưa ra vào năm 1324. William đã viết rằng lời giải thích đơn giản nhất thường là lời giải thích xác đáng nhất, hoặc "Điều gì có thể được giải thích bằng ít giả thuyết hơn thì lại được giải thích một cách vô ích bằng nhiều giả định hơn"[1]. Tức là nếu một vấn đề khoa học được giải thích bằng ít giả thuyết nhất thì sẽ đúng đắn nhất.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hoặc là vấn đề bạn đang giải quyết còn khá mới và yêu cầu sự sáng tạo. Sẽ cần nhiều thời gian hơn, để bạn có thể nghiên cứu 
các tài liệu liên quan và để cho Hệ thống 2 của bạn có thời gian suy nghĩ.&lt;/p&gt;
&lt;p&gt;Note: cho ai chưa biết Hệ thống 2 là gì&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thinking, Fast and Slow is a 2011 book by psychologist Daniel Kahneman.  The book's main thesis is a differentiation between two modes of thought: "System 1" is fast, instinctive and emotional; "System 2" is slower, more deliberative, and more logical&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Life"></category><category term="think"></category><category term="work"></category><category term="how to"></category><category term="problem solving"></category></entry><entry><title>Freeup your diskspace with "dua"</title><link href="https://doanhtu.com/article/freeup-your-diskspace-with-dua/" rel="alternate"></link><published>2023-03-15T22:36:00+07:00</published><updated>2023-03-15T22:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2023-03-15:/article/freeup-your-diskspace-with-dua/</id><content type="html">&lt;p&gt;This evening I want to freeup my diskspace, since 50 GB left (1/10 of my diskspace) is a warning.&lt;/p&gt;
&lt;p&gt;Before that I've tried with &lt;code&gt;du&lt;/code&gt; and &lt;code&gt;sort&lt;/code&gt; but it's so slow and hard to use. &lt;/p&gt;
&lt;p&gt;Then I found &lt;code&gt;dua&lt;/code&gt; (Disk Usage Analyzer) tool and it is a god send. So good.&lt;/p&gt;
&lt;p&gt;To install, just run this command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-LSfs&lt;span class="w"&gt; &lt;/span&gt;https://raw.githubusercontent.com/Byron/dua-cli/master/ci/install.sh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;sh&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;--git&lt;span class="w"&gt; &lt;/span&gt;Byron/dua-cli&lt;span class="w"&gt; &lt;/span&gt;--target&lt;span class="w"&gt; &lt;/span&gt;x86_64-unknown-linux-musl&lt;span class="w"&gt; &lt;/span&gt;--crate&lt;span class="w"&gt; &lt;/span&gt;dua&lt;span class="w"&gt; &lt;/span&gt;--tag&lt;span class="w"&gt; &lt;/span&gt;v2.17.4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;then &lt;code&gt;dua&lt;/code&gt; any directory you want (with &lt;code&gt;/*&lt;/code&gt; after path).&lt;/p&gt;
&lt;p&gt;For example: &lt;code&gt;dua ~/.cache/*&lt;/code&gt; and &lt;code&gt;dua ~/.local/*&lt;/code&gt; may supprise you like it does to me.&lt;/p&gt;
&lt;p&gt;Try and find out. Good luck.&lt;/p&gt;</content><category term="Hack"></category><category term="ubuntu"></category><category term="freeup"></category><category term="diskspace"></category></entry><entry><title>Pywright - Render javascript websites</title><link href="https://doanhtu.com/article/pywright-render-javascript-websites/" rel="alternate"></link><published>2022-11-19T22:36:00+07:00</published><updated>2022-11-19T22:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-11-19:/article/pywright-render-javascript-websites/</id><summary type="html">&lt;p&gt;Demo: &lt;a href="https://pywright.fly.dev"&gt;pywright.fly.dev&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What is Playwright?&lt;/h2&gt;
&lt;p&gt;Playwright is a browser automation library from Microsoft. It can be used to automate tasks in the browser, for testing purpose.&lt;/p&gt;
&lt;p&gt;But we can use it to scrape data from websites that use javascript to render the content.&lt;/p&gt;
&lt;p&gt;Think about Facebook, Twitter, Instagram, etc. They use javascript to render the content. So we can't scrape them with normal tools like &lt;code&gt;requests&lt;/code&gt; or &lt;code&gt;scrapy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Selenium is a popular tool for scraping javascript websites. It's powerful, have a lot of features, but it's slow and hard to use.&lt;/p&gt;
&lt;p&gt;Playwright is a newplayer in this field. It's fast, have excelent simple API.&lt;/p&gt;
&lt;h2&gt;What is Pywright?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Pywright&lt;/strong&gt; is a API service writen in python that use Playwright to render javascript websites. You can easily deploy it to any cloud provider then use it as a service.&lt;/p&gt;
&lt;h2&gt;Install Pywright&lt;/h2&gt;
&lt;p&gt;I've created a docker image for Playwright. It's contain …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Demo: &lt;a href="https://pywright.fly.dev"&gt;pywright.fly.dev&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What is Playwright?&lt;/h2&gt;
&lt;p&gt;Playwright is a browser automation library from Microsoft. It can be used to automate tasks in the browser, for testing purpose.&lt;/p&gt;
&lt;p&gt;But we can use it to scrape data from websites that use javascript to render the content.&lt;/p&gt;
&lt;p&gt;Think about Facebook, Twitter, Instagram, etc. They use javascript to render the content. So we can't scrape them with normal tools like &lt;code&gt;requests&lt;/code&gt; or &lt;code&gt;scrapy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Selenium is a popular tool for scraping javascript websites. It's powerful, have a lot of features, but it's slow and hard to use.&lt;/p&gt;
&lt;p&gt;Playwright is a newplayer in this field. It's fast, have excelent simple API.&lt;/p&gt;
&lt;h2&gt;What is Pywright?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Pywright&lt;/strong&gt; is a API service writen in python that use Playwright to render javascript websites. You can easily deploy it to any cloud provider then use it as a service.&lt;/p&gt;
&lt;h2&gt;Install Pywright&lt;/h2&gt;
&lt;p&gt;I've created a docker image for Playwright. It's contain a simple Flask API server, so you can use it as a microservice.&lt;/p&gt;
&lt;p&gt;I will create only 2 &lt;code&gt;workers&lt;/code&gt; by default, you can change it by setting &lt;code&gt;WORKERS&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;h2&gt;How to use Pywright&lt;/h2&gt;
&lt;p&gt;Just use &lt;code&gt;POST&lt;/code&gt; method to send a request to the server at endpoint &lt;code&gt;/scrape&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The request body must be a JSON object with 1 field: &lt;code&gt;url&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://ipinfo.io&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The response will be a HTML string of the website.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;Example with &lt;code&gt;httpie&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;http://localhost:5000/scrape&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://ipinfo.io
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or with &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Content-Type: application/json&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{&amp;quot;url&amp;quot;: &amp;quot;https://ipinfo.io&amp;quot;}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http://localhost:5000/scrape
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or with &lt;code&gt;requests&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://localhost:5000/scrape&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://ipinfo.io&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="playwright"></category><category term="python"></category><category term="scraping"></category><category term="tutorial"></category><category term="pywright"></category></entry><entry><title>Deploy "The Lounge" on Fly.io</title><link href="https://doanhtu.com/article/deploy-the-lounge-on-flyio/" rel="alternate"></link><published>2022-11-17T21:59:00+07:00</published><updated>2022-11-17T21:59:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-11-17:/article/deploy-the-lounge-on-flyio/</id><summary type="html">&lt;h2&gt;What is "The Lounge"?&lt;/h2&gt;
&lt;p&gt;"The Lounge" is a self-hosted web IRC client. It's a fork of Shout, which is no longer maintained. The Lounge is actively maintained and has a lot of features.&lt;/p&gt;
&lt;p&gt;Screen shot:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The Lounge" src="https://thelounge.chat/img/thelounge-screenshot.png"&gt;&lt;/p&gt;
&lt;p&gt;Website:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://thelounge.chat/"&gt;https://thelounge.chat/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Deploy on Fly.io&lt;/h2&gt;
&lt;p&gt;Follow these steps to deploy "The Lounge" on Fly.io:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Create Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;thelounge/thelounge:latest&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;9000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2. Create new Fly.io app&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;fly launch&lt;/code&gt; and follow the instruction. You can choose any name and server region you want.&lt;/p&gt;
&lt;p&gt;Or you can copy this &lt;code&gt;fly.toml&lt;/code&gt; file (replace &lt;code&gt;&amp;lt;app-name&amp;gt;&lt;/code&gt; with your app name):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# fly.toml file generated for iirc on 2022-11-17T21:46:27+07:00&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;app-name&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;kill_signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SIGINT&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;kill_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;[env]&lt;/span&gt;

&lt;span class="k"&gt;[experimental]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;allowed_public_ports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;auto_rollback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="k"&gt;[mounts]&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ircdata&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/opt/thelounge&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;[[services]]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;http_checks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;internal_port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9000&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;app&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tcp&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;script_checks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[services.concurrency]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hard_limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;soft_limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;connections&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[[services.ports]]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;force_https …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;What is "The Lounge"?&lt;/h2&gt;
&lt;p&gt;"The Lounge" is a self-hosted web IRC client. It's a fork of Shout, which is no longer maintained. The Lounge is actively maintained and has a lot of features.&lt;/p&gt;
&lt;p&gt;Screen shot:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The Lounge" src="https://thelounge.chat/img/thelounge-screenshot.png"&gt;&lt;/p&gt;
&lt;p&gt;Website:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://thelounge.chat/"&gt;https://thelounge.chat/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Deploy on Fly.io&lt;/h2&gt;
&lt;p&gt;Follow these steps to deploy "The Lounge" on Fly.io:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Create Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;thelounge/thelounge:latest&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;9000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2. Create new Fly.io app&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;fly launch&lt;/code&gt; and follow the instruction. You can choose any name and server region you want.&lt;/p&gt;
&lt;p&gt;Or you can copy this &lt;code&gt;fly.toml&lt;/code&gt; file (replace &lt;code&gt;&amp;lt;app-name&amp;gt;&lt;/code&gt; with your app name):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# fly.toml file generated for iirc on 2022-11-17T21:46:27+07:00&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;app-name&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;kill_signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SIGINT&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;kill_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;[env]&lt;/span&gt;

&lt;span class="k"&gt;[experimental]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;allowed_public_ports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;auto_rollback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="k"&gt;[mounts]&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ircdata&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/opt/thelounge&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;[[services]]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;http_checks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;internal_port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9000&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;app&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tcp&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;script_checks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[services.concurrency]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hard_limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;soft_limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;connections&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[[services.ports]]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;force_https&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[[services.ports]]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tls&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;[[services.tcp_checks]]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;grace_period&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1s&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;15s&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;restart_limit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2s&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3. Create new volume&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You need to create a new volume to store data. The Lounge will store all data in &lt;code&gt;/var/opt/thelounge&lt;/code&gt; folder.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fly&lt;span class="w"&gt; &lt;/span&gt;volumes&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;ircdata&lt;span class="w"&gt; &lt;/span&gt;--region&lt;span class="w"&gt; &lt;/span&gt;sin&lt;span class="w"&gt; &lt;/span&gt;--size&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I've added &lt;code&gt;[mount]&lt;/code&gt; section to my &lt;code&gt;fly.toml&lt;/code&gt; file above.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[mounts]&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ircdata&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/opt/thelounge&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;4. Deploy&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fly&lt;span class="w"&gt; &lt;/span&gt;deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;5. Create new user&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fly&lt;span class="w"&gt; &lt;/span&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;console&lt;span class="w"&gt; &lt;/span&gt;-C&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;su -s /bin/sh node&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then run this command to create new user:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;thelounge&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;6. Access&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can access your "The Lounge" at &lt;code&gt;&amp;lt;app-name&amp;gt;.fly.dev&lt;/code&gt;. Or run &lt;code&gt;fly open&lt;/code&gt; to open it in your browser.&lt;/p&gt;
&lt;p&gt;Good luck and have fun.&lt;/p&gt;</content><category term="Programming"></category><category term="fly.io"></category><category term="server"></category><category term="irc"></category><category term="howto"></category></entry><entry><title>Fly.io - perfect solution</title><link href="https://doanhtu.com/article/flyio-perfect-solution/" rel="alternate"></link><published>2022-11-07T09:47:00+07:00</published><updated>2022-11-07T09:47:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-11-07:/article/flyio-perfect-solution/</id><summary type="html">&lt;h2&gt;Fly.io - A review&lt;/h2&gt;
&lt;p&gt;After a month trying Fly.io, I must say that:&lt;/p&gt;
&lt;p&gt;&lt;span class="underline"&gt;Fly.io is &lt;strong&gt;awesome!&lt;/strong&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After a year using Hosthatch, I tired of their terrible uptime, sometime the servers is down for 2 days. I'm not sure why, but I'm sure that I'm not going back to them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Luckily, I've found Fly.io. It's cheap, fast and reliable. I'm moving all my services to Fly.io. And to be honest, it's so easy that make me feel like I'm cheating.&lt;/p&gt;
&lt;h2&gt;Guide to migrate&lt;/h2&gt;
&lt;p&gt;If you have a Dockerfile for your service, you can migrate to Fly.io in 5 minutes.&lt;/p&gt;
&lt;p&gt;Here are some examples.&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/dani-garcia/vaultwarden"&gt;Vaultwarden (No Postgres, No Redis)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Create Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;vaultwarden/server:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Launch a new app&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;fly launch&lt;/code&gt; and follow the instruction. You can choose any name and server region you want.&lt;/p&gt;
&lt;p&gt;After deployed, you can access at &lt;code&gt;&amp;lt;app-name&amp;gt;.fly.dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create new …&lt;/strong&gt;&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Fly.io - A review&lt;/h2&gt;
&lt;p&gt;After a month trying Fly.io, I must say that:&lt;/p&gt;
&lt;p&gt;&lt;span class="underline"&gt;Fly.io is &lt;strong&gt;awesome!&lt;/strong&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After a year using Hosthatch, I tired of their terrible uptime, sometime the servers is down for 2 days. I'm not sure why, but I'm sure that I'm not going back to them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Luckily, I've found Fly.io. It's cheap, fast and reliable. I'm moving all my services to Fly.io. And to be honest, it's so easy that make me feel like I'm cheating.&lt;/p&gt;
&lt;h2&gt;Guide to migrate&lt;/h2&gt;
&lt;p&gt;If you have a Dockerfile for your service, you can migrate to Fly.io in 5 minutes.&lt;/p&gt;
&lt;p&gt;Here are some examples.&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/dani-garcia/vaultwarden"&gt;Vaultwarden (No Postgres, No Redis)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Create Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;vaultwarden/server:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Launch a new app&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;fly launch&lt;/code&gt; and follow the instruction. You can choose any name and server region you want.&lt;/p&gt;
&lt;p&gt;After deployed, you can access at &lt;code&gt;&amp;lt;app-name&amp;gt;.fly.dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create new volume&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Just need 1GB for now, you can scale later. Why 1GB? Because they give us 3GB storage for free every month. You can run 3 apps for free.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fly&lt;span class="w"&gt; &lt;/span&gt;volumes&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;vol-name&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;--region&lt;span class="w"&gt; &lt;/span&gt;sin&lt;span class="w"&gt; &lt;/span&gt;--size&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After created, add &lt;code&gt;[mount]&lt;/code&gt; section to your &lt;code&gt;fly.toml&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[mounts]&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;vol-name&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/data&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Set ENVs&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are 3 ways to set ENVs (Secrets) for your app:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;flyctl secrets set&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;[env]&lt;/code&gt; section in &lt;code&gt;fly.toml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cat .env | flyctl secrets import&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Deploy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;flyctl deploy&lt;/code&gt; to deploy your app.&lt;/p&gt;
&lt;p&gt;You can also use &lt;code&gt;flyctl deploy --no-cache&lt;/code&gt; to skip cached build, or &lt;code&gt;flyctl deploy --local-only&lt;/code&gt; to deploy using local docker.&lt;/p&gt;
&lt;p&gt;Then run &lt;code&gt;fly open&lt;/code&gt; to open &lt;code&gt;&amp;lt;app-name&amp;gt;.fly.dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Migrate data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can use the Web UI of Vaultwarden to export/import data as JSON format.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Config domain&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Root-domain&lt;/p&gt;
&lt;p&gt;The documentation has excellent guide for this. You can follow it &lt;a href="https://fly.io/blog/how-to-custom-domains-with-fly/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But I still copy a version here for lazy people like me.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Let&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;say&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Fly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;quartz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nx"&gt;flyctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;quartz&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;over&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DNS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AAAA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;records&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPv6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nx"&gt;flyctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;certs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;quartz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nx"&gt;flyctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;certs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;quartz&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;certificates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;being&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;issued&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//example.com and use your application with auto-renewing Let&amp;#39;s Encrypt TLS certificates, edge TLS, HTTP/2 support and more.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sub-domain&lt;/p&gt;
&lt;p&gt;First, execute &lt;code&gt;flyctl certs create &amp;lt;app-name&amp;gt;.&amp;lt;your-domain&amp;gt;.com&lt;/code&gt;. Then add a new CNAME record to your DNS provider, redirect to &lt;code&gt;&amp;lt;app-name&amp;gt;.fly.dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the result of &lt;code&gt;flyctl certs check &amp;lt;app-name&amp;gt;.&amp;lt;your-domain&amp;gt;.com&lt;/code&gt; look like this, you are successfully deployed Vaultwarden.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;.&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;.&lt;span class="nv"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;has&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;been&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;issued&lt;/span&gt;.
&lt;span class="nv"&gt;Hostname&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;.&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;.&lt;span class="nv"&gt;com&lt;/span&gt;

&lt;span class="nv"&gt;DNS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Provider&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cloudflare&lt;/span&gt;

&lt;span class="nv"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Authority&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Let&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;s Encrypt&lt;/span&gt;

&lt;span class="err"&gt;Issued                    = rsa,ecdsa&lt;/span&gt;

&lt;span class="err"&gt;Added to App              = 27 minutes ago&lt;/span&gt;

&lt;span class="err"&gt;Source                    = fly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Kudos to this &lt;a href="https://til.simonwillison.net/fly/custom-subdomain-fly"&gt;awesome article&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Tricks and tips&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Copy file to app server&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;flyctl&lt;span class="w"&gt; &lt;/span&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;sftp&lt;span class="w"&gt; &lt;/span&gt;shell
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then you can use &lt;code&gt;sftp&lt;/code&gt; command to copy file to app server. Example: &lt;code&gt;put &amp;lt;local-file&amp;gt; &amp;lt;remote-file&amp;gt;&lt;/code&gt; or &lt;code&gt;get &amp;lt;remote-file&amp;gt; &amp;lt;local-file&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I'll keep using it and write more review/guide later. If you have any question, feel free to ask me.&lt;/p&gt;</content><category term="Programming"></category><category term="fly.io"></category><category term="server"></category><category term="review"></category><category term="awesome"></category></entry><entry><title>Django Signal + Celery</title><link href="https://doanhtu.com/article/django-signal-celery/" rel="alternate"></link><published>2022-07-20T10:31:00+07:00</published><updated>2022-07-20T10:31:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-07-20:/article/django-signal-celery/</id><content type="html">&lt;p&gt;Nếu bạn muốn dùng Celery task trong các Signals của Django, bạn cần làm như sau để tránh tình trạng bắn task quá nhanh, khiến bên trong &lt;code&gt;task&lt;/code&gt; nếu query &lt;code&gt;pk=id&lt;/code&gt; sẽ bị lỗi NotFound (do dữ liệu chưa kịp lưu vào database).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;

&lt;span class="nd"&gt;@receiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_model_post_save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ở đây ta đợi transaction commit xong mới chạy task. Problem solved.&lt;/p&gt;</content><category term="Programming"></category><category term="django"></category><category term="celery"></category></entry><entry><title>Suy ngẫm về sự Ngẫu nhiên</title><link href="https://doanhtu.com/article/suy-ngam-ve-su-ngau-nhien/" rel="alternate"></link><published>2022-06-26T11:13:00+07:00</published><updated>2022-06-26T11:13:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-06-26:/article/suy-ngam-ve-su-ngau-nhien/</id><summary type="html">&lt;h1&gt;Ngẫu nhiên là gì?&lt;/h1&gt;
&lt;p&gt;&lt;span class="red-underline"&gt;&lt;a href="https://vi.m.wikipedia.org/wiki/Ng%E1%BA%ABu_nhi%C3%AAn"&gt;&lt;em&gt;Ngẫu nhiên&lt;/em&gt;&lt;/a&gt;&lt;/span&gt; (&lt;a href="https://en.m.wikipedia.org/wiki/Randomness"&gt;randomness&lt;/a&gt;),
một ý tưởng nền móng cho sự phát triển của khoa học, được định nghĩa trên wiki như sau:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/ngau-nhien.png" /&gt;&lt;/p&gt;
&lt;p&gt;Và nó hoàn toàn đúng. Loài người đã từ chỗ không biết gì đến sự ngẫu nhiên, cho đến khi lợi dụng được nó để phát triển vượt bậc.&lt;/p&gt;
&lt;p&gt;Đầu óc chúng ta không được thiết kế để có cái gọi là &lt;em&gt;giác quan&lt;/em&gt; (intuition) về sự ngẫu nhiên, mặc dù nó xảy ra liên tục trong cuộc sống của mỗi người.
Vì thực ra ý tưởng này mới được khái quát bằng toán gần đây (từ thế kỷ 16), nên điều này hoàn toàn có thể hiểu được.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/randomness-history.png" /&gt;&lt;/p&gt;
&lt;p&gt;Nếu toán là logic cho sự &lt;span class="circle"&gt;chắc chắn&lt;/span&gt; (certainty), thì xác xuất là logic cho sự &lt;span class="circle"&gt;bất định&lt;/span&gt; (uncertainty).&lt;/p&gt;
&lt;p&gt;Nghĩa là sao?&lt;/p&gt;
&lt;h1&gt;So sánh&lt;/h1&gt;
&lt;p&gt;Toán được xây dựng trên cơ sở các số nguyên, ví …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Ngẫu nhiên là gì?&lt;/h1&gt;
&lt;p&gt;&lt;span class="red-underline"&gt;&lt;a href="https://vi.m.wikipedia.org/wiki/Ng%E1%BA%ABu_nhi%C3%AAn"&gt;&lt;em&gt;Ngẫu nhiên&lt;/em&gt;&lt;/a&gt;&lt;/span&gt; (&lt;a href="https://en.m.wikipedia.org/wiki/Randomness"&gt;randomness&lt;/a&gt;),
một ý tưởng nền móng cho sự phát triển của khoa học, được định nghĩa trên wiki như sau:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/ngau-nhien.png" /&gt;&lt;/p&gt;
&lt;p&gt;Và nó hoàn toàn đúng. Loài người đã từ chỗ không biết gì đến sự ngẫu nhiên, cho đến khi lợi dụng được nó để phát triển vượt bậc.&lt;/p&gt;
&lt;p&gt;Đầu óc chúng ta không được thiết kế để có cái gọi là &lt;em&gt;giác quan&lt;/em&gt; (intuition) về sự ngẫu nhiên, mặc dù nó xảy ra liên tục trong cuộc sống của mỗi người.
Vì thực ra ý tưởng này mới được khái quát bằng toán gần đây (từ thế kỷ 16), nên điều này hoàn toàn có thể hiểu được.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/randomness-history.png" /&gt;&lt;/p&gt;
&lt;p&gt;Nếu toán là logic cho sự &lt;span class="circle"&gt;chắc chắn&lt;/span&gt; (certainty), thì xác xuất là logic cho sự &lt;span class="circle"&gt;bất định&lt;/span&gt; (uncertainty).&lt;/p&gt;
&lt;p&gt;Nghĩa là sao?&lt;/p&gt;
&lt;h1&gt;So sánh&lt;/h1&gt;
&lt;p&gt;Toán được xây dựng trên cơ sở các số nguyên, ví dụ 1, 2, 3, 4 ... nghĩa là đếm được. Vì đấy là cách sớm nhất là nguyên thủy nhất con người được làm quen với toán.&lt;/p&gt;
&lt;p&gt;Sau đó ta đặt các biến, ví dụ như&lt;/p&gt;
&lt;p&gt;&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math display="block" xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mspace linebreak="newline"&gt;&lt;/mspace&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mspace linebreak="newline"&gt;&lt;/mspace&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;
x = 1 \\
y = 2 \\
z = x + y
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6444em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace newline"&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.625em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;y&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6444em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace newline"&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.04398em;"&gt;z&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.625em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Toán dần dần tách biệt ra khỏi các con số. Nó bắt đầu dựa vào logic nhiều hơn.
Vì nếu ta có thể chứng minh được một định lý là đúng theo logic, thì nó sẽ luôn đúng trong mọi trường hợp.&lt;/p&gt;
&lt;p&gt;Với xác suất, ta cũng có thể đặt biến cho một sự việc ngẫu nhiên, gọi là biến ngẫu nhiên (random variable)&lt;/p&gt;
&lt;p&gt;&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math display="block" xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mtext&gt;s&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;a&lt;/mtext&gt;&lt;mo&gt;ˊ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt;ng ng&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;a&lt;/mtext&gt;&lt;mo&gt;ˋ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt;y 27/6/2022 c&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;o&lt;/mtext&gt;&lt;mo&gt;ˊ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt; mưa từ 9 đ&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;e&lt;/mtext&gt;&lt;mo&gt;ˆ&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;ˊ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt;n 12 giờ&lt;/mtext&gt;&lt;/mrow&gt;&lt;mspace linebreak="newline"&gt;&lt;/mspace&gt;&lt;mi&gt;Y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mtext&gt;quay x&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;u&lt;/mtext&gt;&lt;mo&gt;ˊ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt;c s&lt;/mtext&gt;&lt;mover accent="true"&gt;&lt;mover accent="true"&gt;&lt;mtext&gt;a&lt;/mtext&gt;&lt;mo&gt;˘&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;ˊ&lt;/mo&gt;&lt;/mover&gt;&lt;mtext&gt;c ra được mặt 6&lt;/mtext&gt;&lt;/mrow&gt;&lt;mspace linebreak="newline"&gt;&lt;/mspace&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;
X = \text{sáng ngày 27/6/2022 có mưa từ 9 đến 12 giờ} \\
Y = \text{quay xúc sắc ra được mặt 6} \\
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6833em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.07847em;"&gt;X&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.2079em;vertical-align:-0.25em;"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;s&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˊ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;ng ng&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˋ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;y 27/6/2022 c&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;o&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˊ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt; m&lt;/span&gt;&lt;span class="mord latin_fallback"&gt;ư&lt;/span&gt;&lt;span class="mord"&gt;a từ 9 &lt;/span&gt;&lt;span class="mord latin_fallback"&gt;đ&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.9579em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˆ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3.2634em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˊ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;n 12 giờ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace newline"&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6833em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.22222em;"&gt;Y&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.1523em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;quay x&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;u&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˊ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;c s&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.9579em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.6944em;"&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;˘&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3.2634em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="accent-body" style="left:-0.25em;"&gt;&lt;span class="mord"&gt;ˊ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;c ra &lt;/span&gt;&lt;span class="mord latin_fallback"&gt;đư&lt;/span&gt;&lt;span class="mord"&gt;ợc mặt 6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace newline"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Với mỗi biến trên, thay vì có kết quả là số, ta sẽ có kết quả là một &lt;em&gt;xác suất&lt;/em&gt; sự việc đấy xảy ra, có thể từ 0 (không thể xảy ra) đến 1 (chắc chắn xảy ra)&lt;/p&gt;
&lt;p&gt;Với xác suất cổ điển, khi coi mọi thứ có khả năng xảy ra là như nhau, thì việc tính toán khá dễ dàng nhưng không thực tế.&lt;/p&gt;
&lt;p&gt;Vì sao? Vì trên thực tế có quá nhiều yếu tố ảnh hưởng lẫn nhau, và khi có quá nhiều biến số, mỗi biến lại ảnh hưởng đến nhau theo một kiểu khác nhau thì tính toán được là điều không thể.&lt;/p&gt;
&lt;h1&gt;&lt;a href="https://www.yudkowsky.net/rational/bayes?repost3yearslater"&gt;Bayes Theorem&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Như đã nói trên, xác suất cổ điển là không thực tiễn. Những bộ óc vĩ đại như Newton cũng còn phạm sai lầm khi dính đến xác suất.&lt;/p&gt;
&lt;p&gt;Vào thế kỷ 17, một nhà thống kê học tên Thomas Bayes đã tìm ra được một định lý, mà định lý đó hiện giờ là hòn đá nền móng cho xác suất thống kê hiện đại.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/bayes-theorem.png" /&gt;&lt;/p&gt;
&lt;p&gt;Nói đơn giản ra thì ông tìm được bản chất của xác suất. Nếu bạn muốn tìm hiểu thêm thì mua quyển &lt;code&gt;How not to be wrong&lt;/code&gt; đọc nhé.&lt;/p&gt;
&lt;p&gt;Khi chúng ta hiểu được về xác suất, khoa học đã tiến bộ nhanh không tưởng.&lt;/p&gt;
&lt;p&gt;Vì khi chúng ta hi sinh một chút sự chính xác, thì sự thật bắt đầu dần được tiết lộ.&lt;/p&gt;
&lt;h1&gt;Quy luật và sự tương quan&lt;/h1&gt;
&lt;p&gt;Toán và xác suất giống nhau ở 1 chỗ, đó là nhằm tìm ra các quy luật và mối tương quan của vạn vật.&lt;/p&gt;
&lt;p&gt;Các quy luật đó được viết lại dưới dạng các ký tự toán học, để có thể truyền đạt được ý tưởng nhanh nhất và chính xác nhất có thể.&lt;/p&gt;
&lt;p&gt;Ví dụ như Euler Formula, một phương trình nhìn qua tưởng chừng đơn giản, nhưng đã &lt;a href="https://news.ycombinator.com/item?id=27392911"&gt;hợp nhất được 4 lĩnh vực&lt;/a&gt;: đại số, lượng giác, số phức, và tích phân.&lt;/p&gt;
&lt;p&gt;&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math display="block" xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;
e^{ix} = cos(x) + i sin(x)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8747em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.8747em;"&gt;&lt;span style="top:-3.113em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1em;vertical-align:-0.25em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;cos&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1em;vertical-align:-0.25em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Với &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;x=\pi&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, ta có Euler Identity&lt;/p&gt;
&lt;p&gt;&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math display="block" xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;
e^{i\pi} = -1
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8747em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.8747em;"&gt;&lt;span style="top:-3.113em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.03588em;"&gt;iπ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Với &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;τ&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;x=\tau=2\pi&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.1132em;"&gt;τ&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6444em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math display="block" xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;
e^{i\pi} = 1
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8747em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.8747em;"&gt;&lt;span style="top:-3.113em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.03588em;"&gt;iπ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6444em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From Chapter 22 of The Feynman Lectures on Physics, Volume I:&lt;/p&gt;
&lt;p&gt;"We summarize with this, the most remarkable formula in mathematics: &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;e^{i\theta} = cos(\theta) + i sin(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8491em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.8491em;"&gt;&lt;span style="top:-3.063em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1em;vertical-align:-0.25em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;cos&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1em;vertical-align:-0.25em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;br&gt;
This is our jewel.&lt;br&gt;
We may relate the geometry to the algebra by representing complex numbers in a plane; the horizontal position of a point is &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, the vertical position of a point is &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;y&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.625em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;br&gt;
We represent every complex number, &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;x + iy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.854em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Then if the radial distance to this point is called &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;r&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.4306em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;r&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and the angle is called &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, the algebraic law is that &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;x + iy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2222em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.854em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is written in the form &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;r e^{i\theta}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8491em;"&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;r&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.8491em;"&gt;&lt;span style="top:-3.063em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, where the geometrical relationships between &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mtext&gt;x, y, r, and &lt;/mtext&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\text{x, y, r, and }\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden="true" class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;x, y, r, and &lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal" style="margin-right:0.02778em;"&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; are as shown. This, then, is the unification of algebra and geometry."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Còn xác suất thì sao?&lt;/p&gt;
&lt;h1&gt;Bayes Modeling và Model Inference&lt;/h1&gt;
&lt;p&gt;Xác suất khác với toán ở chỗ, nó ko có một con số cụ thể cho bạn, mà chỉ cho bạn biết được một thứ gọi là &lt;a href="https://vi.m.wikipedia.org/wiki/Ph%C3%A2n_ph%E1%BB%91i_x%C3%A1c_su%E1%BA%A5t"&gt;phân phối&lt;/a&gt; (&lt;a href="https://en.m.wikipedia.org/wiki/Distribution_(mathematics)"&gt;distribution&lt;/a&gt;). Dùng &lt;em&gt;phân phối&lt;/em&gt; này bạn có thể tìm ra được quy luật giữa các dữ liệu đầu vào.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/linear-example.png" /&gt;
&lt;img src="https://doanhtu.com/static/images/distribution.png" /&gt;&lt;/p&gt;
&lt;p&gt;Ví dụ như, hút thuốc lá có tăng tỷ lệ ung thư không? Bạn đi tìm &lt;strong&gt;ngẫu nhiên&lt;/strong&gt; 100 người trên 18 tuổi, rồi tạo 1 bảng gồm 2 cột, 1 cột là có hút thuốc trên 1 năm hay ko, cột còn lại là có ung thư hay không. Sau khi tạo model và có kết quả, ta có thể xem được có mối tương quan hay không và có thể đưa ra hành động phù hợp.&lt;/p&gt;
&lt;p&gt;Đây là bước khởi đầu cho khoa học đích thực, sự hỗn loạn được công thức hóa, và con người có thể kiểm chứng nhiều giả thuyết của mình chính xác hơn.&lt;/p&gt;
&lt;h1&gt;Kỷ nguyên mới&lt;/h1&gt;
&lt;p&gt;Vấn đề bắt đầu khi bạn có quá nhiều dữ liệu. Nhưng giỏi ứng biến, những người khai phá internet thời đầu đã bắt đầu manh nha biến đống dữ liệu đấy thành mỏ vàng.&lt;/p&gt;
&lt;p&gt;May mắn theo định luật Moore, công nghệ phát triển theo cấp số nhân, các thuật toán dùng để phân tích và dự đoán được đưa vào sử dụng để tìm ra quy luật.&lt;/p&gt;
&lt;p&gt;Và điều kỳ diệu bắt đầu xuất hiện. Những tác vụ đơn giản như nhận diện hình ảnh, tưởng chừng như không thể&lt;/p&gt;
&lt;p&gt;&lt;img src="https://imgs.xkcd.com/comics/tasks_2x.png" /&gt;&lt;/p&gt;
&lt;p&gt;thì giờ dùng điện thoại cũng có thể làm được.&lt;/p&gt;
&lt;p&gt;Cả một kỷ nguyên mới được mở ra cho nhân loại, nhờ lợi dụng được sự ngẫu nhiên. Nhưng, họ đã làm như thế nào?&lt;/p&gt;
&lt;h1&gt;Machine Learning &amp;amp; Deep Learning&lt;/h1&gt;
&lt;p&gt;&amp;lt;Đón xem phần 2&amp;gt;&lt;/p&gt;</content><category term="Math"></category><category term="random"></category><category term="life"></category></entry><entry><title>Contabo server review</title><link href="https://doanhtu.com/article/contabo-server-review/" rel="alternate"></link><published>2022-06-21T23:03:00+07:00</published><updated>2022-06-21T23:03:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-06-21:/article/contabo-server-review/</id><content type="html">&lt;h3&gt;A review&lt;/h3&gt;
&lt;p&gt;After a month trying Contabo, I must say that:&lt;/p&gt;
&lt;p&gt;&lt;span class="red-underline"&gt;Don't use their servers&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Their storage bandwith policy is good, I will keep continue using it. But no way I'm go back for their server.&lt;/p&gt;
&lt;p&gt;It's always down!&lt;/p&gt;
&lt;p&gt;I have no idea why.&lt;/p&gt;
&lt;p&gt;Their supporter is nice, but did not help.&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;I'm going to use HostHatch for an experiment.&lt;/p&gt;
&lt;p&gt;They have a lot of locations in Asia, like Hongkong, Singapore and Japan (with cheap price).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/hosthatch.png" /&gt;&lt;/p&gt;
&lt;p&gt;I'll comeback for more reviews.&lt;/p&gt;
&lt;p&gt;You can register with my affiliate link &lt;a href="https://cloud.hosthatch.com/a/2597"&gt;here&lt;/a&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="contabo"></category><category term="server"></category><category term="review"></category></entry><entry><title>Move Docker volumes to other server</title><link href="https://doanhtu.com/article/move-docker-volumes-to-other-server/" rel="alternate"></link><published>2022-06-02T18:43:00+07:00</published><updated>2022-06-02T18:43:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-06-02:/article/move-docker-volumes-to-other-server/</id><summary type="html">&lt;h3&gt;New home&lt;/h3&gt;
&lt;p&gt;I've been self-hosted a few services for my daily needs, and I choosed Hetzner because of their's pricing.&lt;/p&gt;
&lt;p&gt;But now after I know Contabo, I will move my services to Contabo, because it's cheaper and more powerful.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/contabo.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/hetzner.png" /&gt;&lt;/p&gt;
&lt;p&gt;I can reduce the server cost for about 30%. Neet.&lt;/p&gt;
&lt;p&gt;But I don't want to lose my data. And I don't want to spent a lot of time migrate things either.&lt;/p&gt;
&lt;p&gt;Luckily, all of my projects was deployed using Docker. If you don't know Docker, now is good time to start because it's awesome.&lt;/p&gt;
&lt;h3&gt;Moving data&lt;/h3&gt;
&lt;p&gt;Let's say I want to move from server A (Hetzner) to server B (Contabo)&lt;/p&gt;
&lt;p&gt;And my jobs now are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate ssh key (&lt;code&gt;ssh-keygen -t ed25519&lt;/code&gt;) and add public key to server B &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rsync -av&lt;/code&gt; my projects from A to B&lt;/li&gt;
&lt;li&gt;Find the right directory where Docker bind volumes with &lt;code&gt;docker inspect &amp;lt;container_name …&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;h3&gt;New home&lt;/h3&gt;
&lt;p&gt;I've been self-hosted a few services for my daily needs, and I choosed Hetzner because of their's pricing.&lt;/p&gt;
&lt;p&gt;But now after I know Contabo, I will move my services to Contabo, because it's cheaper and more powerful.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/contabo.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/hetzner.png" /&gt;&lt;/p&gt;
&lt;p&gt;I can reduce the server cost for about 30%. Neet.&lt;/p&gt;
&lt;p&gt;But I don't want to lose my data. And I don't want to spent a lot of time migrate things either.&lt;/p&gt;
&lt;p&gt;Luckily, all of my projects was deployed using Docker. If you don't know Docker, now is good time to start because it's awesome.&lt;/p&gt;
&lt;h3&gt;Moving data&lt;/h3&gt;
&lt;p&gt;Let's say I want to move from server A (Hetzner) to server B (Contabo)&lt;/p&gt;
&lt;p&gt;And my jobs now are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate ssh key (&lt;code&gt;ssh-keygen -t ed25519&lt;/code&gt;) and add public key to server B &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rsync -av&lt;/code&gt; my projects from A to B&lt;/li&gt;
&lt;li&gt;Find the right directory where Docker bind volumes with &lt;code&gt;docker inspect &amp;lt;container_name&amp;gt; | grep "Source"&lt;/code&gt;
   &lt;img src="https://doanhtu.com/static/images/inspect_docker.png" style="padding-top: 10px;" /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want to archive database&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;tar cvf&lt;/code&gt; everything inside &lt;code&gt;.../_data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rsync&lt;/code&gt; tar files to new server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tar xvf&lt;/code&gt; them to new &lt;code&gt;~/backup&lt;/code&gt; directory&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Build and up docker services&lt;/li&gt;
&lt;li&gt;Stop services&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rsync&lt;/code&gt; backup directory to binded directory path from &lt;code&gt;step 3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repeat step 4 for other services&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After that you can safely delete the extracted directories. Install &lt;code&gt;nginx&lt;/code&gt; and copy config files from A -&amp;gt; B.&lt;/p&gt;
&lt;p&gt;You might want to keep the &lt;code&gt;tar&lt;/code&gt; file for a bit longer to prevent issues.&lt;/p&gt;</content><category term="Programming"></category><category term="docker"></category><category term="server"></category><category term="volume"></category></entry><entry><title>Trick for Python dev</title><link href="https://doanhtu.com/article/trick-for-python-dev/" rel="alternate"></link><published>2022-05-03T10:27:00+07:00</published><updated>2022-05-03T10:27:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-05-03:/article/trick-for-python-dev/</id><content type="html">&lt;p&gt;If you are a Python dev, I will share with you this trick to avoid future Python related problems.&lt;/p&gt;
&lt;p&gt;After install a new, fresh OS, you should install those &lt;a href="https://github.com/pyenv/pyenv/wiki#suggested-build-environment"&gt;dependencies&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Example, after installed a new Ubuntu for my PC, I will run this command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;build-essential&lt;span class="w"&gt; &lt;/span&gt;libssl-dev&lt;span class="w"&gt; &lt;/span&gt;zlib1g-dev&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
libbz2-dev&lt;span class="w"&gt; &lt;/span&gt;libreadline-dev&lt;span class="w"&gt; &lt;/span&gt;libsqlite3-dev&lt;span class="w"&gt; &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;llvm&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
libncursesw5-dev&lt;span class="w"&gt; &lt;/span&gt;xz-utils&lt;span class="w"&gt; &lt;/span&gt;tk-dev&lt;span class="w"&gt; &lt;/span&gt;libxml2-dev&lt;span class="w"&gt; &lt;/span&gt;libxmlsec1-dev&lt;span class="w"&gt; &lt;/span&gt;libffi-dev&lt;span class="w"&gt; &lt;/span&gt;liblzma-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then I will install &lt;code&gt;pyenv&lt;/code&gt;, which I think is the best python version management system.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-L&lt;span class="w"&gt; &lt;/span&gt;https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And I never have a problem with Python anymore.&lt;/p&gt;</content><category term="Programming"></category><category term="python"></category><category term="pyenv"></category></entry><entry><title>Awesome Machine Learning Resource</title><link href="https://doanhtu.com/article/awesome-machine-learning-resource/" rel="alternate"></link><published>2022-04-22T10:57:00+07:00</published><updated>2022-04-22T10:57:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-04-22:/article/awesome-machine-learning-resource/</id><content type="html">&lt;ol&gt;
&lt;li&gt;Articles&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://blog.floydhub.com/n-shot-learning/"&gt;What is n-shot learning?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://paperswithcode.com/sota"&gt;Meta AI State-of-the-art&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://uvadlc-notebooks.readthedocs.io/en/latest/index.html"&gt;UvA Deep Learning Tutorial&lt;/a&gt;&lt;/p&gt;</content><category term="MachineLearning"></category><category term="machine learning"></category><category term="awesome"></category></entry><entry><title>What is mask attention?</title><link href="https://doanhtu.com/article/what-is-mask-attention/" rel="alternate"></link><published>2022-04-15T15:50:00+07:00</published><updated>2022-04-15T15:50:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-04-15:/article/what-is-mask-attention/</id><content type="html">&lt;p&gt;&lt;a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/"&gt;Visualizing A Neural Machine Translation Model (Mechanics of Seq2seq Models With Attention)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Under the hood, the model is composed of an &lt;span class="underline"&gt;encoder&lt;/span&gt; and a &lt;span class="circle"&gt;decoder&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class="bracket"&gt;The encoder processes each item in the input sequence, it compiles the information it captures into a vector (called the context). After processing the entire input sequence, the encoder sends the context over to the decoder, which begins producing the output sequence item by item.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=UNmqTiOnRfg"&gt;A friendly introduction to Recurrent Neural Networks&lt;/a&gt;
&lt;br&gt;&lt;/p&gt;</content><category term="MachineLearning"></category><category term="machine learning"></category><category term="deep learning"></category><category term="python"></category><category term="pytorch"></category></entry><entry><title>Kaggle Bird Classification with sound</title><link href="https://doanhtu.com/article/kaggle-bird-classification-with-sound/" rel="alternate"></link><published>2022-04-08T16:36:00+07:00</published><updated>2022-04-08T16:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2022-04-08:/article/kaggle-bird-classification-with-sound/</id><summary type="html">&lt;h1&gt;Problem&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://www.kaggle.com/competitions/birdclef-2022/overview"&gt;Kaggle url&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As the “extinction capital of the world,” Hawai'i has lost 68% of its bird species, the consequences of which can harm entire food chains. Researchers use population monitoring to understand how native birds react to changes in the environment and conservation efforts. But many of the remaining birds across the islands are isolated in difficult-to-access, high-elevation habitats. With physical monitoring difficult, scientists have turned to sound recordings. Known as bioacoustic monitoring, this approach could provide a passive, low labor, and cost-effective strategy for studying endangered bird populations.&lt;/p&gt;
&lt;p&gt;Current methods for processing large bioacoustic datasets involve manual annotation of each recording. This requires specialized training and prohibitively large amounts of time. Thankfully, recent advances in machine learning have made it possible to automatically identify bird songs for common species with ample training data. However, it remains challenging to develop such tools for rare and endangered species, such as …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;h1&gt;Problem&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://www.kaggle.com/competitions/birdclef-2022/overview"&gt;Kaggle url&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As the “extinction capital of the world,” Hawai'i has lost 68% of its bird species, the consequences of which can harm entire food chains. Researchers use population monitoring to understand how native birds react to changes in the environment and conservation efforts. But many of the remaining birds across the islands are isolated in difficult-to-access, high-elevation habitats. With physical monitoring difficult, scientists have turned to sound recordings. Known as bioacoustic monitoring, this approach could provide a passive, low labor, and cost-effective strategy for studying endangered bird populations.&lt;/p&gt;
&lt;p&gt;Current methods for processing large bioacoustic datasets involve manual annotation of each recording. This requires specialized training and prohibitively large amounts of time. Thankfully, recent advances in machine learning have made it possible to automatically identify bird songs for common species with ample training data. However, it remains challenging to develop such tools for rare and endangered species, such as those in Hawai'i.&lt;/p&gt;
&lt;p&gt;The Cornell Lab of Ornithology's K. Lisa Yang Center for Conservation Bioacoustics (KLY-CCB) develops and applies innovative conservation technologies across multiple ecological scales to inspire and inform the conservation of wildlife and habitats. KLY-CCB does this by collecting and interpreting sounds in nature and they've joined forces with Google Bioacoustics Group, LifeCLEF, Listening Observatory for Hawaiian Ecosystems (LOHE) Bioacoustics Lab at the University of Hawai'i at Hilo, and Xeno-Canto for this competition.&lt;/p&gt;
&lt;p&gt;In this competition, you’ll use your machine learning skills to identify bird species by sound. Specifically, you'll develop a model that can process continuous audio data and then acoustically recognize the species. The best entries will be able to train reliable classifiers with limited training data.&lt;/p&gt;
&lt;p&gt;If successful, you'll help advance the science of bioacoustics and support ongoing research to protect endangered Hawaiian birds. Thanks to your innovations, it will be easier for researchers and conservation practitioners to accurately survey population trends. They'll be able to regularly and more effectively evaluate threats and adjust their conservation actions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Thinking&lt;/h1&gt;
&lt;p&gt;After reading, I have no clue what to do. Thus I have to learn from the others. I look up from the leaderboard, and almost all of them do not have any public code.
Fair enough, since this is a competition with big reward.&lt;/p&gt;
&lt;p&gt;But then I found someone interesting.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://doanhtu.com/static/images/vlome.png" /&gt;&lt;/p&gt;
&lt;p&gt;Do notice he has &lt;code&gt;Code(6)&lt;/code&gt;. And we see one of his old notebook:&lt;/p&gt;
&lt;p&gt;https://www.kaggle.com/code/vlomme/surfin-bird-2nd-place&lt;/p&gt;
&lt;p&gt;Seem like this guy understand bird sound and deep learning. And at the time of this writing, he is the second place of the leaderboard.&lt;/p&gt;
&lt;p&gt;So now to have a place in this competition, we learn from him first. Then improve later.&lt;/p&gt;</content><category term="MachineLearning"></category><category term="machine learning"></category><category term="deep learning"></category><category term="kaggle"></category><category term="python"></category><category term="pytorch"></category></entry><entry><title>Overcome the fear</title><link href="https://doanhtu.com/article/overcome-the-fear/" rel="alternate"></link><published>2021-07-27T09:36:00+07:00</published><updated>2021-07-27T09:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-07-27:/article/overcome-the-fear/</id><summary type="html">&lt;p&gt;One day you don't know what to do anymore. The future is so unpredictable. Too much choices. You must make the decission.&lt;/p&gt;
&lt;p&gt;Yes, the &lt;strong&gt;pain&lt;/strong&gt; is real. The fear is real. You want to run away from it. Why should you suffer from those horrible feelings? You can find other thing to do, the "easier" things.&lt;/p&gt;
&lt;p&gt;But don't.&lt;/p&gt;
&lt;p&gt;Because each time you let them scare you aways, you learned nothing. You are not improved. &lt;em&gt;You are not lived&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Change is hard. Makes you feel like everything you have done is wrong. You're failed. You must find a new way, a new approach, a new mindset to achieve your goal.&lt;/p&gt;
&lt;p&gt;It sucks. But it's neccessery. It's the way nature works. Improvise, adapt, overcome.&lt;/p&gt;
&lt;p&gt;And after all the hard works, the map of the real world will be updated. You know how things works now. It's awesome.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;/p&gt;
&lt;video controls width="550" loop autoplay="autoplay" muted&gt;
&lt;source src="https://doanhtu.com/static/webm/future.webm" type="video/webm"&gt;
Scene from Billions S03E04
&lt;/video&gt;
&lt;p&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;But …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One day you don't know what to do anymore. The future is so unpredictable. Too much choices. You must make the decission.&lt;/p&gt;
&lt;p&gt;Yes, the &lt;strong&gt;pain&lt;/strong&gt; is real. The fear is real. You want to run away from it. Why should you suffer from those horrible feelings? You can find other thing to do, the "easier" things.&lt;/p&gt;
&lt;p&gt;But don't.&lt;/p&gt;
&lt;p&gt;Because each time you let them scare you aways, you learned nothing. You are not improved. &lt;em&gt;You are not lived&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Change is hard. Makes you feel like everything you have done is wrong. You're failed. You must find a new way, a new approach, a new mindset to achieve your goal.&lt;/p&gt;
&lt;p&gt;It sucks. But it's neccessery. It's the way nature works. Improvise, adapt, overcome.&lt;/p&gt;
&lt;p&gt;And after all the hard works, the map of the real world will be updated. You know how things works now. It's awesome.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;/p&gt;
&lt;video controls width="550" loop autoplay="autoplay" muted&gt;
&lt;source src="https://doanhtu.com/static/webm/future.webm" type="video/webm"&gt;
Scene from Billions S03E04
&lt;/video&gt;
&lt;p&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;But it's a loop. Your believes may colapse again. The world changes. You must change, either.&lt;/p&gt;
&lt;p&gt;I love this quote from Keynes. &lt;strong&gt;"When the facts change, I change my mind - what do you do, sir?"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And you sir, should do the same.&lt;/p&gt;</content><category term="Life"></category></entry><entry><title>Django full text search (Postgres)</title><link href="https://doanhtu.com/article/django-full-text-search-postgres/" rel="alternate"></link><published>2021-05-24T11:18:00+07:00</published><updated>2021-05-24T11:18:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-05-24:/article/django-full-text-search-postgres/</id><summary type="html">&lt;p&gt;Let's say we have a large database, few milions row, one-to-many relationship models with some text field, and we want to &lt;strong&gt;search&lt;/strong&gt; some keywords.&lt;/p&gt;
&lt;p&gt;Traditional way will be real pain and slow, I know. So let's do something smart and enjoy lightning-fast execution with &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/search/"&gt;Full Text Search&lt;/a&gt;.&lt;/p&gt;
&lt;img alt="" src="https://media.giphy.com/media/10vA3MTGTKeb16/giphy.gif" style="width: 500px;" /&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Suppose we have an app named &lt;cite&gt;main&lt;/cite&gt; and it's models look like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Parent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;children&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, we want to search &lt;em&gt;keyword&lt;/em&gt; in childs content, and we want to do it quick! You can do like &lt;a class="reference external" href="https://stackoverflow.com/questions/40405003/django-postgres-full-text-search-in-reverse-related-models"&gt;this&lt;/a&gt;, but that not quick enough for me. Maybe because I have too damn much data. But there are other way. First we need to add this line to &lt;cite&gt;settings.py&lt;/cite&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;django.contrib.postgres …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Let's say we have a large database, few milions row, one-to-many relationship models with some text field, and we want to &lt;strong&gt;search&lt;/strong&gt; some keywords.&lt;/p&gt;
&lt;p&gt;Traditional way will be real pain and slow, I know. So let's do something smart and enjoy lightning-fast execution with &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/search/"&gt;Full Text Search&lt;/a&gt;.&lt;/p&gt;
&lt;img alt="" src="https://media.giphy.com/media/10vA3MTGTKeb16/giphy.gif" style="width: 500px;" /&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Suppose we have an app named &lt;cite&gt;main&lt;/cite&gt; and it's models look like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Parent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;children&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, we want to search &lt;em&gt;keyword&lt;/em&gt; in childs content, and we want to do it quick! You can do like &lt;a class="reference external" href="https://stackoverflow.com/questions/40405003/django-postgres-full-text-search-in-reverse-related-models"&gt;this&lt;/a&gt;, but that not quick enough for me. Maybe because I have too damn much data. But there are other way. First we need to add this line to &lt;cite&gt;settings.py&lt;/cite&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;django.contrib.postgres&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
 &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we add &lt;cite&gt;SearchVectorField&lt;/cite&gt; to the model&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;search_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SearchVectorField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally we can create index&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.postgres.search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SearchVectorField&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.postgres.indexes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GinIndex&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;search_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SearchVectorField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;indexes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GinIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;search_vector&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now for the old data, we need to run this line to update their search vector, you may run this as a script or run it in &lt;cite&gt;python manage.py shell&lt;/cite&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.postgres.search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SearchVector&lt;/span&gt;

&lt;span class="n"&gt;Child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_vector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SearchVector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That will do the trick. Now you can search like a pro, high accuracy and high performance.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_vector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_vector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;parent&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# To get all parent objects, for various purposes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You may think, &amp;quot;Oh, simple and elegant, like the way nature should be&amp;quot;. But that's not it. We not done yet. We need to &lt;strong&gt;update search vector for new created objects&lt;/strong&gt; too. And we'll using the power of &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/signals/"&gt;Django Signal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let's create a file &lt;cite&gt;signals.py&lt;/cite&gt; inside &lt;cite&gt;main&lt;/cite&gt; directory, and fill it with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db.models.signals&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;post_save&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.dispatch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.postgres.search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SearchVector&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;main.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Child&lt;/span&gt;

&lt;span class="nd"&gt;@receiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_search_vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;Child&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_vector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SearchVector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You may ask &amp;quot;Why not just assign &lt;code&gt;instance.search_vector=SearchVector('content')&lt;/code&gt; then &lt;code&gt;instance.save()&lt;/code&gt;?&amp;quot;. Good question, but we can not do that. You may try and got this error&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;F&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;expressions&lt;span class="w"&gt; &lt;/span&gt;can&lt;span class="w"&gt; &lt;/span&gt;only&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;used&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;update,&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;insert.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Search and read the reasons. Last thing, we need to register the signal to our app. Update the file &lt;cite&gt;main/apps.py&lt;/cite&gt; to add this line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;main.signals&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then &lt;cite&gt;main/__init__.py&lt;/cite&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;default_app_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;main.apps.MainConfig&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we are officially done. Good luck.&lt;/p&gt;
</content><category term="Math"></category><category term="django"></category><category term="postgres"></category><category term="index"></category><category term="full"></category><category term="text"></category><category term="search"></category></entry><entry><title>PyMC3 install tips (Ubuntu 20.04)</title><link href="https://doanhtu.com/article/pymc3-install-tips-ubuntu-2004/" rel="alternate"></link><published>2021-03-23T11:58:00+07:00</published><updated>2021-03-23T11:58:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-03-23:/article/pymc3-install-tips-ubuntu-2004/</id><content type="html">&lt;p&gt;To install and use PyMC3 with pyenv without Theano error, when install python you need to add flag &lt;strong&gt;CONFIGURE_OPTS=--enable-shared&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Example:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;CONFIGURE_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;--enable-shared&lt;span class="w"&gt; &lt;/span&gt;pyenv&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;.8.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Source: https://stackoverflow.com/questions/21342931/error-importing-theano&lt;/p&gt;</content><category term="Programming"></category><category term="pymc3"></category><category term="theano"></category><category term="install"></category></entry><entry><title>Move docker data to another location (Ubuntu)</title><link href="https://doanhtu.com/article/move-docker-data-to-another-location-ubuntu/" rel="alternate"></link><published>2021-03-18T20:12:00+07:00</published><updated>2021-03-18T20:12:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-03-18:/article/move-docker-data-to-another-location-ubuntu/</id><content type="html">&lt;p&gt;Goal: I want to move my existing Docker data to new location (&lt;em&gt;/mnt/Data&lt;/em&gt;), for more free space.&lt;/p&gt;
&lt;p&gt;Solution:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Stop Docker service&lt;br&gt;
&lt;code&gt;sudo systemctl stop docker&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; and insert this  &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;graph&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/mnt/Data/docker&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Move old data to new location&lt;br&gt;
&lt;code&gt;sudo rsync -aqxP /var/lib/docker /media/Data/&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Temporary move old data to other directory&lt;br&gt;
&lt;code&gt;sudo mv /var/lib/docker /var/lib/docker.old&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start docker service&lt;br&gt;
&lt;code&gt;sudo systemctl start docker&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check new config work&lt;br&gt;
&lt;code&gt;docker info | grep -i root&lt;/code&gt;
This should output new location&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove old data  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Profit&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;P/s: I'm using Docker version &lt;strong&gt;20.10.6&lt;/strong&gt;, build 370c289&lt;/p&gt;</content><category term="Programming"></category><category term="docker"></category><category term="install"></category></entry><entry><title>Khiêm tốn mà học</title><link href="https://doanhtu.com/article/khiem-ton-ma-hoc/" rel="alternate"></link><published>2021-03-05T22:04:00+07:00</published><updated>2021-03-05T22:04:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-03-05:/article/khiem-ton-ma-hoc/</id><content type="html">&lt;p&gt;Càng lớn bạn sẽ càng mất kiên nhẫn khi học một thứ gì mới, nhất là những thứ căn bản.
Nhưng càng căn bản càng phải chắc chắn, chớ có suy nghĩ mình biết hết rồi và hãy lắng nghe tập trung hơn.&lt;/p&gt;</content><category term="Life"></category></entry><entry><title>DSK - Khuyên</title><link href="https://doanhtu.com/article/dsk-khuyen/" rel="alternate"></link><published>2021-02-24T21:38:00+07:00</published><updated>2021-02-24T21:38:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-02-24:/article/dsk-khuyen/</id><summary type="html">&lt;p&gt;Đốt thêm điếu nữa ông êi&lt;/p&gt;
&lt;div&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/NbRUexrPNrU?start=213" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Đôi khi khi đối diện với tử thần thì cái mình cần là chữ nhẫn&lt;/div&gt;
&lt;div class="line"&gt;Đời lắm lời khuyên nhưng bố mày đéo cần tư ... vấn (Oh)&lt;/div&gt;
&lt;div class="line"&gt;Tao có một ước mơ, tao mong mấy thằng ra vẻ cử nhân chúng mày đi tự vẫn,&lt;/div&gt;
&lt;div class="line"&gt;vì mấy thằng ngu thì chém gió như thần.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="line"&gt;Lời khuyên: đôi lúc là vô giá đôi lúc lại đéo có ... giá trị,&lt;/div&gt;
&lt;div class="line"&gt;đôi lúc là méo mó vẹo vọ và đéo có khả thi, cái lời khuyên&lt;/div&gt;
&lt;div class="line"&gt;nghèo khó chỉ được mỗi cái hoa mĩ.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="line"&gt;Khuyên đéo mất tiền (nên) bọn mày hát như là ca sĩ (oh)&lt;/div&gt;
&lt;div class="line"&gt;Những cái mồm ung thư cần hóa trị&lt;/div&gt;
&lt;div class="line"&gt;Những lời khuyên trọc lóc, lời khuyên rụng và lời khuyên không mọc tóc&lt;/div&gt;
&lt;div class="line"&gt;Khuyên thì bọn mày là dân chuyên yo, khuyên chỉ vì nhân duyên,&lt;/div&gt;
&lt;div class="line"&gt;khuyên như để nhân quyền …&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Đốt thêm điếu nữa ông êi&lt;/p&gt;
&lt;div&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/NbRUexrPNrU?start=213" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Đôi khi khi đối diện với tử thần thì cái mình cần là chữ nhẫn&lt;/div&gt;
&lt;div class="line"&gt;Đời lắm lời khuyên nhưng bố mày đéo cần tư ... vấn (Oh)&lt;/div&gt;
&lt;div class="line"&gt;Tao có một ước mơ, tao mong mấy thằng ra vẻ cử nhân chúng mày đi tự vẫn,&lt;/div&gt;
&lt;div class="line"&gt;vì mấy thằng ngu thì chém gió như thần.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="line"&gt;Lời khuyên: đôi lúc là vô giá đôi lúc lại đéo có ... giá trị,&lt;/div&gt;
&lt;div class="line"&gt;đôi lúc là méo mó vẹo vọ và đéo có khả thi, cái lời khuyên&lt;/div&gt;
&lt;div class="line"&gt;nghèo khó chỉ được mỗi cái hoa mĩ.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="line"&gt;Khuyên đéo mất tiền (nên) bọn mày hát như là ca sĩ (oh)&lt;/div&gt;
&lt;div class="line"&gt;Những cái mồm ung thư cần hóa trị&lt;/div&gt;
&lt;div class="line"&gt;Những lời khuyên trọc lóc, lời khuyên rụng và lời khuyên không mọc tóc&lt;/div&gt;
&lt;div class="line"&gt;Khuyên thì bọn mày là dân chuyên yo, khuyên chỉ vì nhân duyên,&lt;/div&gt;
&lt;div class="line"&gt;khuyên như để nhân quyền&lt;/div&gt;
&lt;div class="line"&gt;Tao cũng đéo ngờ người tốt giờ còn nhiều hơn là quân Nguyên&lt;/div&gt;
&lt;div class="line"&gt;chứ khuyên thì dễ lắm, con đường mới truân truyên&lt;/div&gt;
&lt;div class="line"&gt;Đừng nói nữa, giữ lại những cái lời không thuận miệng,&lt;/div&gt;
&lt;div class="line"&gt;thích luyên thuyên thì khuyên đi, ai cũng có phần riêng, tao xem phim đéo cần tiếng, homie&lt;/div&gt;
&lt;/div&gt;
</content><category term="Life"></category><category term="dsk"></category><category term="rap"></category></entry><entry><title>Live like there's no tomorrow</title><link href="https://doanhtu.com/article/live-like-theres-no-tomorrow/" rel="alternate"></link><published>2021-01-05T15:43:00+07:00</published><updated>2021-01-05T15:43:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2021-01-05:/article/live-like-theres-no-tomorrow/</id><content type="html">&lt;p&gt;Bỏ mẹ tự nhiên nghĩ mai mà mình oẳng hay là tận thế thì sao?&lt;/p&gt;
&lt;p&gt;Nghĩ xong thấy nhiều năng lượng hơn. Mình chợt nhận ra là lo làm gì nhiều, thích gì làm mẹ đi.&lt;/p&gt;
&lt;img alt="Cứ bình tĩnh mà sống" src="https://doanhtu.com/static/images/calm.gif" /&gt;
</content><category term="Life"></category><category term="life"></category></entry><entry><title>My math notes - Part 1</title><link href="https://doanhtu.com/article/my-math-notes-part-1/" rel="alternate"></link><published>2020-09-07T23:36:00+07:00</published><updated>2020-09-07T23:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-09-07:/article/my-math-notes-part-1/</id><summary type="html">&lt;div class="section" id="sequence"&gt;
&lt;h2&gt;Sequence&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Sequence"&gt;https://en.wikipedia.org/wiki/Sequence&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Sequence is like list&lt;/li&gt;
&lt;li&gt;Often write like this: &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;a_n, b_n, c_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example: &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;msub&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\{(p_t, v_t)_{t=1,...,T}\}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;{(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3283em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mtight"&gt;...&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.13889em;"&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2861em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; where &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;p_t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.625em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the price associated with tick &lt;em&gt;t&lt;/em&gt; and &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;v_t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.5806em;vertical-align:-0.15em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the volume associated with tick &lt;em&gt;t&lt;/em&gt;. The so-called tick rule defines a sequence &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;msub&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\{b_t\}_{t=1,...,T}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;{&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;}&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3283em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mtight"&gt;...&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.13889em;"&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2861em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; where&lt;/p&gt;
&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;{&lt;/mo&gt;&lt;mtable rowspacing="0.36em" columnalign="left left" columnspacing="1em"&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mrow&gt;&lt;mtext&gt;if &lt;/mtext&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mrow&gt;&lt;mtext&gt;if &lt;/mtext&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo mathvariant="normal"&gt;≠&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;/mtable&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;b_t=
\begin{cases}
    b_{t-1} &amp;amp;\text{if \(\Delta{p_t}=0\)} \\
    \frac{\Delta{p_t}}{\Delta{p_t}} &amp;amp;\text{if \(\Delta{p_t}\neq0\)}
\end{cases}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8444em;vertical-align:-0.15em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:3em;vertical-align:-1.25em;"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter" style="top:0em;"&gt;&lt;span class="delimsizing size4"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:1.7146em;"&gt;&lt;span style="top:-3.7146em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3011em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2083em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-2.2746em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.9244em;"&gt;&lt;span style="top:-2.655em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;Δ&lt;/span&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;p …&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="sequence"&gt;
&lt;h2&gt;Sequence&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Sequence"&gt;https://en.wikipedia.org/wiki/Sequence&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Sequence is like list&lt;/li&gt;
&lt;li&gt;Often write like this: &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;a_n, b_n, c_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.1514em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example: &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;msub&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\{(p_t, v_t)_{t=1,...,T}\}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;{(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.1667em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3283em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mtight"&gt;...&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.13889em;"&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2861em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; where &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;p_t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.625em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the price associated with tick &lt;em&gt;t&lt;/em&gt; and &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;v_t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.5806em;vertical-align:-0.15em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal" style="margin-right:0.03588em;"&gt;v&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the volume associated with tick &lt;em&gt;t&lt;/em&gt;. The so-called tick rule defines a sequence &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;msub&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;.&lt;/mi&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\{b_t\}_{t=1,...,T}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;{&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;}&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3283em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mtight"&gt;...&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight" style="margin-right:0.13889em;"&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2861em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; where&lt;/p&gt;
&lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;{&lt;/mo&gt;&lt;mtable rowspacing="0.36em" columnalign="left left" columnspacing="1em"&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mrow&gt;&lt;mtext&gt;if &lt;/mtext&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;mtr&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;mtd&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mrow&gt;&lt;mtext&gt;if &lt;/mtext&gt;&lt;mstyle scriptlevel="0" displaystyle="false"&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/msub&gt;&lt;mo mathvariant="normal"&gt;≠&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;/mstyle&gt;&lt;/mtd&gt;&lt;/mtr&gt;&lt;/mtable&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;b_t=
\begin{cases}
    b_{t-1} &amp;amp;\text{if \(\Delta{p_t}=0\)} \\
    \frac{\Delta{p_t}}{\Delta{p_t}} &amp;amp;\text{if \(\Delta{p_t}\neq0\)}
\end{cases}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class="katex-html" aria-hidden="true"&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:0.8444em;vertical-align:-0.15em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut" style="height:3em;vertical-align:-1.25em;"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter" style="top:0em;"&gt;&lt;span class="delimsizing size4"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:1.7146em;"&gt;&lt;span style="top:-3.7146em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.3011em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2083em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-2.2746em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.9244em;"&gt;&lt;span style="top:-2.655em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;Δ&lt;/span&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2963em;"&gt;&lt;span style="top:-2.357em;margin-left:0em;margin-right:0.0714em;"&gt;&lt;span class="pstrut" style="height:2.5em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size3 size1 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.143em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3.23em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="frac-line" style="border-bottom-width:0.04em;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-3.4461em;"&gt;&lt;span class="pstrut" style="height:3em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;Δ&lt;/span&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2963em;"&gt;&lt;span style="top:-2.357em;margin-left:0em;margin-right:0.0714em;"&gt;&lt;span class="pstrut" style="height:2.5em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size3 size1 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.143em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.4811em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:1.2146em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="arraycolsep" style="width:1em;"&gt;&lt;/span&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:1.7146em;"&gt;&lt;span style="top:-3.7146em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;if Δ&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="top:-2.2746em;"&gt;&lt;span class="pstrut" style="height:3.008em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;if Δ&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.2806em;"&gt;&lt;span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"&gt;&lt;span class="pstrut" style="height:2.7em;"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:0.15em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&lt;span class="mrel"&gt;&lt;span class="mord vbox"&gt;&lt;span class="thinbox"&gt;&lt;span class="rlap"&gt;&lt;span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"&gt;&lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="mord"&gt;&lt;span class="mrel"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="fix"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace" style="margin-right:0.2778em;"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist" style="height:1.2146em;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
</content><category term="Math"></category><category term="note"></category><category term="math"></category></entry><entry><title>Shynet - Website analytic thay thế cho Google</title><link href="https://doanhtu.com/article/shynet-website-analytic-thay-the-cho-google/" rel="alternate"></link><published>2020-08-26T22:36:00+07:00</published><updated>2020-08-26T22:36:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-08-26:/article/shynet-website-analytic-thay-the-cho-google/</id><summary type="html">&lt;div class="section" id="i-gioi-thieu"&gt;
&lt;h2&gt;I. Giới thiệu&lt;/h2&gt;
&lt;p&gt;Nếu các bạn chưa biết thì hiện nay đang có trend khá nổi trên cộng đồng mạng là từ bỏ các công cụ của các tập đoàn lớn như Google, Facebook, Apple, Amazon etc...
nhằm mục đích lấy lại tự do cho các internet user, chặn sự xâm phạm quyền riêng tư và bảo mật của người dùng.&lt;/p&gt;
&lt;p&gt;Nhưng cá nhân mình thì thấy chẳng có lý do gì để làm thế, trừ khi một dịch vụ bắt trả quá nhiều tiền để sử dụng hoặc có quá nhiều quảng cáo, thì mình mới ko dùng.&lt;/p&gt;
&lt;p&gt;Còn lại thì thời đại vẫn cứ đổi thay, và như các công ty lớn đó làm vậy cũng nhằm mục đích chính là nâng cao trải nghiệm người dùng. Chứ mình thì ko tin vào mấy cái thuyết âm mưu cho lắm.&lt;/p&gt;
&lt;p&gt;Dù sao thì mình cũng đã tìm hiểu …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="i-gioi-thieu"&gt;
&lt;h2&gt;I. Giới thiệu&lt;/h2&gt;
&lt;p&gt;Nếu các bạn chưa biết thì hiện nay đang có trend khá nổi trên cộng đồng mạng là từ bỏ các công cụ của các tập đoàn lớn như Google, Facebook, Apple, Amazon etc...
nhằm mục đích lấy lại tự do cho các internet user, chặn sự xâm phạm quyền riêng tư và bảo mật của người dùng.&lt;/p&gt;
&lt;p&gt;Nhưng cá nhân mình thì thấy chẳng có lý do gì để làm thế, trừ khi một dịch vụ bắt trả quá nhiều tiền để sử dụng hoặc có quá nhiều quảng cáo, thì mình mới ko dùng.&lt;/p&gt;
&lt;p&gt;Còn lại thì thời đại vẫn cứ đổi thay, và như các công ty lớn đó làm vậy cũng nhằm mục đích chính là nâng cao trải nghiệm người dùng. Chứ mình thì ko tin vào mấy cái thuyết âm mưu cho lắm.&lt;/p&gt;
&lt;p&gt;Dù sao thì mình cũng đã tìm hiểu 1 vài thứ thay thế cho các công cụ trên, không phải vì mình lo về privacy mà đơn giản là nhu cầu dùng của mình chỉ đến vầy.&lt;/p&gt;
&lt;p&gt;Đơn cử như trang blog này, nhu cầu của mình chỉ là đếm xem có bao nhiêu lượng truy cập, bài nào đươc xem nhiều nhất, và ngày nào có lượt xem tăng cao.&lt;/p&gt;
&lt;p&gt;Chấm hết. Không cần đến Google Analytic.&lt;/p&gt;
&lt;p&gt;Nên mình đã tìm hiểu và quyết định chọn &lt;a class="reference external" href="https://github.com/milesmcc/shynet"&gt;Shynet&lt;/a&gt;&lt;/p&gt;
&lt;img alt="Shynet Screenshot" src="https://doanhtu.com/static/images/analytic.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="ii-huong-dan"&gt;
&lt;h2&gt;II. Hướng dẫn&lt;/h2&gt;
&lt;p&gt;Mình chọn Shynet cũng 1 phần vì nó được viết bằng Django, mà mình thì dùng Django cũng được 4 - 5 năm rồi nên có vấn đề gì cũng sẽ dễ custom và fix.&lt;/p&gt;
&lt;p&gt;Để deploy Shynet khá dễ vì giờ đã có Docker.&lt;/p&gt;
&lt;p&gt;Đầu tiên là cần 1 server. Bạn có thể dùng &lt;a class="reference external" href="https://m.do.co/c/405dc57e87c4"&gt;Digital Ocean&lt;/a&gt; (Link affiliate, bạn sẽ có $100 dùng trong 60 ngày, còn mình sẽ được $25)&lt;/p&gt;
&lt;p&gt;Nên chọn Ubuntu 18.04 cho stable. Sau đó là &lt;a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04"&gt;cài Docker&lt;/a&gt; và &lt;a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04"&gt;Docker compose&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sau đó chạy các command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;nginx
mkdir&lt;span class="w"&gt; &lt;/span&gt;shynet
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;shynet
touch&lt;span class="w"&gt; &lt;/span&gt;.env
touch&lt;span class="w"&gt; &lt;/span&gt;docker-compose.yml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;File &lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;shynet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;milesmcc/shynet:latest&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;8009:8080&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;db&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;.env&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;postgres:latest&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;expose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;5432&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_USER=shynet&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_PASSWORD=secret_password&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_DB=shynet_db&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;shynet-db:/var/lib/postgresql/data&lt;/span&gt;

&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;shynet-db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;File &lt;strong&gt;.env&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# This file shows all of the environment variables you can
# set to configure Shynet, as well as information about their
# effects. Make a copy of this file to configure your deployment.

# Database settings (PostgreSQL)
DB_NAME=shynet_db
DB_USER=shynet
DB_PASSWORD=secret_password
DB_HOST=db
DB_PORT=5432

# General Django settings
DJANGO_SECRET_KEY=random_secret_key

# For better security, set this to your deployment&amp;#39;s domain. Comma separated.
ALLOWED_HOSTS=*

# Set to True (capitalized) if you want people to be able to sign up for your Shynet instance (not recommended)
ACCOUNT_SIGNUPS_ENABLED=False

# Should user email addresses be verified? Only set this to `required` if you&amp;#39;ve setup the email settings and allow
# public sign-ups; otherwise, it&amp;#39;s unnecessary.
ACCOUNT_EMAIL_VERIFICATION=none

# The timezone of the admin panel. Affects how dates are displayed.
TIME_ZONE=America/New_York

# Set to &amp;quot;False&amp;quot; if you will not be serving content over HTTPS
SCRIPT_USE_HTTPS=True

# How frequently should the monitoring script &amp;quot;phone home&amp;quot; (in ms)?
SCRIPT_HEARTBEAT_FREQUENCY=5000

# How much time can elapse between requests from the same user before a new
# session is created, in seconds?
SESSION_MEMORY_TIMEOUT=1800

# Should only superusers (admins) be able to create services? This is helpful
# when you&amp;#39;d like to invite others to your Shynet instance but don&amp;#39;t want
# them to be able to create services of their own.
ONLY_SUPERUSERS_CREATE=True

# Whether to perform checks and setup at startup, including applying unapplied
# migrations. For most setups, the recommended value is True. Defaults to True.
# Will skip only if value is False.
PERFORM_CHECKS_AND_SETUP=True

# The port that Shynet should bind to. Don&amp;#39;t set this if you&amp;#39;re deploying on Heroku.
PORT=8080
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rồi chạy &lt;code&gt;docker-compose up -d&lt;/code&gt;. &lt;em&gt;Voila&lt;/em&gt;, bạn đã có &lt;strong&gt;shynet service&lt;/strong&gt; chạy trên port &lt;strong&gt;8009&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Để tạo &lt;strong&gt;superuser&lt;/strong&gt; để quản lý và set &lt;strong&gt;hostname&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="iii-reverse-proxy"&gt;
&lt;h2&gt;III. Reverse proxy&lt;/h2&gt;
&lt;p&gt;Chúng ta sẽ dùng &lt;strong&gt;nginx&lt;/strong&gt; làm &lt;a class="reference external" href="https://www.nginx.com/resources/glossary/reverse-proxy-server/"&gt;reverse proxy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tạo 1 file &lt;code&gt;/etc/nginx/sites-available/shynet&lt;/code&gt; như sau:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Domain&lt;/span&gt; &lt;span class="n"&gt;của&lt;/span&gt; &lt;span class="n"&gt;bạn&lt;/span&gt;

     &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8009&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Real&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rồi chạy&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ln&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/site-available/shynet&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/site-enabled
nginx&lt;span class="w"&gt; &lt;/span&gt;-t
systemctl&lt;span class="w"&gt; &lt;/span&gt;restart&lt;span class="w"&gt; &lt;/span&gt;nginx
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Và thế là ta đã có 1 service chạy analytic cho bất cứ web nào ta muốn.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Hack"></category><category term="self-hosted"></category></entry><entry><title>How to choose your pen</title><link href="https://doanhtu.com/article/how-to-choose-your-pen/" rel="alternate"></link><published>2020-08-12T20:18:00+07:00</published><updated>2020-08-12T20:18:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-08-12:/article/how-to-choose-your-pen/</id><summary type="html">&lt;p&gt;Content source:
&lt;a class="reference external" href="https://www.reddit.com/r/pens/comments/3me6kx/i_write_a_lot_and_am_looking_for_a_good_pen_but_i/"&gt;https://www.reddit.com/r/pens/comments/3me6kx/i_write_a_lot_and_am_looking_for_a_good_pen_but_i/&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="what-makes-a-good-pen"&gt;
&lt;h2&gt;What makes a good pen:&lt;/h2&gt;
&lt;div class="section" id="ergonomics"&gt;
&lt;h3&gt;Ergonomics:&lt;/h3&gt;
&lt;blockquote&gt;
the weight and shape of the pen, plus the material it's made of, determine how the pen feels in your hand.&lt;/blockquote&gt;
&lt;p&gt;Some people prefer lighter pens, others prefer the feel of a hefty pen. If you're writing very quickly, a lighter pen won't tire your hand as quickly, but a heavier pen will give you more control.&lt;/p&gt;
&lt;p&gt;Some pens taper from a thick barrel to the writing point (Parker jotter), while others have a straight barrel nearly all the way to the writing point (Cross century). Other pens will have a rubber grip above the writing point (pilot g2, uni ball signo 207, and most plastic ballpoints). The shape all comes down to personal preference, which is usually decided by the size of your hand and grip technique. However, I have heard people …&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Content source:
&lt;a class="reference external" href="https://www.reddit.com/r/pens/comments/3me6kx/i_write_a_lot_and_am_looking_for_a_good_pen_but_i/"&gt;https://www.reddit.com/r/pens/comments/3me6kx/i_write_a_lot_and_am_looking_for_a_good_pen_but_i/&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="what-makes-a-good-pen"&gt;
&lt;h2&gt;What makes a good pen:&lt;/h2&gt;
&lt;div class="section" id="ergonomics"&gt;
&lt;h3&gt;Ergonomics:&lt;/h3&gt;
&lt;blockquote&gt;
the weight and shape of the pen, plus the material it's made of, determine how the pen feels in your hand.&lt;/blockquote&gt;
&lt;p&gt;Some people prefer lighter pens, others prefer the feel of a hefty pen. If you're writing very quickly, a lighter pen won't tire your hand as quickly, but a heavier pen will give you more control.&lt;/p&gt;
&lt;p&gt;Some pens taper from a thick barrel to the writing point (Parker jotter), while others have a straight barrel nearly all the way to the writing point (Cross century). Other pens will have a rubber grip above the writing point (pilot g2, uni ball signo 207, and most plastic ballpoints). The shape all comes down to personal preference, which is usually decided by the size of your hand and grip technique. However, I have heard people claim that a thicker pen takes less effort to hold, therefore it does not tire the hand as quickly.&lt;/p&gt;
&lt;p&gt;Focusing on the grip, pen materials usually fall into one of 3 categories: rubber, plastic/resin, or metal. A rubber grip is lightweight and tactile, which makes the pen easy to hang on to. However, it does increase the thickness of the pen, which may deter people who prefer a thin pen. Plastic/resin is also lightweight, but doesn't offer as much friction as rubber. In my experience, resin doesn't get terribly slippery when sweated on compared to plastic. However, it's mainly used in high quality fountain pens. Metal pens typically have the least grip of the group, but can be finished with grooves or a good brush job to increase friction.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ink-and-ink-delivery-system"&gt;
&lt;h3&gt;Ink and ink delivery system:&lt;/h3&gt;
&lt;blockquote&gt;
this is the type of ink and how the ink gets on the paper.&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ballpoint&lt;/strong&gt;: ballpoint pens use an oil/alcohol-based ink. If you've ever cut open a ballpoint pen in elementary school, you'll notice that it's very gluey. ballpoint pens are the least likely to smudge/smear/bleed, and cheaper ballpoints will need a bit of encouragement to move across the paper. putting pressure on the pen to write is what tires out the hand&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rollerball&lt;/strong&gt;: rollerball pens also use a ballpoint tip, but have a water-based ink. they move much more quickly across paper, and create a fairly clean line. as such, they require much less pressure to put ink on paper. however, they are prone to some smudging/smearing/bleeding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gel Rollerball&lt;/strong&gt;: similar to the liquid ink rollerball, except the ink has a higher viscosity. This means it doesn't take much pressure to write, but is unlikely to smudge like the liquid ink rollerball. these pens can also create much thinner, cleaner lines due to the gel ink's higher viscosity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fountain&lt;/strong&gt;: the fountain pen uses a free flowing ink cartridge, and a solid nib to deliver the ink. I believe ink flows into the paper through osmosis (the paper being porous and &amp;quot;sucking&amp;quot; the ink from the nib), but don't quote me on that. fountain pens take absolutely no pressure to draw ink, and move smoothly across paper. I think if you're getting a tired hand, a fountain pen would solve the problem. However, fountain pens do require you to refill the ink. pens like the twsbi eco or twsbi 580 have huge ink resevoirs and rarely need to be refilled, whereas the metropolitan or safari can take ink cartridges or be converted to use a piston resevoir.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Felt tip&lt;/strong&gt;: felt tip pens use a spongy cartridge that is soaked in ink, and then delivered to the paper through the hard felt writing end. they require very little pressure to draw ink, but more effort to move the pen across the paper than a gel or rollerball. they are typically all plastic construction. a bold felt tip pen is often called a &amp;quot;sign pen&amp;quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="all-that-being-said"&gt;
&lt;h2&gt;All that being said...&lt;/h2&gt;
&lt;p&gt;The best pen is the one that fits your hand and writing style. It will take some time to find the right one, but it's possible. I think you'll also find that the best pens are usually capped, not retractable. I do have some recommendations for pens you can get for &amp;lt;$50.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Ballpoint&lt;/strong&gt;: Parker jotter, cross century, zebra f701, uni ball jetstream, fisher space pen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rollerball&lt;/strong&gt;: uni-ball vision elite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gel&lt;/strong&gt;: pilot g2, pilot hi-tec&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fountain&lt;/strong&gt;: pilot metropolitan M, lamy safari M, twsbi 580 F/M&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Felt tip&lt;/strong&gt;: papermate flair M, pilot fineliner, pilot sign pen, pentel color pen fine point&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think if you have one ballpoint, one felt tip, and one rollerball/gel/fountain, you will have all your bases covered. e.g. parker jotter, lamy safari and pilot fineliner. (and a pencil)&lt;/p&gt;
&lt;/div&gt;
</content><category term="Life"></category><category term="life"></category></entry><entry><title>Các tài liệu hay về sức khỏe</title><link href="https://doanhtu.com/article/cac-tai-lieu-hay-ve-suc-khoe/" rel="alternate"></link><published>2020-08-06T00:00:00+07:00</published><updated>2020-08-06T00:00:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-08-06:/article/cac-tai-lieu-hay-ve-suc-khoe/</id><content type="html">&lt;div class="section" id="i-su-that"&gt;
&lt;h2&gt;I. Sự thật&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://liamrosen.com/fitness.html"&gt;http://liamrosen.com/fitness.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="Life"></category><category term="fitness"></category></entry><entry><title>Đứa con của Thượng đế - Ramanujan</title><link href="https://doanhtu.com/article/dua-con-cua-thuong-de-ramanujan/" rel="alternate"></link><published>2020-08-05T19:06:00+07:00</published><updated>2020-08-05T19:06:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-08-05:/article/dua-con-cua-thuong-de-ramanujan/</id><content type="html">&lt;img alt="Srinivasa Ramanujan" src="https://doanhtu.com/static/images/ramanujan.jpg" /&gt;
&lt;div class="section" id="i-thuo-so-khai"&gt;
&lt;h2&gt;I. Thuở sơ khai&lt;/h2&gt;
&lt;p&gt;Ngày xưa mình đọc được trong những quyển sách, bài báo,
rằng có những người đạt được những năng lực tưởng như siêu nhiên,
kiểu như thần đồng toán học không cần ai chỉ dạy cũng có thể hiểu và làm được
những phép toán kỳ diệu.&lt;/p&gt;
&lt;p&gt;Mình thì mình không tin đâu.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Math"></category><category term="math"></category><category term="ramanujan"></category></entry><entry><title>Elixir note</title><link href="https://doanhtu.com/article/elixir-note/" rel="alternate"></link><published>2020-02-28T00:00:00+07:00</published><updated>2020-02-28T00:00:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2020-02-28:/article/elixir-note/</id><summary type="html">&lt;h3&gt;Module&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Bắt đầu bằng chữ in hoa và dạng CamelCase&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chứa các function, các function &lt;strong&gt;phải&lt;/strong&gt; viết trong một module.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Có thể viết dạng &lt;code&gt;Module.Part.One&lt;/code&gt;. Chỉ là syntactic sugar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Bot.Chat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hi there&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nc"&gt;Bot.Chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Function&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Phải viết trong một module&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Giá trị return là dòng cuối, không giống như Python phải &lt;code&gt;return something&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tên function viết thường, vi_du_nhu_the_nay&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; trả về &lt;em&gt;true&lt;/em&gt; hoặc &lt;em&gt;false&lt;/em&gt;, &lt;code&gt;!&lt;/code&gt; ám chỉ function có thể raise runtime error&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;def&lt;/code&gt; và &lt;code&gt;defmodule&lt;/code&gt; là các &lt;em&gt;macro&lt;/em&gt;, ko phải keyword&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyTool.Math&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;\\&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Dùng &lt;code&gt;|&amp;gt;&lt;/code&gt; (pipeline), kết quả trả về được đưa vào args đầu tiên của function đằng sau&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arity&lt;/strong&gt; là số args …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;h3&gt;Module&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Bắt đầu bằng chữ in hoa và dạng CamelCase&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chứa các function, các function &lt;strong&gt;phải&lt;/strong&gt; viết trong một module.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Có thể viết dạng &lt;code&gt;Module.Part.One&lt;/code&gt;. Chỉ là syntactic sugar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Bot.Chat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hi there&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nc"&gt;Bot.Chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Function&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Phải viết trong một module&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Giá trị return là dòng cuối, không giống như Python phải &lt;code&gt;return something&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tên function viết thường, vi_du_nhu_the_nay&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; trả về &lt;em&gt;true&lt;/em&gt; hoặc &lt;em&gt;false&lt;/em&gt;, &lt;code&gt;!&lt;/code&gt; ám chỉ function có thể raise runtime error&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;def&lt;/code&gt; và &lt;code&gt;defmodule&lt;/code&gt; là các &lt;em&gt;macro&lt;/em&gt;, ko phải keyword&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyTool.Math&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;\\&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Dùng &lt;code&gt;|&amp;gt;&lt;/code&gt; (pipeline), kết quả trả về được đưa vào args đầu tiên của function đằng sau&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arity&lt;/strong&gt; là số args của một function. Rất quan trọng vì trong một module có thể def nhiều function tên giống nhau nhưng khác về args nhận vào.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Ở đây ta có 2 func: Foo.add/1 &amp;amp; Foo.add/2 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;defp&lt;/code&gt; để tạo private function&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Xem thêm import và alias ở https://elixir-lang.org/getting-started/alias-require-and-import.html&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Các func trong &lt;code&gt;Elixir.Kernel&lt;/code&gt; tự động được import vì phải dùng nhiều&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nên có type cho các function để có thể dùng &lt;strong&gt;dialyzer&lt;/strong&gt; phân tích về sau.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;@spec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Anonymous function call with dot&lt;/span&gt;
&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Atom&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Các atom được giữ trong một &lt;em&gt;atom table&lt;/em&gt;, có giá trị là chính nó và có lợi về mặt performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nc"&gt;AtomOne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:&amp;quot;Elixir.AtomOne&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Tự được thêm Elixir vào trước&lt;/span&gt;

&lt;span class="kn"&gt;alias&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyIO&lt;/span&gt;

&lt;span class="nc"&gt;MyIO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:&amp;quot;Elixir.IO&amp;quot;&lt;/span&gt;
&lt;span class="nc"&gt;MyIO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Elixir.IO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Data types&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;#### Tuple&lt;/span&gt;
&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;James&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# get item by index&lt;/span&gt;
&lt;span class="n"&gt;new_me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;put_elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Update item at index&lt;/span&gt;

&lt;span class="c1"&gt;#### List&lt;/span&gt;
&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nc"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Get item by index&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Check item in list&lt;/span&gt;
&lt;span class="n"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Get head&lt;/span&gt;
&lt;span class="n"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Get tail&lt;/span&gt;
&lt;span class="n"&gt;new_numbs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numbs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Cheaper to add head than tail&lt;/span&gt;

&lt;span class="c1"&gt;#### Map&lt;/span&gt;
&lt;span class="n"&gt;langs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;python&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1991&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;elixir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2011&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;langs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:not_found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Get with default value&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;python_born&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;langs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:python&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;langs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:golang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Raise error&lt;/span&gt;
&lt;span class="n"&gt;langs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# If key is an atom&lt;/span&gt;

&lt;span class="c1"&gt;#### String&lt;/span&gt;
&lt;span class="c1"&gt;# Strings are binaries&lt;/span&gt;
&lt;span class="sx"&gt;~s(&amp;quot;Ahihi &amp;quot; tai sao the)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Sigil&lt;/span&gt;
&lt;span class="sx"&gt;~S(Not escaped \n)&lt;/span&gt;

&lt;span class="s1"&gt;&amp;#39;ABC&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Character list&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ABC&amp;#39;&lt;/span&gt;
&lt;span class="sx"&gt;~c(Character list sigil)&lt;/span&gt;
&lt;span class="sx"&gt;~C(Unescaped sigil #{3 + 0.14})&lt;/span&gt;
&lt;span class="c1"&gt;# Character lists aren’t compatible with binary strings.&lt;/span&gt;
&lt;span class="c1"&gt;# To convert a character list to a binary string, you can use List.to_string/1.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Format&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dùng &lt;code&gt;mix format&lt;/code&gt; để tự format code cho đẹp.&lt;/li&gt;
&lt;li&gt;Có thể tìm plugin cho editor đang dùng để tự format khi save.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Programming"></category><category term="programming"></category></entry><entry><title>Ý tưởng mới: Hôm nay tôi tiết kiệm được bao nhiêu?</title><link href="https://doanhtu.com/article/y-tuong-moi-hom-nay-toi-tiet-kiem-duoc-bao-nhieu/" rel="alternate"></link><published>2019-05-01T00:00:00+07:00</published><updated>2019-05-01T00:00:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2019-05-01:/article/y-tuong-moi-hom-nay-toi-tiet-kiem-duoc-bao-nhieu/</id><summary type="html">&lt;p&gt;&lt;strong&gt;Ý tưởng mới: Hôm nay tôi tiết kiệm được bao nhiêu?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chúng ta rất ngại việc phải ghi lại chi tiết từng đồng một họ tiêu pha, vì điều đó làm ta hối hận khi nhìn lại.&lt;/p&gt;
&lt;p&gt;Nhưng nếu ta ghi lại những thứ mà ta tiết kiệm được thì sao?&lt;/p&gt;
&lt;p&gt;&lt;img alt="Smart" src="https://media.giphy.com/media/d3mlE7uhX8KFgEmY/giphy.gif"&gt;&lt;/p&gt;
&lt;p&gt;Ví dụ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hôm nay tôi muốn ăn gà rán + hamberger, nhưng thay vì đó tôi đã đi ăn cơm ở gần nhà. Thay vì tốn &lt;strong&gt;120k&lt;/strong&gt;, thì tôi chỉ mất có &lt;strong&gt;30k&lt;/strong&gt;. Tiết kiệm được 90k và lại còn đỡ béo hơn nhiều.&lt;/li&gt;
&lt;li&gt;Hôm nay tôi muốn mua một thứ rất ngầu trên mạng. Nhưng thay vì thế tôi ngồi suy nghĩ lại và thấy mình cũng ko có nhu cầu sử dụng nó. Vì thế tôi tiết kiệm được khoảng &lt;strong&gt;$50&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Hôm nay tôi muốn đi nhậu ghê gớm, nhưng thay vì thế tôi mua 1 chai bia …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Ý tưởng mới: Hôm nay tôi tiết kiệm được bao nhiêu?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chúng ta rất ngại việc phải ghi lại chi tiết từng đồng một họ tiêu pha, vì điều đó làm ta hối hận khi nhìn lại.&lt;/p&gt;
&lt;p&gt;Nhưng nếu ta ghi lại những thứ mà ta tiết kiệm được thì sao?&lt;/p&gt;
&lt;p&gt;&lt;img alt="Smart" src="https://media.giphy.com/media/d3mlE7uhX8KFgEmY/giphy.gif"&gt;&lt;/p&gt;
&lt;p&gt;Ví dụ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hôm nay tôi muốn ăn gà rán + hamberger, nhưng thay vì đó tôi đã đi ăn cơm ở gần nhà. Thay vì tốn &lt;strong&gt;120k&lt;/strong&gt;, thì tôi chỉ mất có &lt;strong&gt;30k&lt;/strong&gt;. Tiết kiệm được 90k và lại còn đỡ béo hơn nhiều.&lt;/li&gt;
&lt;li&gt;Hôm nay tôi muốn mua một thứ rất ngầu trên mạng. Nhưng thay vì thế tôi ngồi suy nghĩ lại và thấy mình cũng ko có nhu cầu sử dụng nó. Vì thế tôi tiết kiệm được khoảng &lt;strong&gt;$50&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Hôm nay tôi muốn đi nhậu ghê gớm, nhưng thay vì thế tôi mua 1 chai bia và ít đồ khô về ăn, và tôi tiết kiệm được khoảng &lt;strong&gt;$80&lt;/strong&gt; cho những cuộc ăn chơi hát hò. Tôi lại còn có thêm thời gian để đọc sách và làm việc nữa.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Và cứ thế, dần rồi sẽ cộng lên, và có thêm cả bảng tính xem với những khoản tiết kiệm trên, &lt;strong&gt;nếu được đầu tư thì sau 5 năm, 10 năm, 20 năm sẽ thành một khoản khổng lồ như thế nào.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chưa kể, nếu ta còn ghi lại cả những thành công khi tránh ko ăn những đồ junk food khi đang diet, ta cũng có thể tính ra được lượng calo ta giảm được. &lt;strong&gt;Và từ đó, sau 6 tháng, sau 1 năm, sau 5 năm cơ thể ta sẽ khoẻ hơn đến mức nào.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ý tưởng này sẽ được thực hiện với website http://homnaytoi.com hoặc 1 domain nào đó mình nghĩ ra trong lúc làm :D&lt;/p&gt;
&lt;p&gt;Stack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;Bulma.io&lt;/li&gt;
&lt;li&gt;VueJS (Maybe, cho Front-end và Mobile App)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deadline: 1 tuần. Nghĩa là đến 8/5/2019 phải có bản demo để show và sử dụng được.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Just do it!" src="https://media.giphy.com/media/jndc0TQq9fvK8/giphy.gif"&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="programming"></category><category term="idea"></category></entry><entry><title>Dùng Raspberry Pi để gửi và nhận SMS với Sim900A</title><link href="https://doanhtu.com/article/dung-raspberry-pi-de-gui-va-nhan-sms-voi-sim900a/" rel="alternate"></link><published>2018-10-10T00:00:00+07:00</published><updated>2018-10-10T00:00:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2018-10-10:/article/dung-raspberry-pi-de-gui-va-nhan-sms-voi-sim900a/</id><summary type="html">&lt;p&gt;Hướng dẫn kết nối module Sim900A với Raspberry Pi 3 B+, dùng để gửi và nhận tin nhắn SMS&lt;/p&gt;
&lt;p&gt;Dạo này vì lý do công việc nên cần phải tìm cách kết nối và sử dụng module Sim900A với con Raspberry Pi 3, dùng để nhận SMS.&lt;/p&gt;
&lt;p&gt;Tìm hiểu mấy hôm, rất là cực nên hôm nay mình viết lại bài này, cho những ai cần tới sau này đỡ tốn thời gian mày mò lại từ đầu.&lt;/p&gt;
&lt;h2&gt;Chuẩn bị&lt;/h2&gt;
&lt;p&gt;Để bắt đầu, bạn cần:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Một combo &lt;strong&gt;Raspberry Pi 3 B+&lt;/strong&gt; đầy đủ nguồn, thẻ nhớ, đã cài đặt &lt;strong&gt;Raspbian&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Một module &lt;strong&gt;Sim900A&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/sms_900a.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dây chuyển đổi USB — UART PL2303 (Có thể không có)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/PL2303.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Đầy đủ dây nối&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/gpio_string.jpeg"&gt;&lt;/p&gt;
&lt;h2&gt;Kết nối&lt;/h2&gt;
&lt;p&gt;Chỉ cần bạn kết nối đúng các cổng &lt;em&gt;Tx, Rx, Gnd và nguồn 5v&lt;/em&gt; vào Pi là xong. Tham khảo ảnh dưới:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/gpio_map.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Ảnh thực tế (Nếu kết nối thẳng vào GPIO …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Hướng dẫn kết nối module Sim900A với Raspberry Pi 3 B+, dùng để gửi và nhận tin nhắn SMS&lt;/p&gt;
&lt;p&gt;Dạo này vì lý do công việc nên cần phải tìm cách kết nối và sử dụng module Sim900A với con Raspberry Pi 3, dùng để nhận SMS.&lt;/p&gt;
&lt;p&gt;Tìm hiểu mấy hôm, rất là cực nên hôm nay mình viết lại bài này, cho những ai cần tới sau này đỡ tốn thời gian mày mò lại từ đầu.&lt;/p&gt;
&lt;h2&gt;Chuẩn bị&lt;/h2&gt;
&lt;p&gt;Để bắt đầu, bạn cần:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Một combo &lt;strong&gt;Raspberry Pi 3 B+&lt;/strong&gt; đầy đủ nguồn, thẻ nhớ, đã cài đặt &lt;strong&gt;Raspbian&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Một module &lt;strong&gt;Sim900A&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/sms_900a.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dây chuyển đổi USB — UART PL2303 (Có thể không có)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/PL2303.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Đầy đủ dây nối&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/gpio_string.jpeg"&gt;&lt;/p&gt;
&lt;h2&gt;Kết nối&lt;/h2&gt;
&lt;p&gt;Chỉ cần bạn kết nối đúng các cổng &lt;em&gt;Tx, Rx, Gnd và nguồn 5v&lt;/em&gt; vào Pi là xong. Tham khảo ảnh dưới:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/gpio_map.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Ảnh thực tế (Nếu kết nối thẳng vào GPIO)&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/rasp_sms_1.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/rasp_sms_2.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Còn nếu kết nối qua USB&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/rasp_sms_3.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Cài đặt&lt;/h2&gt;
&lt;p&gt;Đầu tiên ta cần mở cổng &lt;strong&gt;ttyS0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bạn có thể dùng “raspi-config” để mở UART:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/rasp_config.jpg"&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Trong “Interfacing Options”, chọn “Serial”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chọn “No” khi được hỏi “You want a login shell over serial?”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chọn “Yes” khi được hỏi “You want the hardware enabled?”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Khởi động lại&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thực ra, bạn có thể sửa file &lt;em&gt;/boot/config.txt&lt;/em&gt; và sửa &lt;strong&gt;enable_uart=1&lt;/strong&gt;, và &lt;strong&gt;console=serial0,115200&lt;/strong&gt; (hoặc &lt;strong&gt;console=ttyS0,115200&lt;/strong&gt;) ở trong &lt;em&gt;/boot/cmdline.txt&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Và bạn có thể bật &lt;em&gt;terminal&lt;/em&gt; lên và test xem kết nối thành công chưa bằng cách gửi command &lt;strong&gt;AT\r\n&lt;/strong&gt; đến khi nào trả về &lt;strong&gt;OK&lt;/strong&gt; là thành công. (Nếu kết nối qua GPIO thì sẽ là &lt;strong&gt;/dev/ttyS0&lt;/strong&gt;, còn qua USB thì sẽ là &lt;strong&gt;/dev/ttyUSB0&lt;/strong&gt;)&lt;/p&gt;
&lt;p&gt;Ví dụ:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/read_sms.png"&gt;&lt;/p&gt;
&lt;p&gt;Link asciinema:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/4000/0*rI0-d-OfRpAlDkFn.png"&gt;&lt;/p&gt;
&lt;p&gt;Sử dụng thư viện sau để kết nối và làm việc với SMS Module:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://smstools3.kekekasvi.com/"&gt;http://smstools3.kekekasvi.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ví dụ về kết quả nhận được bằng lệnh &lt;strong&gt;AT+CNMI=3,2,0,0,0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://doanhtu.com/static/images/read_sms_2.png"&gt;&lt;/p&gt;
&lt;p&gt;Về chi tiết cách sử dụng các lệnh AT và các khái niệm GPIO, UART mình sẽ để sang một bài khác.&lt;/p&gt;
&lt;p&gt;Chúc các bạn thành công.&lt;/p&gt;
&lt;p&gt;Tham khảo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://pinout.xyz/"&gt;https://pinout.xyz/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://mlab.vn/9216-huong-dan-lap-trinh-module-sim900a-va-arduino.html"&gt;http://mlab.vn/9216-huong-dan-lap-trinh-module-sim900a-va-arduino.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.developershome.com/sms/checkCommandSupport3.asp"&gt;https://www.developershome.com/sms/checkCommandSupport3.asp&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://raspberrypi.stackexchange.com/questions/82696/how-do-i-connect-gsm-sim-900a-to-a-raspberry-pi-3"&gt;https://raspberrypi.stackexchange.com/questions/82696/how-do-i-connect-gsm-sim-900a-to-a-raspberry-pi-3&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.espruino.com/datasheets/SIM900_AT.pdf"&gt;https://www.espruino.com/datasheets/SIM900_AT.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://hristoborisov.com/index.php/projects/turning-the-raspberry-pi-into-a-sms-center-using-python/#Connecting_the_3gModem"&gt;https://hristoborisov.com/index.php/projects/turning-the-raspberry-pi-into-a-sms-center-using-python/#Connecting_the_3gModem&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="Hack"></category><category term="raspberrypi"></category><category term="sms"></category></entry><entry><title>Liệu chất béo có làm ta béo?</title><link href="https://doanhtu.com/article/lieu-chat-beo-co-lam-ta-beo/" rel="alternate"></link><published>2017-12-08T14:20:00+07:00</published><updated>2017-12-08T14:20:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2017-12-08:/article/lieu-chat-beo-co-lam-ta-beo/</id><summary type="html">&lt;h3&gt;Fat is evil?&lt;/h3&gt;
&lt;p&gt;&lt;img alt="" src="https://media.giphy.com/media/10uct1aSFT7QiY/giphy.gif"&gt;&lt;br&gt;
Trong quyển sách ‘The Big Fat Surprise’, tác giả Nina Teicholz đã viết  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fat is the most unfortunate homonymn in the English language&lt;br&gt;
‘Mỡ’ là từ đồng âm tai hại nhất trong tiếng Anh (và cả tiếng Việt)  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nghĩa là, từ mà chúng ta dùng để chỉ mỡ bụng, cũng là từ mà chúng ta dùng để chỉ thứ dầu/mỡ mà ta dùng để nấu ăn, và cả để ăn nữa. Khoảng 60 năm về trước, có một lý thuyết cho rằng vì lượng chất béo ta ăn vào nhiều calo hơn là carbonhydrate (tinh bột), chúng hẳn là tác nhân gây ra bệnh đau tim và béo phì. Cũng chẳng lạ gì khi chúng ta tin ngay mà chẳng hề suy nghĩ nhiều.  &lt;/p&gt;
&lt;p&gt;Nhưng, điều đó là sai lầm và quá ư là ngây thơ về mặt khoa học. Các chất béo, cụ thể là …&lt;/p&gt;</summary><content type="html">&lt;h3&gt;Fat is evil?&lt;/h3&gt;
&lt;p&gt;&lt;img alt="" src="https://media.giphy.com/media/10uct1aSFT7QiY/giphy.gif"&gt;&lt;br&gt;
Trong quyển sách ‘The Big Fat Surprise’, tác giả Nina Teicholz đã viết  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fat is the most unfortunate homonymn in the English language&lt;br&gt;
‘Mỡ’ là từ đồng âm tai hại nhất trong tiếng Anh (và cả tiếng Việt)  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nghĩa là, từ mà chúng ta dùng để chỉ mỡ bụng, cũng là từ mà chúng ta dùng để chỉ thứ dầu/mỡ mà ta dùng để nấu ăn, và cả để ăn nữa. Khoảng 60 năm về trước, có một lý thuyết cho rằng vì lượng chất béo ta ăn vào nhiều calo hơn là carbonhydrate (tinh bột), chúng hẳn là tác nhân gây ra bệnh đau tim và béo phì. Cũng chẳng lạ gì khi chúng ta tin ngay mà chẳng hề suy nghĩ nhiều.  &lt;/p&gt;
&lt;p&gt;Nhưng, điều đó là sai lầm và quá ư là ngây thơ về mặt khoa học. Các chất béo, cụ thể là chất béo bão hòa, đã trở thành một thứ không thể thiếu trong lịch sử tồn tại của con người. Và khi chúng ta bắt đầu sợ chất béo, đếm từng tí calo một cũng chính là lúc sức khỏe của chúng ta bắt đầu suy giảm không phanh.  &lt;/p&gt;
&lt;p&gt;Tôi ước gì chúng ta hãy suy nghĩ lại về đường, chứ không phải chất béo, thì chúng ta đã không phải khốn khổ như bây giờ. Dù sao thì, mọi thứ cũng đang bắt đầu thay đổi, và trong các chương trình ăn kiêng người ta đã bắt đầu đặt hạn chế đường lên làm ưu tiên.  &lt;/p&gt;
&lt;h3&gt;What to eat?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Số lượng không giới hạn về rau và chất béo tốt. Cơ thể bạn sẽ không để bạn ăn quá nhiều những thứ đó đâu mà lo. Bạn có thể ngồi ăn hết hàng đống snack hay bỏng ngô mà không hề chán, nhưng không thể làm như thế với đống rau được. (Nhưng mà cần tránh ăn nhiềucác loại hạt, nhất là những loại có muối và đã chiên qua)  &lt;/li&gt;
&lt;li&gt;Thịt và các sản phẩm từ sữa, một cách điều độ. Thay vì coi chúng là món ăn chính, hãy coi như là những phần phụ để bạn ăn salad dễ dàng hơn.  &lt;/li&gt;
&lt;li&gt;Nếu ăn carb, chọn những loại carb tốt. Như rau và quả, gạo lứt, kê, yến mạch. Nhưng đừng có ăn nhiều, khoảng 100gram đổ lại mỗi ngày thôi.  &lt;/li&gt;
&lt;li&gt;Một vài thứ tốt cho cơ thể, như là sữa chua, dưa góp, kefir, đậu phụ, kimchi … Google “Probiotic-rich foods” để tìm hiểu thêm.  &lt;/li&gt;
&lt;li&gt;Chất lượng thì tốt hơn là số lượng. Hai thứ đó có sự tương quan với nhau. Chất lượng đồ ăn càng cao thì số lượng cần ăn càng ít.  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What to avoid?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Đường. (Loại tinh luyện)  &lt;/li&gt;
&lt;li&gt;Carb. Nhiều carb quá sẽ đầu độc cơ thể bạn. Ăn nhiều hơn 200gram carb mỗi ngày cũng có hại tương tự như ăn nhiều đường tinh. Nó làm ta chóng đói, thèm ăn carb hơn, và càng ăn nhiều thì lại càng thèm hơn nữa.  &lt;/li&gt;
&lt;li&gt;Thức ăn nhanh. Những loại thức ăn chế biến sẵn được thiết kế để làm ta thèm ăn hơn. Chúng cực kỳ dễ hấp thụ, và không cần suy nghĩ để ăn. Như đã thấy, chúng ta ăn junk food cực kỳ nhanh, vì thế não chúng ta vẫn đòi ăn tiếp dù không cần.  &lt;/li&gt;
&lt;li&gt;Tránh xa những đồ ăn mà ta không nhận ra chúng, kể cả chúng được làm từ những thứ tươi sống. Hãy chọn táo thay vì nước táo.&lt;/li&gt;
&lt;li&gt;Tránh dùng những thứ dầu được chế biến công nghiệp. Những thứ dầu ăn ôxy hóa cao như dầu hướng dương, dầu đậu nành, dầu ngô và dầu hạt cải sẽ làm hại đến tế bào của chúng ta, có khả năng gây viêm nhiễm cao hơn. Thay vào đó, hãy dùng dầu quả bơ, dầu olive, dầu dừa, hoặc mỡ động vật (loại bão hòa) từ các động vật ăn cỏ.  &lt;/li&gt;
&lt;/ul&gt;</content><category term="Life"></category></entry><entry><title>Pi</title><link href="https://doanhtu.com/article/pi/" rel="alternate"></link><published>2017-11-24T23:11:00+07:00</published><updated>2017-11-24T23:11:00+07:00</updated><author><name>Do Anh Tu</name></author><id>tag:doanhtu.com,2017-11-24:/article/pi/</id><summary type="html">&lt;!-- Summary: Short version for index and feeds --&gt;

&lt;p&gt;Số &lt;strong&gt;pi&lt;/strong&gt;&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; (ký hiệu: π) là một hằng số toán học có giá trị bằng tỷ số giữa chu vi của một đường tròn với đường kính của đường tròn đó. Hằng số này có giá trị xấp xỉ bằng 3,14159265358979. Nó được biểu diễn bằng chữ cái Hy Lạp π từ giữa thế kỉ 18.&lt;br&gt;
π là một số vô tỉ, nghĩa là nó không thể được biểu diễn chính xác dưới dạng tỉ số của hai số nguyên. Nói cách khác, nó là một số thập phân vô hạn không tuần hoàn. Hơn nữa, π còn là một số siêu việt - tức là nó không phải là nghiệm của bất kì đa thức với hệ số hữu tỉ nào. Tính siêu việt của π kéo theo sự vô nghiệm của bài toán cầu phương. Các con số trong biểu diễn thập phân của π dường như …&lt;/p&gt;</summary><content type="html">&lt;!-- Summary: Short version for index and feeds --&gt;

&lt;p&gt;Số &lt;strong&gt;pi&lt;/strong&gt;&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; (ký hiệu: π) là một hằng số toán học có giá trị bằng tỷ số giữa chu vi của một đường tròn với đường kính của đường tròn đó. Hằng số này có giá trị xấp xỉ bằng 3,14159265358979. Nó được biểu diễn bằng chữ cái Hy Lạp π từ giữa thế kỉ 18.&lt;br&gt;
π là một số vô tỉ, nghĩa là nó không thể được biểu diễn chính xác dưới dạng tỉ số của hai số nguyên. Nói cách khác, nó là một số thập phân vô hạn không tuần hoàn. Hơn nữa, π còn là một số siêu việt - tức là nó không phải là nghiệm của bất kì đa thức với hệ số hữu tỉ nào. Tính siêu việt của π kéo theo sự vô nghiệm của bài toán cầu phương. Các con số trong biểu diễn thập phân của π dường như xuất hiện theo một thứ tự ngẫu nhiên, mặc dù người ta chưa tìm được bằng chứng nào cho tính ngẫu nhiên này.&lt;br&gt;
&lt;img alt="golden-ratio" src="https://iibawards-prod.s3.amazonaws.com/app/public/ckeditor_assets/pictures/78/content_pi2.jpeg"&gt;&lt;br&gt;
Trong hàng ngàn năm, các nhà toán học đã nỗ lực mở rộng hiểu biết của con người về số π, đôi khi bằng việc tính ra giá trị của nó với độ chính xác ngày càng cao. Trước thế kỉ 15, các nhà toán học như Archimedes và Lưu Huy đã sử dụng các kĩ thuật hình học, dựa trên đa giác, để ước lượng giá trị của π. Bắt đầu từ thế kỉ 15, những thuật toán mới dựa trên chuỗi vô hạn đã cách mạng hóa việc tính toán số π, và được những nhà toán học như Madhava của Sangamagrama, Isaac Newton, Leonhard Euler, Carl Friedrich Gauss, và Srinivasa Ramanujan sử dụng.
Trong thế kỉ 21, các nhà toán học và các nhà khoa học máy tính đã khám phá ra những cách tiếp cận mới - kết hợp với sức mạnh tính toán ngày càng cao - để mở rộng khả năng biểu diễn thập phân của số π tới 1013 chữ số[1]. Tháng 10 năm 2014, kỷ lục này được nâng lên 13.300.000.000.000 chữ số bởi một nhóm nghiên cứu lấy tên là houkouonchi.[2] Các ứng dụng khoa học thông thường yêu cầu không quá 40 chữ số của π, do đó động lực của những tính toán này chủ yếu là tham vọng của con người muốn đạt tới những kỉ lục mới, nhưng những tính toán đó cũng được sử dụng để kiểm tra các siêu máy tính và các thuật toán tính nhân với độ chính xác cao.&lt;br&gt;
Do định nghĩa của π liên hệ với đường tròn, ta có thể tìm thấy nó trong nhiều công thức lượng giác và hình học, đặc biệt là những công thức liên quan tới đường tròn, đường elip, hoặc hình cầu. Nó cũng xuất hiện trong các công thức của các ngành khoa học khác, như vũ trụ học, lý thuyết số, thống kê, phân dạng, nhiệt động lực học, cơ học và điện từ học. Sự có mặt rộng khắp của số π khiến nó trở thành một trong những hằng số toán học được biết đến nhiều nhất, cả bên trong lẫn bên ngoài giới khoa học: một số sách viết riêng về số π đã được xuất bản; có cả Ngày số pi; và báo chí thường đặt những tin về kỉ lục tính toán chữ số mới của π trên trang nhất. Một số người còn cố gắng ghi nhớ giá trị của π với độ chính xác ngày càng tăng, đạt tới kỉ lục trên 67.000 chữ số.  &lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://vi.wikipedia.org/wiki/Pi"&gt;https://vi.wikipedia.org/wiki/Pi&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Math"></category><category term="pi"></category><category term="learn"></category><category term="math"></category></entry></feed>