OmniAICreator/Qiita-1.07M huggingface dataset:
PostmanでAPIのテストを書く

## はじめに
Postmanはいいぞ

PostmanはAPI開発時に役立つツールです。無料で使い始めることができます。

* APIクライアント
* 自動テスト
* モックサーバ

などなど、API開発にあたってはお世話になる機能が揃っています。OAS(OpenAPI Specification)のファイルをインポートして、APIへのリクエストを自動的に生成してくれるのが非常に便利です。

## APIのテスト

Postmanでは、APIへのリクエストを定義、保存しておくことができます。リクエストに対しては、テストを設定しておくこともでき、リクエスト送信時にテストも実行されます。

リクエストは複数まとめてCollection(第1階層)、Folder(第２階層以降)という単位で管理が可能です。Collection Runnerという機能で、Collection単位でテストを一斉に実行できます。

### テストの書き方

リクエストのTestsタブから、このリクエストに対するテストを記述することができます。まずは、スニペットを使ってみるのがよいでしょう。発展的なテストを記述したいときなどは、Chai Assertion Libraryの[API Reference](https://www.chaijs.com/api/bdd/)を参照するとよいです。

### テスト例

```js
// ステータスコードに対するテスト
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

// 応答時間に対するテスト
pm.test("Response time is less than 200ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(200);
});

// JSONの中身に対するテスト
var jsonData = pm.response.json();
pm.test("id=1, name=taro, age > 18 のJSONが返ってくる", () => {
    pm.expect(jsonData.id).to.eql(1);
    pm.expect(jsonData.name).to.eql("taro");
    pm.expect(jsonData.age).to.gt(18);
});

// JSONのプロパティに対するテスト
pm.test("historyの中にはstudiesという配列型のプロパティがあり、要素が2つ以上存在する", () => {
    pm.expect(jsonData.history).to.have.property("studies");
    pm.expect(jsonData.history.studies).to.be.an("array");
    pm.expect(jsonData.history.studies).to.be.not.empty;
    pm.expect(jsonData.history.studies).to.have.lengthOf.at.least(2);
});
```

## テストの実行

重複しますが、リクエストをSendすると同時にテストが実行されます。また、テストだけを一括して実行したい場合はRunnerを使ってCollectionやFolder単位でテストが可能です。


## おわり

APIに対するテストを書いておくことで、仕様の明確化や、コード修正等に伴うデグレードを抑えることが可能です。また、今回は触れませんでしたがテスト環境や本番環境など、URLが異なる環境を事前に定義して素早く切り替えることが可能ですので、APIの開発する上では非常に頼りになるツールです。
【Unity】アニメーションによってポジションやローテーションがずれる時（自分用）

![“shot” 2020-12-08 13.12.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/a007b6b0-c665-8662-d918-f46291367914.png)


・Root Transform Rotation
・Root Transform Position(Y)
・Root Transform Position(XZ)

の「Bake Into Pose」にチェックを入れたらアニメーションを連続再生してもポジションやローテーションがずれることはなかった。


[Unity参考リファレンス](https://docs.unity3d.com/ja/current/Manual/RootMotion.html)
個人的に便利だと思ったgitコマンド集

# 背景
完全独学で触ってきたgitですが、流石に体系的に勉強した方がいいだろうと思って、勉強しました。
そこで学んだ便利なコマンドを記載していきます。なお、gitを使っている方々にとっては当たり前の内容となっております。
完全に個人的な備忘録です。

ちなみに勉強した本は[GitHub実践入門](https://www.amazon.co.jp/GitHub%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-Pull-Request%E3%81%AB%E3%82%88%E3%82%8B%E9%96%8B%E7%99%BA%E3%81%AE%E5%A4%89%E9%9D%A9-PRESS-plus/dp/477416366X)です。まだ読み途中なので、読み終えたら追記もしくは別記事で投稿します。

# コマンド集
## コミットメッセージ
いきなりコマンドではなくてすみません笑。コミットメッセージには、フォーマットがあるらしく、それに則った方が今後便利だなと思いました。
1行目: コミット内容のようやく
2行目: 空白行
3行目以降: コミット内容の詳細内容や背景など

## 過去のコミットメッセージ1行目のみ表示

```
git log --pretty=short
```

## ファイルの差分表示

```
git log -p [file name]
```

## ワークツリーとステージ領域の差分確認

```
git diff
```

## ワークツリーと最新コミット領域の差分確認
変更したファイルを全てステージ領域に追加すると、 `git diff` では何も差分が表示されなくなる。
最新コミットと比較したい時には、下記のようなコマンドを実行する。
```
git diff head
```

## ブランチの流れを視覚的に表示

```
git log --graph
```


## 新しいブランチを作成し、そちらに切り替える

```
git checkout -b [branch name]
```

## 現在のリポジトリでの作業ログ

```
git reflog
```

## ブランチを戻す

```
git reset --hard [hash value]
```
＊ハッシュ値については、 `git log --graph` や `git reflog` などを使って確認すること
＊戻した後に、 `git reflog` などを使ってハッシュ値を取得できれば、再度戻す前の状態にも戻れる。

## ブランチのマージ（及びコンフリクトの確認）
マージ先のブランチ(例えば、masterブランチ)にいる状態で実行する。

```
git merge [branch name]
```
＊事前にマージ元、マージ先のgit pull origin [branch name]などをしておき、ブランチを最新化しておく。
＊コンフリクトが起きたら、対象ファイルを開き、修正して再度ステージング及びコミットする

## 直前のコミットメッセージを修正

```
git commit --amend
```

## 複数コミットをまとめる
直前2つのコミットをまとめたい場合

```
git rebase -i head-2
```
＊ここのheadは最新コミットを指す。

```
pick [hash value] [commit message1] # 最新の1つ手前のコミット
pick [hash value] [commit message2] # 最新コミット
```
最新コミットの方のpickをfixupに書き換えることで、
1つ手前のコミットにまとめることができる。
コミット後に見つけた軽微なバグ修正などで使う。
なお、改竄方法はgit rebaseコマンド実行時に表示されているので、そちらを読むことでより理解できるだろう。


## リモートリポジトリの登録

```
git remote add origin git@github.com:hoge/huga.git
```
＊originという識別子は今後、git@~として認識されるようになる。
＊なお、push時に-uオプションを付けることで上流ブランチとして登録させることができる
例、 `git push -u origin master`
ちなみに上の例は、origin(リモートリポジトリ)のmasterブランチにpushしているという意味。
masterの部分を別のブランチ名にすると、そのブランチにpushされる。
そのブランチが存在しない場合は、作成される。

## リモートリポジトリを含めたブランチの確認

```
git branch -a
```
* master
  remotes/origin/master
リポジトリにもよるが、おそらく上記のように表示される。
上記では、ローカルリポジトリのmasterブランチにいて、リモートリポジトリにはmasterブランチのみが存在しているという意味。
remotesが(ローカルではなく)リモートリポジトリを指しており、originは先ほど指定した特定のリモートリポジトリを指している。

## リモートリポジトリのブランチをチェックアウトする
リモートリポジトリにあるブランチを元に手元のローカルリポジトリにブランチを作成する

```
git checkout -b develop origin/develop
```
＊リモートリポジトリにdevelopブランチがある前提


## 最新のリモートリポジトリの情報をローカルリポジトリに反映
例えば、別の開発者によってリモートリポジトリに変更が生じた場合、下記コマンドでそれをローカルリポジトリにも反映させる。

```
git pull
# もしくは
git pull origin develop # originのdevelopの変更をローカルに反映
```
リモートリポジトリのブランチが変更されていた場合、このコマンドでローカルリポジトリにもその変更が反映される。
なお、変更がかぶっていた場合、コンフリクトが発生する。

## 直前のコミットまでワークツリーを戻す
これで何かやらかしても直前まで簡単に戻せる。

```
git reset --hard HEAD
```

## ローカルブランチの削除
整理のためにも不要になったローカルブランチは削除しておきたい。

```
git branch -d [branch name]
```
対象ブランチをローカルでチェックアウトしている状況ではエラーが発生するので、別ブランチにチェックアウトしておくこと。
web会議・web面接をちょっとよくするコツ！

こんにちは！ウェブクルー AdventCalendar 9日目の記事です。
クリスマスも近づいていますが、今年は社内でクリスマス会も出来なさそうなので
アドベントカレンダーで少しでもクリスマス気分をと思います。

#はじめに
改めまして、ウェブクルーで人事をしています[＠wc_asukasaito](https://qiita.com/wc_asukasaito)です。
弊社wantedlyやnoteなどに出現しています。フリー素材卒業したいです笑

今回テーマとしている「web会議・web面接をちょっとよくするコツ！」は、
今年の4月、緊急事態宣言が出て月間100件以上の面接をオンラインで行った実体験から
みなさんのweb会議・web面接の場を少しでも良いものにできたらと考えたものです。

**※内容には個人の意見が入っていますため、必ずこの方法が正しい・これでなければならないというものではありませんので予めご了承ください。**

#目次
・前提として
・事前準備のポイント
・会議・面接中のポイント

#前提として
本記事は、カメラオンで会議・面接に参加する上でのコツを書いているものとなります。
カメラオンでの参加が絶対だ！推奨する！というわけでもありませんし、
前述のとおり個人の意見ですので、「カメラオンならいいわ～・・」と思う方は
ぜひ他の記事をチェックしてみてくださいね！
[ウェブクルーアドベントカレンダー 2020](https://qiita.com/advent-calendar/2020/webcrew)

#事前準備のポイント
さて、本題に入ります。（前置き長くてすみません笑）
事前準備のポイントはいくつかあります！

###ポイント1：音に気を配る
音声に気を配るのももちろんですが、ここでいう「音」は音声以外の「音」です。
近頃音漏れしづらい物件の人気が上がっていることは、よく耳にされる情報と思います。
気にしている方は多いと思いますが、意図せず入ってきてしまう「音」は案外多いです。

**例1)PCのモーター・ファンの音**
ノートPCは長時間web会議などをしていると、負荷がかかって大きな音がすること、ありますよね。
PCの端末そのまま、スピーカー＆マイクで話していると、聞き手が気になるほどの音量になることもあります。
![PCファン音.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912861/c7b6990d-01fe-3db1-2ce0-aa0c252c3176.jpeg)

**例2)カフェや外部施設での、他の利用客の物音・声**
特にお昼～午後の時間帯は人が多い＋お子さんも多くいる時間帯でもあります。
BGMがかかっている施設だと自分で音量が調整できないので、聞き手が気になることもありそうです。

**例3）窓を開けていることで入ってくる風・車などの音**
換気を習慣にしている方・お店・場所が増えている中、思ったより拾ってしまう「音」です。シンプルに窓や扉は閉めましょう笑

###ポイント2：背景に気を配る
ラフな話をするときは別として、web会議・web面接の場では
その目的に集中できる場づくりをするのが良いと考えています。

また、あらぬ予想・判断をされるのを避けることもできます。
（背景がごちゃついてたら、整理整頓が苦手なのかな？など）

▼すぐやるなら
・とにかく壁に寄る：壁との距離が近ければ余計なものは映らない！
・暗い場所は避ける：自分の雰囲気も暗くなる＋聞き手が表情を読み取れない！

#会議中・面接中のポイント
###ポイント1：顔は全部正面から映す・肩くらいまで映す
案外多いな～と思ったのが、↑をしていない方でした。
顔半分しか出てない・どんな斜めからのカメラなの？笑・顔大きすぎなど・・笑
普段サブマリン（デスクの下に沈みこむ座り方）型の人などはご注意を。
![座り方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912861/80b436bd-d678-9a77-e401-2f116d49aea8.png)
映さな過ぎも映しすぎも見づらくなるので、カメラの角度調整してみてくださいね。

###ポイント2：自分から大事な話をする・これだけは伝えたい！という時の目線はカメラ
これは、正直難しいです！
相手の様子を見たいし、自分がどう映ってるかも確認したい・・と思います。
普段から目を合わせて喋るのもちょっと嫌だし・・という方もいると思います。

でも案外、聞き手からすると自分に目線が向くと「おっ！」てなるのは保証します。
ずっと見すぎていると不自然ですが笑
相手の様子を映している画面を、自分のカメラの近くに持ってくるとぼんやり視野に入るので目線をカメラに向けながら、確認することもできるのでオススメです！

###ポイント3：身振り手振り
これはweb会議（大人数）・web面接の際に有効だと考えています。
**例1）とにかく頷きは大きく！**
聞いているか正直画面越しだと伝わりづらいです笑
かといって相槌は邪魔になる可能性があるので、双方大げさなくらい頷きましょう！
頷かなくとも、**口角を上げているだけでも少し違います！**
※表情筋の筋トレかと思うくらい、1日2時間以上口角上げてると痛くなるのでご注意

**例2）普段やらなくてもジェスチャーを取り入れてもいいかも？！**
その点についてお話したいのは2点で、の時に「2」とジェスチャーをしたり
ラフな会議であればOKですか？と聞くときに「OK」のジェスチャーをして、相手にも返してもらったり
質問がある人は？と聞くときに自分から「手を挙げて」促したり・・
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912861/770a5603-3e10-c371-e7d8-11a0e8d2dc74.png)
最初は慣れなかったり恥ずかしくても、分かりやすさは格段に上がるはずです！

***
つらつらと書いてきましたがあくまでも個人的な意見であり、超画期的な方法でもありません。
見たけど、web会議・カメラオンもいらないしテキストでいーよ。って思う方もいると思います笑
ただ、web会議や面接の場では「伝わる」ために、ちょっと気恥ずかしくても↑をして
良い場にしてもらえたらと思いますので、頭の片隅にでも置いていただけたら、と！

さて！！明日は[@tomoyuki-matsudaさん](https://qiita.com/tomoyuki-matsuda)です。
人事×エンジニア目線で書いてくれるとのことなのでお楽しみに！
Vimコマンドを覚える際にお世話になったリソース3選

※この記事は[Fringe81 Advent Calendar](https://qiita.com/advent-calendar/2020/fringe81) 7日目の記事です。

こんにちは！

今回は自分がVimコマンドを覚える際にお世話になったリソースを3つまとめてみました。

# vimtutor

大体の場合お使いのターミナルで

```
vimtutor
```

と打てば始まり、実際に手を動かす演習形式で幅広く重要なことが学べます。

![vimtutor_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621165/73958b6f-7617-7bcf-275f-5d90c5b8eb69.png)
「敷居が高いイメージがあったけど割と試してみるといけるかも、、！」と自身がついたり、「Vimの学習は実際に手を動かして学ぶことが大事なんだな」という意識にさせてくれる教材で、特に一番最初に取り組む教材としておすすめです。

前に一度実施済みの方でも、しばらくして繰り返し周回してみると良いかもしれません。案外大事な事項が忘れられてしまっていたり、身についていなかったりしますので、、。（自分はジャンプ履歴を言ったり来たりできる`Ctrl-O`、`Ctrl-I`等を取りこぼしていました、、）

# quickref

書籍や記事で一通りコマンドを見渡したとしても、ほとんどのことは時間経過で忘れてしまっていて、実際にVimを触ってるときに、より少ない手数を実現できるコマンドはとっさに出てこないもので、、

お気に入りのチートシートを見つけ、それを使って自分はどんなコマンドをまだ使いこなせてないかを定期的にチェックすることは大事だと思います。

僕のお気に入りは、`:h quickref`と入力すると出てくるチートシートで、内容の網羅性とVimからのアクセスのしやすさが他より優れており良いです。

![quickref_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621165/e858a9fd-0386-427a-37c5-8a56be848285.png)
![quickref_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621165/ba46b371-24b1-239a-9ea9-bc630a71a3cb.png)
※英語で書かれていますが、写真のように[vimdoc-ja](https://github.com/vim-jp/vimdoc-ja)というプラグインをインストールして翻訳版を利用することもできます。

自分のお気に入りのチートシートでのおさらいの仕方は、チートシートの編集ロックを解除して、馴染みの無いコマンドの動きをその場で試し書きをしていきながら確認していく方法です。

- `:h quickref`と打つと、最初、上半分、編集不可でチートシートが出てくる
- `CTRL-W _`でチートシートを最大化
- `:set modifiable`でチートシートを編集可能に
- チートシートに記載されているコマンドを周辺のテキストを対象に試してみる（くれぐれも保存をしないようにお気をつけください、、）

# VimGolf

マクロやドットコマンド等、存在は知っていても実際に手を動かしてみないと使いどころや活用シーンがなかなかピンとこないコマンドってあります。そういったものは[VimGolf](http://www.vimgolf.com/)の問題をいくつか周回することで掴めたなーという実感があります。

VimGolfは、与えられた課題を可能な限り少ないキーボード打鍵数で解決することを競うゲームで、

少しの環境構築とTwitterアカウントあればお手軽にいつでも遊ぶことができます。

自分のよりも一つ少ない打数でカップインしたユーザの解答をカンニングすることができるのが特徴で、

以下のようなフローで進めていくことで、結構なコマンドを手になじませていくことができおすすめです。

1. 一度自分なりに答えを考えて提出してみる
2. 自分よりの上位のユーザの解答を見れるので真似して打ってみる
3. わからないキー表記があれば`:h keycodes`、わからないコマンドがあれば`:h コマンド名`もしくは`:h quickref`で都度しらべてみる
4. 真似した解答を自分の解答として提出する
5. こんどはもう一打少ないユーザの解答が見れるのでまた真似して打ってみる
6. 1~5を繰り返す
7. 最終的に世界記録に辿り着きその解答のシンプルさに感動する
8. 一連のフローで新出コマンドを5~6個ほど反復練習している
WSL2のUbuntuでsystemdをPID1で動作させる

WSL2のubuntu20.04のPID1がinitになっているのでsystemdへ変更した際の備忘録
#環境
windows 10 home
OSビルド19041.630
#手順
microsoft storeからubuntu20.04をインストール
デフォルトだとPID1はinitになっている

```
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0    892   568 ?        Sl   09:56   0:00 /init
```
Genieの依存パッケージであるdaemonize/dbus/policykit-1をaptでインストール

```
sudo apt update
sudo apt install -y daemonize dbus policykit-1
```

リポジトリを追加

```
wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb
```
time outするからキャンセルする

更新

```
sudo apt update; sudo apt upgrade
```

パッケージリスト消去

```
sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
```
.NET を再インストール

```
sudo apt-get install -y gpg
wget -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget https://packages.microsoft.com/config/ubuntu/20.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y {dotnet-package}
```
Genieのインストール
https://github.com/arkane-systems/genie

```
sudo apt-get install -y dotnet-runtime-3.1
sudo su

apt install lsb-release
cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list
sudo deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
sudo deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
EOF

apt update
apt install -y systemd-genie

#ルートパーティションにラベルを付けるためFilesystem名確認
df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb        251G  1.7G  237G   1% /

#ラベルをつける
sudo e2label /dev/sdb cloudimg-rootfs

genie -s
```
確認

```
$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.1  0.0 173368 13000 ?        Ss   12:27   0:02 systemd
```

genie自動起動

```
vi .bashrc
#以下追記
if [[ ! -v INSIDE_GENIE ]]; then
  exec /usr/bin/genie -s
fi
```
Buffalo製NASのバックアップタスクを登録する際に関係ないエラーが出ることがある

少なくとも私が扱っているTerastationシリーズでは、**バックアップタスクの登録数は8個**、**タスクの中身は25個**まで登録が可能だそう。

9個目のタスクを登録しようとしても、登録ボタンが押せなくなる。これは仕様というかユーザーマニュアルにも書いてあるので問題ないんですが、

私が気になっているのはタスクの中身に26個目を登録して実行しようとした場合に出るエラーです。

ちゃんとした文面を覚えてないのでそもそもこの記事が役に立つかどうかすら怪しいんですが、

**「世代管理数を指定した場合、バックアップ先に指定できるのは本製品の共有フォルダーおよび本製品に接続したUSBドライブだけです」**
という風に怒られます。

状況として差分バックアップを選択しているので、世代管理はそもそもできないんですよね。

まとめると、

* **26個目のタスクを登録してしまっているので、バックアップの実行はまずできない**
* **しかし、エラーの内容は世代管理数が云々...となってしまっている(本来は中身が多すぎる的なエラーが出てほしい)**
* **差分バックアップを選択しているから、世代管理の話が出てくるのはおかしい**

なので、上記のように怒られてしまったらタスクの中身の数を見直してみてください。
写真も図も用意できずすみません....
Qiitaに投稿した記事をWordPressにも自動投稿してみた

##はじめに

（19日に投稿予定でしたが、14日が空いたので早めに投稿してみました。）

普段はpythonを使ってエンジニアしたり、PHPでWeb系のお仕事したりと広く浅くプログラミングやってます。

pythonでこんなことできるよみたいな紹介ができればと思います。

スクレイピングとかも面白いかなと思ったのですが、そのあたりの記事はたくさんあるしなぁとか悩んだ結果、せっかくだしQiitaAPIを触って何かしてみようと思いました。

なので今回は、QiitaAPIを使ってQiitaに自分が投稿した記事を自分のサイト（WordPress）にも投稿できるよというのを紹介したいと思います。

python始めた方向けにpythonこんなことできるよという雰囲気を味わってもらえたらいいなと思っているので、細かい部分は省きながら説明していきます。

##準備が必要なもの

今回の自動化で事前に準備が必要なのは、

１、QiitaAPIのアクセストークン
２、自分のWordPressのAPI用アカウント情報

それぞれの準備については今回の目的から外れますので参考になるサイトをそれぞれ張っておきます。

１、[こちら](https://qiita.com/r_ishimori/items/def8a8636d6ac14b0f26)
２、[こちら](https://masamayu.com/wordpress%e3%81%ae%e8%87%aa%e5%8b%95%e6%8a%95%e7%a8%bf%e3%82%92%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f/)


##サンプルコード

今回は解説ではなくてこんなことできるよの紹介記事になるのでサンプルコードと実際にこの記事を自分のサイトに自動投稿してみた結果をご紹介します。

```
import requests
import json


def main():
    qiita_token = "QiitaAPIのアクセストークン"
    headers = {
            'Content-Type': 'application/json',
            'Charset': 'utf-8',
            'Authorization': 'Bearer {}'.format(qiita_token)
        }
    pf = PostFunctions()
    r_get = requests.get("https://qiita.com/api/v2/users/QiitaのユーザーID/items/", headers=headers)
    results = r_get.json()
    for result in results:
        article_id = result["id"]
        if pf.postcheck(article_id):
            pass
        else:
            title = result["title"]
            content = result["rendered_body"]
            pf.postadd(article_id)
            Article2WP(title, content)


class PostFunctions():
    # 既にWPに投稿されているか確認
    def postcheck(self, article_id):
        with open("article_id.txt", "r", encoding="utf8") as f:
            id_list = [s.strip() for s in f.readlines()]
            if article_id in id_list:
                return True
            else:
                return False
    # WPに投稿した記事IDを追加
    def postadd(self, article_id):
        with open("article_id.txt", "a", encoding="utf8") as f:
            print(article_id, file=f)

def Article2WP(title, content):
    user_id = "WP投稿用アカウントID"
    password = "WP投稿用アカウントパスワード"
    end_point_url ="https://自分のサイトドメイン/wp-json/wp/v2/posts/"
    payload = {
        'title': title,
        'content': content,
        'status': "draft",
        'comment_status': 'closed',
        'featured_media': アイキャッチ画像ID,
        'categories': カテゴリーID,
    }
    headers = {'content-type': "Application/json"}
    r = requests.post(end_point_url, data=json.dumps(
        payload), headers=headers, auth=(user_id, password))
```

基本的なコードはこれだけです。

定期実行するように作ってありますので既に自動投稿した記事をテキストファイルにメモしておくようにしていますが、そのあたり不要な方は削ってしまってもきちんと動きます。

##最後に

個人的にはもう少し時間かかるかなと思ったのですが、かなり便利なAPIが双方に用意されていたのでただAPI叩いただけになってしまいました。

この記事を実際に自分のサイトに自動投稿してみましたのでどんな感じに投稿されたか気になる方は見てみてください。

[こちら](https://mofumofu-tips.com/mofu-tie/qiita-wordpress/)

Qiitaと自分のサイトに投稿したい需要があるのか分からないですが、誰かの参考になったら嬉しいです。
【初心者】Rubyでbinding.pryを使う方法【絶対使うべき】



## 概要
勉強会で、Rubyで「binding.pry」を使えるようにする方法を学びましたので、まとめました。


## 設定方法
#### ①Gemfileを作成


```terminal:ターミナル 
 touch Gemfile
```
Railsではなく、rubyのフォルダにGemfileを作るという考え方がなかったので、驚きました。
Github：[https://github.com/pry/pry](https://github.com/pry/pry)

#### ②Gemfileを記述
githubを参考に、コピペします

```terminal:Gemfile
gem 'pry', '~> 0.13.1'
```


#### ③インストール


```terminal:ターミナル 
bundle install
```

#### ④設定

```ruby:main.rb
#pryを読み込みたいファイルに記述する
require'pry'
```


#### ⑤使い方
```rb:main.rb
#止めたいところに記述
binding.pry
```

上記を入力してある状態でコードを実行すると
「binding.pryを記述したところ」でとまるので、以下のようなことを試してください。

- 変数に何が格納されているか？
- 期待している値は入っているか？
- binding.pryの部分で止まるのか？そうでない部分でエラーが出るか？


以上になります。


## まとめ 
binding.pryを使えるようになって、putsやpに出力させる必要がなくなり、開発効率が上がりました。
難しそうと思って使っていなかった過去の自分を叱りたいです。
使ったことがない方は使ってみてください。
修正と再利用に強いPSDデータ

#前書き
はじめまして。オークファンでデザイナーをしている@af_nsです。
前職も含め4年ほど、ECサイトでの画像制作（商品画像や特集のバナーなど）を中心に行ってきました。
今回は、そういった画像制作において、クオリティを保ちつつ、効率的に制作をする為に意識していることについて書いていきたいと思います。

それは、**修正や再利用に強いデータづくり**です。

ECサイトのバナー制作は媒体や掲載箇所に応じて様々なバナーサイズが必要になったり、後から他の人のデータを流用して別のバナーを作ったりすることも多いと思います。
そのため**「修正がしやすい」「自分以外の人も編集しやすい（＝未来の自分も編集しやすい）」**ことが重要になります。

#修正や再利用に強いデータのポイント
##1.スマートオブジェクト
とにかく使用する画像素材はスマートオブジェクト化しておきましょう！

めちゃくちゃお世話になる機能でありながら、初期設定ではショートカットキーが割り当てられていないので、適当に使いやすいキーを割り当てるのがおすすめです。
レイアウトの修正や、バナーのリサイズなど、画像を変形させることが多いため、画質の劣化を防ぐためにも必ず素材がスマートオブジェクトになっているか確かめながら制作していきましょう。

##2.スマートフィルター
色調補正なども元画像をいじるのではなく、スマートオブジェクト化してからスマートフィルターで対応しましょう。
やっぱりもうちょっと明るく！とか、元画像のままで、という時も非破壊で調整出来るので便利です。
同じくらいの明るさの画像を、同じだけ明るくしたいという時には調整レイヤーで、という風に使い分けるのも良いと思います。

##3.レイヤーの整理整頓
ここはどれくらい自分の作成したデータを他人が扱う可能性があるか、にもよりますが、最低限のグループ化とグループ名の変更をしておくと修正時に楽になります。特に特集バナーや商品画像などは時間に追われて制作をすることも多いと思うので、あまり神経質に全てのレイヤーに名前をつける必要はありません。

**「背景」「商品」「モデル画像」「メインキャッチ」「サブキャッチ」「装飾」**などその画像を構成するものを大きく分けて判別できるようになっていればいいと思います。

リサイズする時どういうまとまりでレイアウトしなおすことになるか、を想定するのがおすすめです。

また、不要なレイヤー（特に不要な調整レイヤーなど）は消します。ガイドなど、制作時は必要で書き出し時に不要なものは、それとわかるようにグループ化しましょう。

##4.修正・変更を予測して作る
例えば下記のようなデザインをする場合・・・
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889741/8493c9f6-17e7-5e90-02dd-7c0b188156ac.png)
どちらも完成した画像の見た目は一緒ですが、作り方が違います。
上は写真っぽいフレームをシェイプで作成してそこに画像を当て込むイメージ、
下は画像自体を切り抜いて写真っぽいフレームの効果を付けているイメージです。

こういったデザインの場合、以下のような修正が想定できます。

**「もうちょっと全体を入れてトリミングして」「フレームの大きさを長方形にして」「こっちの画像に差し替えて」「複製して写真が重なりあってる感じにして」**など・・・

この場合、そういった修正への対応が楽そうなのは上のシェイプでクリッピングしている方だと思います。
下はフレームの形を変える時にマスクを作り直す必要があります。
逆に、レイヤーマスクを活用した方がいい場面というのももちろんあるので、重要なのは、**「とりあえず見た目を作るのではなく、修正・変更を予測して最適な方法を選択する」**ということになります。

#最後に
ざっくり、最低限重要なポイントについて書かせていただきました。
データの作り方は人それぞれで、様々な方法があります。
自分が制作をする時は自分以外の誰かがこのデータを修正することを想像して、
人の作ったデータを修正する時はどういうところが直しやすくて直しにくいのかを意識すると、修正や再利用に強いデータが効率的に作れるようになると思います👍
カレンダーでの日付選択で、選択可能な日付を制限する方法

#目次
1. はじめに
2. 実装方法
    3. カレンダーウィジェットのpropertiesから設定する
    4. コードで設定する 
3. まとめ
4. 参考

#はじめに
カレンダーウィジェットで、ユーザーが選択できる日付を制限したい時があると思います。
カレンダーの日付選択で選択可能な日付を制限する方法は

* カレンダーウィジェットのpropertiesから設定する
* コードで設定する

の2通りありますので、それぞれご紹介していきます！

#実装方法
1. 画面作成
まず、例として生年月日を入力してもらう画面を作成します。
カレンダーウィジェットと、ユーザーに生年月日の入力を促すメッセージを配置します。
![カレンダーウィジェット配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/477731e3-0cf2-d5ce-4254-bdc861a65722.png)

2. 選択範囲制限
次に上記であげたそれぞれの方法で、日付の選択範囲を制限する方法を説明します。
アプリの仕様や実装したい内容に合わせて、どちらかの方法を試してみてください！

## 方法1：カレンダーウィジェットのpropertiesから設定する

カレンダーウィジェットを選択すると画面右に表示されるpropertyのCalendarから選択可能な開始日と終了日を選択できます。
ただしこの方法だと日付を決め打ちになってしまいます。
![StartDateとEndDate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/6cde17ed-ac00-9ad3-93ee-52af0f6f4d0a.png)

今日から○年後以降は選択できないようにしたい！
△ヶ月以前は選択できないようにしたい！
...その場合は、次に紹介する方法を試してみてください。

## 方法2：コードで設定する
今回は、生年月日を入力するアプリなので100年前の1月1日から本日まで、入力範囲を制限してみましょう。

```frmInputBirthdayController.js
define({ 
    onPreShow : function(){
    // カレンダー日付初期化(今日の日付を表示)
    var today = new Date();
    this.view.calBirthday.clearData();
    this.view.calBirthday.dateComponents = [today.getDate(), today.getMonth() + 1, today.getFullYear()];
    // 本日以降の日付を選択不可
    this.view.calBirthday.validEndDate = [today.getDate(), today.getMonth() + 1, today.getFullYear()];
    // 100年前の1月1日以前の日付を選択不可
    this.view.calBirthday.validStartDate = [1, 1, today.getFullYear() - 100];
  },
});
```
関数`onPreShow`の中に上記のようなコードを書きます。
`validEndDate`で選択終了日を`[dd, mm, yyyy, hh, mm, ss]`の配列で指定できます。
`validStartDate`で選択開始日も同様の配列で指定します。
`dateComponents`はカレンダーに表示されるデフォルトの日付を指定できます。こちらも`[dd, mm, yyyy, hh, mm, ss]`の配列で指定できます。
フォーマットの配列のうちhh, mm, ss(時:分:秒)は特に指定されていない場合は00:00:00に設定されます。
もし時刻まで制限したい場合は使ってみてください！


次に関数(onPreShow)と画面(frmInputBirthday)をActionで紐付けます。
紐づけたいFormを選択しpropertiesのActionから`preShow`のEditを選択します。
InvokeFunctionを選択しドロップダウンから`onPreShow`を選択すれば紐づけ完了です！
![Action紐付け.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9da7fc0d-1f45-b7e7-3326-19c0c1c50ea4.png)


では実際にどうなるか見てみましょう。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/rhwX8TXeja">pic.twitter.com/rhwX8TXeja</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1336509808384516102?ref_src=twsrc%5Etfw">December 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
指定した範囲内しか選択できないようになっているかと思います。

#まとめ
今回のような生年月日の入力はもちろん、日付を入力する場面は多々あると思います。
その際、ユーザーに範囲内で選択して欲しい時に活用してみてください！
ご精読ありがとうございました！

#参考
Calendar propertiesの説明：
validStardDateの説明
https://docs.kony.com/7_3/konylibrary/visualizer/viz_widget_prog_guide/Content/Calendar_Properties.htm#validSta
validEndDateの説明
https://docs.kony.com/7_3/konylibrary/visualizer/viz_widget_prog_guide/Content/Calendar_Properties.htm#validEnd
dateComponentsの説明
https://docs.kony.com/konyonpremises/Subsystems/Widget_User_Guide/Content/Calendar_Basic_Properties.htm#dateComp
Unity 2020から自動実装プロパティのバッキングフィールドにSerializeField属性をつけるとプロパティ名が表示される

[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos)の10日目の記事です。
昨日は@kerimekaさんの[【Android】root判定によるチート対策](https://qiita.com/kerimeka/items/b93ca27508d9c0664637)でした。

---


## Unity 2019以前
C# 7.3から自動実装プロパティのバッキングフィールドに属性をつけられるようになりましたが、`SerializeField`属性をつけるとInspectorの表示が残念なことになってました。

```csharp
public class Sample : MonoBehaviour
{
    [field: SerializeField]
    public int ValueA { get; private set; }
}
```
こう書くと
![property-backing-field-2019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98727/2b17c4e7-a67f-d403-c2f1-da467ee847f2.png)
こう表示されてしまう。

ラベルだけ上書きする`PropertyDrawer`を自作したら使い勝手が良くなりそうな気がしますが、実際はうまくいきません。
そのあたりは下記の記事で説明されています。
[Unityで自動実装プロパティに表示名を指定する](https://takap-tech.com/entry/2019/12/07/221403)

## Unity 2020
2020からは

```csharp
public class Sample
{
    [field: SerializeField]
    public int ValueA { get; private set; }
}
```
と書くと
![property-backing-field.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98727/74e5fea3-de5f-c72a-a9b2-9ac6554b4ad5.png)
こう表示されるようになりました。

ちなみに表示名はプロパティ名ですがyamlに保存されるのはバッキングフィールドの名前です。
![sample-prefab-yaml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98727/26078113-8180-8b74-4d80-0f243bb7905c.png)

## 結論
Unity 2020から自動実装プロパティのバッキングフィールドに`SerializeField`属性をつけるとプロパティ名がいい感じに表示されるようになりました🎉

---
本当はInspectorでいい感じに表示する拡張を公開する予定だったのですが、2020でチェックしていたところ何もしなくてもプロパティ名が表示されたのでやめました。

---
明日は@kenta-sanです！
WordPressで新規投稿時のURLをデフォルトで連番化

ワードプレスのテーマtwentytwentyを基盤に、新規投稿を作成した際に記事のURLの末尾をデフォルトで連番にする実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

投稿ページや固定ページのパーマリンクは、デフォルトだとタイトルに入力した文字がそのまま入力されます。
URLに日本語が含まれるとエンコードされてごちゃごちゃしてしまいます。
記事のパーマリンクをデフォルトで連番にしてすっきりさせましょう。

まずは、パーマリンク設定で「カスタム構造」を選択してください。記入欄は %postname% のままで大丈夫です。
次に、functions.php に、下記コードを任意の場所に追記します。

```functions.php
// スラッグ名が日本語だったら自動的にnum＋id付与へ変更（スラッグを設定した場合は適用しない）
function auto_post_slug( $slug, $post_ID, $post_status ) {
    if ( preg_match( '/(%[0-9a-f]{2})+/', $slug ) ) {
        $slug = 'num-' . $post_ID;
    }
    return $slug;
}
add_filter( 'wp_unique_post_slug', 'auto_post_slug', 10, 4  );
```

新規投稿をしようとするとパーマリンクにnum-1と表示されているのがわかります。
※日本語云々関係無しに一律で連番にする場合、中の if 文を取り除けば実装できます。
【PHP】本番環境と開発環境が同じドメイン内で構築されている場合のファイルパス分岐処理

## はじめに
フロント実装者でもときどきPHPを用いた実装を担当することがあると思います。
今回は実際にあった例を用いて、対策を共有できればと思います。

## 今回のケース
・別の制作会社さんがPHPで作成・運営していたサイトを引き継いだ
・同じドメイン内に本番環境（ドメイン直下）と開発環境（例：ドメイン/develop）がある
・構成を完璧には引き継いでいない（もはや分かる人がいないそうな）ので、できるだけ改修せずにローカロリーで対応する

### 問題点
前述のとおり本番・開発でディレクトリが違うのだが、PHPでパスルート分岐などをしていないので、作業ファイルをまるっとコピペができない。
よって、開発環境で更新作業を行い、OKが出たら差分箇所を漏れなく本番環境用ファイルに反映させなければならない。大変な二度手間だ。やりたくない。ムキー

### 対応策
結論から書くと、パスルートを下記の記述に統一させることで対応しました。

```
<?php
// ドキュメントルートとディレクトリ構成を取得
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$dir = explode('/',$_SERVER["REQUEST_URI"]);

// 開発環境（develop）配下のファイルにはパスルートに /develop を付与
if( $dir[1] == 'develop' ) {
	$current_dir = $doc_root . '/develop';
} else {
	$current_dir = $doc_root;
}
```

これをconfig.php とかにして読み込ませつつ、

```
<?php require($_SERVER["DOCUMENT_ROOT"] . '/develop/inc/header.php'); ?>
```

上記のように書かれていたインクルード部分を

```
<?php require($current_dir.'/inc/header.php'); ?>
```

と書き換えました。
これにより、記述の差異が無くなるので本番・開発用ファイルを1つに統合でき、二度手間は解消されました。


### まとめ
どういう経緯でこのような構成になっていたのかは分かりませんが、設計の段階で運用の面倒さ、リスクはある程度予測できたと思うので、もうひと工夫しておいてくれればゴニョゴニョと思いました。
でもPHPは昔すこしだけ勉強していたが役に立った気がして、それはそれで良かったと思いましたまる

変なところや、こういうやり方あるよーっていうのがあればご教示いただけると大変ありがたいです。

#### 参考にさせていただいたURL
https://www.php.net/manual/ja/function.set-include-path.php
https://webnetamemo.com/coding/php/201803016775
WordPressでカテゴリーで記事を絞り込む（管理画面）

ワードプレスのテーマtwentytwentyを基盤に、管理画面の投稿一覧ページにおいて、投稿をカテゴリーで絞り込めるようにする機能の実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

今回は投稿一覧ページにカテゴリーを表示させて、絞り込みできるようにしようと思います。
下記のfunctions.phpの任意の場所に追記します。

```functions.php
function my_add_filter() {
global $post_type;
    if ( 'news' == $post_type ) {
    ?>
    <select name="tax_news">
        <option value="">タクソノミー指定なし</option>
        <?php
        $terms = get_terms( 'tax_news' );
        foreach ( $terms as $term ) { ?>
        <option value="<?php echo $term->slug; ?>" <?php if ( $_GET['tax_news'] == $term->slug ) { print 'selected'; } ?>><?php echo $term->name; ?></option>
        <?php } ?>
    </select>
    <?php
    }
}
add_action( 'restrict_manage_posts', 'my_add_filter' );
```

![wp_nomiss_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670866/23a338e2-6d85-ab96-3ebf-34d98923214f.png)
こんな感じにカテゴリーが表示され、絞り込みができるようになりました。
newsやtax_newsなどは、カスタム投稿やタクソノミーを作成したときのものを入力してください。
AmazonLinux2 + Ruby on Rails6でSQLite古いエラー

エンタメ系企業の社内もろもろを担当しているakibinです。

Twitterアカウント @AkibinMusic
[Youtubeチャンネル](https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg)

#内容
AmazonLinux2を立てて、Railsをインストールしたけどアプリ起動したら以下がエラーが出た場合の対処方法を書き書きします。

【エラー】
**Your version of SQLite (3.7.17) is too old. Active Record supports SQLite >= 3.8.**

#なぜエラーが出るのか
AmazonLinux2にはsqlite3のバージョン3.7がデフォルトでインストールされており、これがyumで利用しているらしく、削除することはできません。がしかし、Rails 6を動かすには、sqlite3のバージョン3.8以上が必要なので、古い！と↑で怒ってるんですね。

#対処方法
既存のSQLiteはほっておいて、3.8以上のSQLiteを別途インストールします。

```bash:
# アプリ用のユーザのホームディレクトリで作業（私は）
$ cd /home/appuser 
# 3.34.0をダウンロード
$ wget https://www.sqlite.org/2020/sqlite-autoconf-3340000.tar.gz
$ tar xzvf sqlite-autoconf-3340000.tar.gz
$ cd sqlite-autoconf-3340000
# もとから入っているsqliteと競合しないように /opt/sqlite/sqlite3にインストールする
$ ./configure --prefix=/opt/sqlite/sqlite3
$ make
$ sudo make install
# バージョン確認
$ /opt/sqlite/sqlite3/bin/sqlite3 --version
3.34.0 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b
```

アプリで使用するSQLiteとして、今回インストールしたSQLiteをgemで指定する。

```bash:
# アプリ用のディレクトリに移動
$ cd /var/www/rails/webapp 
# gemで新しいSQLiteを指定
$ gem install sqlite3 -- --with-sqlite3-include=/opt/sqlite/sqlite3/include \
   --with-sqlite3-lib=/opt/sqlite/sqlite3/lib
# 指定が正しくできているか確認
$ irb
irb(main):001:0> require 'sqlite3'
=> true
irb(main):002:0> SQLite3::SQLITE_VERSION
=> "3.34.0"  # できてる
irb(main):003:0> exit
```

あと新しいSQLiteにパスを通す必要があるので以下作業実施。

```bash:
$ echo 'export LD_LIBRARY_PATH="/opt/sqlite/sqlite3/lib"' >> .bash_profile
$ source .bash_profile
```

これで再度アプリ起動するとエラー解消して以下が出ました！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/f60c4652-38e5-0561-1fe2-47bdadd646d4.png" width=40%>

[こちらの記事](https://blog.serverworks.co.jp/tech/2020/01/19/rails6/)参照してSQLite部分のみ抜粋させていただきました！わかりやすかったです！

今年も終わるは早いわ…

# 2020年12月31日：SQLiteが使えなかったので追記
SQLiteを使おうとしたところ、以下エラーが発生しました。

```bash
user$ sqlite3
sqlite header and source version mismatch linux
新しいバージョン
古いバージョン
```
SQLiteへのリンクが古いほうになっていることで発生しているようです。
リンク先を新しい方にします。

```bash
user$ sudo mv /usr/bin/sqlite3 /usr/bin/sqlite3_old #古いバージョンを一応バックアップ
user$ sudo ln -s /opt/sqlite/sqlite3/bin/sqlite3 /usr/bin/sqlite3 #新しいバージョンへシンボリックリンクをはる
```

```bash
user$ sqlite3 -version
3.34.0 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b
user$ sqlite3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> 
```

使えるようになりました！

年末の早朝（am6:00）にこれやってると思わなかったぞ、初めにこの記事書いた俺よ…

良いお年を。
WordPressで投稿編集画面をビジュアルエディタにする

ワードプレスのテーマtwentytwentyを基盤に、WordPressの投稿編集画面をビジュアルエディタで編集できるようにする実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

htmlの知識があまりない人なら、意味不明なコードが書いてあるテキストエディタよりビジュアルエディタの方を使いたいですよね。
![wp_nomiss_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670866/3e052b4b-700f-b388-1eeb-f611d466bbb8.png)
ビジュアルエディタで編集すると、WordPressの仕様でpタグやspanタグが自動挿入されますが、静的コーディングの段階でその想定をしていないと大幅に崩れてしまうことがあります。

以下の点に注意してコーディングしましょう。

・記事コンテンツエリア内の要素にはクラスなしでデザインがあたるようにする。
・要素がどんな順番で置かれても余白が不自然にならないようにする。

また、ビジュアルエディタで記事を作成・編集するときに実際のウェブ上のデザインが当たっているようにするととても分かりやすいのでおすすめです。

ビジュアルエディタを実際のサイト上のデザインに近づけるための方法をご紹介いたします。
editor_style.css（エディタ用CSS）に、サイト用のCSSをインポートする方法です。
WP構築時に、サイトのスタイルを記述しているCSSファイルに、ビジュアルエディタ上に適用させるためのクラス「.wp-editor」も追加します。

```style.css
.news-block article h2,//実際のサイト用のクラス
.wp-editor h2 {//管理画面用のクラス
  border-bottom: 4px solid #eaaeb1;
  position: relative;
  padding-bottom: 10px;
  font-size: 24px;
  margin: 60px 0 20px;
}
.news-block article h2,//実際のサイト用のクラス
.wp-editor h2:after {//管理画面用のクラス
  position: absolute;
  content: "";
  display: block;
  border-bottom: 4px solid #ca353b;
  bottom: -4px;
  width: 33%;
}
```

このように管理画面にもCSSが当たるようにクラスを追記したら、そのCSSファイル（以下の例の場合style.css）をeditor_style.cssでインポートします。

```editor_style.css
//editor_style.cssに記述
@import url("style.css");
```

最後にそのeditor_style.cssをfunctions.phpで読み込みます。

```functions.php
// editor_style.css読み込み
function add_editor_style_cb() {
  add_editor_style();
}
add_action('admin_init', 'add_editor_style_cb');
```

これでビジュアルエディタにも共通のスタイルが適用されるようになります。
![wp_nomiss_27_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670866/7986a406-057e-da55-0a56-a229f0fce465.png)
プレビューを見なくてもビジュアルエディタ上でデザインが確認できるので便利ですね。
WordPressでバージョンアップの警告バナーを消す

ワードプレスのテーマtwentytwentyを基盤に、管理者画面に表示されるWordPressのバージョンアップを促すバナーを非表示にする実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwenty

# 作業

WordPressの新しいバージョンが公開されると、ダッシュボードにこのような通知が出てきます。
![wp_nomiss_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670866/f960ed4d-80fc-24a2-15c9-daeea0c8bd8b.png)
「今すぐ更新してください。」と書いてあると、クライアントは「更新しないと何かまずいのかな？」と感じてアップデートしてしまうかもしれません。
そのようなことがないように、ダッシュボードの更新通知は管理者のみに表示させるようにして、他の権限グループでは非表示にしておきましょう。
ユーザー権限の分け方については後述の「ユーザーの権限を分ける」にて紹介しています。

管理者権限以外で更新通知を非表示にするには、以下のコードをfunctions.phpの任意の場所に追記してください。

```php
//更新通知を管理者権限のみに表示
function update_nag_admin_only() {
  if ( ! current_user_can( 'administrator' ) ) {
    remove_action( 'admin_notices', 'update_nag', 3 );
  }
}
add_action( 'admin_init', 'update_nag_admin_only' );
```

![wp_nomiss_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670866/fff8a945-4120-094c-84aa-f745623e7704.png)
これで管理者権限以外のユーザーには更新通知が届かなくなりました。

詳しくは下記の参考サイトをご覧ください。
管理画面に表示される更新通知を非表示にする

また、WordPressのデフォルトの設定では、メジャーバージョン・マイナーバージョンは自動で更新されないようになっていますが、ビルドバージョンは自動更新となっています。
ビルドバージョンの更新内容は細かな不具合の修正で、バグやセキュリティホールが見つかった場合に修正をあててくれます。ビルドバージョンの自動更新は切らない方がよいでしょう。
pyenv-virtualenv 環境で jupyter notebook を開きたい

## 概要

とあるOSSライブラリを使ってみようとしていたとき、
jupyter notebookの形でexample コードが実装されていた。

まずはいつも自分が使っているpyenv-virtualenvの環境から
単純にjupyter notebook を起動。

```
jupyter notebook
```

としてブラウザを開いて、

```
import ****
```

とすると、`modulue not found`

と怒られた。


## pyenv-virtualenv　環境から jupyter notebook を開く

この状況では、
https://qiita.com/shierote/items/421af3c741c0f9956b09
ここを参考にすることで解決した。ありがとうございます。
【Stereo Depth】GC-Net : Cost VolumeでConcatenationを使った最初のネットワーク?!

<h1>End-to-End Learning of Geometry and Context for Deep Stereo Regression</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/48ee9371-08f4-bccf-d9a9-d7bc92eb9271.png)
Cost VolumeでConcatenationを使った形のモデルは現在主流となっていて、恐らくこの論文が最初に提案したのではないかなと。
*過去にはcorrelation(相関性)という方法でInnerProduct(内積)が良く使われていた。
とりあえず、過去の方法より何が良いのか見ていきたいと思う


<h1>新規性</h1>
<h2>Cost Volume</h2>
図の2D Convlutionで抽出した特徴量Map(Channel,Height,Width)を0[pixel]~maxdisparity[pixel]まで1つずつずらして左右の画像を結合する事でCostVolume(Disparity,Channel,Height,Width)が作れる。

これはSGM(Semi Global Matching)等で行われてたPatchをスライドさせる作業の役割を果たす。

得たCost Volumeに対して3D CNNを行うことで、Disparity方向にも情報を畳み込む事が出来、Disparity のSmoothness等を加味してMatching Scoreを出力(Disparity,Height,Width)してくれる。


<h2>Soft ArgMax</h2>
Disparity方向に最大値を取って出力とするのではなく、Soft Maxをして合計が1になるようにして、それぞれのDiaparityに重みを掛けることで最終的な出力とする。そうすることで、sub-pixel accuracyを得れる。

しかし、最大値を取るより、逆に精度が悪くなることもあると思う。

<h1>結果</h1>
・Cost VolumeにConcatenationする方法を新たに提案した
・シンプルで理解しやすく良いモデル



<h1>参考文献</h1>
End-to-End Learning of Geometry and Context for Deep Stereo Regression
https://arxiv.org/pdf/1703.04309.pdf
GitHub SSH接続設定 ed25519

## 手順

- 基本[公式](https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)に倣い設定する。

### 1. SSHキー生成

```bash
ssh-keygen -t ed25519 -f id_ed25519_github -C "your_email@example.com"
```

- fオプションでファイル名を指定。
- メールアドレスは自分の GitHub メールアドレスに置き換え。

### 2. パスフレーズは設定しない

- enterキーを2回。
 
### 3. よってssh-addもしない

### 4. SSH キーをクリップボードにコピー

- 必ず __.pub__ を追加する。

#### macのコマンド

```bash
pbcopy < ~/.ssh/id_ed25519_github.pub
```

#### Windowsのコマンド

```bash
clip < ~/.ssh/id_ed25519_github.pub
```

### 4. GitHubにSSH キーを登録

1. クリップボードにコピーしたキーを[GitHub](https://github.com/settings/ssh/new) Keyにペースト。
1. Titleは何でもよいがクライアントPC名などを付与しておくと判別しやすい。

    - `user_name@macbookpro`
    - `user_name@macbookair`

### 5. ~/.ssh/config を編集

- GitHubはデフォルトで**id_ed25519ファイルの秘密鍵を探す**。
- **id_ed25519_githubを参照して欲しい** のでその編集をする。

```bash
vi ~/.ssh/config
```

```.ssh/config
Host github.com
    HostName github.com
    IdentityFile ~/.ssh/id_ed25519_github
    User git
```

### 6. SSH 接続をテストする

- 出力されたメッセージに、自分のユーザ名を確認できたら成功。

```bash
ssh -T git@github.com

> Hi username! You've successfully authenticated, but GitHub does not
> provide shell access.
```

### 7. 使用していない鍵は削除

- GitHub側　[SSH keys](https://github.com/settings/keys)
- クライアントPC側　`~/.ssh/oldkey.pub` && `~/.ssh/oldkey`

## 参考

- [新しい SSH キーを生成して ssh-agent に追加する
](https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
同名のカラムを持つActiveRecordをjoinして、生SQLでそのカラムを指定でwhere絞りするとambiguousだと怒られる

~~また一つ大人になったのでメモ~~
ちょっと勘違いしていた。

## 問題ないケース(動作検証してない)

```ruby
Pencase(id: integer, pen_id: integer, color_id: integer)
Pen(id: integer, pencase_id: integer, color_id: integer)
```

この時、以下を実行すると、

```ruby
# Pencaseのcolor_idが111のものだけをとりたい
Pencase.joins(:pen).where(color_id: 111)
```

こんなSQLが走る。

```sql

SELECT
    "pencases".*
FROM
    "pancases"
INNER JOIN
    "pens"
AND "pens"."pencas_id" = "pencasess"."id"
WHERE "pencases"."color_id" = 111
```

## 問題なケース

ただし、これを以下のように生SQLで書いてしまうと

```
# Pencaseのcolor_idが111のものだけをとりたい
Pencase.joins(:pen).where("color_id = 111")
```

こんなエラーが吐かれる。

```terminal
ActiveRecord::StatementInvalid:
PG::AmbiguousColumn: ERROR:
column reference "color_id" is ambiguous
```

color_idが被っているからだめ。

要は、同名のカラムを持つActiveRecordをjoinして、生SQLでそのカラムを指定してwhereするとambiguousだと怒られる。


## 解決方法(動作検証してない)

(`Pencase.joins(:pen).where(color_id: 111)`でいいんだけど、それは一旦忘れていただきたい)

- where内ででテーブル名を指定した生SQLを書く。
    - 今回の場合だと、`Pencase.joins(:pen).where("pencase.color_id = #{color_id}")`
- whereでfilterしたい方のActiveRecordに、scopeを作り、生SQLを書くのではなくてそれを使う(多分いける)
    - 今回の場合だと、Pencaseに`scope :whose_color_id_is, (color_id) -> { where(color_id: color_id }`を作り、`Pencase.joins(:pen).whose_color_is(111)`でOK。
- どちらかのテーブルをマイグレーションしてカラム名を変更し、ダブりをなくす
    - 比較的ナイーブなやり方である。












## 参考

- https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58
    - 自分の記事はこの記事の劣化版です。
- https://stackoverflow.com/a/30262524
    - 自分と同じことで嘆いている人への答え
いまさらウィンドウ位置復元処理の話

# はじめに

ずっとQiita Advent Calendarに参加してみたかったんですが、自信はまったくなくて参加していませんでした。
今年のカレンダー一覧を眺めていたときに「このカレンダーなら先々月あたりにあったことが書けるかも」と思ったので、記事にしてみました。

# 現象というか

2020年、急にテレワークが流行りました。（否応なしに巻き込まれた皆さん、お疲れ様です）
初めはソフト屋（およびソフトに強い人々）だけだったテレワークも、時間が経つにつれて別の専門性を持つ方々にも適用されていき、そして起きたのです。

「昨日まで使っていた○○が、今日起動したら表示すらされない！！」
　※タスクバーには表示されていたんですけれどね。

タイトルと合わせれば、何が起きたか察した方も多いと思います。

* 昨日＝会社でいつもの環境（ノートパソコンにディスプレイを接続）
* 今日＝自宅に持ち帰ったノートパソコンだけの環境

接続していたディスプレイに○○のウィンドウを置いたまま終了し、ディスプレイがない状態で立ち上げ直した。
そして○○に実装されていたウィンドウ位置（およびサイズ）の復元処理が、存在しないディスプレイ側にウィンドウを表示した。

ウィンドウの復元処理を実装した or しようと思ったことがある人なら、直ぐにわかる現象かもしれませんが、専門外の人はパニックです。
数日にわたり、質問者と○○の部分が変わっただけの質問が何回もありました。いつも同じ助言で皆さん解決したようです。
対処は、Alt+SPACE → M　→ 矢印キーでウィンドウを見えるところまで移動する。それだけです。

なお、Win+矢印キーはこの現象にはあんまり役に立たないです。
Windows10 21h2ぐらいで直るかしら？

なんと、皆さんおなじみ TortoiseSVN も○○に該当しました。


# 歴史は繰り返された？

Windows 95/98の頃でしょうか。いろいろな人がPCを手にできるようになって、インターネットもそこそこ使えるようになって、窓の手とかVectorとかのサイトを介して沢山のフリーソフトが生まれました。それは、沢山のプログラマが生まれたことを示します。

あの頃、結構な人数の人が思いました。私も思いました。
限られたデスクトップ領域、いつも使うソフトも決まっている。作業しやすい配置やウィンドウサイズもいつも同じ。だったら起動する度にその状況を再現してほしい。

そんな需要に応えるように、起動時のウィンドウ位置をWindowsにお任せするのではなく、記録した前回値で表示するコードを実装するソフトが増えました。
その処理をどう書けば良いのか、サンプルコードと共に掲載するWeb記事も増えました。
<details><summary>それらの大半が **考慮不足** でした。</summary>
当時、この考慮不足を指摘し、考えねばならぬことをまとめた素敵なブログ記事があったのですが、いまさら検索しても見つかりません。どなたか「これじゃね？」という方は是非ともコメントでお知らせいただきたく……。</details>

でも、当時のパソコン環境のおかげで不具合は顕在化しませんでした。当時はタワーと呼ばれるぐらい重いパソコンとブラウン管モニタが、今よりずっと高額でした。モニタの解像度も、Windowsが扱える解像度も数種類で、Videoカード（マザーボードにGPUが乗っているなんて有り得ない）だって高くて、モニタが2台ある環境なんて出版関係ですか？みたいにレアでした。

Windows XPが出始めた頃でしょうか。液晶ディスプレイを使う人が増えました。今のと比べものになりませんが、ノートPCも出てきました。使える解像度も種類が増えました。（WXGAが2種類あるのは勘弁してほしい）

その結果、「顕在化しないんだから良いじゃん」と放置されていた考慮不足が遂に顕在化します。

**前回値を覚えたタイミングと、それを読み込んだタイミングで、デスクトップ領域のサイズが違う。**

その考慮不足です。

<details><summary>結果、ウィンドウが見えないところに表示されたり、サイズがハチャメチャで戻すのに苦労したり、 **たかが** 親切機能のためにソフトを使うまでに **余計な手間** を払う羽目になった人は多いのでは。</summary>
ちなみに、この考慮不足があるコードの多くでは、前回値を覚える際に「ウィンドウが最大化 or 最小化されている場合」の考慮不足も多く見られます。
　最大化したまま終了したら、通常のウィンドウサイズがディスプレイめ一杯に表示された。
　最小化したまま終了したら、タイトルバーだけのサイズで表示された。
この経験がある人、それなりにいるのでは？</details>

しかも、プログラマからしても **たかが** 親切機能のために時間も頭も使いたくないんですよ。
仕事としてプログラム組むようになってからウィンドウ復元処理を要求されると「それで売れる訳でもないのに面倒でバグの温床を要求しやがって」と思いましたね。
実際、今も使われているソフトの復元処理、バグがあっても放置されているでしょう？

だからこそ、ン十年も前と同じことが、2020年に再びプチ騒動になった訳ですが。

# Windows UX Guidelines

ようやく「技術の変化」に触れた話です。前置き長すぎでした。

この騒動でやっぱりアテにするのはUX guidelinesかなと思いまして。だってWindowsアプリのユーザビリティのお話ですもの。
ということで、**Windowsアプリケーションを作る人間が一読しておくべき** もの、Windows UX Guidelinesを引いてみましょう。

Windows98～Windows7版まで、その中にはウィンドウの配置について言及がありました。
つまりアプリが起動したときに表示するウィンドウの位置は、プログラマが責任を持つものだったと解釈できます。

<details><summary>構造すら刷新された最新版「[Design and code for Windows apps](https://docs.microsoft.com/en-us/windows/uwp/design/)」では、ウィンドウ位置の話が見当たりません。</summary>
まあ、マルチデバイス＝スマホすら想定した状態でウィンドウ位置って言われても...とは思います。</details>
上記と同じ考えでいけば、もはや (Windows10以降では) ウィンドウ位置はプログラマが関与すべきでないものになった、と言えるでしょう。

ディスプレイの解像度だけなら未だしも、テキスト他の拡大率まで **再起動なし** でホイホイ変更できる環境で、ウィンドウ位置や配置を制御するコードをバグなく実装するの、想像するだけで面倒ですね。払ったコストだけのメリット、もう得られないでしょう。

# 私見に溢れたまとめ

まさか2000年頃の騒動を COVID-19が再燃させるとは思いませんでした。という驚きと共に私見で〆ます。

ウィンドウの復元処理なんて無駄な実装はいますぐ削除しよう！
BurpでAxiosのHTTPS通信をのぞき見る

Burpを使ってAxiosの通信内容を確認する方法です。

要点は、burp+ブラウザの場合とは異なりトンネルの確立を明示的にやらなければならない、ということです。

## 証明書の準備
### derファイルを出力
BurpのProxyタブ→Optionタブから、`Import / export CA certificate`をクリックし、ウィザードで`Certificate in DER format`を選択してder形式で(以下では`out.der`)出力します。
### derをpemに変換
以下のコマンドを実行して、derファイルをpem形式(以下では`cert.pem`)に変換します。

```shell
openssl x509 -inform der -in out.der -out cert.pem
```
以下では生成したpemをスクリプトと同一のディレクトリに置くものとします。

## スクリプト
### ライブラリの準備
`axios`,`fs`の他に[`tunnel`](https://www.npmjs.com/package/tunnel)を使います。
### コード
```typescript:axios-burp.ts

import axios from "axios";
import * as fs from "fs";
import * as tunnel from "tunnel";

async function main() {
    try {
        const agent = tunnel.httpsOverHttp({
            // Burp
            proxy: {
                host: "127.0.0.1",
                port: 8080
            },
            ca: [fs.readFileSync("./cert.pem")]
        });

        await axios.get("https://postman-echo.com/get?foo1=bar1&foo2=bar2", {
            httpsAgent: agent
        });
    } catch (e) {
    }
}

main();
```

### 実行結果

```shell
% ts-node axios-burp.ts
{
  args: { foo1: 'bar1', foo2: 'bar2' },
  headers: {
    'x-forwarded-proto': 'https',
    'x-forwarded-port': '443',
    host: 'postman-echo.com',
    'x-amzn-trace-id': 'Root=1-5fc6e5e4-36f4714f2d2c8a9a5d91149d',
    accept: 'application/json, text/plain, */*',
    'user-agent': 'axios/0.21.0'
  },
  url: 'https://postman-echo.com/get?foo1=bar1&foo2=bar2'
}
```

![axios-burp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44208/4add7193-eb43-0efe-1fac-3edb7d4f1e6f.png)


この他にも`axios.get`のオプションで`proxy`を指定して(このとき`scheme`は`"https"`を指定しないとエラー)、burpのinvisible proxyを有効にすることで、`tunnel`を使わずに通信内容をのぞき見ることが可能です。ただし、この方法だとクライアントとburpの間の通信(`CONNECT`リクエストなど)を観察できないので[^1]、上の方法がおすすめです。

[^1]: burpから見る方法はないのだろうか？

## 参考リンク
プロキシを介したHTTPS通信のしくみについては以下の記事が参考になりました。
[HTTPSとCONNECTメソッド - ITの窓辺から]
(http://realizeznsg.hatenablog.com/entry/2018/08/07/070000)
StrapiからGCSへファイルをアップロードする方法

Strapi Advent Calenderの8日目は、StrapiのAPIを介して、ファイルをGoogle Cloud Storageへアップロードする方法を紹介します。

Strapi Advent Calenderのその他の記事は[こちら](https://qiita.com/advent-calendar/2020/strapi)

# GCS接続準備
1. GCPでサービスアカウントを作成(ロールはストレージ管理者)・サービスアカウントJSONをDL

2. Strapiに`strapi-provider-upload-google-cloud-storage`モジュールをインストール

```
$ npm i strapi-provider-upload-google-cloud-storage
```

3.Strapiの`<project_name>/config/plugin.js` に追記

```javascript
module.exports = ({ env }) => ({
 upload: {
   provider: 'google-cloud-storage',
   providerOptions:{
     "serviceAccount": "サービスアカウントJSON",
     "bucketName": "<GCSのバケット名>",
     "baseUrl": "https:// storage.googleapis.com/<GCSのバケット名> "
   }
 }
});
```

# 1. ファイルのみPOSTするときの例(/upload)
ファイルだけアップロードする場合は、StrapiのUploadプラグインを使用します。

```typescript:example.ts
    const body = new FormData();
    body.append('files', fileObject);
    return this.http
      .post(environment.apiUrl + '/upload', body)
      .toPromise()
      .then((res) => {
        const response: any = res;
        return response;
      })
      .catch(this.errorHandler);
```
# 2. ファイルを含んだコレクションタイプをPOSTするときの例(/collection type)
ファイルだけアップロードするときとは違い、コレクションタイプのcreate APIにPOSTする形になります。
FormDataにファイルデータを追加する前に、一旦ファイル以外のデータをキー名'data'として、JSON文字列に変換して追加します。
ファイルデータは、キー名を`files.{フィールド名}`にして追加します。

ex) 画像のようなコレクションタイプに対してPOSTする場合
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194954/86ae9e87-d425-30eb-dcbe-689c27aa154a.png">


```typescript:example.ts
    const body = new FormData();
    // Mediaタイプ以外のフィールドをdataに格納
    body.append('data', JSON.stringify({
      user_id: '01',
      text: 'aaaaaa',
    }));
    // ファイルをfiles.{フィールド名}に格納
    body.append('files.photo', fileObject);
    JSON.stringify(body);
    return this.http
      .post(environment.apiUrl + '/messages', body)
      .toPromise()
      .then((res) => {
        const response: any = res;
        return response;
      })
      .catch(this.errorHandler);
```
コードで書くGoogleSpreadSheet（IFS&IFERROR編）

今回はGoogleスプレッドシートの鬼便利関数、
**IFS**とオマケとして**IFERROR**について書いていきます。🌞

####`今回すること`

><シート１>
<img width="400"alt="sheet1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/8596312f-69aa-d41c-87da-fb6089a8c64a.png">
＜シート2＞
<img width="400"alt="sheet２"src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/86ee636b-f1f0-174d-0823-db6f9fc5956b.png">

・プルダウンで都道府県選択
・人口情報が選ばれた都道府県によって変わる
・人口情報は**シート２**から取ってくる

##準備編

######`プルダウン作成`

[データ]→[データの入力規則]→[リスト直接指定]→[都道府県入力]
<img width="400"alt="pulldown" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/1619d90b-4811-144c-1666-3fc595f8b8b1.png">

##実践編(IFS)

######`コード書く　❶`
<img width="400"alt="pic1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/07ed8870-0c2b-cd45-0092-3182be4a9802.png">
＊人口の横のセルに書いていきます！

```=IFS (D25="北海道",'シート2'!C3 , D25="青森県",'シート2'!C4 ,D25="岩手県" ,'シート2'!C5)
```

<font color="Crimson">意味：</font>”都道府県”の横のセル、**プルダウンのセル**（D25）が **”北海道”**の時、**シート2**に記載されている**北海道の人口の値**（C3）を取ってくる

****
######`コード書く　❷`

＊毎回”北海道”と書くのが面倒な場合！

```=IFS (D25='シート2'!B3,'シート2'!C3 , D25='シート2'!B4,'シート2'!C4,D25 = 'シート2'!B5,'シート2'!C5)
```

<font color="Crimson">意味：</font>”都道府県”の横のセル、**プルダウンのセル**（D25）が  **”北海道”**（シート2のB3）の時
の時、**シート2**に記載されている**北海道の人口の値**（C3）を取ってくる

##オマケ（IFERROR）

######`情報（値）がなかった時`

<img width="600"alt="pic3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/07fb8c7f-4188-c010-a87a-0c6794ea9cff.png">


＊返して欲しい値がなくてnullであった時に返す返答を決めたい時！
```=IFERROR(IFS (D25='シート2'!B3,'シート2'!C3 , D25='シート2'!B4,'シート2'!C4,D25 = 'シート2'!B5,'シート2'!C5),"値がないよ！")
```
<font color="Crimson">意味：</font>もし人口の情報がなかったら**”値がないよ”**と返事して

<img width="300"alt="pic４" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/4c48322b-b2a5-c862-5f81-3b46b59cd4b6.png">

##完成形


<img width="200"alt="pic6" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/83862a25-c06f-2b7e-3069-cc4f32eb9fc0.png"><img width="200"alt="pic7" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/af695cc5-d4c1-984f-1455-5082cf77bf6e.png">

****
都道府県入力は地道で大変な作業だからこの時にIFSを使うことはオススメしないかも...😱
ちょっとしたプルダウンの時に使ってみてね🌟
AIの顔認識機能について

今回は、AIの顔認識機能について調べたので紹介します。

##AIが顔認証を行う流れ
AIが顔認証を行うためには、3つのステップがあります。

1.　入力画像が顔認証アルゴリズムに送られる。

2.　顔認証アルゴリズムが入力画像に対する顔の埋め込みを作成する。

3.　顔認証アルゴリズムが入力画像の顔の埋め込みをデータベース内の顔の埋め込みと比較する。

です。

「顔の埋め込み」というのは、顔画像をアルゴリズムが理解可能なデータに変換することです。顔のキーポイントを数値化することで、データベース内の顔のデータと比較することができるようになるそうです。

##AIの顔認識機能の実用例
・スマートフォンのロック解除
・マンションの入り口、オフィスの正面ロビーなど、顔認識技術によるセキュリティゲート
・顔認識AIによるキャッシュレス決済
・顔認識での犯人追跡

など、主にセキュリティ面での活躍をしています。

##マスク着用時の顔認証
顔認識機能自体は、何年も前からスマートフォンの顔認識でのロック解除など、様々な面で活用されてきました。しかし、私が今回記事として取り上げようと思った理由は「マスク着用時の顔認識」について興味を持ったからです。
マスクを着用している場合、鼻や口、輪郭など、顔のキーポイントとなる部分が全く見えなくなってしまうので、認識ができないのではないかと思っていました。
しかし、その対策として開発されたアルゴリズムは、目の周りに重点を置いて顔の埋め込みをする、というものです。
まず、まずマスク着用の有無を判定し、マスクを着けている場合は目の周り、そうでない場合は鼻や口などから特徴点を抽出し、顔の認証を行うという、マスクの有無に応じて分析アルゴリズムを切り替えるシステムでした。このアルゴリズムにより、マスク着用時でも99.9％で顔認証が実現されたようです。

##感想
コロナの蔓延は非常に急なことであったにも関わらず、臆せずにその対策となるシステム開発を行っていく世界中の開発者の人たちの姿勢や対応力に驚かされました。私も、もっと勉強をしてスキルを磨き、そのような人材になろうと思いました。