OmniAICreator/Qiita-1.07M huggingface dataset:
多相ヴァリアントの型推論はどこまで厳密にできるか

多相ヴァリアントを触っていたときに気づいた小ネタの紹介。

# ある再帰的コード

```ocaml
let rec x = `N[x; `M] in x 
```

ここで ``` `N[x; `M]``` は ``` `N([x; `M])``` のようにコンストラクタ ``` `N``` にリストを適用しただけのコード。

これは μ記法 を使うと ```μx. `N [x; `M]``` とかける。最初に ``` `N``` が来て、そのあとは ```[`N[...]; `M]``` と続く無限木（あるいはグラフ）を表す。

# 単一化ベースの型推論に対する(私の)過剰な期待

多相ヴァリアントの熱烈なファンとしては、この「**最外は``` `N```のみ**」という性質が型に現れてほしいところだが、OCaml処理系は次のように推論する：

```ocaml
[> `M | `N of 'a list ] as 'a
```

最外にも ``` `M``` が出現しうると推論されてしまう。 これは型推論の過程で `x` の出現と `x` の定義に同じ型変数を割り当ててしまうため、といったらよいのだろうか。

ただし上のようなケースが現実のプログラミング場面で頻繁に現れるかといえばかなり疑問ではある。
意外なコーナーケース以上のものではない、かもしれない。

# どう直す

x を1回展開して

```ocaml
let rec x = `N([`N[x; `M]; `M]) in x 
```

```[`N(...); `M]``` の部分に結び目を移して、`N を再帰定義の外に出す。

```ocaml
let rec y = [`N(y); `M] in `N(y)
```
こうすれば、推論される型は期待通り

```ocaml
[> `N of [> `M | `N of 'a ] list as 'a ]
```

となる。


# 余談

ICFP'16 の [Set-Theoretic Types for Polymorphic Variants (Castagna et al.)](https://arxiv.org/pdf/1606.01106.pdf) ではサブタイピングと HM(X) による型推論が提案されており、より精密な型が推論されるようになっている。
型推論器はこちらで触ってみることができる：

http://www.cduce.org/ocaml/

リストがないので if 文で似たようなコードを書いてみると、

```
# recfun f x -> `n (if x then f x else `m);;
- : Bool -> `n(X1) where X1 = `n(X1) | `m
- = <fun>
```

のように、期待通りの型が推論される。面白い。

とはいえ、こんなコーナーケースを見つけたのは初めてだし、私は今の OCaml の型推論には満足している。
さいきょうのMacBook Proに育てるための神アプリ一覧

PC入れ替えとかでどれ入れてたっけ、入手先は？となるので、一覧を作ってみた


## 統合環境

|ソフトウェア名|説明|URL|
|:--|:--|:--|
|VScode|言わずもがな。神。動いていない日は無い。|https://code.visualstudio.com/|


## 配信関連

|ソフトウェア名|説明|URL|
|:--|:--|:--|
|ManyCam|VirtualCamera+VirtualMicが使える神アプリ。クロマキー対応|https://manycam.com/|
|Krisp|マイクのノイズキャンセリング処理を行ってくれる神アプリ|https://krisp.ai/|

## 操作環境改善

|ソフトウェア名|説明|URL|
|:--|:--|:--|
|Karabiner-Elements|macにWindowsキーボートをつなげても、Macのキー配列で操作ができる神アプリ|https://karabiner-elements.pqrs.org/|
【初学者向け】最新版AWS認定ソリューションアーキテクト-アソシエイト(SAA-C02)合格までの道のり【2020年12月】

#はじめに
エンジニア未経験の私がAWS SAAを取得した勉強法についてです。
これからAWS SAA取得を目指す方の参考になればと思います。
なお具体的なサービスの内容については記述致しません。
下記の教材で学べば十分合格できると思います。
![AWSASSスコア.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702780/39908584-1bcd-1c14-02a3-d0cf29f55146.png)


#合格時のスキルセット
・実務未経験
・プログラミング学習を本格的に初めて5ヶ月目
・AWS経験は少々（EC2、RDS、CloudWatch等を使用し、ポートフォリオサイトをデプロイしたことがあるレベル）

#勉強した期間
2020年11月7日から12月18日までの約40日間。
計160時間～200時間は学習にあてたと思います。

#使用した教材
[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)

Udemyで配信している講座です。AWSの主要サービスをハンズオン形式で学びながら試験対策もしっかり出来るので最もオススメです。
全くAWSを触ったことのない人にも親切な作りですし、試験の出題傾向を押さえつつ本試験とほぼ同難易度の模擬試験も3回分ついてくるのでセールの時に購入しておくとかなりお得だと思います。最初から最後までお世話になりました。
※全体的に音声が聞き取りづらいところだけマイナスです・・・

[【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)

同じくUdemyで配信している問題集です。前述の口座と同時購入しましたが、1回分模擬試験が被っているので実質5回分でした。AWSSAAの試験において出題形式に慣れておくことはとても重要なので、なるべく数多くの問題を解いておく方が良いと思います。
ちなみに最初に解いた時はどの模擬試験でも正答率40~50%程度でした（試験直前での正答率は80～90%くらいです）。復習では正答を確認するだけでなく`なぜその他の回答は誤答なのか`という点を押さえる事が重要です。各種サービスの内容とユースケースをしっかりと学んでいきましょう。難易度は本番と同程度だと思います。

[徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書](https://www.amazon.co.jp/dp/4295005495/)
1回通しで読みました。AWS全体の内容をさくっと学ぶのにはいいかもしれませんが、AWSは常にサービスの内容が変化していくので、あえて1年近く前に発行された本で学習する必要はないと思います。模擬試験も現在の試験にはあまり即してないように思えました。

※補足
[AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト - アソシエイト　改訂第2版 Kindle版](https://www.amazon.co.jp/dp/B08MVXRFFN/ref=dp_kinw_strp_1)
どうしても書籍で学習したい方で、資格取得までの日数に余裕のある方は来年1/21に発売予定のこちらの本で学習する方が良いかもしれません。内容は把握していないので保証はできませんがSAA-C02に対応しているようですし、変化の速いサービスの学習はなるべく新しいテキストで勉強するに越したことはないと思います。


[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)
WEB問題集です。有料会員になる必要がありますが2020年12月時点で#1~#140まで出題があり大体1000問近くの問題が掲載されています。#1~#140までを1周した後は#90~#140を2周しました。後半の問題になるにつれ現在の試験に近い内容になっているので。#90以降を重点的に学習するのがオススメです。順次問題も追加されるようなので、常に最新の試験に近い問題が解けるのではないでしょうか。試験前の最後の追い込みは大部分このサイトに頼っていました。
また、このサイトに掲載されている合格記は是非読んでみて下さい。直近で合格された方たちの率直な感想が読めるのでかなり参考になります。実際の試験に出た内容を踏まえて、確実に押さえておくべきサービスなどのアドバイスが載っておりかなり精度が高かったです。実際そのおかげでとれた問題が何問かありました。先人に感謝です。


AWS Black Belt
Udemy講座のスライドで十分対応できる試験内容だとは思いますが、
試験直前にS3などの頻出サービスについてはBlackBeltのスライドを確認しました。

#本試験について
受験料16,000円
試験時間130分
問題数65問
1000点満点中720点以上で合格です。
大体80分くらいで解き終わって残りの時間は見直しにあてました。
わからない問題にはマークをつけれるのでつけておきましょう。
一週目は半分くらい回答に確信が持てなかったのでマークしてたと思います。
当たり前に聞こえるかも知れませんが一番重要なのは`問題文をよく読むこと`です。
すぐに正解がわからなくても落ち着いて問題をよく読みましょう。
見直しは絶対したほうがいいです、集中力が切れても最後まで諦めないで下さい。
ちなみにピアソンVUEのテストセンターで受験しました。試験は毎日のようにやっていたので、前々日に予約しました。

#最後に
そもそものインフラの知識も乏しく実務未経験なので飲み込みが遅かったのかもしれませんが資格取得まで1ヶ月以上かかりました。聞き覚えのない言葉がたくさん出てくるので初めは苦労しましたが、毎日学習を継続してなんとか合格することが出来ました。この記事を読まれた方が無事試験に合格できるように祈っております。
JavaScript~関数~

#はじめに
何とか三日坊主は回避できました。今日で4回目です。
今回は関数について投稿していきます。
関数が使えるようになるとかなり便利なので自分も復習しながら書いていきます。
#関数
関数とは処理をひとまとめにして変数や定数のように名前をつけて繰り返し使いやすくできます。
復習になりますが変数と定数は「値」に対して名前をつけて関数は「処理」に対して名前をつけます。
構文は次のようになります。

```JavaScript:関数
function 関数名(引数){処理内容} //関数を定義する
return 値 //関数内で値を返す
関数名(); //関数を実行します。
```
このように関数とは、ある入力値を受け取って処理を行い、その結果を返す仕組みのことです。
functionで関数を定義し、任意の関数名を設定します。{}で囲まれた部分が関数の処理内容になります。
実例は次のようになります。

```JavaScript:実例
function name(a){
  const result = a + b;
  return result;
}
```
この例は入力値「a」を受け取り「 a + 2 」の結果を返す関数「name」の定義です。入力値「a」のことを引数といいます。
関数から返る値のことを戻り値といいます。上の例だと「result」が戻り値です。
ここで注意が必要なのが「return」によって関数の処理は終了するのでそれ以降の処理は実行されません。

```JavaScript:実行不可
function name(a){
  const result = a + b;
  return result;

  console.log('日本')
//returnの後に記述しているので実行されない
}
```
またreturnはいくつも記述でき、次のように引数の条件によって戻り値を変えるような使い方ができます。

```JavaScript:実例
function total(a,b){
  if (a >= 100){
    return = a;
}
return = b;
}

//「if」について別の機会に投稿しますが上記の関数は「a」が100以上なら「return a」が実行され「return b」は実行されません。
//「a」が100未満なら「return b」だけが実行されます。
```
定義した関数を使用する場合は次のように使います。

```JavaScript:関数の使用
function total(price,count){
  const result = price * count;
  return result;
}

const amount = total(1000,3)
console.log(amount); //結果3000

//result = price * count なので今回の場合は「 1000 × 3 = 3000 」と出力されます。
```
#終わりに
今回の内容は以上になります。関数は初めて勉強したときは難しかったのですが
アプリを開発するときに何度も使いそこでわかってきました。なので読んで分かりにくい場合は
実際に書いてみて実行してみると案外すんなり理解できたりします。
自分もまだまだ理解している範囲は少ないので今後も勉強していきます。
最後まで読んでいただきありがとうございました。
pg_repackについて調べてみた

これは、[PostgreSQL Advent Calendar 2020](https://qiita.com/advent-calendar/2020/postgresql)の22日目の記事となります。

昨日の記事は [@tom-sato](https://qiita.com/tom-sato)さんの[Pgpool-II 4.2 で何がどう変わったか？](https://qiita.com/tom-sato/items/c01d4df39a6bb19e2b17)でした。

私は開発エンジニアとしてPostgresqlを利用しているのですが、
悩みごとを[Postgresqlのコミュニティ](https://www.postgresql.jp/node/188)に相談させていただいた時に教えていただいたツール`pg-repack`を紹介させてもらいます。

#### pg-repackとは

`pg-repack`はテーブルの再編成を行えるPostgreSQLの拡張ツールです。
PostgreSQL Advent Calendar 2015で既に一度、中の人が直々に書かれた記事 [運用で役立つツールpg_repackのご紹介](https://qiita.com/bwtakacy/items/3be7a3e1540ccef7c9e3)もあるのですが、
最近の状況も含め、改めて紹介できればと思います。

テーブルの再編成を行う方法として`VACUUM FULL`コマンドなどがありますが、テーブルのに排他ロックがかかり、しかも実行に長い時間がかかるなど、リリース時の対応に頭を悩ませることになります。

私の場合、データクリーニングのために稼働中のDBに大量のUPDATEをかけた結果、不要領域が一度に増えすぎてパフォーマンスが低下したことがありました。
大量のUPDATE・DELETEがもたらす影響については[PostgreSQLアンチパターン：UPDATEの濫用](https://qiita.com/masudakz/items/9b4b9b94b9462165101e)が分かりやすくまとまっています。

不要領域が著しく増えた時には`VACUUM FULL`コマンドでテーブルの再編成を行う方法がありますが、長時間の排他ロックがかかるためリリース時の対応に頭を悩ませることになります。

その点`pg-repack`はごく短い間しか排他ロックをかけないため、稼働中のサービスに対するリリース戦略として有効な手段となります。

#### リリース状況
2020年12月時点でのバージョン情報です。

| 公式サイトURL |https://reorg.github.io/pg_repack/|
|:-:|:-:|
| 最新バージョン|pg_repack 1.4.6|
| Postgresql対応バージョン|PostgreSQL 9.4, 9.5, 9.6, 10, 11, 12, 13|

最新バージョンのリリース日付は2020年9月30日と、着々と開発が進んでいるようです。
また、公式サイトを日本語訳ページで見ると、対応バージョンが9.6までしか表示されない点に注意です(上記`reorg`の原文ページのReleaseで対応状況が確認可能)。

#### pg_repackの再編成の種類
既に何度か書きましたが、pg_repackはテーブルの再編成を行うツールです。
ただ、再編成の方法についてはいくつかバリエーションがあります。

・オンラインCLUSTER(テーブルデータを物理的にINDEX順で並び替え)
・指定カラムでレコードを並び替える
・オンラインVACUUM FULL (レコードのすきまを詰める)
・指定テーブルのインデックス再構築・再配置

#### コマンド実例
コマンドは`pg_repack...[SCHEMA_NAME]`の形式で、
`...`の部分にオプションをつけることで再編成の方法や対象テーブルを指定できます。


・スキーマ全体に`CLUSTER`・`VACUUM FULL`を実行
(クラスター化テーブルへは`CLUSTER`,非クラスターテーブルへは`VACUUM FULL`を実行)

```
pg_repack test_schema
```
・カラムを指定してレコードを並び替え(カラム指定の`CLUSTER`)

```
# -o 整列に使うINDEXカラム指定
pg_repack -o role_id -t user test_schema
# カラムは複数指定可能
pg_repack -o role_id,id -t user test_schema
```
・テーブルを指定して`VACUUM FULL`を実行

```
# -n VACUUM FULL指定オプション
pg_repack -n -t foo test_schema
# 複数テーブルを指定することも可能
pg_repack -n -t foo -t bar test_schema
```
・指定したテーブルのインデックス再編成

```
# -x
pg_repack -x -t users test_schema
```
・コマンドを実行内容を確認したい(Dry Run)

```
# -N 実施内容をメッセージとして出力
pg_repack -N test_schema
```

#### 注意点
・再編成にはテーブルとインデックスを合わせたデータサイズ**2倍**の空き領域が必要
・pg_repackを実行できるのは**スーパーユーザ**のみ
・再編成の内容によっては対象テーブルに主キーorNOT NULL+ユニーク制約をもつインデックスが存在している必要あり

### まとめ
本来ならハンズオン的な内容を書きたかったのですが・・・、
恥ずかしながら、インストールでつまづいてしまい、試したことを書くことができませんでした。
今後、試した結果を記事にできたらと思います!

また、レベルの高い記事にビビリつつも、なんとか投稿する勇気がなくなる前に記事を投稿することができました。
これもPostgresqlコミュニティの温かさのお陰です。

明日は[sawada_masahiko](https://qiita.com/sawada_masahiko)さんの投稿です!
Railsのバリデーション設定でハマった話

こんばんは
アロハな男、やすのりです！

今日はポートフォリオ作成中にモデルのバリデーションでハマった話をしていきたいと思います！！

もしかしたら明日は我が身かも...？

#結論
Userモデルのパスワードへのバリデーションは

```ruby
on: :create
```
を使おう！

#ハマった時の状況
え、いやどういうこと...？
となってしまうと思うので、順を追って説明していきます。

まずポートフォリオではユーザーが会員登録された場合は、専用のマイページがあったり口コミ投稿ができたりする機能をRailsのGemである`devise`で作成していました。

そんな機能の中で、マイページで行える**『自身のユーザー情報変更機能ページ』**で事件が起こりました...

#何があったのか？
ユーザー情報の変更ページではユーザー名やアイコン画像等を変更することができるページなんですが、`devise`を使用していると通常は変更の際に毎回パスワードの入力が必要になります。

ただ、『少しの変更で毎回パスワードを入力するのは面倒だなぁ...』という人のために、パスワードを入力しなくても良い様にするメソッドを`devise`は用意してくれています。

```ruby:registrations_controller.rb
protected

def update_resource(resource, params)
  resource.update_without_password(params)
end
```
最初はこのメソッドはコメントアウトされているので、コメントアウトを外すことでユーザー情報更新の際でもパスワードを入力しなくてもよくなるはずでした。

しかし実際に変更内容を入力して`更新ボタン`を押してみると...

![スクリーンショット_2020-12-22_22_48_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/a791873d-7ec8-54a4-e5fa-99c72fff3da2.jpeg)

『あれ...え、なんで!?パスワードの入力を求められたぞ...!?』
もちろん、この状況でパスワードと確認用パスワードを入力して`更新ボタン`を押すとユーザー情報が更新されはするんですけど...

俺が欲しかったのはこんなよくわかんない機能じゃな〜い！！

ということで、いろいろ調べてみると原因が判明しました。

#原因
察しのいい方はもうお気づきかもしれませんが...
そう、今回の事象の原因は`Userモデルで設定したパスワードのバリデーション`のせいだったんです！！

どういうことかと言うと、今回パスワードのバリデーションとして

```ruby
presence: true(カラムが空だと登録されないオプション)
```

を設定していたんですが、この`カラムが空だと登録できない`という部分が効いてしまっていたんです...!!
つまり、
>Userモデル『お、ユーザー情報を更新するぞ〜』
>　　　　　　　　　↓
>Userモデル『deviseのコントローラーでパスワードがいらない設定もできてるな〜』
>　　　　　　　　　↓
>Userモデル『あれ、でもモデルのバリデーションでパスワードが必要だな...』
>　　　　　　　　　↓
>Userモデル『はい、パスワードも入力してくださ〜い』
>

と言う流れになっていた様です...なんという...

#解決策
原因がわかればあとは簡単です。
パスワードに適用されていたバリデーションを**ユーザー登録の時だけ**かかる様に設定しなおせば良いだけです。

そこで冒頭でお見せした、

```ruby
on: :create # コントローラーのcreateアクションの時のみ動作する様にするオプション
```
が必要になります！

今回の私のコードで書くと

```ruby:user.rb
  with_options presence: true do
    # ユーザー新規登録時のみバリデーションを適用する。
    with_options on: :create do
      validates :password
      validates :password_confirmation
    end
  end
```

※いろいろ他にもバリデーションを記述はしていますが、パスワードだけを抜き出しています。

さぁ、これで無事にユーザー情報が更新される様になりました！
めでたしめでたし



#最後に
ユーザー機能もパスワードのバリデーションも比較的多くのアプリで必要になってくる機能だと思いますので、もし同じ様なことがあった際は参考にしてみてください！

この件に関するご指摘・アドバイスはどんどんいただきたいと思っていますので、コメントお待ちしています！！
Linuxの先読みキャッシング  read_ahead_kb

この記事面白すぎる！

> # 先読み
必要なデータをユーザから要求があるたびに同期的に読み込んでいると、ディスクの I/O 待ちに時間がかかる。そのため、 I/O 要求がシーケンシャルリードだと判断した時点で要求されていない後続のブロックを先読みしておき、キャッシュを充実させる。先読みしたデータは使われるかもしれないし、無駄になるかもしれない。
先読みすることでどの程度効率化されているかを動作確認する。
> https://www.kimullaa.com/entry/2019/12/01/130347


```ruby
#// 先読みが有効であることを確認する
cat /sys/block/sda/queue/read_ahead_kb

# cache削除
echo 3 > /proc/sys/vm/drop_caches

# （先読みあり) 読み込み速度計測
time dd if=/dev/sda of=/dev/null bs=10M count=100

#先読みを無効にする
echo 0 > /sys/block/sda/queue/read_ahead_kb

# cache削除
echo 3 > /proc/sys/vm/drop_caches

# （先読みなし）読み込み速度計測
time dd if=/dev/sda of=/dev/null bs=10M count=100

```

# result
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/5967bc99-99c6-b51c-4e95-3ec87f4f40c9.png)

```ruby

[root@localhost test]# cat /sys/block/sda/queue/read_ahead_kb
4096
[root@localhost test]# echo 3 > /proc/sys/vm/drop_caches
[root@localhost test]# time dd if=/dev/sda of=/dev/null bs=10M count=100
100+0 records in
100+0 records out
1048576000 bytes (1.0 GB) copied, 1.53053 s, 685 MB/s

real	0m1.566s
user	0m0.000s
sys	0m1.074s
[root@localhost test]# #先読みを無効にする
[root@localhost test]# echo 0 > /sys/block/sda/queue/read_ahead_kb
[root@localhost test]# echo 3 > /proc/sys/vm/drop_caches
[root@localhost test]# time dd if=/dev/sda of=/dev/null bs=10M count=100
100+0 records in
100+0 records out
1048576000 bytes (1.0 GB) copied, 37.3734 s, 28.1 MB/s

real	0m37.386s
user	0m0.001s
sys	0m25.442s
[root@localhost test]#
```
業務中にメモった検証時の注意事項を振り返ってみた。

## はじめに

この記事は Hamee Advent Calendar 2020 23日目の記事です。
この記事を書くにあたって、2019年のアドカレを振り返ってみたところ、[一人でこっそり使ってた仕組みを、他の人にも使ってもらえるようにした話。](https://qiita.com/myblackcat7112/items/1229828745db1ece1b34)を書いていたみたいです。何かを作ったよ！ここを工夫したよ！って記事ですね。気が向いたら読んでやってくださいNE！

さて、本題に入ります。
新卒1年目の時は、開発をして検証を依頼するだけのことが多かったのですが、2年目になって後輩ができたのもあって、徐々に検証依頼されることも多くなりました。ここでの検証というのは、開発者がある機能を追加するなり改修するなりしたときに、解決したい課題をその方法で本当に解決できるのか、その方法が最善な選択なのかどうか、既存の機能に影響を与えていないかどうかを確認することです。

そう頭ではわかっているのですが、結果としてリリース可否の段階でリリース判定者に差し戻しされてしまうことが結構あり、その度、開発者とリリース判定者に申し訳ない気持ちになっています。
もちろん、検証者としては、頼まれたからにはリリースしても問題のない品質であることを速く正確に確認してあげたいし、もし開発者が気づいていないバグや考慮漏れなどがあればそれを指摘し、リリース判定者を安心させたいものです。

そこで、指摘を受けるたびに、自分の未熟さを再認識し同じ指摘を再びされないように、とslackのtimesに記録してきました。ただ書き留めるだけでは忘れてしまうのと、開発者として検証項目を考慮するときにも役立つので、この機会に振り返ってみようと思います。
コードレビューの話よりももっと手前の話なので、もしかすると誰かの役に立つかもしれないし、全く役に立たないかもしれませんが......

## 改修する機能やそれを呼び出している機能でわからないことは無いようにする！
タイトルそのままですね。改修対象の機能が、どこでどのように呼び出されるのか、どの画面で使われているのかを全て調べるということです。同じメソッドでもその呼び出し元の環境によって挙動が異なるかもしれません。理解が曖昧な部分に実は重要なロジックが書かれていたということもあったりします。
ソースコードだけを追っているとわかりにくかったり、見逃してしまうこともあるかもしれませんので、必ずマニュアルや資料があればそれらも確認し、実際にユーザーと同じように動かして確認することを意識しようと思います。

## コメント文を過信しすぎないこと
これもそのままなのですが、ちゃんとコードを読めよという話です。改修に改修を重ねたプロダクトだと当初のコメントと実際のコードの内容に解離が発生することがあります。実際にあったのは、元々はとあるユーザーさんの要望に答えるために実装されたメソッドだったものが、現在では全ユーザーが共通で利用する可能性のあるメソッドになっていたということがありました。改修時にコメントの修正をし忘れている場合もあるので、コメントは過信しすぎずにコードを読んで実際の処理を把握した方がいいと思います。

## すでに入っている値やデータの対応についても考えること
バグなどによって、本来入ることが想定されないデータがDBのカラムに入ってしまうことがあるかもしれません。このような時は、バグの原因を突き詰めてバリデーションを強化するなどの対応をすることになると思います。この対応により、新しく入ってきた値には問題はなくなるのですが、改修以前に入っていたデータに関しては直接DBにクエリを流すなどして対応しない限り変わりません。そのままだと、既存のデータを呼び出して使うときに、想定外の文字列などが混入した状態で呼び出されてしまい、動作に影響を与え続けるかもしれません。
そのため、改修だけでなく、既存のデータにも気を配っているかを確認するように心がけようと思います。

## ユーザーに画面から設定などを変更してもらったときに、DBで変更内容を確認すること
私の業務では、稀に特定のユーザーのDBに直接変更を加えることがあります。そのとき、画面からできることはできるだけユーザーにやっていただくようにして、データの不整合がなるべく起きないようにします。ただし、ユーザーが変更を加えられるのは、現在表示されているものだけです。ですが、過去のバージョンの設定値や項目を、データの整合性を担保したり、将来的に設定を再利用するなどの理由で物理削除ではなく論理削除(非表示)で残しておくこともあると思います。
このような非表示のデータは、ユーザーが変更することができないため、こちら側で適切に処理をしてあげる必要があります。今は非表示の設定も表示されるときが来ないとも限りませんので、その時にユーザーが困ることがないように気を付けようと思います。

## 改修前後で予期しない変更がないか、DBのカラムを比較して確認してみる
影響範囲の大きな改修やリファクタでは何が起きるかわからないということもあるかもしれません。そのような時は変更前後のDBの状態をdumpなどで保持し、変更前後のカラムを比較します。このとき、本来変更されるはずのないカラムで差分が出ていたら、なんらかのバグが残っている可能性があります。変更されるはずのカラムが変更されていない場合もこの方法で気づくことができます。
こんな簡単な例ではありがたみがあまりないかもしれませんが、ageが20から200に変わるなんてことがあればさすがにバグに気づけそうですよね。
必要であれば検証者として、このチェックをやってみるといいかもしれません。

変更前 

|id|name|age|
|---|---|---|
| 1 |  test | 20  | 

変更後

|id|name|age|
|---|---|---|
|1|test| 200| 


## おわりに
このほかに、画面にちゃんと出ているからと言って、DBのカラムを見ないのは危険だぞ、とか、変更箇所にあるif文は全部通ることを確認して、とかまぁ当たり前と言われてしまいそうなメモが残ってました......（おいおい......）
とはいえ、先輩方から指摘いただいたことではあるので、真摯に受け止めて日々の検証や開発に生かして行こうと思います。
SAS環境の構築　- SAS University Edition -

##当記事の目的
　・「SASを扱う案件に参画することになった」方
　・「最近のトレンドで"ビッグデータ"や"機械学習"で調べていたらSASに辿り着いた」方

　上記の方々にSAS言語の環境構築をして頂き、**実際にSAS言語を動かせる状態になる事**が目的です。
　SAS言語の説明は割愛し、**SAS University Edition**を用いた環境構築の方法のみを記載します。

　※環境構築は簡単で、**1時間前後**でSAS言語が実行出来る環境が作成出来ます！

#####SAS University Editionとは
　・学生や社会人が、非営利目的で利用できる**無償**のSASソフトウェアです。
　・Virtual BoxやVMwareの**仮想環境**で実行します。

##SAS University Editionの導入方法
　「仮想環境の入手」～「SAS言語の実行」の中で重要な点を抜粋して記載していきます。
　(今回はWindowsユーザ向け)
　
　詳細は下記の公式HPの手順を参照して下さい。とても丁寧に記載されています。
　　[SAS® University Editionダウンロード&インストール・ガイド](https://www.sas.com/ja_jp/software/university-edition/download-software.html)

　1. 仮想環境の入手
　　SAS University Editionを実行するには仮想環境が必要です。今回はVirtualBoxを用います。
　　[当リンク](https://www.virtualbox.org/wiki/Downloads)でWindows用のVirtualBoxを入手しましょう。

　2. SASファイル保存用のフォルダを作成
　　仮想環境上のSAS University Editionで作成されたSASファイルは、全てローカル上に保存します。
　　ローカルPC上の任意の場所に _SASUniversityEdition_ というフォルダとその中に、_myfolders_
　　というサブフォルダを作成しましょう。

　3. SAS University Edition vAppをダウンロード
　　[SAS® University Editionダウンロード&インストール・ガイド](https://www.sas.com/ja_jp/software/university-edition/download-software.html)　から入手できます。
　　SASユーザーのアカウント登録は必須です。

　4. 設定
　　仮想環境とSAS University Editionの入手が完了しましたので、以下の設定を行います。
　　①SAS University EditionのVirtualBoxへのインポート
　　②手順2で作成した_myfolders_フォルダのVirtualBoxとの共有



　5. SAS言語の実行
　　①VirtualBox上でSAS University Editionを起動します。
　　②起動が完了したら、ローカルPCのブラウザに「 _http://localhost:10080_ 」を入力します。
　　③SAS Studioにアクセスされ、SAS言語が自由に記述・実行出来るようになっています。
　　※[SASチュートリアルはこちら](https://www.sas.com/ja_jp/training/tutorial.html)

##最後に
>費用はゼロ。成果は無限大。

と公式HPに書いてある通り、環境構築に時間がかからず、それであり、ほぼ商用と同じ機能を
使うことが出来るので皆さまも是非一度試してみてはいかがでしょうか。
漢字の文章のふりがなの簡易チェック

# 学習用データでやらかした
学習用データの漢字の文章と，そのふりがなを人力で用意した．ただちょくちょくふりがなが間違っている．または写し間違えている．たまに原文も日本語がおかしく，てにをはが間違ってる．そんなときにふりがなに直すときに善意で直してしまったようだ．
例
原文：ドレスが塗りたてのペンキがついてるよ。 
かな：ドレスがぬりたてのペンキについてるよ。
「が」が「に」に直ってる．

正しいんだけどこれはこれで問題．なのでこれを見つける

## コード
当然だが漢字の文の中のひらがなはふりがなの方にも存在する．なので漢字に存在するひらがなをそれぞれカウントし，ひらがなのときにそれが減ってたらミスとする．

```python
HIRAGANA: List[str] = [chr(i) for i in range(12353, 12436)]
KATAKANA: List[str] = [chr(i) for i in range(12449, 12532 + 1)]
def check(kanji: str, hurigana: str) -> bool:
    flag = True
    for i in range(len(HIRAGANA)):
        # 漢字での出現回数
        kanji_appear: int = 0
        kanji_appear += kanji.count(HIRAGANA[i])
        kanji_appear += kanji.count(KATAKANA[i])
        # ひらがなでの出現回数
        hirangana_appear: int = 0
        hirangana_appear += hurigana.count(HIRAGANA[i])
        hirangana_appear += hurigana.count(KATAKANA[i])
        if kanji_appear > hirangana_appear:
            print(HIRAGANA[i], kanji_appear, hirangana_appear)
            flag = False
    for l in ['、', '。']:
        # 漢字での出現回数
        kanji_appear: int = kanji.count(l)
        # ひらがなでの出現回数
        hirangana_appear: int = hurigana.count(l)
        if not kanji_appear is hirangana_appear:
            print(l, kanji_appear, hirangana_appear)
            flag = False
    if not flag:
        return False
    return True
```
もちろん漢字のふりがな自体のミスは考えられる
けどだいぶマシになるんじゃないかな？
Gatsbyでのコンテンツ管理方法

Gatsbyではマークダウン、Googleスプレッドシート、Wordpressなどの従来のCMSなどの様々なデータソースを選択することができます。
そして、１つのデータソースに限る必要もなく、複数のデータソースを組み合わせることもできます。

##Contentfulについてについて
Contentful】入門。Conentfulとは？導入方法・設定手順の解説
https://fromscratch-y.work/ja/blog/technology/other/start-contentful/

【画像解説】Contentfulの使い方【活用方法も紹介】
https://colorfree-map.com/howto-contentful

##GraphQLでContentfulのデータを扱うための準備
####プラグインの準備

```
yarn add gatsby-plugin-contentful
```

gatsby-config.jsにプラグインの設定を追加します。 optionsではContentfulのSpaceID,AccessToken, HOSTを指定する。
ただし、ファイルを直接記述せず環境変数を利用します。（ファイル中にトークンを残したくないため、環境変数を使用する）

＊環境変数とは、OSが設定値などを永続的に保存し、利用者や実行されるプログラムから設定・参照できるようにしたもの。プログラムの実行時などに必要となる、利用者やコンピュータごとに内容が異なる設定値などを記録するために用いられる。


```
{
resolve: `gatsby-source-contentful`,
options: {
  spaceId: process.env.CONTENTFUL_SPACE_ID;
  accessToken: process.env.CONTENTFUL_ACCESS_TOKEN;
  host: process.env.CONTENTFUL_HOST;
 },
},
```
 


####開発サーバーの起動
環境変数にした３つの値を指定して、開発サーバーを起動します。（デプロイ時にも環境変数が必要になる）

```
CONTENTFUL_SPACE_ID=***** CONTENTFUL_ACCESS_TOKEN=***** CONTENTFUL_HOST=cdn.contentful.com gatsby develop -H 0.0.0.0
```

####GraphiQLで確認する
GraphiQLにアクセスして、プラグインが機能していることを確認します。



参考文献：
Webサイト高速化のための静的サイトジェネレーター　GatsbyJSで実現する高速＆実用的なサイト構築
IT用語辞典：http://e-words.jp/w/%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0.html
右も左も分からない「タコ助」が、「開発環境」の構築と「Hello Python」コード記述実行

右も左も分からない「タコ助」が、「開発環境」の構築と「Hello Python」コード記述実行
△
・右も左も知らない私が、「VsCode」で「Python」の学習を始めて16日が過ぎた。
　(合計33時間27分、一日平均2時間強)　
・結果、「開発環境」の構築と「Hello Python」コード記述実行。
・この期間は、主に動画による学習。
・サポートは、二件。（内、一件回答なし）
△
・で、この期間を評価するに「かかり過ぎ」の一言に尽きる。
・その理由は、「要領」が悪い。
・何故「要領」が悪いか？
・性分もあるが、知らな過ぎる。
△
・で、第二段階の具体的な「プログラム学習」に入る前にはたと思う。
・「…このまま、突入したら、二の舞を踏むのでは？」と。
・で、「第一段階」を振り返る事で「二の舞い」を回避出来るのではないかと思い、これを
　書く事にした。
△
・先ずは、「vsコード　初心者　動画」とGoogleで検索。
・で、表示された「動画」を視聴。
・この時、何個かの動画があったが…「長くもなく、短くもなく」程度の思いで選択。
・動画を視聴するが…当然「珍紛漢紛」の連続だが…。（冷や汗）
・兎にも角にも、視聴する。
・視聴する主な内容は、ザックリ「VsCodeとは、何か？」と「VsCode」」「Anaconda3」の
　インストール手順。
・インストールは、比較的問題なし。
・が、五日目の視聴で、「頓挫」。
・理由は、「Git」へのアクセス。

「　Gitは、プログラムのソースコードなどの変更履歴を記録・追跡するための
　分散型バージョン管理システムである。　」

・と、言う事であるが…「超難解」で、今の私には「不必要」と、早々の退散。
・然し、少し「賢く」なる。(笑)
・で、何と「プログラミング」が出てこずこの「動画」は終わり。(笑)
△
・再び、「VsCode　パイソン　開発　入門」でGoogle検索。
・で、上記と同じ「基準」で「動画」選択。
・動画を視聴しつつ、プログラムを書いて動かしてみる。
・結果、「エラー」。
・「エラー」解決に取り組む。（泥沼にハマる…笑いと涙）
・先ずは、「エラー」」文の「熟読」。（の、つもり）
・で、「Windows PowerShell」を インストール。（流れ）
・次は、「 Anaconda3　」「環境変数」を設定。
・結果、「エラー」。
・以後、検索に検索を重ね、諸々挑戦するがダメ。
・で、次は、違う「動画」でスタート。
△
・初めに、「 Anaconda3　」「VsCode　」を「アンインストール」。
・「VsCode」「Python」を再インストール。
・この「動画」は、「Anaconda3」無しでの「動画」。
・で、動画を視聴しつつ、プログラムを書いて動かしてみる。
・結果、「エラー」。（心…ボキとおれる＝ (笑)）
・「追い打ち」をかけるように「エラー」文には、削除した「Anaconda3」の「文字」あり。
・流石、立ち上がる事が出来ず、「サポート」に頼る。
・「サポートの指摘によると「Pythonインタープリター」を選択しなさいとの事。
・無事、解決。（むせび泣く）
△
・書きながら思う。
・知らない事は、本当に恐ろしい。
・何故ならば、「エラー」文に囚われ…画面に「解決方法」が表示されているのに
　気づかない。
・次に、思う事は必ず「記録」をとる事。
・「記録」が無いと、自分が何をしたかが分からなくなる。
・これは、「必須」。
・で、「サポート」を受ける前に自身の行いが重要だが、程度を決めておく事。
・何故ならば、私の性分も禍したのだが…何でも調べて解決しようとすると、「膨大」な量
　と時間を要する。（無論、見極めは難しい）
△
・この拙い「文」が、新たに挑戦する方、「頓挫」している方の一助になれば目下の幸いです。
LinuxがPage cacheを使って高速化するのを体験してみる

こちらの超素敵な記事をまんま真似するだけです。
https://www.kimullaa.com/entry/2019/12/01/130347


rootで実行します。

```ruby
# でかいファイルを作る
 dd if=/dev/zero of=/tmp/large.txt count=100 bs=10M

# 今のcache状態
 vmstat

# cache削除
 echo 3 > /proc/sys/vm/drop_caches

# cacheが減った状態
 vmstat

# １回目
time cat /tmp/large.txt > /dev/null

# cacheが載った状態
 vmstat

# 2回目は早くなるはず
time cat /tmp/large.txt > /dev/null

# お掃除
rm -rf /tmp/large.txt
```

# result

10倍になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/43c175ae-a4e0-aac9-9628-220b57fdccef.png)


```ruby

[root@localhost test]# # でかいファイルを作る
[root@localhost test]#  dd if=/dev/zero of=/tmp/large.txt count=100 bs=10M
100+0 records in
100+0 records out
1048576000 bytes (1.0 GB) copied, 1.29639 s, 809 MB/s
[root@localhost test]#
[root@localhost test]# # 今のcache状態
[root@localhost test]#  vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0  79216      0 1692164    0    0  1084  2053  166  195  3  2 95  0  0
[root@localhost test]#
[root@localhost test]# # cache削除
[root@localhost test]#  echo 3 > /proc/sys/vm/drop_caches
[root@localhost test]#
[root@localhost test]# # cacheが減った状態
[root@localhost test]#  vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 1592220      0 179268    0    0  1086  2053  166  195  3  2 95  0  0
[root@localhost test]#
[root@localhost test]# # １回目
[root@localhost test]# time cat /tmp/large.txt > /dev/null

real	0m1.455s
user	0m0.008s
sys	0m1.075s
[root@localhost test]#
[root@localhost test]# # cacheが載った状態
[root@localhost test]#  vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 567092      0 1204456    0    0  1565  2053  170  200  3  2 95  0  0
[root@localhost test]#
[root@localhost test]# # 2回目は早くなるはず
[root@localhost test]# time cat /tmp/large.txt > /dev/null

real	0m0.139s
user	0m0.003s
sys	0m0.135s
[root@localhost test]#
```
GRC(SEOキーワードチェックツール）をmacOS Big Surで動かす

# 背景と目的
- GRCをmacで動かしたい
- 今までは定番ツールだったwineがCatalinaあたりから動かない
- でもどうにかしてGRCを動かしたい

# 環境
- MacBook Air2020 (intel版）
- macOS Big Sur 11.1（20C69)

# やったこと
1. [GRCのmac向けインストールページ](https://seopro.jp/grc/wine) からwine用のインストーラをダウンロードする1. Wineskin Unofficial をダウンロードするため、 [ここ](https://github.com/Gcenx/WineskinServer/releases/tag/V1.8.4) から `Unofficial.Wineskin.Winery.zip` をダウンロードする
2. zipを解凍して出来た `Unofficial Wineskin Winery.app` を起動し、 `Installed Engines` の追加ボタンを押し、 `WS11WineCX64Bit19.0.1-1` を選択してInstall ※2020/12/23時点での最新Engineっぽい
3. Wrapper VersionのUpdateを実行しておく
4. Wineskin の `Create New Blank Wrapper` を押し、適当な名前をつける ※何かインストールするナビゲーションが出たらインストールしておく
5. 4で作成したappを開く
6. Advancedを押し、 [Tools] -> [Winetricks] を開く
7. `corefonts` と `riched20` をそれぞれインストールする（チェック付けてRunを押す)
8. 終わったらCloseし [Install Software] -> [Choose Setup Executable] を押す
9. 1でダウンロードしたexeを指定する
10. GRCのインストーラが起動するので、案内に従ってインストールを進める
11. 最後、インストールが終わるとWineskinがエラーとなるが無視する
12. 9のappを右クリックし、 [パッケージの内容を表示] -> [drive_c] -> [users] -> [Public] -> [Desktop] を表示する
13. おそらくmacのデスクトップにGRCのフォルダが出来ているので、そのフォルダごと12の [Desktop] 内に移動する
14. 9のappを再度開き、 [Advanced] -> [Windows EXE] に 13 のフォルダに有る `GRC.exe` を指定してTestRunすると、GRCが起動する

# 思ったこと
- SERPOSCOPE使えばよかったんじゃなかろうか…
React開発者必見!!先日発表されたReact Server Componentsとは？

## はじめに
12月21日、Facebookから予期せぬクリスマスプレゼントが配られました🎁
reactjsによって、[こちら](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html)にReact Server Componentsなるものが突如発表され、React界隈でとても話題になっています。
僕もTwitterでこのニュースを見つけて、ReactでServer???なんかやばそう。そう思いながらこのページを覗くと、説明はどうやら動画のみっぽい。
しゃーねーなーっつって、動画開いたら再生時間**57分**。当然全部英語...。おいおい、頼むよほんと。
まあ眠くなりかけながらなんとか見終えて、個人的にまとめてみました。
僕がこれ書いてる時点では、ある程度体系的な日本語での記事はほんとにいくつか散見される程度だったので、
日本最速（ほぼ）で紹介します？
それじゃー早速どうぞ。


## 対象の読者
- Reactへの知見がある程度ある方
- React Server Components興味あるけど、動画長げーしって方


## React Server Componentsの概要
React Server Componentsは、サーバーサイドにComponentsを置いて、そこからデータ取得を行うことで、余分なネットワーク通信を介したデータのやりとりを減らし、アプリケーションの高速化を実現します。
Componentの種類には
- ${Component名}.client.js　（フロントでレンダリング）
- ${Component名}.server.js　（サーバーサイドでのレンダリング）
- ${Component名}.js　（Shared Component、詳細は後述）
の3つがあります。

## 何がいいか

### 1.backend内で直接データをfetchできるため、取得速度が早い

```javascript:NoteList.server.js
export default function NoteList() {
  const notes = fetch('http://localhost:4000/notes').json(); // ラップしなくて良い

  return notes.length > 0 ? (
    <ul>
      {
        notes.map(note => (
          <li>
            <SidebarNote note={note} />
          </li>
        ))
      }
    </ul>
  )
}
```
動画では上記のようなコードが紹介されています。server.jsファイルでも、普段のReactの記法とに大した差分はありません。
言うとすれば、notesのfetch処理は同期的に扱われるため、普段のようにuseEffect等のhooksでラップする必要はありません。

こちらは.server.jsファイルなので、サーバーサイドでのレンダリングがされます。
このようにデータの取得をserverレンダリングのコンポーネントで行うことで、スムーズなデータの受け渡しが可能となり、レンダリングが高速になります。

### 2. server.jsのcomponentで使われるライブラリはnode_modulesに入らないため、clientでの余分なダウンロードがいらない
動画では日付をフォーマットするために、date-fnsというライブラリを用いて説明がされていました。これを用いた日付のフォーマット処理をserver.jsで行うことにより、date-fnsがフロントにビルドされるnode_modulesのディレクトリに居なくなります。
これによって少しでもビルドするモジュールの容量を減らすことができ、アプリケーションの高速化に繋がります。

### 3. SSRと異なり、client-sideのStateが保持される
ここまで聞いて、いやいやSSRやんけ。って思いましたね？
動画内では、SSRとの違いとしてStateの扱いについての違いが挙げられていました。
React Server Componentsでは、useState等で管理されるクライアントのstateが初期化されず、クライアント側でそのまま保持されます。
これはReact Server Componentsがページ全体のHTMLへのレンダリングをせず、必要なComponentのみ再レンダーが走るよう、特殊なフォーマット形式（一見jsonに似てるけどそれともちょっと違う）への変換を行うために可能なそう。

### 4. SharedComponentを使って、server / clientでのレンダリングが柔軟に切り替えられる
サーバーサイドでレンダリングを行うserver.jsファイルに書かれたComponentはフロントとのインタラクティブ性を持つような実装はできません。
つまり、eventListener(onClickとかね)やuseStateは使えません。
そのため、これらのフロントとのインタラクティブ性が必要なComponentはclientでのレンダリングを行い、そうでない部分に関してはサーバーサイドでのレンダリングをするのが理想的といえます。
Shared Component（${Component名}.jsファイルに定義される）はどんなComponentをimportしているかによって、クライアントによるレンダリングを行うか、サーバーサイドでのレンダリングにするかが決定されます。
動画ではnoteのプレビュー機能を例に解説されていました。
noteは完成された投稿を閲覧するだけの場合であれば、フロントとのインタラクティブ性は特にないため、サーバーサードによるレンダリングで十分そうです。ですが、プレビュー機能となると、ユーザーの修正に合わせて常に表示内容が変更される必要があります。この場合はフロントでのレンダリングが必須です。

Componentの切り分けを適切に行うことで、Componentを共通化しながら柔軟にどちらでレンダリングするかをハンドリングできます。

## 終わりに
いかがだったでしょうか？基本的にはデータのfetchをサーバーサイドでレンダリングするComponentで行い、フロントとのインタラクティブ性があるComponentで使う場合はpropsとして渡すと言う感じになりそうです。
詳細については、下記の動画を参考にしてください、また、demoのrepositoryも公開されているので、自分も後で触ってみようかと思います。
正式に公開されるのが楽しみですね。

## 参考
https://www.youtube.com/watch?v=TQQPAU21ZUw
データ分析で気をつけること

# この記事について
最近BIツールを使って数字を出すことが多くなりました。
使うデータ使わないデータをまとめ複雑怪奇なグラフや表を量産しています:robot:
分析する上でこれは良くないので、自戒の念を込めて年内に反省し来年こうしようという気持ちで書きました。

# 分析の目的・背景・狙いの理解
いきなり数字を出そうとすると結局よくわからないものが気軽に出来上がってしまいます。
文脈、前後関係、事情、背景、状況の理解。つまり**コンテキストの理解**が一番必要ではないかと思いました。

# データの依頼ってざっくりとした状態で来る
コンテキストを100%理解して進めることができれば良いのですが、一番最初はどんな感じなの？とりあえずやってみてよな感じでデータを出すことが多かったりします。
データの特徴を理解することを目的とした初動調査が必要で、これは**探索的データ分析**、英語ではExplanatory Data Analysis（EDA)と呼ばれています。

この状態は濾過前の泥水のようで、綺麗な状態ではありません。
相手が本当に知るべき内容以外の情報が多々含まれた状態です。

私が直近出している数字は主にこのEDAの状態が多く、これが複雑怪奇なグラフや表となっている状態でした。

## 説明的、予測的、指示的データ分析
探索的データ分析後に重要なことだけをまとめ、具体的に説明し**伝え**なければなりません。

**説明的データ分析（Descriptive)**
こうなってるのはこういう理由です的なもの


**予測的データ分析（Descriptive)**
このままいくと将来的にこうなります的なもの


**指示的データ分析（Prescriptive）**
意思決定をするためにこの数字あげたらこうなります的なもの

ざっくりというとこの**3種**にわかれます。
ここでもコンテキストが重要になってきます。**「誰に／何を／どんなふうに」**です。

### 誰に
対象を誰にするかで表現方法は変わってきます。
分析結果に興味がある全員にささるような多方面にいい顔をする分析結果を作る必要はないのではと考えました。
いろんなニーズに答えたくなります。ただ**意思決定者**に伝えられるようにするのが１番効果的で伝わるのではないかと思います。

### 何を
相手に知ってもらいたい内容です。

個人的に一番難しいのはこれではないかと感じています。
データを出した上で、**意思決定者**に次の行動を選んでもらうのが良いかと思っていました。
しかし一段踏み込み自分で理解した内容を基に次のアクションの提示までできると、「あっ、そうなんだ」のような感想だけで終わらず施策への落とし込みや次の課題に対して進めることができデータの提示だけで終わらずに済みそうです。

### どんな風に
**「誰に／何を」**が定まれば、それをどのように伝えるかで結果が変わりそうです。
**重要なことをまとめ意思決定者に伝えるように・・・**とは書きはしました。
ただ重要なものだけが羅列されて説明するよりも、違った角度のデータも取り入れたものにしておかなければスムーズに進まないなと感じています。肯定したい気持ちはありつつも否定したい気持ちってみんな持ってますよね・・・。

# まとめ
データ分析は相手のことを理解し説明するという真のコミュニケーション能力が求められるものなんだなぁと再認識させられました。
コミュ障を脱却してコミュ強になる方法みたいな記事を誰か描いてくれないかしら・・・。
デザインの四大原則＜近接について＞

このアドベントカレンダーの記事を書くにあたり、
デザイナーの私が、エンジニアさんやディレクターさんのちょこっと役に立つような内容とは…と思いましたが、
まぁデザイナーなので、サイトやアプリデザインに限らず、ちょっとした資料作成の際にでも使えるような、デザインのテクニックを書きたいと思います。

##デザインの4大原則

デザインの基本中の基本の考え方、ベースとして、4つの原則があります。

1. 近接（Proximity）
2. 整列（Alignment）
3. 強弱（Contrast）
4. 反復（Repetition）

デザインの基本の基本なので、用途としては、「パッと目を引くビジュアルを作る事」ではなく、「情報をわかりやすくまとめる事」になります。

この中でも、今回は近接（Proximity）について書きたいと思います。

##近接（Proximity）とは

人は、位置が近く並べられたものを「関係があるもの」と認識して無意識のうちにグルーピングをします。

例えば、コンビニで、チョコレートとポテトチップスは別々の＜棚＞にあると思いますが、近い＜列＞で陳列されていると思います。「お菓子」と関係でグルーピングをしているので、初めて行くコンビニで考えなくても、大体の位置が把握できるのだと思います。

情報と情報の配置を整理整頓するだけでも、視覚的にわかりやすく、まとめる事ができます。

まずは、例として以下の図を見てください。チョコレートが大好きです。
![SampleImage01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901132/d1871c00-2bd7-ae32-eac9-c803437230a1.png)


要素と要素はすべて5pxづつスペースをあけて統一したつもりですが、ちょこっとづつぶれていたり、ズレている部分もあります。
（目視で配置をすると、ズレることもあるので、今回は意図的にずらしました。）

チョコレートの商品が並んでいることはわかりますが、決して見やすいとは言えないと思います。
5pxづつスペースをとっているので、体裁は整うはずなのですが、それぞれの要素が均等に配置されているので、要素と要素の関係性が、逆にわかりづらくなっています。

では、グルーピングを意識して、整理整頓してみます。

![SampleImage02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901132/2ef954ed-b0ec-8a22-0720-255293bc3f16.png)

改善した点は、
・画像が円系なので、画像と商品名を近接させるために、テキストをセンター寄せにした。
・各商品とのスペース（余白）を30pxにした。
この2つと整理整頓だけです。

商品ごとのグルーピングにメリハリがついて、わかりやすくなったかと思います。
画像・商品名・説明文は一つのグループなので「関係性がある余白感」（5px）、
各商品と商品は、別のグループなので「関係性がない余白感」（今回は30px）で、設定しました。

このように、情報と情報の配置を整理整頓するだけで、視覚的にわかりやすく、まとめる事ができます。

##やっぱり情報の「整理整頓」と「余白」が大事
私が、デザインでいつも意識しているのは、「余白」と「整理整頓」になります。
このあとに続く、四大原則の整列／強弱／反復にもつながりますが、要素が整っていると、なんとなくでもデザインとして完成度がグッとあがります。

「なんか画面がもっさりしてるなぁ…」と感じたら、大体余白で解決できるので、試していただけたらと思います。

###参考文献
・Robin Williams（著）, 米谷 テツヤ（監修, 翻訳）, 小原 司（監修, 翻訳）, 吉川 典秀（翻訳）,  [ノンデザイナーズ・デザインブック [第4版]](https://www.amazon.co.jp/E3-83-8E-E3-83-B3-E3-83-87-E3-82-B6-E3-82-A4-E3-83-8A-E3-83-BC-E3-82-BA-E3-83-BB-E3-83-87-E3-82-B6/dp/4839955557/ref=dp_ob_title_bk), マイナビ出版.

タイトルにあるように、エンジニアさんからディレクターさん、企画さんなどのノンデザイナーから、私のような独学デザイナーで「デザインの基礎がわからない…」というような方にもオススメです。
LaTeXで(robustに)赤打ち消し線を入れる

# はじめに
論文校正に使う
![kouiuyatsu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118901/b1cfe78c-a450-d98f-9d8c-06a6c733b612.png)
を$\LaTeX$でどうやって実現するかという話です. ~~Markdown記法で書こうとしたらうまくできませんでした~~

なお参考にしたsiteからcodeを持ってきていますが, 比較のためcommand名を改変しています.

なぜそうなるのかを理解せずにとりあえず動くからヨシ!で書いているため, 問題のある書き方になっているかもしれません.

# コピペ用結論

```LaTeX:
\usepackage{ulem}
\usepackage{xcolor}
\DeclareRobustCommand{\erase}{\bgroup\markoverwith{\textcolor{red}{\rule[.5ex]{2pt}{0.4pt}}}\ULon}
\newcommand{\add}[1]{\textcolor{blue}{#1}}
```

でdocument環境内で

```LaTeX:
\erase{こういうやつ}
```
という使い方をします.

なお`\add`は校正の際に加筆部を青色にすることがあるのでそのためのおまけです.

以下ではなぜこのような定義になったのか解説します.

# 経緯とか
## そもそも`ulem`に`sout`あったやん?
`\usepackage{ulem}`して`\sout{こういうやつ}`すれば打ち消し線が表示されます. ~~こういうやつ~~.
単に黒色の打ち消し線が引きたければこれで十分です.
これを赤色にしたいと思うとやや面倒でした.

## `\textcolor`と`\sout`を組み合わせればええやん?
[ここ](https://lilaboc.work/archives/17240764.html)には

```LaTeX
%改行されない
\newcommand{\erase}[1]{\textcolor{red}{\sout{\textcolor{black}{#1}}}}
```

すればよいと書いてありました. 一見問題ないのですが, 改行されなくなってしまいました[^1].
[^1]: 記事を書くために`bxjsarticle`で日本語のsampleを作っていたら文字の色まで正しく表示されない不具合まで起きてしまいました...

![kouiuyatsu1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118901/b10586ea-a9d8-43e4-e31a-065d16be14d8.png)

## `\sout`の代わりを自分で定義すればええやん?
`ulem.sty`は自分で`\sout`のようなcommandを自分で定義できるようになっています.
この機能を利用して[ここ](https://latex.org/forum/viewtopic.php?t=17481)に書いてあるように定義すれば改行されるようになりました.

```LaTeX
%改行される
%\captionや\section内では使えない
\newcommand\erase{\bgroup\markoverwith{\textcolor{red}{\rule[.5ex]{2pt}{0.4pt}}}\ULon}
```

## `\protect`や`\DeclareRobustCommand`を使う(終わり)
[^2]: Shuntaro Sumita `(@smiphys3141)`さん, ありがとうございました.
`\protect`を使うとcaption内でも使えることを教えてもらいました[^2]．

```LaTeX
\protect\erase{こういうやつ}
```

こうするとcaption内でも動作します.

ただ毎回`\protect\erase{こういうやつ}`するのは面倒なので
[ここ](http://www.proton.jp/main/latex/macro_protect.html)を参考にして同様の効果が得られるようにしたものが最終的な定義です.

```LaTeX
%最初と同じもの
\DeclareRobustCommand{\erase}{\bgroup\markoverwith{\textcolor{red}{\rule[.5ex]{2pt}{0.4pt}}}\ULon}
```

# ※ `soul.sty`について
上で参考にした[2つ目のsite](https://latex.org/forum/viewtopic.php?t=17481)には`soul.sty`を使う方法も書いてあります.
一見簡単でいいのですが, 日本語や`\cite`と組み合わせると動かなくなったため使えませんでした.

```LaTeX
\usepackage{soul,xcolor}
\begin{document}
\setstcolor{red}
\st{こういうやつ} %動かない
\end{document}
```

# おまけ: BibTeXと一緒に使う場合
BibTeXでhyperlink付き文献listを作成するとき, 文献titleをhyperlink付きの斜体として記述することがあります.
BibTeXで出力される斜体の処理は`\emph`になるようですが, `ulem.sty`も使っていると`ulem.sty`はdefaultで`\emph`を下線として処理します.
こうして発生した文献list中の下線が改行に失敗します.
この下線も改行するように奮闘するのも一つかもしれませんが, そもそもこれは意図しない下線ですので下線を引かれないようにすれば解決します.
`\usepackage{ulem}`の代わりに`\usepackage[normalem]{ulem}`とすることで`\emph`が下線として処理されなくなります.

```LaTeX:
\usepackage[normalem]{ulem}
\usepackage{xcolor}
\DeclareRobustCommand{\erase}{\bgroup\markoverwith{\textcolor{red}{\rule[.5ex]{2pt}{0.4pt}}}\ULon}
\newcommand{\add}[1]{\textcolor{blue}{#1}}
```

http://kawaiihaseigi.blogspot.com/2013/01/ulemstyemph.html
【NeosVR】ボイスバッチ【作ってみた】

#はじめに
この記事は「[NeosVR Advent Calendar 2020](https://adventar.org/calendars/5277)」の22日目です！
昨日は、@noawhiteさんの「【NeosVR】LogiX＋Node.jsでWebSocketを使ってみる - Qiita](https://qiita.com/noawhite/items/9c22a19ab150943dfbb7)」でしたω

---
僕(https://twitter.com/TewiEwi_no96) がNeosVRで人にモノづくり教える時に説明する内容を記します。
NeosVRが好きになるキッカケになってもらえると嬉しいです。
#必要知識
・デブチップの使い方(https://neosvrjp.memo.wiki/d/DevToolTip)
・ロジックスチップの使い方(https://neosvrjp.memo.wiki/d/LogiX)

---
デブチップのコンテキストメニューから新規作成。

以下のような階層構造にしてください。
Voice - Badge
┣Assets
┃┣Material
┃┃┗texture
┃┃　┗List
┃┗Mesh
┣Visuar
┃┗render
┣Moduals
┃┗Switch
┃　┗(logix)
┗DV
![20201221234516_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/59d2be95-3d85-5dd3-382f-3a4087dbb985.jpeg)
#コンポーネントの追加
下記のオブジェクトにAttach Componentをトリガーしてコンポーネントを追加していきます。

<b>・Voice - Badge</b>
Data -> Dynamic -> DynamicVariableSpace
設定値変更
SpafeName:null → Voice - Badge

<b>・Material</b>
Assets -> Materials -> UnlitMaterial　(マテリアルを決めます)
設定値変更
Texture: null → StaticTexture2D(後出)
BlendMode:opaque → Alpha

<b>・texture</b>
Assets -> StaticTexture2D
URL: Null → ValueMultiplexer<Uri> - Target(後出)

<b>・List</b>
Utility -> ValueMultiplexer<T>(Uri)
Values(list):nul ↓
0:アイコンのURL(ミュート)
1:アイコンのURL(ウィスパー)
2:アイコンのURL(ノーマル)
3:アイコンのURL(シャウト)
4:アイコンのURL(ブロードキャスト)
※ファセットのボイスアイコンからURLを参照した。

<b>・Mesh</b>
Assets -> Procedual Meshes -> QuadMesh

<b>・render</b>
Renderering -> MeshRenderer
設定値変更
Mesh: null → QuadMesh
Materials(list):add
0:null → UnlitMaterial

<b>・DV</b>
Data -> Dynamic -> SynamicReferenceVariable<T>(Slot)
設定値変更
VariableName:null → VoiceBadge
Reference:null → Vouve - Badge

#LogiXを組む
ノードブラウザを開いて以下のようにつないでSwitchにパッキングしてみましょう！
Variables -> DynamicVariableInput'1 -> Slot
Slot -> GetActivUser
User -> UsereVoiceMode
Math -> Enums -> EnumToInt'1 -> SessionAccessLevel
UpdatingRelay
ListのValueMultiplexerのIndexにドライブする。
![20201222005936_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/4a4ff9db-ef36-7113-5d09-388de60caad9.jpeg)
お疲れ様でしたω
#FUNBOXで支援してもらえると記事を書く励みになります。
https://frick.fanbox.cc
#終わりに
明日は、銀鮭さんの✕✕です。
#おまけ
最初はこんな感じのロジックスを組んでいたのですが、アエトリズさんからアドバイスいただいて上記の形になりました。
改めてありがとう、アエトリズさんω
![20201221234445_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/b3794ecc-82fc-7ba3-0da2-3737b53c8859.jpeg)
作り続けるために大事なこと

この内容は [個人アプリ/サービス開発の進め方と運用、得た学び 【PR】 Lenovo Advent Calendar 2020](https://qiita.com/advent-calendar/2020/lenovo_app)の23日目の記事です。

#自分のサービス紹介
僕は趣味で3年半程前からマンガログサービス[マンガ読んだ！！](https://manga-yonda.com/)を作り続けています。作り始めたきっかけは息子が1歳の誕生日を迎えたことで、それまではほぼ全部の時間を息子に使っていたので、少しずつでも自分の時間を取って何か作れないかなと思って始めました。このサービスは公開してからも既に2年半以上経っていますが、ユーザー数もPVもかなり少なくとてもメジャーと言えるサービスではありません。

#作り続けているという価値
多分Qiitaでバズりやすいのは短期間で多くのPVやユーザーを獲得した話だと思います。もちろん僕もそういうのは憧れるし有益な情報だと思います。長く続けてかつ流行っていないサービスの話など誰も興味ないかもしれません。それでも3年半以上、殆ど毎日家で趣味でコツコツと作り続けているのは多少なりとも価値があると思っています。今回、作り続けることについて記事（ポエム？）を書きました。

#自分の好きなものを作る
僕が考える、作り続けるために大事なことは、自分の好きなものを作ることです。僕はマンガが好きです。それはもう本当に誰よりも好きです。子供の時からおこづかいの殆どはマンガに使っており自宅にはマンガが2000冊以上あったし、高校生の時から今日現在に至るまで1日1時間ぐらいはコンビニで立ち読みするのが日課だし、結婚するまでは週末はほぼマンガ喫茶に行っていたし、今でも毎日マンガアプリを読みまわっているし、大切なことは全てマンガから教わりました。マンガログサービスを作っている理由の一つは、将来的には色んなマンガ読んだランキングを作って、僕が全ての1位を独占したいというのもあります。自分の好きなものそして欲しいもの作るのは作り続けるためにはとても大事です。

#自分の好きな道具で作る
次に作り続けるために大事なことは、自分の好きな道具を使うことです。毎日作り続けるのであれば、毎日作るための道具をさわることになります。僕にとって作るための道具はC#です。僕は兎に角C#が好きです。初めてC#をさわった時に一目惚れをして、それ以来ずっとC#を使っています。C#で人生が変わったと言っても大げさではなくて、C#がきっかけで[勉強会](https://cs-reading.connpass.com/)を開催することになって、C#がきっかけで[MicrosoftMVP](https://mvp.microsoft.com/ja-jp/PublicProfile/4040061?fullName=Bin%20%20Matsui)に選ばれて、C#がきっかけで[書籍](https://www.amazon.co.jp/dp/B00TO25UUA/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)を執筆することになって、C#がきっかけで専門学校の[講師](https://www.vantan-game.com/index.php)になることになって、C#がきっかけで[転職](https://www.codeer.co.jp/Member)することになりました。ここ10年以上自分の人生の節目には必ずC#が出てきます。C#でプログラムを書くのがただただ楽しいです。毎日使っている道具が好きな道具であることも作り続けるためにはとても大事です。

#辞めないためには鈍感力も必要
好きなものを、好きな道具で作っても、作ることを辞めてしまうことはあると思います。例えば他人からの批判です。もちろん「このサービス最悪だな」というような直接的な批判は僕も経験ありません。そうではなくて、自分で批判と思ってしまうようなケースです。ようやく出来た自分のサービスを大々的にSNSで発表して、そこで一切レスがつかなかったりするだけでも、辞めてしまいたい気持ちになることはあると思います。また、他人の成功体験でメンタルが削れることもあります。つまり他の人は3ヶ月で圧倒的な成果を出しているのに、自分は1年かけてもそれ以下の成果しか出していないという事実を突きつけられるとやはり凹みます。極端に言えば悪意のないアドバイスですらそれが刃として刺さることもあると思います。冷静になって考えれば、書いたことは全て被害妄想ですが、他人の評価や成功は気にしないと思える能力、ある種の鈍感力は作り続けるためには意外と大事だと思います。

#作り続けるための明確な目標をもつ
さて、作り続けることでやることは増えていきます。実際僕も最初の目標である、サービスを公開してからの方がやりたいことはずっと増えました。ある程度作り続けた時に、さらに続けるために大事なことは明確な目標を持つことです。僕も作り出した時は考えていなかった大きな目標を決めました。現在僕のサービスには20万冊以上のマンガのページがあります。これはマンガサービスの中でも多い方だと思います。しかし世の中にはまだまだ沢山のマンガがあります。例えばマンガ出版社であっても、その会社が出したマンガの全情報は載っていません。出版社にも依りますが、絶版したマンガはHPからも外してしまうケースが殆どです。紀伊国屋書店やAmazonなどは絶版になったマンガも乗っていますが、それでも全部ではありません。全てのマンガを載せているサイトは現状どこにもないと思います。僕の目標は「世の中の全てのマンガの情報が載っているサービスを目指す」です。

#作り続けることで得られるものは沢山ある
使う人が少なくても、世の中で話題になっていなくても作り続けることで得られるものは沢山ありました。僕はこのサービスを作るまでWebの実務経験がほぼありませんでしたが、今ではクライアント、サーバ、クラウドまで一通りのことは分かります。[Qiitaで軽くバズった](https://qiita.com/binnmti/items/84d48766f5068ec8d06b)こともあります。最近では[モブプロでの定期ミーティング](https://manga-yonda.connpass.com/event/198341/)みたいなこともやっていてアドバイスをくれる友人も増えました。その内PVやユーザー数のアップにも注力して、またそういう記事も書ければと思います。作り続けていれば必ず目的を叶えられるとは言いませんが、少なくとも続けることは目的を叶えるための最も確実な方法だと思います。

#まとめ
最後にここまで書いてきて何ですが、個人開発において作り続けることが一番大事なことではないと思います。大事なことは自由であることだと思います。いつ始めても、またいつ辞めても良い。作り続けても良い。その自由こそが個人開発において一番大事なことだと思います。だからこそ、もし作り続けるのであれば、出来れば自分の意思以外の要因で辞めない方が幸せだと思います。もし今回の記事が誰かにとって作り続ける一つの要因になったのであれば嬉しいなと思います。
【API Gateway】APIの管理

## アクセス制御
API Gatewayおよびアップストリームへのアクセス制御には以下4つの方法がある

### 1. リソースポリシー
JSON形式のリソースポリシーを定義することで、API Gatewayにアクセスを許可／拒否するリソース・アクセスソース・アクションを指定可能

指定出来るアクセスソースは以下の3種類
**・** 任意のAWSアカウントのIAMユーザー
**・** アクセス元のIPアドレス
**・** 任意のアカウントのVirtual Private Cloud（VPC）またはVPCエンドポイント

（例）"aws:SourceIP"で指定したCIDRブロックからのAPIを拒否するリソースポリシー

```:リソースポリシー
{
　　"Version": "2020-11-30",
　　"Statement": [
　　　　{
　　　　　　"Effect": "Allow",
　　　　　　"Principal": "*",
　　　　　　"Action": "execute-api:Invoke",
　　　　　　"Resource": [
　　　　　　　　"arn:aws:execute-api:region:account-id:api-id/*"
　　　　　　]
　　　　},
　　　　{
　　　　　　"Effect": "Deny",
　　　　　　"Principal": "*",
　　　　　　"Action": "execute-api:Invoke",
　　　　　　"Resource": [
　　　　　　　　"arn:aws:execute-api:region:account-id:api-id/*"
　　　　　　],
　　　　　　"Condition": {
　　　　　　　　"IpAddress": {
　　　　　　　　　　"aws:SourceIp": ["192.0.3.0/24", "198/51/100.0/24"]
　　　　　　　　}
　　　　　　}
　　　　}
　　]
}

```

### 2. IAM認証
APIの各要素へのアクセス権限を設定したIAMポリシーを作成し、IAMユーザーやIAMロールに付与することで、APIへのアクセスの制御が可能になる
（※ 対象のAPIメソッドでIAM認証を有効化する必要あり）

### 3. Lambdaオーソライザー
LambdaオーソライザーというLambda関数を作成することで、認証プロバイダーでの認証結果をもとにAPIへのアクセス制御をメソッド単位で行うことが可能

以下、Lambdaオーソライザーを用いてAPIアクセスを行うフロー
**1.**　認証プロバイダーで認証を行い、トークンを取得する
**2.**　トークンを含めてAPIリクエストを行う
**3.**　API Gatewayがトークンの値をもとにLambdaオーソライザーで認可を行う
**4.**　認可の結果をもとにAPI Gatewayがリクエストを許可・拒否する

### 4. Cognitoオーソライザー
認証プロバイダーとしてCognitoユーザープールを用いることで、認証プロバイダーでの認証結果をもとにAPIへのアクセス制御をメソッド単位で行うことが可能

以下、Cognitoオーソライザーを用いてAPIアクセスを行うフロー
**1.**　Cognitoユーザープールで認証を行い、トークンを取得する
**2.**　トークンを含めてAPIリクエストを行う
**3.**　API Gatewayがトークンの値をもとにCognitoユーザープールで認可を行う
**4.**　認可の結果をもとにAPI Gatewayがリクエストを許可・拒否する

## スロットリング
スロットリング設定を行いリクエスト数を制限することで、アップストリームで処理するリクエスト数を制御することが出来る

- AWSアカウント単位・メソッド単位・APIキー単位で設定が可能
- **レート**（1秒あたりのリクエスト数）と **バースト**（リクエストの同時実行数）を設定する

### 使用量プランとAPIキー
**APIキー**：API Gatewayの使用量を制限するために発行するアクセスキー
（各APIメソッドでAPIキーを使用する設定にすると、APIメソッドを実行するリクエストにはAPIキーが必須となる）

- APIキーの使用量制限は、**使用量プラン** という設定項目でスロットリング設定を行い、APIキーを使用量プランに紐付けることで設定可能
- 使用量プランのスロットリング設定では、レート・バーストの他に **クォータ**（日・週・月あたりのリクエスト数）を設定する 

## モニタリング
CloudWatch, CloudTrail, X-Rayと連携して監視を行うことが可能
マネージメントコンソール上に標準で用意されている API Gateway ダッシュボードで、各APIの利用状況をステージごとに可視化して確認出来る

標準で以下項目の確認が可能

- API呼び出し
- キャッシュヒット（APIキャッシュが有効の場合のみ）
- キャッシュミス（APIキャッシュが有効の場合のみ）
- レイテンシー
- 統合のレイテンシー
- 4XXエラー・5XXエラーの数
[Ruby]作成されてから〇〇以上経ったレコードのみ取得・選択する方法

#作成されてから〇〇以上経ったレコードのみ取得・選択する方法

##結論
`Record.where('created_at < ?', 1.minute.ago).order(created_at: :desc)`

重要なのは`('created_at < ?', 〇〇)`

〇〇に好きな条件を入れるだけ。

1時間前なら`1.hour.ago`
1日前なら`1.day.ago`

##質問
クオーテーション使わない方法やベタープラクティスってありますか？

意外と見つけづらい情報でした。。。
リザーブドインスタンスはいいぞー。

最近の主流であるAWS。
これを活用していない会社はまずWEB系にはないだろ（いや、azureとかGCPで冗長化している会社は多くあると思いますが）

そんな皆さん御用達のAWSのいいところなんてもうすでにネタが切れて、皆さんに細かい部分まで書かれているはず。
私はそれらを超えるものを書ける器量はないと断言できる。

よって実環境のEC2インスタンス（もちろん私が担当しているサービスのみです）がリザーブインスタンス化するとどれぐらいコストを節約したか、皆さんにご報告いたします。

ぶっちゃけ、価格的に節約金額は2割か3割程度なはずだが、グラフを見ると「かなり減ってるやん、これ」と思ってしまう印象のため勢いあまりご紹介したいと思う次第で、殴り書きしております。

# 現状のインスタンス数（一部のサービス）とコスト

まず、私が担当しているサービスのEC2インスタンス環境を公開しよう！

|インスタンスタイプ	|インスタンス数|
|---|---|
|c4.xlarge	|6|
|c5.xlarge	|1|
|c5n.large	|1|
|m4.large	|1|
|t2.large	|4|
|t2.medium	|2|
|t2.micro	|4|
|t2.nano	|5|
|t2.small	|4|
|t3.medium	|1|
|t3.nano	|5|
|t3.small	|7|
|**合計**|**41**|
現状41のEC2インスタンスが稼働しております。（2020年11月現在）
そして、（5ヶ月間の平均ですが）現状1ヶ月あたりの金額として、2,712.85米ドル（日本円1ドル104円換算282,136円）ほどかかっております。
ちなみに、リザーブドインスタンスは一切購入していません。（リザーブドインスタンスは以前に買っていたが、今後のスケールアップなどもあって買ってなかったそうやで・・・。）



ここから、幾つかのリザーブドインスタンスを購入します。
スプレッドシートなどを利用して最適解を探ろうと思ってましたが「AWS Cost Explorer」=>「予約」=＞「推奨事項」にそってクリックしてもらうと、現状にあった推奨リザーブドインスタンス購入数を表示されます。（なんて便利）

↓イメージ図
![Cost_Management.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516317/4544b9cc-98d4-d217-039d-f511cd337f21.png)
これを見る限り、すでに7,439米ドル(日本円773,656円)25％節約できるよと書いている。1年間、スタンダード前払なしで。

では、AWS推奨するインスタンスタイプの構成は以下の通り

|インスタンスタイプ	|インスタンス数|
|---|---|
|c4.large	|12|
|t2.nano	|133|
|t3.nano	|37|
|c5.large	|2|
|t3.nano	|4|
|c5n.large	|1|
|t2.nano	|24|
|m4.large	|1|
|**合計**|**214**|

おやおや？現状の構成とは異なったインスタンス数とインスタンスタイプの構成です。
なぜかと言うと、推奨事項はある程度柔軟な構成になるようにできる限り下位のインスタンスを購入する仕組みのようです。
下位のインスタンスタイプ二つで、上位のインスタンスタイプ一つと同じ価値になるようで、
例としてnano2つで、micro1つ分と言うことになるようです。
詳しくは、AWSの1次情報を！（https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-resource-limits.html）

そのため、まだスケールダウン時の再構成がしやすいかもしれないですね？
いやそれでも、現状からの再構成を考えるのは縛りプレイのようで難しいですが・・・。
余談ですが、リザーブドキャッシュノードでは、そういった柔軟な構成はできないようです。（AWSの人にききましたので、信憑性のある情報かと・・・）



## リザーブドインスタンス購入後のグラフ
ででで、実際どんな感じに下がるかと言いますと、これは言葉よりグラフで見せるほうが早いかなと思いますので、
グラフで表示します。

デデン！
![Cost_Management.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516317/20c482bb-6aab-0296-175e-9033098ffef9.png)
購入した日は12月16日と12月17日です。
二日に渡った理由は、購入できるリザーブドインスタンス数（月に1リージョン20ほどしか買えない・・・）が限られてたことを知ったため、日をまたいで購入する形となってしまいました。。。

制限を解除する必要がありますが、詳しくは一次情報を！
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-reserved-instances.html

16日と17日は、購入した日だからか費用が跳ね上がっています。

|日 |米ドル|
|---|---|
|16日|569米ドル|
|17日|354米ドル|
|**合計**|**923米ドル**|

ちなみにリザーブドインスタンスを買った当初、私は一つ勘違いをしておりました。
**前払いなし**と選択したはずなのに、「なんでこんなにグラフ跳ね上がってるんや」ということ。
私の中では、日単位に分散してまばらになるイメージだったのです。

####だって前払いなしって書いてたやん・・・

このことで上司には異常な数値報告をしまくった私、恥ずかしい・・・。

そんなこんなで、リザーブドインスタンスは月に一度大きく費用がかかる仕組みのようです。
ですので、いきなりコストが増加してもそれはリザーブドインスタンスですのでご安心ください。

話は戻します。

リザーブドインスタンスを購入する前は、EC2コストは日平均90米ドルぐらいかかっております。
そのため、大体11日ほどでリザーブドインスタンスの購入費用は回収できて、それ以降はほぼほぼ4米ドル以下というイメージ。
あれ？このまま推移するとEC2の月額は、（イレギュラー除いて）4米ドル×31日+923米ドル=1,047米ドルぐらいになるんじゃないのか？
日平均90米ドルを月にしても2,710米ドル。
その金額とリザーブドインスタンスの金額を比べて、月額半額以上の節約になるのか？
あれ？3割ぐらいの節約金額はどこいったんや・・・。

ただ、若干コスト計算に含まれていない数字も大いにあると予想されるので、おそらく月末のどこかで帳尻合わせをするのだろうかと思われるが、それを踏まえてもこの目に見える節約効果は大きいなと思うわけです。

もし、まだリザーブドインスタンスを購入していない人がいれば、ぜひとも推奨設定で購入してみてほしい。（もちろん自己責任でね？）

弊社自身、一部のみならず全体のサービスで購入すれば、もしかしたら毎月ハイスペックmacが買えるぐらいの節約になるのではないかと期待しております。

以上、リザーブドインスタンスの報告でしたー。
WindowsでEmacsっぽいキーバインドば使いたい

## Windowsで開発したい
もともとMac,Linux環境下で開発していたのですが、WSL2&VSCode環境がいい感じになってWindowsでもいい感じに開発できそうなのでWindows環境も整えたくなりました。
しかし、ブラウザやらなんやらのテキスト編集時のショートカットが効かず`ctrl+fbnp`, `ctrl+a`, `ctrl+e`あたりを無意識に押してしまう癖があるといちいちフラストレーションが溜まります。これをなんとかする方法を探していました。

## AutoHotKeyでやる
Mac環境においてはKalabinerでそのへんの設定をしてたので、これの代替を探していました。WindowsにはAutoHotKeyという独自スクリプトでキーボードを制御できるアプリケーションを見つけたのでこれでやります。

### AutoHotKeyインストール
https://www.autohotkey.com/
こちらからインストールします。画面に従ってポチポチすると入ります。

### ahkファイルを書く
とりあえず、`ctrl+h` で`BackSpace`が入力されるところを目標に書きます。VSCode&[autohotkey-plus](https://marketplace.visualstudio.com/items?itemName=cweijan.vscode-autohotkey-plus
)が便利でした。
`.ahk`なファイルを作成します。

```
#SingleInstance, Force
SendMode Input

^h::Send, {Bs}
```

と書き込みVsCode上から、`Run Script`すると`Ctrl+h`が効くようになりました。また、保存してファイルを右クリックして実行しても動くと思います。簡単便利です。

### 最終的に
```
#SingleInstance, Force

SendMode Input
SetWorkingDir, %A_ScriptDir%

^p::Send, {Up}
^n::Send, {Down}
^b::Send, {Left}
^f::Send, {Right}
^e::Send, {End}
^a::Send, {Home}
^h::Send, {Bs}
```

これで`ctrl+fbnp`, `ctrl+a`, `ctrl+e`, `ctrl+h`が効くようになりました。便利
Ruby のエイリアスメソッドはどれを使っても同じ？

Ruby はメソッド名にエイリアス（別名）が多い言語です。
例えば `Enumerable` の `map` と `collect` の二つはエイリアスの関係にあり，どちらを使っても同じ結果になります。
そこで，どちらを使うかは好みの問題となり，「map 派」「collect 派」という言葉まで生まれてしまいました。

では，メソッドに複数の名前があったとき，本当にどれを使っても同じなのでしょうか。
そうとも言い切れない例があります。

Integer には，「レシーバーに 1 足した数を返す」メソッドがあり，`next`，`succ` という二つの名前を持っています。
エイリアスなので機能はもちろん変わらないのですが，速度が違います。

benchmark_driver というベンチマークテスト用 gem をインストールし，

```next-succ.yaml
benchmark:
  - 1.next
  - 1.succ
```

という YAML ファイルを用意して，

```shell
benchmark-driver next-succ.yaml
```

としてみましょう。結果は

```
       1.succ: 134563685.5 i/s 
       1.next:   8751120.9 i/s - 15.38x  slower
```

のように，なんと 15 倍もの速度差が出ました。（追記参照のこと）
実験環境：
`ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin17]`

どうしてこんなことになるかというと，RubyVM 上で `succ` にだけ何らかの最適化が入っているのだそうです。

では，絶対に `next` でなく `succ` を使うべきなのでしょうか。
それは場合によるでしょう。
上の結果を見ると，`Integer#next` だって毎秒 800 万回以上も実行できるのです。
多数回回るループの中で使うとしても，実用的なコードでは，ループの中の他の処理に比べて遙かに軽いことがほとんどでしょう。
マイクロベンチマークでなく現実のコードで `succ` と `next` の違いが処理速度を左右することはそう多くはないかもしれません。

# 追記 2021-11-21

いま改めて同じ方法（マシンは違う）でベンチマークをとってみると，15 倍もの差はなく，2 倍程度でした。Ruby 2.6.3，2.7.4，3.0.2 ともそんな感じです。
styled-componentsのpropsを型を指定して渡す

## はじめに
styled-componentsでdiv要素のwidthをpropsで渡す方法の備忘録です。

## いきなりですが結論

```.ts
const StyledSample = styled.div<{ width: number }>`
  width: ${(props) => props.width};
`;
```

型を指定してあげれば、styled-componentが受け取ったpropsから
アクセスできました。

公式サイトからは、単純な要素(div,button等)とカスタムコンポーネントで
propsの受け取り方が違うみたいなことしか読み取れなかったので、ちょっと苦労しました…
https://styled-components.com/docs/basics#passed-props
Amazon SNS ってどんなサービス？

## 勉強前イメージ

Amazon S*S っていくつかサービスあってややこしくて覚えれてない
SNSのメッセージ送る的なやつ？

## 調査

### Amazon SNSとは

Amazon Simple Notification Service の略で、
アプリケーション間のメッセージや、HTTP、Eメール、モバイルのプッシュ通知を行うことができます。

### Amazon SNSの特徴

- プッシュ型の配信

発信者のトリガーで配信されるため、ポーリング処理よりメッセージの配信に即時性があります

- 複数プロトコルに対応
	- Amazon SQS(Simple Queue Service)
	- AWS Lambda
	- HTTP
	- HTTPS
	- Eメール
	- SMS(Short Message Service)

上記のマルチプロトコルに対応しています

- 低コスト

前払い料金のない従量課金型で安価で提供されています

- シンプルなAPI

他のアプリケーションとも安易に統合させることができます



## 勉強後イメージ

lamdaとかにも入れれるし、
普通にSMS通知もできるし、通知系なら結構何でも行けるって感じなのかな・・・
他のやつ知らんけど
管理画面見てたら簡単そうだったらからやってみよう

## 参考

- [Amazon SNS（Simple Notification Service） について](https://www.acrovision.jp/service/aws/?p=1456)
- [Amazon SNS とは](https://qiita.com/fjisdahgaiuerua/items/2f79042570903416d612)
【Rails】 LIKEで複数の値で検索する方法

# LIKEで複数の値で検索する方法
LIKEで複数の値で検索する方法をメモとして残します。

```gem 'activerecord-like'```を使えばもっと簡単にできるのですが、別の方法として実装してみました。

* https://github.com/ReneB/activerecord-like

# 

```ruby

scope = User.all
names = ['yama', 'mae']
search_sql = []

names = names.map do |n|
    search_sql.push('name like ?')
    "%#{name}%"
end

scope = scope.where( search_sql.join(' or '), *names )
```

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/