chore: update

This commit is contained in:
uetchy 2021-12-14 17:13:26 +09:00
parent 2a2a39f4a7
commit ca831cec40
8 changed files with 154 additions and 146 deletions

View File

@ -9,19 +9,19 @@
"test": "lint-staged"
},
"dependencies": {
"hexo": "^5.4.0",
"hexo-excerpt": "^1.1.6",
"hexo": "^6.0.0",
"hexo-excerpt": "^1.2.1",
"hexo-feed": "^1.1.0",
"hexo-filter-mathjax": "^0.7.0",
"hexo-filter-mathjax": "^0.8.0",
"hexo-generator-archive": "^1.0.0",
"hexo-generator-category": "^1.0.0",
"hexo-generator-index": "^2.0.0",
"hexo-generator-tag": "^1.0.0",
"hexo-renderer-ejs": "^1.0.0",
"hexo-renderer-ejs": "^2.0.0",
"hexo-renderer-pandoc": "^0.3.0",
"hexo-renderer-sass": "^0.4.0",
"hexo-renderer-stylus": "^2.0.0",
"hexo-server": "^2.0.0",
"hexo-server": "^3.0.0",
"hexo-theme-landscape": "^0.0.3"
},
"devDependencies": {

View File

@ -132,7 +132,7 @@ Notes.app に移行しました。
## Flash
ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
## [VirtualBox](https://www.virtualbox.org)

View File

@ -3,8 +3,7 @@ title: 解剖学アトラス
date: 2021-06-08T00:00:00
---
幅優先探索癖の再発です、ありがとう図書館。
アトラスの用途は美術解剖と消化器系の構造理解。
いつもの幅優先探索癖。アトラスの用途は美術解剖と消化器系の構造理解。
# ノート

View File

@ -1,22 +1,22 @@
---
title: Installing Arch Linux
title: Comprehensive Guide for Setting Up Arch Linux
date: 2021-02-12T00:00:00
---
This note includes all commands I typed when I set up Arch Linux on my new bare metal server.
This note includes all commands I typed when I set up Arch Linux on my new server.
> PSA: I published a GitHub repository containing a toolchain to create a clean-room docker environment for building AUR packages
> https://github.com/uetchy/archpkgs
> PSA: I published a toolchain for building AUR packages in a clean-room docker container
> <https://github.com/uetchy/archpkgs>
# Setup
## wipe whole disk
## Wipe whole disk
```bash
wipefs -a /dev/sda
```
## create partition
## Create partition
```bash
parted
@ -31,7 +31,7 @@ set 1 esp on # flag partition 1 as ESP
quit
```
## install file-system
## Install file-system
```bash
mkfs.vfat -F 32 /dev/sda1 # EFI
@ -40,7 +40,7 @@ mkfs.ext4 /dev/sda2 # Arch
e2fsck -cc -C 0 /dev/sda2 # fsck
```
## mount disk
## Mount disk
```bash
mkdir -p /mnt/boot
@ -48,7 +48,7 @@ mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot
```
## install base & Linux kernel
## Install base & Linux kernel
```bash
# choose between 'linux' or 'linux-lts'
@ -62,13 +62,13 @@ pacman -S reflector
reflector --protocol https --latest 30 --sort rate --save /etc/pacman.d/mirrorlist --verbose # optimize mirror list
```
## install essentials
## Install essentials
```bash
pacman -S vim man-db man-pages git base-devel
```
## locale
## Locales
```bash
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
@ -93,7 +93,7 @@ Find `<UUID>` from the output of `lsblk -f`.
findmnt --verify --verbose # verify fstab
```
## bootloader
## Install bootloader
```bash
pacman -S \
@ -110,7 +110,7 @@ grub-mkconfig -o /boot/grub/grub.cfg
- [GRUB/Tips and tricks - ArchWiki](https://wiki.archlinux.org/title/GRUB/Tips_and_tricks)
## network
## Setup network
```bash
hostnamectl set-hostname takos
@ -123,7 +123,7 @@ hostnamectl set-chassis server
127.0.0.1 takos
```
See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd.
See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd, and <https://blog.ivansmirnov.name/set-up-pihole-using-docker-macvlan-network/>.
```ini /etc/systemd/network/wired.network
[Match]
@ -164,13 +164,13 @@ Scope=link
Destination=10.0.1.100/30
```
`ip` equivalent to the above settings:
`ip` equivalent to the above config:
```bash
ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim
ip a add 10.0.1.103/32 dev dns-shim # assign host ip to shim defined in docker-compose.yml
ip link set dns-shim up # enable interface
ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet to shim interface
ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim interface
ip a add 10.0.1.103/32 dev dns-shim # assign the interface an ip address
ip link set dns-shim up # enable the interface
ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet (.100 - .103) to the interface
```
```bash
@ -189,7 +189,7 @@ drill ddg.gg
If `networkctl` keep showing `enp5s0` as `degraded`, then run `ip addr add 10.0.1.2/24 dev enp5s0 ` to manually assign static IP address for the workaround.
## finalize
## Finalize
```bash
exit # leave chroot
@ -204,7 +204,7 @@ timedatectl set-ntp true
timedatectl status
```
## shell
## Shell
```bash
pacman -S zsh
@ -217,7 +217,7 @@ cd ~/.dotfiles
reload
```
## user
## Setup operator user (i.e. user without superuser privilege)
```bash
passwd # change root passwd
@ -235,7 +235,7 @@ usermod -aG sudo <user> # add local user to sudo group
visudo -c
```
## ssh
## SSH
```bash
pacman -S openssh
@ -265,7 +265,7 @@ cd yay
makepkg -si
```
## smartd
## S.M.A.R.T.
```bash
pacman -S smartmontools
@ -275,7 +275,7 @@ smartctl -t short /dev/sda
smartctl -l selftest /dev/sda
```
## nvidia
## NVIDIA drivers
```bash
pacman -S nvidia-lts # 'nvidia' for 'linux' package
@ -283,7 +283,7 @@ reboot
nvidia-smi # test runtime
```
## docker
## Docker
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/arch-overview.html
@ -340,7 +340,7 @@ services:
# Additional setup
## fail2ban
## Fail2ban
```
pacman -S fail2ban
@ -385,10 +385,10 @@ banaction = iptables-allports
```bash
systemctl enable --now fail2ban
fail2ban-client status mailu
fail2ban-client status sshd
```
## telegraf
## Telegraf
```bash
yay -S telegraf
@ -500,6 +500,8 @@ systemctl enable --now telegraf
Dynamic DNS for Cloudflare.
> Start [the GitHub repo](https://github.com/uetchy/cfddns) if you like :)
```
yay -S cfddns sendmail
```
@ -515,13 +517,14 @@ notification:
```ini /etc/cfddns/domains
example.com
dev.example.com
example.org
```
```
systemctl enable --now cfddns
```
## backup
## Backup
```bash
pacman -S restic
@ -554,7 +557,7 @@ WantedBy=timers.target
```bash /etc/backup/run.sh
#!/bin/bash -ue
# usage: run.sh
# https://restic.readthedocs.io/en/latest/040_backup.html#
export RESTIC_REPOSITORY=/path/to/backup
@ -575,8 +578,8 @@ restic backup --tag system -v \
# data
restic backup --tag data -v \
--exclude 'appdata_*/preview' \
--exclude 'appdata_*/dav-photocache' \
--exclude 'appdata_*/preview' \ # nextcloud cache
--exclude 'appdata_*/dav-photocache' \ # nextcloud cache
/mnt/data
# prune
@ -589,8 +592,54 @@ restic forget --prune --group-by tags \
restic check
```
```bash /etc/backup/show.sh
#!/bin/bash
# usage: show.sh <file|directory>
# https://restic.readthedocs.io/en/latest/050_restore.html
export RESTIC_REPOSITORY=/path/to/backup
export RESTIC_PASSWORD=<passphrase>
export RESTIC_PROGRESS_FPS=1
TARGET=${1:-$(pwd)}
MODE="ls -l"
if [[ -f $TARGET ]]; then
TARGET=$(realpath ${TARGET})
MODE=dump
fi
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique| .[]' | fzy)
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
>&2 echo "Command: restic ${MODE} ${ID} ${TARGET}"
restic $MODE $ID ${TARGET}
```
```bash /etc/backup/restore.sh
#!/bin/bash
# https://restic.readthedocs.io/en/latest/050_restore.html
export RESTIC_REPOSITORY=/path/to/backup
export RESTIC_PASSWORD=<passphrase>
export RESTIC_PROGRESS_FPS=1
TARGET=${1:?Specify TARGET}
TARGET=$(realpath ${TARGET})
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique | .[]' | fzy)
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
>&2 echo "Command: restic restore ${ID} -i ${TARGET} -t /"
read -p "Press enter to continue"
restic restore $ID -i ${TARGET} -t /
```
```bash
chmod 700 /etc/backup/run.sh
chmod 700 /etc/backup/{run,show}.sh
ln -sf /etc/backup/restic.{service,timer} /etc/systemd/system/
systemctl enable --now restic
```
@ -598,74 +647,22 @@ systemctl enable --now restic
## Kubernetes
```bash
pacman -S kubeadm kubelet kubectl
systemctl enable --now kubelet
kubeadm init --pod-network-cidr='10.244.0.0/16'
cp /etc/kubernetes/admin.conf ~/.kube/config
pacman -S minikube kubectl
minikube start --cpus=max
kubectl taint nodes --all node-role.kubernetes.io/master- # to allow allocating pods to the master node
# setup flannel network manager
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# setup nginx ingress controller
# TODO
minikube ip
kubectl cluster-info
kubectl get nodes
kubectl get pods -A
kubectl get cm -n kube-system kubeadm-config -o yaml
```
- [Kubernetes - ArchWiki](https://wiki.archlinux.org/index.php/Kubernetes)
- [Kubernetes Ingress Controller with NGINX Reverse Proxy and Wildcard SSL from Let's Encrypt - Shogan.tech](https://www.shogan.co.uk/kubernetes/kubernetes-ingress-controller-with-nginx-reverse-proxy-and-wildcard-ssl-from-lets-encrypt/)
## wildcard certs
## Audio
```bash
pacman -S certbot certbot-dns-cloudflare
echo "dns_cloudflare_api_token = <token>" > ~/.secrets/certbot/cloudflare.ini
chmod 600 ~/.secrets/certbot/cloudflare.ini
certbot certonly \
--email y@uechi.io \
--agree-tos \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
-d "*.uechi.io"
openssl x509 -in /etc/letsencrypt/live/uechi.io/fullchain.pem -text
certbot certificates
```
```ini /etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook "docker exec nginx-proxy-le /app/signal_le_service"
```
```ini /etc/systemd/system/certbot.timer
[Unit]
Description=Twice daily renewal of Let's Encrypt's certificates
[Timer]
OnCalendar=0/12:00:00
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target
```
- [Certbot - ArchWiki](https://wiki.archlinux.org/index.php/Certbot)
- [Welcome to certbot-dns-cloudflare’s documentation! — certbot-dns-cloudflare 0 documentation](https://certbot-dns-cloudflare.readthedocs.io/en/stable/)
- [docker-letsencrypt-nginx-proxy-companion/Standalone-certificates.md at master · nginx-proxy/docker-letsencrypt-nginx-proxy-companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Standalone-certificates.md)
## audio
```bash
pacman -S alsa-utils # maybe requires reboot
pacman -S alsa-utils # maybe requires rebooting system
usermod -aG audio <user>
# list devices as root
@ -730,18 +727,18 @@ pcm.!default {
- [ALSA project - the C library reference: PCM (digital audio) plugins](https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html)
- [Asoundrc - AlsaProject](https://www.alsa-project.org/wiki/Asoundrc)
## firewall
## Firewall
```bash
pacman -S firewalld
# TODO
systemctl enable --now firewalld
```
See [Introduction to Netfilter – To Linux and beyond !](https://home.regit.org/netfilter-en/netfilter/).
# Maintenance
## quick checkups
## Quick checkups
```bash
htop # show task overview
@ -754,7 +751,7 @@ nvidia-smi # verify nvidia cards
ps aux | grep "defunct" # find zombie processes
```
## analyze logs
## Delve into system logs
```bash
journalctl -p err -b-1 -r # show error logs from previous boot in reverse order
@ -766,29 +763,36 @@ journalctl _PID=2434 -e # filter logs based on PID and jump to the end of the lo
journalctl -g 'timed out' # filter logs based on regular expression. if the pattern is all lowercase, matching is case insensitive
```
```
g - go to the first line
G - go to the last line
/ - search for the string
```
- g - go to the first line
- G - go to the last line
- / - search for the string
## force override installation
## Force overriding installation
```bash
pacman -S <pkg> --overwrite '*'
```
## fs issue checklist
## Check memory modules
```bash
pacman -S lshw dmidecode
lshw -short -C memory # lists installed mems
dmidecode # shows configured clock speed
```
## File-system related issues checklist
```bash
smartctl -H /dev/sdd
# umount before this ops
# umount the drive before this ops
e2fsck -C 0 -p /dev/sdd1 # preen
e2fsck -C 0 -cc /dev/sdd1 # badblocks
```
# Common Issues
# Common issues
## Longer SSH login (D-bus glitch)
@ -846,6 +850,12 @@ This occurs after updating linux kernel.
- Run `docker run --rm --gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools -it nvidia/cuda:10.2-cudnn7-runtime nvidia-smi` once.
## `[sudo] Incorrect password` while password is correct
```bash
faillock --reset
```
# Useful links
- [General recommendations](https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups)

View File

@ -3,7 +3,7 @@ title: OAuth 2.0 と JWT 関連 RFC
date: 2021-02-11
---
個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べています
個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べ
## [RFC6749](https://tools.ietf.org/html/rfc6749) — The OAuth 2.0 Authorization Framework

View File

@ -3,51 +3,50 @@ title: 新しい自宅サーバーの構成
date: 2021-02-13T00:00:00
---
10 年ぶりにサーバーを更新しました。初めての AMD、初めての DDR4、初めての NVM Express です。
10 年ぶりにサーバーを更新した。初めての AMD、初めての DDR4、初めての NVM Express
# 用途
- セルフホスト (Docker)
- メールサーバー
- Nextcloud(ファイル、カレンダー、連絡先等)
- プライベート Docker レジストリ
- VPN 等
- 各種セルフホスト (Docker)
- Docker Swarm / K8s のマスター
- 計算実験
- Docker Swarm マスターノード
- VS Code Remote SSH のホストマシン
- VPN 他
# スペック
重いタスクを並列してやらせたいので最優先は CPU とメモリです。メモリはデュアルチャンネルにしたいので [DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選びました。CPU クーラーは Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) です
重いタスクを並列してやらせたいので最優先は CPU とメモリ。メモリは[DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選んだ。CPU クーラーは静音性を考えて Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) 。
> 結果から言うとメモリはもっと必要でした。巨大な Pandas データフレームを並列処理なんかするとサクッと消えてしまいます。予算に余裕があるなら 128GB ほど用意したほうが良いかもしれません
> 結果から言うとメモリは 64GB では足りなかった。巨大な Pandas データフレームを並列処理したり、DeepSpeed でモデルの重みをオフロードするたびに OOM が発動してしまう。最終的に 128GB まで増やす羽目になった
> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなるなど様々な厄災に襲われました。後日 Hynix 製のチップを搭載した V-color 社の ECC 付き U-DIMM に交換してからは、サーバーが安定動作するようになり現在に至ります。やはり 365 日稼働し続けるサーバーには最初からケチらずに ECC 付きメモリを選んでおいた方が賢明です
> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなる災害が起きた。後日 ECC 付きのメモリに交換してからは、現在に至るまでメモリ関連の異常は発生していない。常時稼働するサーバーには最初から ECC メモリを選ぼう
GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用しました。グラフィックメモリが 12GB ちょっとですが、最大ワークロード時でも 5GB は残るので今のところ十分です。必要になったタイミングで増やします
GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用した。グラフィックメモリが 12GB ちょっとしかないが、最大ワークロード時でも 5GB は残るので今のところ十分。
記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD です。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にします
> 結果から言うと GPT-J や Megatron-LM を始めとした億パラメータ級のモデルを学習・推論させるには、DeepSpeed の助けがあったとしても最低 16GB の VRAM が必要だった
マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にしました
記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD 。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にする
電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選びました。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度でした。今後 UPS を買う場合はその付近+バッファを考慮したグレードを選ぶことにします
マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にした
ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/) です
電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選んだ。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度だった
OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選びました。ミニマルなところが好きです。本当に何も用意してくれません。セットアップウィザードとかないです。`which`すらインストールしなければ使えません
ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/)
Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いたので読んでください。入力したコマンドを全て記録しました
OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選んだ。ミニマルと実用の間のバランスが取れていて好み
また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)しました。そちらもご覧ください。
Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いた。
また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)した。
# パーツ選定時のポイント
- [WikiChip](https://en.wikichip.org/wiki/WikiChip)で CPU のモデルやスペックを調査する
- [PCPartPicker](https://jp.pcpartpicker.com/)でパーツのコスト計算をする
- [Bottleneck Calculator](https://pc-builds.com/calculator/)で CPU と GPU の組み合わせを選び、そのうちどちらが性能のボトルネックになるか調べる
- [UserBenchmark](https://www.userbenchmark.com/)でユーザーが投稿したベンチマーク結果を眺める
- パーツ購入前に [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリと相性が良いかチェックする
- [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリとパーツの相性をチェックする
- CPU クーラーは大口径の方が静か
- メモリはデュアルチャンネルによる高速化を目指し 2 枚構成にする
- PSU は Seasonic が評判良い
- 東芝 D01 が HGST の系譜
- [B550](https://www.amd.com/en/chipsets/b550) は長期運用に向いている(らしい)
@ -57,7 +56,7 @@ Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/insta
# 組立ての勘所
- 年間はすべての箱・書類を取っておく
- 少なくとも 1 年間はすべての箱・書類を取っておく(特にメモリは箱自体が保証書代わりになっている場合がある)
- 筐体は無視してまずマザボ、CPU、クーラー、(オンボードグラフィックが無い CPU なら)グラボ、そして電源を繋いで通電・動作テストをする
- [MemTest86](https://www.memtest86.com/)でメモリの動作テストを最後までやる(エラーが出たら交換依頼)
- USB ブートで OS の起動確認
@ -68,4 +67,4 @@ Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/insta
- 駄目ならマザボまたはアダプターメーカーからアップデートを探す
- 安い筐体のネジは柔いことがあるため、強く押し込みながら少しずつ回す
- 山が潰れてきたらゴムシートを挟む
- すべて動いたら、[Probe を送信](https://linux-hardware.org/index.php?view=howto)してデータベースに貢献
- すべて動いたら、[Linux Hardware Database に Probe を送信](https://linux-hardware.org/index.php?view=howto)して貢献

View File

@ -3,12 +3,12 @@ title: 最小送金回数で精算する割り勘アルゴリズム
date: 2021-02-14T00:00:00
---
大人数でキャンプを楽しんだあとに待っているのは耐え難き送金処理です
次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えましょう。
大人数で旅行を楽しんだあとに待っているのは耐え難き精算・送金処理だ
次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えう。
# tl;dr
アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」です。
アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」
1. 全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)
2. 降順でソート(出費過多が先頭)
@ -17,7 +17,7 @@ date: 2021-02-14T00:00:00
# 実験
実際にコードを書いて本当に望んでいる結果が得られるのかを検証します。
実際にコードを書いて本当に望んでいる結果が得られるのかを検証す
```js split-bill.js
const history = [
@ -122,7 +122,7 @@ for (const [_, { name, consumption }] of data) {
}
```
`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られます
`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られ
```md
# Transaction table
@ -145,4 +145,4 @@ B virtually paid ¥81 in total
C virtually paid ¥76 in total
```
プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由です。面倒なことは全部コンピューターにやらせよう。
プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由だ。面倒なことは全部コンピューターにやらせよう!

View File

@ -3,7 +3,7 @@ title: 手のひらサイズのオイルランタン
date: 2021-06-08T00:00:00
---
UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作りました。
UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作た。
![](lantern.jpeg)
@ -17,7 +17,7 @@ UCO キャンドルランタンを改造して手のひらサイズのオイル
# 材料
ほとんどのパーツはドラッグストアやホームセンターで調達できます
ほとんどのパーツはドラッグストアやホームセンターで調達でき
1. 大正漢方胃腸薬(30 ml)
![](taisho.png)
@ -70,8 +70,8 @@ UCO キャンドルランタンを改造して手のひらサイズのオイル
- M8 ボルトが通り、外径がガラス内径に近い低めの瓶を探す
- ガスケットで密封?
## M6 ボルトは微妙
## 失敗例: M6 ボルトは微妙
ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまった。あまりオススメできない。
![](comparison.jpeg)
ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまう。