OmniAICreator/Qiita-1.07M huggingface dataset:
肛門のSLI/SLOを定義する

# おことわり

そこかしこに汚い表現があります、ごめんなさい :bow: 

---

先日、お腹の調子が悪い日がありまして
収まったと思って油断して外出したらビッグウェーブが来てひどい目にあいました
なんとかギリギリで間に合い事なきを得ました

そこで、最近サービスの可用性についていろいろ調べていたせいか
肛門は1回のミスも許されないから大変だなあなどと考えてしまいました
（人体にはもっとエラーが許されない器官がたくさんありますが…）

そこで（？）、今回は肛門のSLI/SLOを定義してみようと思います

# サービスに求められるもの

本来であれば違うんでしょうけど、この流れなので

__うんこを漏らさない__

これが肛門というサービスに求められるものとします

# 「うんこを漏らす」とは

これは考え方が分かれると思います

- トイレ以外で出すこと
    - 草むらに駆け込むのはアウト
- 自分の意志に反して出ること
    - 草むらに駆け込むのはセーフ
    - でも諦めるのはアウトなのでは
- 特殊な例外の考慮
    - 漏れるのを覚悟でバラムツを食べた

このあたりが考慮事項として挙げられます
草むらNGなどの要件は肛門のユーザーによって変わってくると思います
ただし草むらをNGとすると、草むらチャンスがあってもひたすらトイレを目指すことになり、大惨事に発展する可能性がありますので、慎重に話し合いをすべきです
インシデントに重みを付けて草むらは点数を軽く…などとする考えもあるかもしれませんが、SLI定義はシンプルに保つべき（SRE本より）ですのであまり良くないでし__

今回は一番シンプルな「トイレ以外で出すこと」を「うんこを漏らす」の定義とします
つまり、私の肛門に求められることは、__トイレ以外でうんこを出さないこと__です

# 計測方法

うんこを漏らさない率を測定するために、計測する単位を決めましょう

- デイリー
    - 1日を単位として、何日うんこを漏らさなかったかを計測します
    - 1日に複数回漏らした場合の考慮ができなく、1回漏らしたらその日はいくら漏らしてもサービス稼働率が下がることはないので注意が必要です
- 時間
    - デイリーの弱点を補うため、うんこを漏らしている時間で計測します
    - 漏らしてから処理が終わるまでの時間、ということになるでしょか
        - しかしそれは「肛門の稼働」から離れているような気がします
    - 時間の長短で漏らしたダメージがそこまで増減するのか、という疑問もあります
- 機会
    - 防御機会に対するセーブ成功率、と考えるのは良さそうな気がしますが、その場合は「防御機会」を定義する必要がありそうです
        - お腹がグルっとしてヤバい、となったのを1回とするパターン
        - 一般的な肛門の危機は、小さな波や大きな波が複数押し寄せて、それを耐えてトイレ到着で解決。というのが一連の流れになるので、そのひとまとまりを1回とするパターン
            - これは例外が結構ありそうです

今回は一番シンプルなデイリーにしようと思います
1日に複数回漏らした場合はどうするの、という部分は残したままですが、毒を食らわば皿までの精神で（？）

# SLO

目標値はどうしましょう
そりゃあ100%でしょう…と言いたいでしょうけど、100%は目指すなとSRE本に書いてあったので考えてみましょう

単位が1日なのでかなりざっくりとした値になります

- 100日に1回漏らす = 99/100 = 99%
- 1年に1回漏らす = 364/365 ≒ 99.72%
- 2年に1回漏らす = 769/770 ≒ 99.87%
- 3年に1回漏らす = 1094/1095 ≒ 99.91%

うーん、1年に1回が妥当なところですかね
3年に1回はちょっと厳しい気がしますし、100日に1回は漏らしすぎな気がします
これは私の個人的な感覚によるものです、各々体質もあるでしょうし
冒頭では1回でも許されないと言いましたが…

ところで2年を超えてくるともうほとんどパーセンテージ変わらないんですね

# 私の肛門のSLI/SLO

__トイレ以外でうんこを出してしまう日を1年で1回に抑える__

1回漏らしてもらったらその後1年は絶対に漏らさないように対策をし、危ない橋は絶対に渡りません

逆に、本来のSLOの考え方で行くと、1年に1回は出してもいい（エラーバジェット）、ということになります
直近1年うんこ漏らしてないからちょっとお腹の調子悪くてもガンガン電車に乗ってこ！という考え方です
いやー、それはさすがにちょっとないですね、すいません

# ほんとに
すいませんでした :rolling_eyes:
Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED

modelをfitするときにタイトルのようなエラーが出たが，私の場合はGPUの総メモリを制限することで解決した．
参考: https://github.com/tensorflow/tensorflow/issues/45779

# 環境
Ubuntu20.04LTS
cuda 11.1
cuDNN 8.0.5
tensorflow 2.4
GPU: RTX3070

#解決策
https://www.tensorflow.org/guide/gpu#limiting_gpu_memory_growth にあるコード

```python
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)
```

を事前に実行することで解決した．
日常生活を支える技術

この記事は[ラクスAdvent Calendar 2021](https://qiita.com/advent-calendar/2021/rakus) 11日目の記事です。

## はじめに
日々、生活をしていると、面倒に感じることってたくさんありますよね。

私は怠惰なので[^1]、少しでも楽をしたいです。

ということで、この記事では、日々の生活をエンジニアリングを用いて少し楽にしたことについてお話したいと思います。

## 何を楽にしたのか

* ゴミ収集日の通知
    * ゴミ出しってついつい忘れちゃいますよね
* 帰宅予定の通知
    * いちいち聞くのもめんどくさいけど、予定がわからないのも困る

## どうやって楽にしたのか

LINE Messaging APIとFirebaseを使いました。
LINEをUIとして使うことで、アカウントを友だちに追加するだけで、プッシュ通知などの機能を実現することができました。
Firebaseについてはある程度触ったことがあり[^2]、ちょっとしたプロトタイピングにはもってこいのBaasとして採用しました。

### 構成図
![Untitled Diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933553/5d6b525b-97a9-7787-b67a-245695665785.png)

### 動作

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933553/24fe5bab-929b-d29e-c7a2-7962b4ce1f85.png)

**人類を幸せにすることを生業とする**スカイネットくん[^3]です。

* 予め設定された時刻になると、Cloud SchedulerによってCloud Functionsが実行され、Messaging API経由で各種通知が届きます。
    * 7時：ゴミ収集日通知
        * 曜日に応じてメッセージを送ってくれます。
    * 16時：帰宅予定登録通知
        * 今日の帰宅時間登録を促すメッセージを送ってくれます。
        * Messaging APIのクイックリプライという機能を使用しており、自分で値を入力しなくても、予め用意した選択肢がメッセージと共に表示されるため、タップするだけで予定を登録できます。ここで登録した値をCloud Firestoreに保存しています。
        * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933553/9ca311f4-288d-ed86-99e9-d1caf58d63d2.png)

    * 18時：上記で登録した時間に応じて、その日の帰宅予定が通知されます。

## 良い点

* メッセージが届くとプッシュ通知が来るので、返信を忘れない
* 返信が簡単（通知をタップしてトーク画面に遷移したらリプライをタップするだけ、文書を書く必要がない）

**自動化すると想像以上にノンストレス**

## 苦労したこと

* Cloud FirestoreのAPIに慣れてなくて、クエリできるようになるまで半日かかった。
* Cloud Functionsのデプロイに思いの外時間がかかるので、動作確認のリードタイムが長かった。[^4]

## 今後の展望

* GoogleカレンダーAPIで予定を引っ張ってきて、今週の予定一覧とか通知できると便利そう
* 日々の帰宅予定データを貯めているので、逆に帰宅予想とか通知できると面白いかも

## おわりに

ちょっとした個人開発は、生活が楽になるだけでなく、技術力も磨けて一石二鳥！

[^1]: [プログラマの三大美徳] (https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E4%B8%89%E5%A4%A7%E7%BE%8E%E5%BE%B3)

[^2]: とはいえFirebase Functions、Cloud Firestoreは触ったことがなかったのでめっちゃ苦戦した

[^3]: 名前の由来は某サイボーグがサムズアップしながら溶鉱炉に沈んでいく映画

[^4]: jestを使ったローカルでのテストができるように後からリファクタリングしました。TypeScriptとmodule周りの環境設定で大苦戦しました。
BrowserにあるObserverについて

##Preface
現状、Web Browserは現在の一番使われるApplicationなんじゃないかと思いませんか？
大分Web Browserから色々のサービスをアクセスできるようになりました。ユーザーが多くなって、要求もたくさん望まれる。それため、Web Browserもたくさんの機能がどんどん追加されます。その色々の機能から一つのInterfaceを紹介したいと思います。 


## Observer
Observer Interfaceの実際の存在はないですが、WebBrowser APIの種類として述べたいです。このAPIではDOM Elementなどを監視（Observe）して、その変化に対してCallbackを実行する。

https://developer.mozilla.org/en-US/docs/Web/API
このドキュメントによりますと、APIとして２種類があります:

- [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
- [Resize Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API)

でも実際のInterfaceがその二つの上で、他もあります。API未公開するかわかっていません

そのInterfaceはこちら：
- [IntersectionObserver] (https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver)
- [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
- [MutationObserver] (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
- [PerformanceObserver] (https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver)
- [ReportingObserver](https://developer.mozilla.org/en-US/docs/Web/API/ReportingObserver)


このObserver達の特徴として先述べた通り、`observe`という関数があります。
実際[Typescript方定義](https://microsoft.github.io/PowerBI-JavaScript/modules/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.html)を見ればこのInterface達が親のInterfaceをExtendすることはありません。見たら`observe`の引数がバラバラですね。


今回はここまでです、次回Interfaceを一つ一つで紹介しておきます。ドキュメントを見たら把握できると思いますので、読んでいきましょう！
サーバー再起動前後はプロセス(etc)を取得しよう

Plannning-Venue Advent Calendar 2021の6日目です。

https://adventar.org/calendars/7174

前日はnginxで静的サイトの構築でした。

https://www.nzshiroko-bou.com/2021/12/nginx.html?m=1

普段はApacheを触ることがほとんどなので、早速やってみたいと思います。


さて、今回の記事はLinuxサーバーの再起動についてです。

個人で運用しているサーバーの再起動は(私も)結構適当にえいやっとやってしまうのですが、
これがクライアントのサーバーだと話が変わってきます。
素直に再起動してくれればよいのですが、再起動後に不具合が発生したときの保険ということで、
再起動前後に立ち上がっているプロセスを保管しておくとトラブルシュートに役立ちます。

一例として、私がサーバーを再起動する際に教わった各プロセス等の取得について書いていきます。
以下に書くものよりもっとこうしたほうが良いのでは？というものがあればコメントいただけると幸いです。
繰り返し書きますがこれはあくまで一例です。

では行きましょう。

# 最初に
なにはともあれログとして残す上で以下のコマンドを実行します。

```
$ who
$ w
$ hostname
$ ifconfig
$ df -h
```

・whoとwコマンドでログイン情報を確認
・hostnameとifconfigコマンドで対象サーバーを確認
・dfコマンドで容量確認

こんな感じで叩いておけば対象確認と作業前の確認は一通り問題ないかと思います。
後は適当なディレクトリを用意してあげて作業開始です。

以下それぞれのコマンド実行結果をファイルに出力して保存していきます。

# ps

psコマンドで全ユーザの全プロセスを取得します。
オプション等で派閥があるようですが、私は以下のコマンドを実行しています。

```
$ ps auxww
$ ps axww
```

違いは出力フォーマットです。トラブった状況次第でどっちが見やすいかが変わってくると思うので私は両方取っている感じです。

psコマンドのその他オプション等についてはこちら

https://linuxjm.osdn.jp/html/procps/man1/ps.1.html

# netstat

RHEL 7以降では非推奨となっているコマンド(代替はssコマンド)で、デフォルトではインストールされていない場合も増えてきましたね......
だけど叩けるならnetstatでいいじゃんってことで実行しちゃってます。
※EC2だと大体叩けるのでなんだかんだ便利...ホントは変えたほうが良いのですが......

以下2つのコマンドを実行しています。

```
netstat -anp
netstat -rn 
```

オプションについて書いていくと長くなりすぎてしますので以下のmanページでご確認ください(ぶん投げ)

https://linuxjm.osdn.jp/html/net-tools/man8/netstat.8.html

# mount

mountコマンドで現在のmount状況を確認しておきます。
これはオプション無しでそのままです。

```
$ mount
```

その他オプション等についてはこちら

https://linuxjm.osdn.jp/html/util-linux/man8/mount.8.html

# iptables

Amazon Linux等ではセキュリティグループがあるのでデフォルトでdisableされていますが、NATインスタンスだったりDoS対策等でenableになっている場合があります。
再起動の際に稼働状況を確認し、稼働している場合は状態を保存しておきましょう。

```
$ iptables -L
$ iptables -L -t nat
```

-Lで全てのチェインのリストを一覧表示、-t natでNATテーブルを表示します。

詳細はこちら

https://linuxjm.osdn.jp/html/iptables/man8/iptables.8.html

# sysctl

カーネルのパラメータを確認します。
sysctlコマンドに-aオプションを付けて、利用できるすべての値を表示します。

```
$ sysctl -a
```

その他オプションについてはこちら

https://linuxjm.osdn.jp/html/procps/man8/sysctl.8.html

# docker

dockerが稼働している場合はpsで稼働状況を確認しておきます。
-aもつけて停止中のコンテナも確認しておきましょう。

```
$ docker ps -a
```

その他オプションについてはこちら

https://docs.docker.com/engine/reference/commandline/ps/

# まとめ

ざっくりと紹介していきました。
サーバーの再起動は何が起こるかわからないので事前にできるだけの準備はしておいて損は無いですね。

今回初めてアドベントカレンダーに参加していますが、今までなんとなくの理解のままだったものが結構あってショックだったと共に
モチベーションアップにも繋がりました。果たしてSVN構築はできるのだろうか。。。
GASの doGet と doPost のイベントオブジェクトの型定義

`doGet(e)` と `doPost(e)` の引数`e`の型定義。
ブラウザでサクッと済ませたい時用。

# tl;dr
```js:typedef
/**
 * @typedef ApiEventGet
 * @property {string} queryString
 * @property {Object<string, string>} parameter
 * @property {Object<string, string[]>} parameters
 * @property {number} contentLength
 */

/**
 * @typedef _PostData
 * @property {number} length
 * @property {string} type
 * @property {string} contents
 * @property {string} name
 */

/**
 * @typedef ApiEventPost
 * @property {string} queryString
 * @property {Object<string, string>} parameter
 * @property {Object<string, string[]>} parameters
 * @property {number} contentLength
 * @property {_PostData} postData
 */
```

# usage
```js:api.gs
/**
 * @param {ApiEventGet} e
 */
function doGet(e) {
  const id = e.parameters.id
}

/**
 * @param {ApiEventPost} e
 */
function doPost(e) {
  const data = JSON.parse(e.postData.contents)
}
```

# 参照
[Web Apps  |  Apps Script  |  Google Developers](https://developers.google.com/apps-script/guides/web)
log4j2の脆弱性整理

log4j2についてなにが起こっているのかわからなかったので、
整理したことを記載する。

## 問題
![log4j_explanation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739718/d47f5694-eb4c-18fb-bcd1-358c04616707.png)

外部リソースへのアクセス情報が含まれたリクエスト情報を、
log4j2ライブラリのログ出力処理に渡すと、
ログ出力処理内で呼び出されているJNDIを通して外部リソースにアクセスできる。

攻撃者はlog4j2が外部リソースにアクセスできることを利用して、
ログ出力しているサーバ上で悪意のあるプログラムを実行させられる。

## log4j2
ロギングライブラリ。
数多のプロジェクトで利用されている。

## JNDI
Java Naming and Directory Interface
LDAPで、外部リソース（DB,ディレクトリサービスなど）にアクセスできるAPI

```java
package com.sun.jndi
```

## LDAP
LDAP
Lightweight Directory Access Protocol
外部リソースと通信するためのプロトコル

## 修正
https://github.com/apache/logging-log4j2/pull/608/commits/755e2c9d57f0517a73d16bfcaed93cc91969bdee
アクセス許可のあるLDAPのホストとクラスを定義して、
入力に対してアクセス許可されているかどうか判定するように修正

## 利用者としての対策
log4j-2.15.0-rc1 へ アップグレード

https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc1

## 参考
- https://www.randori.com/blog/cve-2021-44228/
- https://www.lunasec.io/docs/blog/log4j-zero-day/
- https://github.com/apache/logging-log4j2/pull/608/commits/755e2c9d57f0517a73d16bfcaed93cc91969bdee
- https://github.com/apache/logging-log4j2/pull/607/files
Windowsのコマンドライン引数でのクォートの話

この記事は、もともとQrunchというサービスに掲載していた記事ですが、サービスごとなくなっていました。今回、[ググって解決しづらかったこと Advent Calendar](https://qiita.com/advent-calendar/2021/gseach)のテーマにぴったりだと感じたので11日目の記事として再掲致します。

以下、公開当時の内容をそのまま載せます。

ここ数年開発時はPowerShellを使っていて、ずっと困っていたことがありました。

例えば`git commit`の`-m`オプションにダブルクォートを渡したくなったとき、[PowerShellではエスケープシーケンスにバッククォートを使う](https://bayashita.com/p/entry/show/90)とのことなので👇のように書いてみたとします:

```pwsh
> git commit -m "Implement `"Hello, world`" finally!"
error: pathspec 'world finally!' did not match any file(s) known to git
```

なぜかダブルクォートが適切にエスケープされていないかのようなエラーになってしまいました。

シングルクォートで囲えばいいだろ、と思ってやってみてもやっぱりダメ:

```pwsh
> git commit -m 'Implement "Hello, world" finally!'
error: pathspec 'world finally!' did not match any file(s) known to git
```

おかしいなぁと悩みながら、なんとなくバッククォートの前にバックスラッシュを付けてみたところ、なんとうまくいくじゃありませんか！

```pwsh
> git commit -m "Implement \`"Hello, world\`" finally!"
On branch master
Your branch is up to date with 'origin/master'.

...
```

なぜだろうと首をひねっていたところ、[Twitterでこんな⬇️情報を教えていただきました](https://twitter.com/objectxplosive/status/1262768174761521152):

- [How Command Line Parameters Are Parsed](http://daviddeley.com/autohotkey/parameters/parameters.htm)

必要なところをかいつまんで説明しましょう。

Windowsにおいてコマンドを呼び出す最もプリミティブなAPI、--- つまり、Windowsで子プロセスを作るあらゆるアプリケーションが間接的に使うAPI ---、[`CreateProcess`](https://docs.microsoft.com/ja-jp/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa?redirectedfrom=MSDN)では、コマンドライン引数は、文字列の配列ではなく**一つの文字列**として渡されるそうなのです。  
しかし、それでは普通のC言語のアプリケーションを書いたとき`main`関数の`argv`が常に2つの文字列<small>（1つめはコマンドの名前ですね）</small>になってしまって不便なので、呼び出された**コマンドが<small>（`main`関数に渡す前に）</small>自らコマンドライン引数をパース**しているというのです！

その際どのようにコマンドライン引数をパースするかは、使用したプログラミング言語、特にCやC++ではVC++ランタイムのバージョンによって異なるそうです😵！

冒頭で紹介したダブルクォートに関するルールも、上記のページにもっと詳しく書かれています。  
つまりバッククォートだけでなくバックスラッシュを付ける必要があったのは、PowerShellの仕様ではなく、Windowsで動くコマンド全般に関する挙動だったんですね！  
どうりでPowerShellについて解説したページには出てこないワケです。

そして、今回は試してませんが、きっとコマンドプロンプトでも同じ問題にぶち当たるのでしょう。

Windowsではコマンドライン引数はアプリケーションがパースする、という話はどこかで聞き覚えがありましたが、ダブルクォートとかも自前で処理してたんですね😰...

ちなみに、実は同じ原因の問題は、`stack test`の`--test-arguments`を使うときにもしばしばぶち当たっていました。  
例えば、Hspecで書いたテストのうち、テストの説明に`foo bar`という（空白を含む）文字列を含むものを実行したいとき:

```pwsh
> stack test --fast --test-arguments "--match `"foo bar`""
Error: While constructing the build plan, the following exceptions were encountered:

Unknown package: bar

Some different approaches to resolving this:


Plan construction failed.
```

これも`git commit`の場合と同様、バッククォートの前にバックスラッシュを付ければ回避できます。

```pwsh
> stack test --fast --test-arguments "--match \`"foo bar\`""
```

もちろん、ダブルクォートの文字列リテラルの代わりに、シングルクォートの文字列リテラルでダブルクォートの前にバックスラッシュを付けるのでも🆗です:

```pwsh
> stack test --fast --test-arguments '--match \"foo bar\"'
```

これで完璧！🙌  
Windowsめんどくさいね！🏁
Unityログにタグをつけて見やすくする方法

この記事は [PONOS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ponos)の15日目の記事です。
昨日は[@honeniq](https://qiita.com/honeniq)さんでした。

## はじめに
Unityのログを標準のまま使用すると見辛くなってしまうことないですか？
開発が進めば進むほど様々なログが増えてしまい自分のログが埋もれてしまうなんて経験をした人も多いのではないでしょうか。
ログのためにあまり時間とお金をかけたくないけど、ログは見やすくしたい！
本日はその状況を打破するべくUnityのConsoleに表示されるログを見やすくする方法について考えてみました。
快適な開発への参考になれば嬉しいです。
(使用しているUnityは2020.3.4f1です)

##　Consoleの検索の有効活用
![スクリーンショット 2021-12-10 21.53.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357546/68ff0262-806d-bbca-a315-c694d6d59c22.png)
まずは元々ある機能でログを見やすくする方法考えました。
目をつけたのはConsole画面の検索機能を利用することです。

メッセージの前にタグ（グルーピングできる目印となれば何でも可です）を入れられるようにすることで必要なものだけ表示できるようにする方法。
ログを出すときにひと手間加える必要がありますが簡易に行えます。

```C#
UnityEngine.Debug.Log($"[{tag}]{message}", context);
```

上記のようにタグを埋め込んでおくと、Consoleの検索窓に対象のタグを入れるだけで見たいものが絞り込めるようになります。
タグ部分を太文字にするなどタグを入れるだけで目に付きやすくできるのでオススメです。

## タグを色付けして目に付きやすくする
続いては「Consoleの検索の有効活用」で紹介したタグをさらに有効活用する方法です。
ログ全て表示しておきたいけど自分の必要なログが探し辛い！といったケースもあるかと思います。
ただ、下の図のように全部白文字だと自分の見たいログがどれだか探せないといったことも。
![スクリーンショット 2021-12-10 22.19.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357546/3220c1da-12d7-fd4d-7f75-ee1572494789.png)
そんな時にタグ部分に色がついていたら探しやすいのでないでしょうか。
本文まで色がつくと逆に色が散らばりすぎて目がチカチカしそうなのでタグのみ色付けしてみました。

```C#
UnityEngine.Debug.Log($"<b><color=#{color}>[{tag}]</color></b>{message}, context);
```
上記のようにして色情報を渡してもらうなどがパッと思いつくところかと思います。
ただ、何色にするのかを自分で考えるのが大変という側面もあるかと思います。
であれば、タグの文字列から自動で色を作成できないか...を考えてみました！
今回は色被りは考慮していませんが自動であれば色を自分で考えなくて済むので楽になるかと思います。

## 文字列を数値に変換し色作成
さて、色を作成する前に考慮しないといけない点があります。
それはRGBカラーだと黒や灰色といったConsole上に載せるには見え辛くなる色がある点です。
見えない色が選ばれてしまうとログを見やすくするという本題から外れてしまい本末転倒な結果になってしまいます。
そこで見え辛い色を避けるためHSL形式で色を作成しRGBにする方式を取ろうと考えました。

```C#
int CalculateTotalColorIntToTagString(string tag)
{
    int val = 0;
    foreach (var c in tag)
    {
        val += (int)c;
    }
    return val;
}

string CreateColor(int colorInt)
{
    int correctionValue = colorInt / 360;
    // 色相を0~1の間に納める
    var hue = (float)(colorInt - (correctionValue * 360)) / 360f;
    // HSV形式をRGB形式に変換
    // 彩度と明度は固定。（数値は適当）
    var color = UnityEngine.Color.HSVToRGB(hue, 1, 1);
    // カラーコードに変換して返す
    return "#" + ColorUtility.ToHtmlStringRGB(color);
}
```
簡易的に作成してみました。
処理の流れとしてはタグの文字をCalculateTotalColorIntToTagStringで一文字ずつアスキーコードにして数値化し合算していきます。
その合計値をCreateColorに渡し、色相として扱いHSVを作成していきます。
彩度と明度を変更する必要はないかと思うのでここでは固定値で使用しています。
作成されたHSVをRGBに変換してカラーコードを作成しました。
![スクリーンショット 2021-12-10 23.54.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357546/48bbb533-370c-a1ad-4822-1d4d9ef1ed98.png)
タグ毎に色が変更されているのが確認できました！
これで見やすくなったのではないでしょうか。

## まとめ
ログの見せ方は少し工夫をすれば見えやすくする方法は様々あると思います。
外部のアセットを導入するなども検討してもいいかと思いますし今回のようにちょっとした方法で改善できる点もあるかと思います。
自分のプロジェクトにあった方法で快適な開発を目指しましょう！

明日は[@jesseniqiita](https://qiita.com/jesseniqiita)さんです。
組織体制が変わってから3ヶ月経っての新米リーダー振り返り

## はじめに

Qiita株式会社 アドベントカレンダー 11 日目は プロダクト開発グループの @fussy113 が担当します！

https://qiita.com/advent-calendar/2021/qiita

9 月からQiita 株式会社のエンジニアの組織体制が大きく変わりました。詳しくは @getty104 が記事を挙げているので気になる方は是非ご覧ください。

https://qiita.com/getty104/items/02c4d01c55cf9c5375e1

私はプロダクト開発グループの中の新しく発足されるチームのリーダーになりました。
そこから3ヶ月ほど経ったのですが、振り返ってみると、こう考える、こうすべきだったなと思うことがあるので、そちらの供養として記事にまとめていきます。
これからチームのリーダーをしていくという方に少しでも参考になればと思います。

## 諸注意

ここでのチームリーダーは以下の人として考えてます

- チームの目標達成に向けて、チームメンバーを引っ張っていく役割の方

また、これから学びを書いていきますが、チームの規模、役割、メンバーなどによってこれらは大きく変わってくると思います。
私のチームはざっとこんな特徴です。

- チームメンバー全員がエンジニア
  - 小~中規模くらい
- これまで別々のプロダクト開発を行なっていたチームが一つのチームとしてまとまった
- 比較的平均年齢の若いチーム

## 失敗からの学び

### 新チーム発足時、チームビルディングの時間はガッツリとるべし

9月から新しいチームでの開発がスタートし、プロジェクトなども進行が始まりました。
しかし最初はなかなかチームとしてうまく仕事を進めることができなかったように思います。

- これまで違う開発チームだったメンバーが集まっていたため、進め方などがバラバラで最適化されていなかったこと
- チームのメンバーそれぞれの強みや弱み、期待することが共有されていなかった
- メンバー同士が本音で語る場づくりができていなかった

プロジェクトを進めるうちにどんどん解決されていくと思って進めていましたが、チーム発足のタイミングでガッツリと時間をとって、チームの相互理解、関係の構築などを行なってもよかったなと今になって思います。
インセプションデッキ などを通じてチームとしての目的の統一、チームメンバーそれぞれの役割を明確にすることで、プロジェクトを進める際にも、最適なメンバーに任せることや、相談をすることがもっと早くできたと思います。

### タスクを抱え込まず、本当に必要なことに時間を割くべし

チーム発足の頃、私はよくIssue や開発外の細かい業務を巻き取って進めていました。スプリントの達成のため、他メンバーにスプリントゴールの達成に注力してもらいたいという意図があったのだと思います。
しかしこうやって私自身がIssue を多く持って進めるのは正しい選択ではありませんでした。
本来私が行うべきマネジメント業務などが疎かになったり、目の前のタスクを完了させるのに目が行きがちになってしまっていました。
私自身の開発工数などはあくまでバッファとして考え、それを使わずにできる方法を考えるように意識しています。

ついつい二つ返事で"自分でやります！" と答えていた内容も、みんなにお願いしたほうが早く終わるかも、もっと別の方法で簡単に出来るかもなどを考えて、本当にチームのために私がやるべき事に集中することが出来るようになるのだと学びました。

## まとめ

- 新チーム発足時、チームビルディングの時間はガッツリとるべし
- タスクを抱え込まず、本当に必要なことに時間を割くべし

## おわりに

チームリーダーの役割としてよく考えてみると当たり前だなと思うことがまだまだできておらず、自身の実力不足を痛感した3ヶ月でした。
細かく挙げるとまだまだ改善すべき点がいっぱい出てきます。
1on1 の際にフィードバックを伝えてくれる上司やメンバーにはいつも感謝しています。。。

若輩者ではありますが、最高のチームを目指して、みんなと一緒に私自身これからも成長していきたいです！

Qiita Advent Calendar 2021 の 12 日目は、 @xrxoxcxox が担当します、お楽しみに:christmas_tree:
Windows11にVisual Studio Codeをインストールする方法

# 概要
様々なプログラミング言語とプラットフォームに対応したコードエディタ（≒プログラムコードを書くためのアプリ）であるVisual Studio CodeをWindows11にインストールします。
Visual Studio Codeを利用しなくてもテキストエディターでコーディングすることはできますが、利用することでコーディングの生産性と品質が飛躍的に向上しますので必ず利用しましょう。
※Windows10の場合でも今回まとめた方法で準備することが可能です。

>参考：Visual Studio Code公式サイト
>https://azure.microsoft.com/ja-jp/products/visual-studio-code

# 事前準備
特になし

# 手順

### おおまかな手順の流れ

1. Visual Studio Codeのインストーラを公式サイトからダウンロードする
1. Visual Studio CodeをWindows11にインストールする

### 1. Visual Studio Codeのインストーラを公式サイトからダウンロードする

Visual Studio Codeの公式サイト（<a>https://azure.microsoft.com/ja-jp/products/visual-studio-code/</a>）へアクセスします。
公式サイトにある「Download now」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/61e795ac-485e-b4be-aef2-9b543eeccbc8.png)
パターンに合わせて3つのインストーラが用意されているので自分に合ったものをダウンロードします。
よくわからなければ「↓ Windows」のボタンをクリックしてください（あなたの環境に合うUser Installerがダウンロードされます）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/fc4595c1-55f1-8ef0-4913-d3c4cb48dad0.png)
<dl>
 <dt>・User Installer</dt>
 <dd>コンピューターにVisual Studio Codeのインストールを実行したユーザーでしかVisual Studio Codeを利用できない。</dd>
 <dt>・System Installer</dt>
 <dd>コンピューターにVisual Studio Codeをインストールすればユーザーを問わず誰でもVisual Studio Codeを利用できる。</dd>
 <dt>・.zip</dt>
 <dd>zipを解答するとインストールなしですぐにVisual Studio Codeを利用できる。</dd>
</dl>

ダウンロードが完了すれば終わりです。

### 2. Visual Studio CodeをWindows11にインストールする

１でダウンロードしたインストーラーを起動します。
［使用許諾契約書の同意］画面が表示されるので［同意する(A)］を選択し［次へ(N)＞］をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/afcf3a5b-5533-b472-37ed-4f04f31dccfc.png)
［インストール先の指定］画面が表示されるのでフォルダを選択し［次へ(N)＞］をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/9f054e27-3750-fb6c-4da8-75b2b589218d.png)
［スタートメニューフォルダーの設定］画面が表示されるのでフォルダを選択、もしくは［スタートメニューフォルダーを作成しない(D)］を選択し［次へ(N)＞］をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/3b051067-4286-1771-f564-f2da0f05707e.png)
［追加タスクの選択］画面が表示されるので追加タスクを選択し［次へ(N)＞］をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/b6747d58-54e0-5e67-1028-0be5ebd4801e.png)
［インストール準備完了］画面が表示されるので設定内容に問題なければ［インストール(I)］をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654264/3dc893f3-6d35-bff6-6f74-db8878d09a6b.png)
これでインストールは完了です。
zipをダウンロードした場合上記のインストールは作業は必要なく、解答したフォルダの中にある「Code.exe」を実行すればVisual Studio Codeが起動します。

ちなみに、Visual Studio Codeの拡張機能はVisual Studio Codeのインストール先フォルダではなく、ユーザーフォルダ（c:\Users\（ユーザー名））の直下に作られた.vscodeフォルダ配下に格納されていきます。そのため、Visual Studio Codeをアンイストールする際は、手動でこちらのフォルダを削除する必要があります。また、拡張機能のインストール先は固定されているため設定を変更することは出来ないようです（拡張機能をインストールするときにフォルダを指定指定する方法はある模様）。
AzureAppServiceにVueやReactのアプリがうまくデプロイできない問題

# はじめに

こんにちは。先日、[ハッカソンリーグ2021 -ルーキーリーグ](https://mashupawards.connpass.com/event/225670/)というハッカソンに参加してきました。
「azure製品を使いたおして、"ポストコロナの〇〇"をつくりだそう！」というハッカソンです！  
シェアハウスの友達と4人でwebサービスを作成し、なんと、優秀賞をいただくことができました！！！ 🎉🎉🎉🎉🎉

今回は、サービスを作成するにあたって,デプロイ時に**どハマった**ことを記事にしました。
同じ問題で時間を食い潰される方がでないように祈りを込めて......

# 要約

- 表題の問題が出たときは、以下のコマンドを、スタートアップ コマンド に設定しよう

```shell
pm2 serve /home/site/wwwroot --no-daemon --spa
# or 
pm2 serve /home/site/wwwroot/build --no-daemon --spa
```

# 何が起こったか

- いつも通りvueプロジェクトを作成、ローカルで動作確認した後、Githubにpush
- AppServiceのデプロイセンターで`Github Action`を作成
- Actionの実行履歴を見ると、正常にデプロイができている
- **あれ、デプロイ前と全く変わってないぞ :thinking: :thinking: :thinking: :thinking:**
- GithubActionの問題かもしれないので、VSCodeのAzureプラグインからデプロイしてみる
- **やっぱりうごかない！初期画面のまま! :thumbsdown: :thumbsdown: :thumbsdown: :thumbsdown:**

![スクリーンショット 2021-12-10 21.17.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266081/549c8d17-e212-f862-7c34-7315de6981d8.png)

# どう対処するか

デプロイしているものが悪いのか、デプロイ先が悪いのかと、dist(build後)のフォルダのみを対象にしたりしてみましたが、全くうまくいかず、調べまくってたところ、StackOverFlowに似た内容の質問を発見しました。

https://stackoverflow.com/questions/56624277/react-app-not-starting-in-azure-app-service

これによると、`pm2`(Node.jsアプリのプロセス管理)を、スタートアッププロセス中に実行するといいとのことでした。

自分はdistのみをデプロイする設定にしていたため、以下のコマンドをスタートアップコマンドに設定しました。

```
pm2 serve /home/site/wwwroot --no-daemon --spa
```

![スクリーンショット 2021-12-11 0.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266081/951c94da-0f50-00bd-dd2a-d9c4855493c7.png)

設定後、ポータルから再起動することで、無事アプリが起動しました！！！ 🎉🎉🎉🎉🎉

![スクリーンショット 2021-12-11 0.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266081/691fc46f-2eda-d716-78b8-553149a0d786.png)


# おわりに

ありがとうございました！ :bow: :bow: :bow:

本当は、ハッカソンで〇〇やりました！とか感想とか書こうかなと思ったのですが、
まぁまぁありふれている内容なので、純粋に自分が困った部分を書くことにしました。

ただ、せっかくなので、ハッカソンで何を作ったかをほんのちょっとだけ紹介しておきます。  

### 何のために、何を、どうやって作ったか

- 存在することで他の人の居心地を良くする人っていいよね
- その人たちが何らかの形で得をするような状態を作り出せたらいいよねという思想のもと、
- **他者の笑顔を作成することにポイントを付与・確認するシステム**を、
- **定期的に写真を撮り**、写っている人の幸せそうかどうかを中心とする**感情値を分析/保存**するという手法で、
- azureサービス(AppService, Functions, FaceAPI),ラズパイ,webカメラを利用して作りました。

以上！！！ [ProtoPediaはこちら](https://protopedia.net/prototype/2814) (デザインがひどい、説明文が少ないのは仕様です)
MySQL Server Exporterを使ってみよう

Prometheus（プロメテウス）という監視システムをご存知でしょうか？
PrometheusとGrafanaを組み合わせることでカッコいい統計情報の可視化が可能になります。

今回はその前段である
PrometheusのMySQL Exporterのインストールとセットアップまでご紹介します。


##環境準備

AlmaLinuxを利用しました。
まずはMySQL本体のインストール、起動を行います。

```
# cat /etc/redhat-release
AlmaLinux release 8.3 (Purple Manul)

# dnf install -y mysql-server
# systemctl start mysqld
```

統計情報取得用のアカウントを用意します。
パスワードは任意で設定してください。

```
# mysql
mysql> CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
```

##MySQL Server Exporterの準備

ここからが本題です。
以下からel8シリーズの最新をダウンロードします。
https://packagecloud.io/app/prometheus-rpm/release/search?q=mysqld

```
# wget --content-disposition https://packagecloud.io/prometheus-rpm/release/packages/el/8/mysqld_exporter-0.13.0-1.el8.x86_64.rpm/download.rpm
```

rpmのインストールを行います。

```
# rpm -Uvh mysqld_exporter-0.13.0-1.el8.x86_64.rpm
```

`/var/lib/prometheus/.my.cnf`に先程作成したユーザーとパスワードを記載します。
socket行にてUNIX domain socketによる接続を行います。

```
# cat /var/lib/prometheus/.my.cnf
[client]
user=exporter
password=XXXXXXXX
socket=/var/lib/mysql/mysql.sock
```

設定ができたら起動します。
自動起動も設定しておきます。

```
# systemctl start mysqld_exporter
# systemctl enable mysqld_exporter
```

以下のコマンドでmysqldが起動している旨の出力が得られれば成功です。
他にもたくさんの情報が取得できます。

```
# curl -s localhost:9104/metrics | grep ^mysql_up
mysql_up 1
```

Prometheusサーバーから取得できるようにポートの許可を入れておきます。

```
firewall-cmd --add-port=9104 --zone=public --permanent
firewall-cmd --reload
```

Prometheus／Grafanaでの可視化については他の記事を参照してください。
Microsoft 認定試験を無料で受験する方法まとめ

# はじめに
みなさん、Microsoft 認定試験がんばってますか？

今回は、これから初めて受験する人も、既にいくつか資格を保持している人も、知って得する無償バウチャー情報をまとめたいと思います。

:::note
私が知らないものもあるかも知れないので、ぜひ補足情報おまちしております。
:::

### 本記事の対象
* 基礎レベル（Fundamentals）の受験を検討している方
* 中級レベル（Associates）の受験を検討している一部の方

※　Associateでも専門的なものや、Expert以上のレベルだと無償バウチャーはない気がします

# 無償バウチャーが受けられるプログラム
## Virtual Training Day
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249707/6ab4e4b8-49cd-637b-927a-8bff0ca96ef8.png)

これが一番馴染みがあるかもしれませんね。
Microsoftアカウントを持っていて、何らかのイベントに参加したことがあると不定期にメールが届くんじゃないかと思います。

Virtual Training Day に参加し、2時間程度のWeb講座を受講することができます。
Fundamentalsレベル（AZ-900やDP-900など）の多くは、この講座を受講することで無償バウチャーが付与されます。

以下のページからも予定を確認できます。
[Microsoft Virtual Training Days](https://www.microsoft.com/ja-jp/events/top/training-days/?activetab=a1:primaryr3%3faaid%3dMDD)
[Event Experiences](https://events.microsoft.com/ja-jp/allevents/?language=%E6%97%A5%E6%9C%AC%E8%AA%9E&search=Virtual%20Training%20Day)

## Microsoft Ignite Cloud Skills Challenge
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249707/de6e72c4-4cd5-90c8-ac6f-205b824a7d60.png)
Ignite の時期に同時開催されるイベントです。
いくつかの試験の中から自分が受講したいものを選択し、MS Learn で経験値を取得することで無償バウチャーが付与されます。

## Certification Week
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249707/d1eff83d-1033-981f-b8fe-4b06a8576c75.png)

今年は8月23日～27日でしたが、毎年この時期なんでしょうか。
全世界で先着5000名なので見つけたら即ポチしましょう！

期間中、Teamsで開催されるセミナーに参加することで無償バウチャーが付与されます。
内容は基本的にすべて英語なので、まぁ聞き流す程度に・・・笑

・・・が、私はなぜか付与されませんでした。涙
サポートに問い合わせるのも面倒ですし諦めてしまいました。

## Certification Week for Partners
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249707/b0ca364c-343d-5a14-0bb5-79085bb94be9.png)

MPN（Microsoft　Partner Network）に参加している企業に向けて開催されているようです。
まだ私も未受講ですが、先ほどの Certification Week と同じような形かと思います。

## mstep
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249707/95f2dc9d-1d7f-5e40-ed8d-b8cbad51ce20.png)

こちらもMPN参加企業向けのサービスです。
Virtual Traning Day と同じようにWeb講座を受講する形となっています。
しかし対象は Fundamentals ではなく、Accosiates レベルのものが多くなっています。

こちらは8時間近くにも及ぶ長時間の講座となっています。
主に試験対策を目的としており、これを1日ちゃんとやればまず間違いなく合格できると思います。

講座が発表されてから短時間で定員になってしまうので、まめにチェックしましょう！

## その他
MS提携の教育プログラムを提供する企業から
「いま講座を受講すると、その後の試験料金は無償！！」
みたいなメールも来ます。ただこれは講座自体がウン万円かかるので、純粋に無償とはいえないかもしれないですね、。

# まとめ
いかがでしょうか。
会社で受験料をせがんでみたり、稟議出したりするのが煩わしい方や、「受験料かかるのに落ちたらどうしよう・・・」なんて心配に思っている方にはこういったプログラムは大変ありがたいんじゃないでしょうか。
ぜひ定期的にチェックしてタダで資格ゲットしましょう！！

この他にも同様のプログラムをご存知の方がいたらぜひ教えてくださいー。では。
ビルドエラー Algorithm HmacPBESHA256 not available

#FlutterでAndroidのビルド時にエラー
java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available

どうやらJDKのバージョンに関するエラーみたい。

##解決法
```
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key -J-Dkeystore.pkcs12.legacy
```
署名鍵を作るときに、このコマンドを叩いてkey.jksを生成すれば解決しました。
Excelでカレンダー作り

Excel関数でカレンダーを作ったときのメモ。


■数値から日付を作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2376158/97de7ffb-1178-d537-ba5c-dfe895a79cd1.png)

■先月末、今月末、来月末の最終日を表示
EOMONTH関数が便利
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2376158/93b4a20a-3a87-7bf6-39b4-f84c4fe74239.png)

■1ヵ月後、1ヵ月前
DATE関数を使う方法と、EDATE関数を使う方法があるが、EDATE関数の方が数式がシンプル！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2376158/f620c414-b67d-b063-f8c8-6b81e301f68c.png)

■日付書式を変更する
セルを選択 > Ctrl + 1 > [表示形式] > ユーザー定義　でも同じことができるが、
今回はTEXT関数を使って書式を変更してみた。
和暦も表示できることを確認した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2376158/481a2253-d9e1-9623-7e44-dacabfe981fd.png)
zxで環境変数を扱う

## 概要

zxスクリプトで環境変数を使用する方法を記します。

https://github.com/google/zx

## 公式サンプルを確認する

まず公式のREADMEに書いてあるサンプルを確認します。

```js
process.env.FOO = 'bar'
await $`echo $FOO`
```

https://github.com/google/zx#passing-env-variables

このサンプルから分かる通り、シェルコマンド内で環境変数を使うには、`process.env`に値が定義されている必要があります。
つまり、環境変数を使うには実行環境の環境変数として定義されていればよい、ということになります。

## 環境変数を定義する

環境変数を定義する方法として、大きく２つあります。
ひとつは実行環境の環境変数として定義する、もう一つは`.env`を使用する方法です。

### 実行環境の環境変数として定義する

環境変数が必要なスクリプトの用途として、CICDが多いと思います。
なのでCICDツールが提供している環境変数の機能を使うと簡単にできます。

### .envを使用する

今回の主題はこちら。
zxはNode環境で実行されるので、npmモジュールも使えます。
なので`.env`を利用するための`dotenv`モジュールをインストールして使ってみます。

https://github.com/motdotla/dotenv

まずは`dotenv`をインストール。

```zsh
yarn add dotnev
```

次に、`.env`ファイルに環境変数を用意。

```
HOGE=hogehogehoge
```

それでは環境変数を呼び出すスクリプトを書いてみます。

```hoge.mjs
#!/usr/bin/env zx

// .envの値がprocess.envに設定されます
require('dotenv').config()

// jsコードでの呼び出し
console.log(process.env.HOGE)
// コマンドで使用する場合は${VALUE}と書きます
await $`echo $HOGE`
```

これでzxで環境変数を扱うことができるようになりました。

ちなみに、`.env`の値を`export`や`source`といったコマンドで環境変数として定義する方法も試しましたが、うまくいかず、`dotenv`を使用するに至りました。

## おわりに

直近の自分の使用例は、JSアプリケーションでnpm scriptsの処理を書く際にzxを使いました。
↓使用イメージ

```package.json
  "scripts": {
    "postbuild": "zx upload-sourcemap.mjs"
  }
```

短いコマンドならば`package.json`内でscriptsに直接コマンドを書きますが、長くなってしまう場合は`zx`を使うと取り扱いがしやすいと感じますね。
chart.js × gon → 変数を用いた動的なグラフが描ける！【Rails】

chart.jsはグラフを描画できるツール。
gonというgemを利用することで、コントローラ内で定義した変数をjsファイルで扱えるようになります。

chart.jsを使ったグラフをrailsアプリに表示するまでの手順は以下の記事で紹介しています。今回はこの記事の続きです。
[chart.jsを使用して、3ステップで簡単にグラフを描く【Rails】](https://qiita.com/i-f/items/7a6f94c97421ba63e6be)

# 1. gonを使用する準備

Gemfileに以下を記述して`bundle install`

```Gemfile.
gem 'gon', '~> 6.2.0'
```

`application.html.erb`に以下の記述を追加

```application.html.erb
<head>
...
  <%= include_gon %>
...
</head>
```


# 2. gonを使ってchart.js用の変数に変換

ここでは`Record`というモデルに、`runday`（走った日）と`distance`（走行距離）というカラムを加えたテーブルを想定しています。`@weekly_records`は直近一週間分のrecordのデータが入っています。
※ pluckメソッドは引数に指定したカラム（distance）の値だけを配列として返してくれます。(今回はrundayとdistanceで一セットになっているデータがpluckメソッドによってdistanceの数値だけが入っている配列になっています)


```records_controller.rb
require "date"
def top
  @today = Date.today
  @weekly_records = Record.where(
    runday: @today.all_week #一週間分のrecordを取得
  )
  gon.weekly_records = @weekly_records.pluck(:distance)
end
```

ちなみにrecordsテーブルに登録されているデータは以下のようになります

```seeds.rb
Record.create(runday: '2021-12-06', distance: '5')
Record.create(runday: '2021-12-07', distance: '3.5')
Record.create(runday: '2021-12-08', distance: '4')
Record.create(runday: '2021-12-09', distance: '8')
Record.create(runday: '2021-12-10', distance: '7')
Record.create(runday: '2021-12-11', distance: '3')
Record.create(runday: '2021-12-12', distance: '5')
```



# 3. chart.jsに挿入

```app/javascript/pack/bbb.js
var ctx = document.getElementById("aaa");
var myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ["月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日", "日曜日"],
    datasets: 
    [
      {
      label: 'ランニング走行距離',
      backgroundColor: 'rgba(102,255,129,0.2)',
      borderColor: 'rgba(122,255,129,0.2)',
      data: gon.weekly_records /* コントローラで定義したgonを代入 */
      }
    ]
  },
  options: {
    scales: {
      yAxes: [{
        ticks: {
          suggestedMin: 0
        }
      }]
    }
  }
});
```

<br>
`rails s`で確認してみます。以下のように表示されていれば成功です！

![スクリーンショット 2021-12-10 23.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/fb99487a-923f-ba7e-75c4-91f9d49df863.png)

# 4. 参考
[chart.jsとgonでグラフを作成する](https://qiita.com/unitrrrr/items/b551a0e34200a43fc888)
[【Rails】 便利なpluckメソッドの使い方をマスターしよう！](https://pikawaka.com/rails/pluck)
[【Rails Chart グラフ】Railsで、投稿に連動した美しいグラフを作ってみよう](https://zenn.dev/be_the_light/articles/1c0933fcc0f8bc)
【覚書】Pythonのバージョン管理について

# はじめに
今回は、Pythonで躓きやすいバージョン管理について、覚書を兼ねて解説（？）します。
使いやすい方法は人によって変わってくると思いますので、いろいろな方法を試していただければと思います。

Pythonでは、複数バージョンをインストールして、切り替えながら使うということが少し複雑になっています。メジャーバージョン（2系・3系）同士では動くのですが、マイナーバージョンを複数インストールすると思ったように動かないことが多々あります。そんなときに、使える方法をご紹介します。

なお、[こちら](https://wisteria-yt.blogspot.com/2021/08/python.html "Pythonのバージョン管理について（覚え書き）")のリメイク版となります。

# 方法
ここからはWindowsとmacOSに分けてそれぞれのおすすめの方法をご紹介します。Windowsの方は[こちら](#pythonランチャー--venv-windows)、macOSの方は[こちら](#pyenv--venv-macos)からご覧ください。

## Pythonランチャー × venv （Windows）
Windows版のPythonをインストールすると、自動的にPythonランチャー（py.exe）がインストールされます。インストールの際に、Python本体にはパスを通さず、Pythonランチャーにパスを通すことで、複数バージョンを簡単に切り替えることができます。
それにプラスして、venv（venvについては[下記](#venvとは)で説明します！）を利用することで仮想環境を構築し、プロジェクトによってパッケージも変えることができます。
詳しくは、[Pythonの複数バージョンの扱い方（Windowsの場合） - ガンマソフト株式会社](https://gammasoft.jp/python/python-version-management/)が分かりやすく説明されています。

## pyenv × venv （macOS）
macOSでは、pyenvというソフトウェアをインストールすることによって、複数バージョンを簡単に切り替えることができます。
それにプラスして、venv（venvについては[下記](#venvとは)で説明します！）を利用することで仮想環境を構築し、プロジェクトによってパッケージも変えることができます。

# venvとは
venvとは、仮想環境を構築するために、Pythonに標準で備わっているツールです。venvの利点は、なんといってもその手軽さです。
venvはPython3.3から標準機能として備わっており、Python3.3以上の場合は、何もインストールすることなく利用できます。また、仮想環境がディレクトリとして作られるため、直感的に扱いやすく問題も起きにくいです。

# Anacondaは嫌い
:::note warn
あくまでも一個人の意見です。そうなんだなぁくらいな感じで読んでください。
:::

確かにAnacondaは、GUIで仮想環境を扱うことができるとても便利なソフトです。
しかし、condaに対応しているパッケージしかインストールすることができず、pipと共存させてしまうと環境ごと破壊されてしまう恐れがあり、とても危険です。また、Anacondaは主に機械学習向けに作られているソフトで、他の分野のパッケージは充実しているとは言い難い状態です。

# まとめ
私の環境の運用方法をまとめてみました。少しでも参考になれば幸いです。
細かい使い方などについては解説していませんが、ググっていただけると良いと思います（他力本願
分からない部分があればなんでも質問してください！

拙い文章ですが、最後までお読みいただきありがとうございました。
U-22プログラミングコンテスト2021でベスト37に入ったこととプロダクトについて

# はじめに
こんにちは、HCB Advent Calendar 2021の10日目を担当する、kudokaiです。
今年は大学の仲間数人とチームを組み、[U-22プログラミングコンテスト2021](https://u22procon.com/)に出場しました。
最終審査進出はなりませんでしたが、事前審査を通りBEST37に残ることができました。
今回は、U-22プログラミングコンテスト2021で作った成果物について紹介します。

# U-22プログラミングコンテスト2021について
1980年から経済産業省が主催している歴史あるコンテストで、今年で41回目の開催になります。
22歳以下を対象としたコンテストであり、プロダクト・テクノロジー・アイデアが評価軸になっています。
今年の開催形態はオンラインとオフラインのハイブリッド開催でした。
プロダクトのジャンルや使用技術を問わず、自由に作品を作ることができます。
今年は374作品が提出されたようです。
（スポンサー企業もかなり豪華でした！）

# 開発経緯
メンバー各々が作りたいプロダクト案を色々持ち寄り、議論を重ねてきました。
最終的には、オンライン状況下でも使用することができるプロダクトを開発すれば、実用性があり、ウケがいいのではという話に着地しました。
ユーザのニーズ、解決すべき問題、問題を解決するアプローチなどのプロダクトの根幹を固めてから開発に移りました。（この辺があやふやだと、メンバー間でプロダクトに対する認識の齟齬が生まれやすく、大きな手戻りが発生する可能性がある）
![iOS の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425368/fe2f40dc-71fd-3a17-6a4f-38691b6ce416.jpeg)
![iOS の画像 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425368/4a8f1d05-ee41-1867-4324-2574636e3f49.jpeg)

# プロダクトについて
「Focus Box」というリモートワーカーの顔の情報から集中力の低下を検知し，作業場所の環境情報より集中力を阻害する要因の改善策を提案するプロダクトを開発しました。
リモートワーカーの集中度合いを瞬きの回数から、集中力を阻害する要因を温湿度とCO2濃度からそれぞれ評価しています。
それぞれの情報の収集方法として瞬きは、Webカメラから顔を検知し、一定時間における瞬きの回数を定期的に測定・記録しています。
温湿度・CO2濃度は、センサーモジュールを搭載したデバイスから情報を定期的に収集しています。

応募時に[PV](https://www.youtube.com/watch?v=aPUW6i975N8)を作っているので、ご覧いただければと思います。

# システム構成
![スクリーンショット 2021-12-10 23.26.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425368/f5a507ed-e540-3c58-0aa3-488be23f505e.png)

- **Device** 
Raspberry Pi4 ModelB でユーザーの作業スペースにおける温湿度とCO2濃度を取得します。

- **Server**
AWSのlambdaとAPIGateway、dynamoDBでユーザーやデバイス、取得した環境データを管理します。
対象のユーザーの作業環境がどのような状態か判定し、結果をフロントエンドに送信します。

- **Web**
ユーザーの瞬きやServerから送られてきた結果からユーザーに休憩を促します。

# 僕が担当した部分
僕はデバイス作成をしました。
RaspberryにCO2センサと温湿度センサを接続し、室内環境データを取得し、データを送信する部分を実装しました。
Raspberry起動後は、Pythonを使ってセンサを制御し、データを加工し、室内環境データを記録したJsonファイルを吐き出してサーバへ送信します。
センサモジュールに付属されている仕様書の偉大さを知りました。(CO2センサはキャリブレーションが必要であることを知らず、異常値を吐き出し続けており、「この空間のCO2濃度やばくね？」みたいな会話をしばらくしてました...)
高校生以来の電子工作だったので、回路設計でつまずくこともありましたが、とても楽しかったです。
抵抗のカラーコードの読み方も忘れていたので、高校で使っていた教科書を引っ張り出して復習しながらやっていました。
ここでカラーコードの覚え方を載せているWebサイトのリンクを掲載しときますね。
[抵抗のカラーコード（抵抗値）の読み方](https://www.jarl.org/Japanese/7_Technical/lib1/teikou.htm)

黒い礼（０）服、小林（１）茶、赤いに（２）んじん....懐かしい！！
高校生の頃はテスト前に呪文のようにブツブツ言いながら頭に入れていました笑

# 最後に
僕は今年22歳なので最初で最後のU-22プログラミングコンテストでした。
小規模なハッカソン(インターンも含めて)には割と参加したことがあったのですが、今回のプロコンのような大規模なコンテストには出場したことがなかったため、いい経験になりました。
そして何より、37/374に残ることができて本当に嬉しかったです。
大学を卒業するまでの残り3ヶ月では、何かしらのコンテストに出場することが難しいと思うので、今回のコンテストで結果を出すことができて本当によかったです。

僕はハッカソンやコンテストの楽しさに取り憑かれているので、社会人になってもハッカソンには出てみたいと思ったり...
C#でカノジョをつくる（10日目）

お疲れ様です。たなしょです。
今日はアプリを作りました。
ちょっとだけ作り方がわかったので今度何かアプリ作ってみたいです。

## 電卓みたいなやつを作った
技術書に載っていた税抜き価格と消費税とその合計を計算してくれるアプリです。
そのアプリをちょっと改造したものを作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/a43d7af3-3d71-c129-2164-b9e1f60e3edb.png)

こんな感じで単価と数量を入力して「計算実行」ボタンを押すと価格が表示されました。
ソースコードはめっちゃシンプルだったのでこんな簡単にアプリができるんだ感動しました。（デザインでオブジェクトを配置するのが一番面倒くさかったです。）

```c#
namespace Calc
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int price, quantity, subtotal, tax, total;
            const double TAX_RATE = 0.08;
            price = Convert.ToInt32(textBox1.Text);
            quantity = Convert.ToInt32(textBox2.Text);
            subtotal = price * quantity;
            tax = (int)(subtotal * TAX_RATE);
            total = subtotal + tax;

            label6.Text = String.Format(subtotal / 1000 > 0 ? "{0:0,000}円" : "{0}円", subtotal);
            label7.Text = String.Format(tax / 1000 > 0 ? "{0:0,000}円" : "{0}円", tax);
            label8.Text = String.Format(total / 1000 > 0 ? "{0:0,000}円" : "{0}円", total);
        }
    }
}
```

やっていることは単純で、textBoxの文字列を取り出してintに変換して、計算して、Textに代入されるだけです。
もっと難しいことをやってるのかと思ったんですけど`オブジェクトの値を取り出す→オブジェクトに値を代入する`ことができれば、
その間のロジックは既存のC#の知識でどうにかなりそうなので意外と難しくないなと思いました。

## 改造したところ
単純に出力個所を参考演算子にして3桁未満なら区切らずそのまま出力させるようにしました。

```c#
label6.Text = String.Format(subtotal / 1000 > 0 ? "{0:0,000}円" : "{0}円", subtotal);
```
今書いてて思ったんですが三項演算子の箇所、`subtotal / 1000 > 0 ? "{0:0,000}円" : "{0}円"`と変数を1000で割って0より大きいかで判別してますが、単に`subtotal >= 1000 ? "{0:0,000}円" : "{0}円`で同様な挙動をしますよね。
これを作ってた時はいったい何を考えてたんだ自分…

## 最後に
今まで写経してプロンプトに数値や文字列が出力されてという一連の流れを繰り返していたので、
新しくGUIアプリの作り方を勉強できてとても面白かったです。やっぱりモノづくり楽しいですね。自分の考えが入り込む余地があるのがいいです。
これからも暇を見つけてくだらないアプリを作っていければなと思いました。
（でもオブジェクトを配置するのはめんどくさいです…）
Unityである物体がカメラに映されているかの判定方法

## やること
物体がカメラに映されているというのはその物体が全部または一部カメラの視錐台の中にあることで、
それを判定するために物体の形とカメラ視錐台との交差判定をすることだ

## 物体の形とカメラ視錐台との交差判定
Unityではそれをするために便利なメソッドが用意してくた
[GeometryUtility.TestPlanesAABB](https://docs.unity3d.com/ja/2020.3/ScriptReference/GeometryUtility.TestPlanesAABB.html)

```c#:GeometryUtility
public static bool TestPlanesAABB (Plane[] planes, Bounds bounds);
```

そのメソッドが二つ引数が必要で、第一引数にカメラの視錐台を渡して、第二引数に物体の形を渡す
交差がある場合`true`が返され、交差がない場合は`false`がか返される

### カメラの視錐台を求める
それもUnityが便利なメソッドを用意してくた。
[GeometryUtility.CalculateFrustumPlanes](https://docs.unity3d.com/ja/2020.3/ScriptReference/GeometryUtility.CalculateFrustumPlanes.html)

```c#:GeometryUtility
public static Plane[] CalculateFrustumPlanes (Camera camera);
```

戻り値の`Plane[]`がカメラの視錐台で、その中に
`[0] = Left, [1] = Right, [2] = Down, [3] = Up, [4] = Near, [5] = Far`
となっている

### 物体の形状を求める
物体の形 `bounds` は `Collider.bounds`、`Mesh.bounds`、`Renderer.bounds`から取得できる
alembicのmigrationでDB情報を環境変数から取得できるようにする備忘録

プライベートで作成しているアプリケーションのmigrationツールとしてalembicを利用しています。
migrationのDB情報を環境変数で取得できると便利だなぁと考えてやってみたので備忘録として記事を書きました。


# 環境の確認と準備

```bash
$ python -V
Python 3.9.4
$ pip freeze | grep alembic
alembic==1.6.5
```

```bash
$ alembic init testalembic
$ tree
.
├── alembic.ini
└── testalembic
    ├── README
    ├── env.py
    ├── script.py.mako
    └── versions
```

今回DBはMariadb 10.5.10を利用します。

# alembic.iniの修正

`alembic init` した際に alembic.ini が作成されて、alembic initファイルには`sqlalchemy.url`セクションが存在します。

```
sqlalchemy.url = driver://user:pass@localhost/dbname
```

直書きでも問題ないのであればこのセクションに情報を記述すればよいのですが、今回は環境変数から取得したいので下記のように変更します。
%(DB_USER)s、%(DB_PASSWORD)、%(DB_HOST)sにそれぞれユーザ名、パスワード、ホストの情報が実行時に挿入されます。

```
sqlalchemy.url = mysql://%(DB_USER)s:%(DB_PASSWORD)s@%(DB_HOST)s/devdatabase
```

# env.pyの修正

`alembic init` した際に env.py が作成されます。

env.pyの下のほうに`run_migrations_online`という関数があるのでここを修正していきます。
[ドキュメント ](https://alembic.sqlalchemy.org/en/latest/api/config.html)を参考に修正していきます。
ドキュメントによると`set_section_option`メソッドでalembic.iniで設定した `%(変数名)s`に対して値を埋め込めるようです。
 

```python:env.py
config.set_section_option("alembic", "DB_USER", os.environ.get("DB_USER"))
config.set_section_option("alembic", "DB_PASSWORD", os.environ.get("DB_PASSWORD"))
config.set_section_option("alembic", "DB_HOST", os.environ.get("DB_HOST"))

connectable = engine_from_config(
    config.get_section(config.config_ini_section),
    prefix="sqlalchemy.",
    poolclass=pool.NullPool,
)
```

ちなみに、`config.get_section(config.config_ini_section)`には下記のように辞書型のデータが入っています。

```
print(config.get_section(config.config_ini_section))
{'here': '<実行されている場所>', 'script_location': '<alembic.initのscript_locationセクションの値>', 'prepend_sys_path': '.', 'sqlalchemy.url': 'mysql://<user>:<password>@<host>/<db>', 'db_user': '<user>', 'db_password': '<password>', 'db_host': '<host>'}
```

これで環境変数からDBの情報をalembicに渡すことができるようになりました。
env.pyはpythonコードなので実際には環境変数以外にもファイルなどをパースして埋め込むなどもできると思います。

# 最後に
alembicのDB情報を環境変数から取得できるようになり自分の中では便利になった感じがあります。
とはいえ、alembic自体最近知って試行錯誤中でありまだまだ改善の余地がありそうです。

# 参考

https://alembic.sqlalchemy.org/en/latest/api/config.html
Dynamics 365 Finance and Operations ~ Export to Azure Data lake ~

ブログ初投稿となります。

D365 Finance and Opeartions (FO) に関する調査をしようとすると、[Dynamics Community](https://community.dynamics.com/) がメインになることが多いかと思います。日本語で解説しているブログはほとんど見たことない気がします。
というわけで僕の備忘録的に使っていくと同時に、みなさんの知識の一助になればと思います。

今回は1つ新機能を紹介していきたいと思います。

# Export to Azure Data Lake とは
D365 FO のデータをAzure DataLake（Azure Data Lake Storage Gen2 = ADLS） へエクスポートする機能です。D365 CE にも同様のサービスである [Azure Synapse Link for Dataverse](https://docs.microsoft.com/ja-jp/powerapps/maker/data-platform/export-to-data-lake) がありますね。

https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/finance-data-azure-data-lake

そもそもデータのエクスポート（FO→外）・連携（FO⇄外）すること自体は、以下のようなものがすでにあります。
・BYOD（Bring Your Own Database（Azure SQL Database））
・OData
・バッチデータAPI
・Export Database （LCSよりbacpacファイルをダウンロード）

ADLSはビッグデータ分析のために、さまざまなサイズ（大容量OK!）、形状、スピードのデータを格納し、複数のプラットフォームと言語であらゆる種類の処理と分析を簡単に実行するために必要な機能がすべて組み込まれています。
つまり、FOのデータをADLSへエクスポートすることで、PowerBIやAzureSynapseなどのツールを用いて、データレイク内のデータの分析、ビジネスインテリジェンス、機械学習のシナリオが可能になります。

例えば、eコマースサイトのログと、FOの請求書および在庫移動データを結びつけることで、「A製品を購入するお客様は、B製品もウケるようだな。B製品の広告をもっと打っていこう。でもB製品は結構在庫少ないから増やしておこう。」のような洞察が得られる。みたいな感じのシナリオですかね。

また、小さなサービスがネイティブに動いているから安定していたり、Azure SQLよりも安価なストレージコストだったり、その他余計なメンテナンスが不要、とBYODよりADLSをお勧めしているようです。

#システム要件
・Tier2 以上
※ Tier1 でも[SQLToADLSFullExport](https://github.com/microsoft/Dynamics-365-FastTrack-Implementation-Assets/blob/master/Analytics/AzureDataFactoryARMTemplates/SQLToADLSFullExport/ReadmeV2.md)で試すことができます。

#データフロー
① 自動的に[^1]エクスポートされた差分データ[^2]は、
② CDM形式のCSVファイル（実データ）とメタデータファイルとして、ADLSのフォルダ（ストレージ）に格納されます。
③ ADLSのデータは[CDMUtilツール](https://github.com/microsoft/Dynamics-365-FastTrack-Implementation-Assets/tree/master/Analytics)を使ってT-SQLでクエリすることができるみたいです。
※ Synapse には、T-SQL を使用して ADLS のクエリを可能にする SQL のオンデマンド機能が含まれています。
私は良く分からないものは、とりあえず絵とか図で感覚をまず掴みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/6a51f4a7-d6af-7086-ca2d-010f098a8bf8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/fe559f7c-012d-d57f-69cd-3774c15cf27b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/1e5bcf03-84ff-311c-1700-e3991ddfaf56.png)

英語になりますが[コチラ](https://community.dynamics.com/365/dynamics-365-fasttrack/b/techtalks/posts/export-to-azure-data-lake-overview-december-14-15-2021)にもTechTalkでMSのFastTrackチームが解説してくれています。

[^1]: 2021/12現在GAされているverだと数時間ごとに更新される。Preview中だが数分（near real time）で更新されるverもある。
[^2]: 挿入・更新・削除の操作による差分のこと
[参考URL]

https://cloudblogs.microsoft.com/dynamics365/it/2021/12/02/unlock-hidden-insights-in-your-finance-and-operations-data-with-data-lake-integration/

https://docs.microsoft.com/ja-jp/dynamics365/fin-ops-core/dev-itpro/data-entities/Azure-Data-Lake-GA-version-overview
PostgreSQLのロジカルレプリケーション使用時の注意点

本エントリーは[PostgreSQL Advent Calendar 2021](https://qiita.com/advent-calendar/2021/postgresql)の11日目です。

# はじめに
PostgreSQLのレプリケーションには、ストリーミングレプリケーションとロジカルレプリケーションの二つのレプリケーションが存在します。
本エントリーではロジカルレプリケーションを使用するにあたり、自身が経験した注意するべき事項を解説します。
(本業が多忙により、図の作成を行うことができませんでした…)

# ロジカルレプリケーションとは
ロジカルレプリケーションは通常(ストリーミング)のレプリケーションと異なり、データベース全体の複製を行いません。
レプリケーション元をパブリッシャー、レプリケーション先をサブスクライバーと呼びます。
サブスクライバーは連携対象のテーブルを選択でき、検索だけではなく更新等も可能となります。
パブリッシャーで更新が発生すると、生成されるログ(WAL(Write Ahead Log))をデコードして更新内容をサブスクライバーに送信します。
サブスクライバーは受信した更新内容を自身のデータベースに反映します。

# ロジカルレプリケーション使用時の注意点
## サブスクライバー側でテーブル更新を行うと、コンフリクトが発生してレプリケーションが停止する可能性がある
サブスクライバー側でレプリケーション対象テーブルに対してデータ追加を行い、パブリッシャー側で同一主キーのデータ追加を行うとコンフリクトが発生します。
コンフリクトが発生するとレプリケーションが停止し、他テーブルの更新も止まってしまいます。
また、パブリッシャー側では連携待ちのWALが溜まっていくことになります。
### 解決策
サブスクライバー側のログを確認し、エラーとなっているデータを確認して削除を行います。
コンフリクトデータが多量にある場合の手っ取り早い解決策は以下の手順となります。

1. パブリッシャー側で、コンフリクト発生テーブルをレプリケーション対象外にする。(ALTER PUBLICATION *name* DROP TABLE *table_name*)
1. サブスクライバー側で、ロジカルレプリケーション情報を更新する。(ALTER SUBSCRIPTION *name* REFRESH PUBLICATION)
1. サブスクライバー側で、コンフリクト発生テーブルのデータを全消去(TRUNCATE)する。
1. パブリッシャー側で、コンフリクト発生テーブルをレプリケーション対象にする。(ALTER PUBLICATION *name* ADD TABLE *table_name*)
1. サブスクライバー側で、ロジカルレプリケーション情報を更新する。(ALTER SUBSCRIPTION *name* REFRESH PUBLICATION)

## マテリアライズドビューは連携対象外
VIEWの内容を永続化できる便利なマテリアライズドビューですが、パブリッシャー側で作成したマテリアライズドビューはレプリケーション対象外です。
### 解決策
postgres_fdwを使用して、サブスクライバー側からアクセスできるようにしてください。
高速化を求める場合はサブスクライバー側にもマテリアライズドビューを作成し、外部テーブルの内容を取得・更新するようにするとよいでしょう。
## 1トランザクション中に膨大なデータを更新すると、後続データの連携に遅延が発生する
1トランザクションで数十GBといった膨大なデータを更新すると、レプリケーション遅延が発生します。
これは、WALをデコードする部分がシングルプロセスで動いているためです。
レプリケーション対象外のテーブル更新でも起こります。
### 解決策
大規模な更新が発生しうるテーブルは、unloggedテーブルにすることをお勧めします。
unloggedテーブルの場合、データベースの再起動でデータが消去されるため、復旧する手段を別途構築する必要があります。
該当テーブルを別データベースクラスタ化してしまい、postgres_fdwでアクセスできるようにする方法もあります。

# 終わりに
ロジカルレプリケーションはとても便利で使い勝手の良いレプリケーションですが、使ってわかる落とし穴があったりします。
似たような事例で悩んでいる方の参考になればと思います。
競プロでいつもやっていること

[競技プログラミングを始めたばかりの人に伝えたいこと Advent Calendar 2021](https://qiita.com/advent-calendar/2021/pre-competitive)の12日目の記事です。
2011年から競技プログラミングを趣味にしています。今回は始めたばかりの人向けということで、短時間コンテストに参加するときにいつもやっていることを共有したいと思います。

## コンテスト一週間前

[競技プログラミングカレンダー](https://competitiveprogramming.info/calendar) (※ 中身はGoogle Calendarなのでimportできます) の予定を見ておきます。(なお [このカレンダーについての記事はこちら](https://qiita.com/hotpepsi/items/61558c680aaab4a36bf3))
海外のコンテストで日をまたぐときは、23時頃に“予定を確認する”みたいな予定を入れたりします。

## コンテスト当日

私の場合はコンテストがはじまる1時間くらい前までに仮眠が取れるのがベストです(なかなかそういうタイミングはないですが)。食事で眠くなるタイプの人は、食べて仮眠して直前に起きるのが一番かもしれません。

## コンテスト直前

ペンとA4～B4の紙を何枚か用意します。私は余った紙を使っていますが、AtCoderではマス目の問題が割とよく出るので、買うなら方眼紙のノートが便利です。
準備運動として軽くストレッチします、瞑想してもいいかもしれません。
飲み物を準備してトイレを済ませておきます。あとメガネを拭きます。
コンテスト5分前くらいになったらエディタやIDEを開きます。もしatcoder-toolsなどの便利ツールを導入しているならコンソールを開いてスタンバイしておきます。

## コンテスト中

問題を解きます。音がない方が集中できる人は耳栓をしてもいいかもしれません。
ちょっと悩んだら図や数値を紙に書きなぐっていきます。
複雑そうなときはNが小さいときだけ解ける愚直解を書くこともあります。提出用の解法とランダムケースで比べて、うまくいかないケースを見つけるのに使ったりします。
普通は簡単な問題から解くと思いますが、集中力はだんだん落ちてくるので、もしかすると自分が解けるぎりぎりの難易度の問題からやったほうが良いのかもしれません。試しにABC 231ではD->C->B->Aという順番でやってみました。たまたまFまで解けましたがこれのせいかどうかは不明です。

## コンテスト後

良くても悪くても結果をTwitterにつぶやきます。新しい色に到達した人をお祝いします。
解説を読み、解けなかった問題を解き直します。正解していても過剰な処理をしていたりするので、改めて書き直します。コメントにアルゴリズムなどを書いておくと、あとで自分の検索の役に立ちます。私はGitHubにもpushしています。
毎回はまりがちなことは、コードのテンプレートにメモで書いておき、次回の開始時に目に入るようにします。topcoder SRMを始めたころは、こんな感じのことを書いていました。

```
// 問題文をよく読む
// サンプルの説明を読む
// 制約の数値は手打ちせずにコピペする
// ゼロのときだけ特別か?
// 負の可能性はあるか?
// intオーバーフローしないか?
```

今はEvernoteに方針のメモを残し、“桁DP”のようにアルゴリズムのタグをつけています。

## ということで

良さげなtipsがあればぜひ教えてください。