OmniAICreator/Qiita-1.07M huggingface dataset:
IIJmio光でVPNを使いつつ、IPoE + transixを両立して快適なリモートワーク生活を送る

## TL;DR

* IIJmio光でPPPoEとIPoEを両立する。
* buffaloのWi-Fi6対応[AX4](https://www.buffalo.jp/product/detail/wsr-1800ax4-wh.html)を使用。
* Macの標準VPN(L2TP)で、VPNのパケットはPPPoEを通す
* VPN必須パケット以外はIPoE環境へ流す(別記事予定)

## 前書き

IPv6のIPoE、transixでネットワークをセットアップするとネットワークの混雑に巻き込まれづらくなり、いつでも速いネットワークを使用できます。

**リモートワーク民大勝利だね！！**

...

そうは問屋が卸さないのです。
リモートワークで必須となるVPN接続。
IPoE環境では接続できないことがあります。
VPNのゲートウェイがIPv4、transix経由では接続できません。
(transixのポート開放制限が影響している可能性)

＼(^o^)／ｵﾜﾀ

## 前提環境

* IIJmio光を契約
* IPoEオプションを有効化済み(2020/07/17現在は無料)
* Mac
* VPNはMac標準のL2TP
* ルータはbuffaloのWi-Fi6対応[AX4](https://www.buffalo.jp/product/detail/wsr-1800ax4-wh.html)

## 目次

* IIJmioはIPoEとPPPoEを共存できる!?
* ルータを設定しよう
* 補足
* あとがき

### IIJmioはIPoEとPPPoEを共存できる!?

参照: https://www.iijmio.jp/imh/ipoe/

実は、IIJmioではPPPoE IPv4とIPoE IPv6環境が共存できるのです。
ルータの設定で、基本的にはIPoEを使用し、VPNパケットはPPPoEを使うようにすればVPNをつなぎつつ快適ライフを送ることが切るのです。

### ルータを設定しよう

[AX4](https://www.buffalo.jp/product/detail/wsr-1800ax4-wh.html)はこれ1台でIPoEとPPPoE併用できる素晴らしいルータなのです。
IPoEとPPPoEのセットアップ、VPNゲートウェイ向けパケットをPPPoEにルーティングしましょう。
(当初はPPPoEパススルーを使って二重ルータで頑張ろうと思ってましたがそのようなことは不要でした。)

#### AX4設定例

##### IPoEの設定

**Internet**タブ
![スクリーンショット 2020-07-17 0.13.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83162/57dc8781-1ec4-b9eb-5eb0-5174e276b09d.png)

**IPv6**タブ
※ここは環境によって設定異なるかも
![スクリーンショット 2020-07-17 0.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83162/2e9efd06-2860-ba67-9737-4d311d3a3fb7.png)

##### PPPoEの設定

**PPPoE**タブ
![スクリーンショット 2020-07-17 0.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83162/b114c0a0-3a8e-ee50-8ec1-96ddd6187456.png)

PPPoE接続先を入力。
接続先経路は「接続先」はPPPoEの名称、「宛先アドレス」はVPNゲートウェイのIPアドレス。
送信元は空欄で登録します。

### 補足

このような設定をすることで、VPNはPPPoEを通ることになり、VPN接続できるようになります。
VPN接続を必要に応じて有効無効を切り替えても良いです。
常時有効化して特定宛先だけVPNを経由させる方法が一番オススメです。
`/etc/ip-up` と `route` コマンドを利用してルーティングを設定するのですが、
Catalinaで設定するための資料が少なくて苦労しました。
こちらは後日、別記事にて方法をまとめたいと思います。

### あとがき

PPPoEとIPoEを共存させるには、二重ルータ構造を作る方法しかヒットしませんでした。
新しくこのAX4を買って、今のASUSルータはPPPoEで使い、AX4はIPoEで静的ルーティングをガッチガチに設定する予定だったのです。そのために短いLANケーブル2本も買い足して用意していました。
AX4単体でPPPoEとIPoEを併用できてしまったので無駄になってしまいました。
うーん。旧ルータとLANケーブルの使いみちどうしようか...
とりあえずAX4が調子崩したとき用の予備として残しておくことにしましょうか。
NextDNSお墨付きの「YogaDNS」って何？

## はじめに
題名に書かれているNextDNSって知ってますか？ 
WebブラウザのFirefoxでお馴染み「Mozilla」と提携しているプライバシー重視型DNSサービスです。[^1]

以前までは、βサービスとして「無料、リクエスト回数無制限」で問い合わせ可能でした。
現在は300,000 request/月まで、それ以上の問い合わせは「GoogleのDNSと何ら変わらない(電子広告や有害情報等のサイトのドメイン解決の拒否機能がない)」DNSとして利用できます。
なお月1.99$で、この制限を気にすることなく利用できます。 
 
本題は「YogaDNS」なので、気になる人は[NextDNS(英語)](https://nextdns.io/ "NextDNS")で確認してみてください。

## 1. 「YogaDNS」とは何ぞ？
DNS鯖を建ててカッコつけたい~~逸般の誤家庭の皆さん~~「できる」人、残念！ 
そんな方々は「CoreDNS」とかで鯖を作りましょう。 
これは、DNSクライアントソフトです。 
つまり、「DNSへの問い合わせを管理できるソフト」といった方が分かりやすいかもしれませんね。 
なお、これはβ版(試験段階)であり、フリーソフトとなっています。
そういえば、記事執筆時点では「YogaDNS」の記事はないですね…
私は、NextDNSのサイトから知りました。 
![mainwindow](http://yogadns.com/docs/main.png "メイン画面(YogaDNS公式ページより)") 

DNS over HTTPS(DoH)や、DNSCrypt、Anonymized DNSに対応(平文にも対応です)。 
また、DNSSECにも対応し、そのDNS解決結果が信頼できるかどうか確認することができます。 
(いずれもオプションです。) 

さらにDNSリーク対策も可能ですし、ドメインごとに異なるインターフェースでDNS解決が出来るようになるなど、~~ちょっとやり過ぎじゃないですかね~~かなり素晴らしいですよねー。 

当然ですが、IPv6も対応です。DNS解決ログだって残せます。 
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675595/d67db285-1293-978c-d03c-e49b40d245b1.png)

機能の大まかな紹介はこの辺にして、「YogaDNS」のセットアップをしていきましょう。 

## 2. YogaDNSのセットアップ
YogaDNSは、記事執筆時点(2020/07/16)で、Windows 7、8、10、Windows Server 2012、2016、2019(32ビット/64ビット両方対応)にしか対応していません。それ以外の人は現時点では諦めましょう。(でも将来的には、マルチプラットフォーム対応になるかも？)

まずは、ダウンロードサイト( http://yogadns.com/download/ )からインストーラを入手します。

インストールが終了した後、再起動なしでこのまま初期設定を行います。初期設定方法は、ウィザード方式です。

ここからは、初期設定を行うDNSホストが、NextDNSか、それ以外かで変わります。
NextDNSで登録する方⇒[ここ]( http://yogadns.com/docs/nextdns/ "Setup-NextDNS")
それ以外(Cloudflare、Google、ISP提供、~~自鯖~~等)の方⇒[ここ](http://yogadns.com/docs/#quick "Setup-Not-NextDNS")
を確認してセットアップしてください。

なお、各種設定等も公式docs( http://yogadns.com/docs/ )にて丁寧に書かれていますので、参考にしてみてください。

## 3. まとめ
- 「YogaDNS」とは、今注目の「DNSクライアントソフト」だった。
- 初期設定はシンプルで、WindowsのDNS拡張ツール的な機能を搭載。

 [^1]: https://blog.mozilla.org/blog/2019/12/17/firefox-announces-new-partner-in-delivering-private-and-secure-dns-services-to-users/
Access-Control-Allow-Origin (CORS 関連) ヘッダーを付与するシンプルな Reverse Proxy (cors-reverse-proxy) を Go 言語で作りました

# 概要

<img width="1248" alt="スクリーンショット 2020-07-17 0.02.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19717/2cc75c96-3d62-57bf-8296-f044a813edd2.png">

* Github
    * https://github.com/kaishuu0123/cors-reverse-proxy
* Docker Hub (コンテナイメージもあります)
    * https://hub.docker.com/r/kaishuu0123/cors-reverse-proxy

# ユースケース

1. ローカルの開発環境などに
2. アプリケーションの連携をする際に、特定のアプリは信用して、リソース(画像や JS など)の読み込みを行いたいときに
    * 具体例がちょっと微妙かもしれませんが、「GROWI と draw.io を連携する際に、draw.io からの読み込みは信用したい」というケースがありました。 ([PR はこちら](https://github.com/weseek/growi/pull/2543))

# 作ったモチベーション

とにかくシンプルに「`Access-Control-Allow-Origin: *` ヘッダを付けるだけ」のコンテナがあってもいいんじゃないかな、と思ったからです。

それに加えて、ネットで探してみたところ、あまり自分の用途に適したリバプロが見つからなかったので、「自分好みにカスタムしていくのも Go の勉強がてら楽しいだろうな」と思ったからです。

「あー、アレのことか！」と思っていただくために、少し CORS policy に関するお話を書いておきます。

* Web 開発をしているとよく CORS policy の問題?でコンテンツ読み込みが block されるときがあります。開発者コンソールで下記のようなメッセージを見たことがある方はいらっしゃると思います。

```
... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

* 非常に正しいですし、セキュリティ上必要な保護かもしれませんが、開発上「問題ない」と判断した上で block されたくない場合があります
* 回避策として、2パターン程度考えられます
    1. nginx や Apache を間に挟み込んで、 `Access-Control-Allow-Origin: *` Header を付与するというケース
    2. アプリのミドルウェアに CORS 関連のパッケージを導入して設定を行う
* `1.` も現実的な案ですが、 container を利用した開発時に若干の手軽さに欠けます
    * もちろん、nginx や Apache などのコンフィグファイルを作成して、container 渡してあげる方法はありますが、そもそも `Access-Control-Allow-Origin: *` Header を付与するためだけにコンフィグファイルを用意するのは手間

という課題があって、作ることにしました。

# 使い方

* 詳細は [README.md](https://github.com/kaishuu0123/cors-reverse-proxy/blob/master/README.md) に記載していますが、環境変数、コマンドライン引数で Reverse Proxy 先の URL を設定したり、動作するポート番号を変更したりできます。

```shell
docker pull kaishuu0123/cors-reverse-proxy

docker run -it -d \
  -e CORS_REVERSE_PROXY_TARGET_URL=http://example.com \
  -e CORS_REVERSE_PROXY_HOST=0.0.0.0 \
  -p 8181:8081 \
  --name cors-reverse-proxy \
  kaishuu0123/cors-reverse-proxy
```

| CLI Option(Long) | Shorthand | Environment Variables         | Example               | Default   |
| ---------------- | --------- | ----------------------------- | --------------------- | --------- |
| --target-url     | -t        | CORS_REVERSE_PROXY_TARGET_URL | `http://example.com/`   |           |
| --host           | -h        | CORS_REVERSE_PROXY_HOST       | `0.0.0.0`             | localhost |
| --port           | -p        | CORS_REVERSE_PROXY_PORT       | `8888`                | 8081      |
| --origin         | -o        | CORS_REVERSE_PROXY_ORIGIN     | `http://example.com/` | `*`       |

# さいごに

Logging などはまだまだなので、今後も気づいたら引き続き開発をしていこうと思います。

こういった小さい実装をすることでコンテナ間の連携を手軽に変更できるのは UNIX の哲学っぽくていいなぁと思いました °˖✧◝(⁰▿⁰)◜✧˖
htopのカラムが示すヤツ

「はぁーなんだっけ？」って毎度なるヤツです。
`htop`は使い方やおすすめツールなんかで紹介されがちだけど、カラム内容とセットで触れた記事は少ないので。

# だいたいデフォルトで表示されてるモノ

`man htop`に記載されている内容に、少し味を足したものです。内容的には`top`とほぼ同じモノです。

<dl>
<dt>PID</dt>
<dd>プロセスID。</dd>
<dt>USER</dt>
<dd>プロセスオーナーのユーザ名。</dd>
<dt>PRIORITY (PRI)</dt>
<dd>プロセスのカーネル内部の優先度。<br>nice値に20を足した値が表示される。<br>リアルタイムプロセスとは異なる。</dd>
<dt>NICE (NI)</dt>
<dd>プロセスのnice値は19（低）から-20（髙）まで。<br>優先度の変更は権限のあるユーザーでなければならない。</dd>
<dt>M_SIZE (VIRT)</dt>
<dd>プロセスの仮想メモリのサイズ。</dd>
<dt>M_RESIDENT (RES)</dt>
<dd>プロセスの常駐メモリ(text + data + stack)のサイズ。プロセスが実際使っているメモリサイズ。</dd>
<dt>M_SHARE (SHR)</dt>
<dd>プロセスの共有ページ（共有メモリ）のサイズ。</dd>
<dt>STATE (S)</dt>
<dd>プロセスの状態：<br>
　<strong>S</strong> - スリーピング<br>
　<strong>R</strong> - 実行中<br>
　<strong>D</strong> - ディスクスリープ<br>
　<strong>Z</strong> - ゾンビ（親の終了ステータスの読み取り待ち）<br>
　<strong>T</strong> - トレースまたは一時停止<br>
　<strong>W</strong> - ページング
</dd>
<dt>PERCENT_CPU (CPU%)</dt>
<dd>プロセスが現在使用しているCPU時間をパーセンテージで表した値。</dd>
<dt>PERCENT_MEM (MEM%)</dt>
<dd>プロセスが現在使用しているメモリをパーセンテージで表した値。</dd>
<dt>TIME (TIME+)</dt>
<dd>プロセスがユーザとシステムに費やした時間。</dd>
<dt>IO_RATE (DISK R/W)</dt>
<dd>I/Oレート。読み書き（IO_READ_RATE + IO_WRITE_RATE）の合計。</dd>
<dt>Command</dt>
<dd>プロセスのフルコマンドライン。プログラム名や引数を含む。</dd>
</dl>

## VIRTについて

VIRTは*Virtual Memory*、つまり仮想メモリのサイズの値を示していますが、勘違いしてはいけないのが、Windowsで言う「仮想メモリ」やLinuxなどの「SWAP・ページ」とはやっている**仕事内容が全然まったくウルトラ違う**のです。

簡潔に述べると、プロセスに仮で割り当てているメモリの総量で、その気になったらそれぐらい使い倒す**予定**であることを示す値。

実際に**示されたメモリ量全部を使われることはまず無い**。
常にデカい量が示されるが、コードや共有してるライブラリ、スワップアウトされたページとマップ、とにかくそのプロセスが絡んでる全ての総量を仮想的に示してるから、かなり目立っているけど、基本無視しても良い部分（なんかJava実行してるとまあまあ目立つ）。

プロセスはいつでもアクセス出来て、アクセスすると物理メモリになるから、実際にプロセスが使われているメモリ量はRESをみるだけで良い。

この辺はみんな「🤔」ってなるかもね。私もなった。

**参考：**

- [減り続ける利用可能メモリ……そしてついにリブート！ (2/3)](https://www.atmarkit.co.jp/ait/articles/0812/16/news121_2.html)
- [Windowsではページング ファイルのことを「仮想メモリ」と呼ぶ？件](https://qiita.com/ksasaki/items/f914790f8a8c9488293d)

# 上記以外

やる気が湧いたら書く(˘ω˘)

<!--
<dl>
<dt>PID</dt>
<dd>プロセスID</dd>
<dt>STATE (S)</dt>
<dd>プロセスの状態：<br>
　<strong>S</strong> - スリーピング<br>
　<strong>R</strong> - 実行中<br>
　<strong>D</strong> - ディスクスリープ<br>
　<strong>Z</strong> - ゾンビ（親の終了ステータスの読み取り待ち）<br>
　<strong>T</strong> - トレースまたは一時停止<br>
　<strong>W</strong> - ページング
</dd>
<dt>PPID</dt>
<dd>親のプロセスID</dd>
<dt>PGRP</dt>
<dd>プロセスのグループID</dd>
<dt>SESSION (SESN)</dt>
<dd>プロセスのセッションID</dd>
<dt>TTY_NR (TTY)</dt>
<dd>プロセスを制御しているターミナル</dd>
</dl>

-->
RPGツクールMZを公開されている情報だけでベタほめする

[RPGツクールMZ](https://tkool.jp/mz/)の発売日(8月20日)が発表されました。
プラグイン作者として、どの新機能に魅力を感じるかを記事にしたいと思います。


##プラグインコマンドの改善
[ユーザビリティを強化(ツクールMZ公式)](https://tkool.jp/mz/new_function/usability.html)
プラグインコマンドに型が付きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92869/a34e6a74-b324-d207-c5bd-c625dcfe1b1e.png)
旧型式では、上記画像のようにただ文字列を並べるのみだったので、ヘルプを読みに行って調べる必要がありました。
しかし、ツクールMVのプラグインパラメータに類似した形式をとるようになり、入力間違いを警戒する必要がなくなりました。
変数を設定することも可能なので、戻り値を持ったプラグインコマンドのようなものも作れるでしょう。
現時点では不明ですが、アクター指定部分に直指定と変数指定の2バージョンを個別に作る必要がありそうなのが難点です。
今後の発表に期待です。

##競合解決への手段の増加
プラグインの配布URLが追加可能になり、最新版を参照してもらいやすくなりました。
また、導入順序に対する警告が可能となったことで、警戒すべきプラグインへの対策が少しは改善しました。
必須プラグインの概念の導入は、複数ファイルで構成されたプラグインや他のプラグインの拡張用プラグインの配布を容易にします。

##公式プラグインの強化
今回はツクールMVのプラグイン作者として有名なトリアコンタンさんが公式プラグインの担当に加わりました。
発売後もメンテナンスされるでしょうから、自分のプラグインの足りない機能を借りることができるでしょう。
特に動的文字列プラグインなど汎用的なプラグインの機能を借りることができるのは大きいです。


##タイムプログレス戦闘の標準実装
いわゆるATB戦闘プラグインです。
名称が異なるのは、ATB(アクティブタイムバトル)が商標登録されているからという噂。
ツクールMVにATBプラグインは複数ありましたが、問題が多くて作者がさじを投げてサポートが止まっています。
中身が汚く複雑で問題が多く、問題が次から次へと出てくるATB系プラグインは公害と呼ぶのがふさわしい内容です。
もちろん、プラグインを使う一般ユーザーはお構いなしにそのサポートを他のプラグイン作者に投げてきます。
プラグイン作者の間では「ATB系プラグインの話が来たらサポートしないのが基本」という雰囲気が作られていました。
しかし、公式が実装することで統一された標準が生まれ、対処が容易になりました。
これからはATB戦闘に頼って特別感を出すことは不可能となるでしょう。

##アニメーションエディタにEffekseerを採用
RPGツクールのアニメーションエディタはツクール2000の頃の設計を長く引きずっていました。
20年も古い設計を引きずっていれば、使い勝手の悪さが目立ってきます。
Effekseerは10年ほど前からあるオープンソースのパーティクルアニメーションツールです。
ツクール上で使えたら便利だろうと思っていたので、公式による採用は大歓迎です。

なお、海外フォーラムでは**Elfkisser**という奇妙な別名が付いています…


#終わりに
箇条書きするとこれだけですが、まだ何か隠されているらしいです。
ツクールMZはツクールMVの問題点を改良した良い新作です。
これを機にMVのサポートを切って引っ越すプラグイン作者も多いでしょう。
複雑化したプラグインをゼロベースで書き直す良い機会です。
CRONの設定方法。ユースケースからサンプルまで

# CRONってなに
CRONは定期的にジョブを実行してくれる

## ユースケース
* 定期的にサーバのリソース状況をファイルに吐き出したい。
* 毎月決まった集計処理を実行したい。
* 特定のWEBサイトに定期的にアクセスして情報を収集したい

##重要度
★★★★★(5/5)
かなり重要。エンジニアであればぜひ覚えておきたい。AWSのクラウドウォッチ、lambdaで実行のタイミングを指定する際もCRONの形式で記載する。

(※どれくらい重要かという指標は個人的にはかなり大事だと思っている。ITエンジニアは覚えることが盛りだくさんなので、特にエンジニアなりたての頃は重要な技術から先に覚えていく必要があるし、ベテランのエンジニアも細かい技術よりも先に重要なものから覚えていく必要がある。すべての技術を完璧にすることはできない)

## 設定方法 
設定方法は以下2つ。linuxのディストリビューションによっては非推奨の方法もあるので、環境に合わせて使い分けるとよい（面倒なので自分の場合はいつもcrontab -eで書いている）

* crontab -e で編集する
* /etc/cron.dディレクトリに設定ファイルを作成する

## その他操作方法など
### crontab -l
登録されているcronの確認
### crontab -r
設定の削除（こわいw）
### /var/log/cron
結果はここに出力されるので見て確認すべし

## 構文
* m（分） h（時間） D（日付） M（月） d（曜日） user commandの順番で記載する。
* 複数指定の場合はカンマ区切りで指定する。ex:1,2
* 範囲指定はハイフンでつなぐ。ex: 1-3
* すべてを指定する場合はアスタリスク * 

## 詳細
* 曜日の指定は0,7が日曜日なので、たとえば日曜始まりと考えれば0,1,2,3,4,5,6で考えればよく、月曜はじまりが好きな場合は1,2,3,4,5,6,7と考えればよい（わかりやすい！設計した人すごい）
* 間隔を指定する場合は*/3のような形で記載する。

## サンプル
* 0 0,8 * * * sampleuser /home/sampleuser/bin/test.sh
→0,8時にtest.shをsampleuserで実行する
* 0 0 1,15 * 1              毎月1日、15日の月曜0:00に実行（ユーザ、ファイルは省略します）
* 10 5 1 * * 　          　 毎月1日の5:10分に実行（ユーザ、ファイルは省略します）
* 0 5 * * 1-6　　          月曜から土曜の5:00に実行（ユーザ、ファイルは省略します）
ユーザ画像の表示(Ruby on Rails)

#プログラミングの勉強日記
2020年7月17日　Progate Lv.207
Ruby on RailsⅦ

#プロフィール画像を表示する仕組み
　データベースに画像のファイル名を保存しておき、そのファイル名の画像を表示する。ファイルを保存するために、usersテーブルにimage_nameカラム(string型)を用意する。

#初期画像の設定
　ユーザの登録時にimage_nameカラムの値が`default_user.jpg`となるようにする`create`アクション内の`@user`を定義しているところで、`new`メソッドの引数として`image_name`を追加する。

```ruby:users_controller.rb
def create
  @user=User.new(
    name:params[:name]
    email:params[:email]
    image_name:"default_user.jpg"
  )
  ....
```

#ビューに画像を表示
　HTMLの`<img>`タグを使う。画像は`public/user_images`フォルダに保存されているので、srcの値は`/user_images/〇〇`となる。

```erb:users/show.html.erb
<img src="<%= "/user_images/#{@user.image_name}" %> >
```

#画像の送信
　`<input>`タグに`type=file`を追加することで画像ファイルを選択するボタンを表示できる。画像の送信は特殊なので、`form_tag`に`{multipart: true}`を追加する。

```erb:users/edit.html.erb
<%= form_tag("...", {multipart: true}) do %>
```

#送信された画像の保存
　ファイル名をデータベースに保存するのはnameやemailの更新と同様に、`@user.image_name`を上書きする。

```ruby:users_controller.rb
def update
  @user=User.find_by(id: params[:id])
  @user.name=params[:name]
  @user.email=params[:email]
  @user.image_name="#{@user.id}.jpg"
  ...
```

　画像を保存するためには画像データを元に画像ファイルを受けとる必要がある。ファイルを作成するためには、Rubyで用意されている`File`クラスを用いるが、画像データは特殊なテキストファイルなので、`File.write`ではなく、`File.binwrite`を使う。変数`image`に対し、readメソッドを使うことでその画像データを取得できる。
　画像を保存する処理は画像データが送信されたときのみにする。この場合、画像ファイルを`params[:image]`で受け取り、`if params[:image]`で画像が送信されているか判定できる。

```ruby:users_controller.rb
def update
  if params[:image]
    @user.image_name="#{@user.id}.jpg"
    image=params[:image]
    File.binwrite("public/user_images/#{@user.image_name}", image.read)
  end
  ....
```
NoMethodError: undefined method `[]' for nil:NilClass



```
bundle exec rails assets:precompile RAILS_ENV=production
```
すると

```
NoMethodError: undefined method `[]' for nil:NilClass
```

拡張子.css を .scss に変更する

（https://stackoverflow.com/questions/24809432/asset-compiling-crashing-on-server-environment-with-nomethoderror-undefined-m）
nexjsを触ってみました。

# nexjsとstyled-jsxを使ってみた。
最近nextjsを使用する機会があり、構築周りをやってなかったので、勉強のためにnextjsの構築とstyled-jsxの使い方を少し調べてみました。

---

## nextjsの構築
nextjsの構築にあたって、nextjsのチュートリアルがあったので参考にやってみました。
https://nextjs.org/learn/basics/create-nextjs-app/setup

---

### Reactアプリの準備
```
npm init next-app 任意のプロジェクト名 --example "https://github.com/zeit/next-learn-starter/tree/master/learn-starter"
```

npm init next-app 任意のプロジェクト名でnextjsのアプリが作れます。
--exampleをつけると指定したテンプレートを利用できるみたいです。

---

作成したディレクトリまで移動し、

```
npm run dev
```
を実行すると以下のような画面が表示されるかと思います。

---

<img width="1438" alt="スクリーンショット 2020-07-15 10.52.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/91db8d01-4b64-cd26-1612-ea543463a568.png">

---

こんな感じでnextjsアプリがすぐ立ち上がります。
これでnextjsを勉強する初歩の初歩の準備ができました。

---

ちなみにこのページは
プロジェクト名/pages/index.jsが表示されているので
試しに文言などを変えてみると更新されると思います。

エディタを保存してブラウザを確認しにいくとリロードをしなくても内容が変わっているかと思います。
(なぜリロードしなくても内容が変わるのかはまた別の機会に調べたいと思います。reactの開発サーバーにhot reloadingという機能があるらしくそれのおかげとかなんとか)

---

### styled-jsx
上記の方法でnextjsの導入ができました。
ほとんど何もしてなかったので、デフォルトで導入されているstyled-jsxについてどういう書き方ができるか少し調べてみました。

---

styled-jsxは以下のような使い方ができます。

```jsx
export default function Home() {
  return (
    <div>
      <p>サンプルテキスト</p>

      <style jsx>{`
        p {
          color: red;
        }
      `}</style>
    </div>
  )
}

```

基本的にはこのような形で記述ができます。
また、この```<style jsx>```で定義したcssはこのファイル内にしか適用されないので
別のファイル、コンポーネント間でトラブルが起こることは少ないかと思います。

---

#### globalな宣言
逆にglobalなcssを宣言したい場合は以下のようにすれば実現できます。

```jsx

export default function Home() {
  return (
    <div>
      <p>サンプルテキスト</p>

      <style jsx global>{`
        p {
          line-height: 1.5;
        }
      `}</style>
    </div>
  )
}
```

```<style jsx global>```とすればこのコンポーネント意外にも適用できるのでうまく使えば
使いやすいかもしれません。

---

#### クラス
クラス名を付けたい場合は

```jsx

export default function Home() {
  return (
    <div>
      <p className="sampleText">サンプルテキスト</p>

      <style jsx global>{`
        .sampleText {
          line-height: 1.5;
        }
      `}</style>
    </div>
  )
}
```

<p className="sampleText">とすれば普通のcssと同じ感覚で使用できますね。

---

こんな感じでnextjsを触る準備ができたのでもっと触っていきたいと思います。
css周りで他にもstyled-componentsやCSS Modulesやemotionなど色々あるみたいなので触ってみたいと思います。

---

## 終わり
Athenaを使ってCloudTrailログから、APIコールをカウントする

- AWSにて特定のAPI呼び出しで、エラーの発生が増えてきたので、その調査の覚書

## 指定したAPI呼び出しの件数

```
SELECT eventSource, COUNT(*) AS count
FROM "$DBNAME"."$TABLENAME"
WHERE eventName='$EVENTNAME'
AND eventTime > '2020-03-01T00:00:00Z'
GROUP BY DATE_FORMAT(from_iso8601_timestamp(eventTime), '%Y-%m-%d');
```

## 指定したAPIの日別の呼び出し件数

```
SELECT DATE_FORMAT(from_iso8601_timestamp(eventTime), '%Y-%m-%d') AS time, COUNT(*) AS count
FROM "$DBNAME"."$TABLENAME"
WHERE eventName='$EVENTNAME'
AND eventTime > '2020-03-01T00:00:00Z'
GROUP BY DATE_FORMAT(from_iso8601_timestamp(eventTime), '%Y-%m-%d');
```

## 指定したAPIと呼び出し元の日別の呼び出し件数

```
SELECT DATE_FORMAT(from_iso8601_timestamp(eventTime), '%Y-%m-%d') AS time, eventSource, userAgent, COUNT(*) as Count
FROM "$DBNAME"."$TABLENAME"
WHERE eventName='$EVENTNAME'
AND eventTime > '2020-03-01T00:00:00Z'
GROUP BY DATE_FORMAT(from_iso8601_timestamp(eventTime), '%Y-%m-%d'), eventSource, userAgent;
```

## 備考
- S3上のCloudTrailログが多いと、クエリ実行時にAtheanのコスト増加およびTimeoutでになってしまうので、Athenaのテーブル作成の際に、ディレクトリを掘り下げて作成する
- CloudTrailをAthenaで分析する際のテーブル作成は、CloudTrail上から（テーブル作成のための）クエリの生成および実行ができる
動的型付けと静的型付けについて

- 「静的型付け・動的型付け」は両者ともプログラミング言語の種類である。
**「型付け」：プログラムがオブジェクトの構造(≒変数の型)に関する整合性を検査する機能の事である。**

- 動的や静的とは、
**「状況によって状態を変える」**か**「状況によらず状態を変えない」**かである。
動的は、英語でdynamic（ダイナミック）と書かれ、状況によって状態を変えることを表す。
静的とは、英語でstatic（スタティック）と書かれ、状況によらず状態を変えないことを表す。
※状況によらず状態を変えないとは、動作しているシステム内で、あらかじめデータが固定されていて、それ以降データが変化しないという意味である。

- 動的型付け：プログラミングにおいて変数などのデータ型をあらかじめ決めることをせずに、実行時の実際の値でデータ型を判断する。

- 静的型付け：変数などのデータ型をあらかじめ決めて置き、実行する際には指定されたデータ型で定義される。

- 静的型付け言語の例：Java、C言語、Swiftなど

- 動的型付け言語の例：Ruby、PHP、Python、JavaScriptなど

参考サイト：https://www.gixo.jp/blog/5963/
Golang：現在の日時を unixtime で取得する


```go
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now().Unix()  // ココ
	fmt.Println(now)
	fmt.Println(time.Unix(now, 0))
}
```

結果

```bash
$ go run main.go
1594910484
2020-07-16 23:41:24 +0900 JST
```
Pythonでcronライクにジョブを定期実行させる

pythonでタスクキューを実現するライブラリに[huey](https://github.com/coleifer/huey/blob/master/docs/index.rst)というものがあります。同じタスクキューのライブラリで有名な[celery](https://celeryproject.org/)に比べてシンプルにジョブの定期実行を実装できます。
なお今回は通常のタスク実行には触れません。

## 事前準備

- ライブラリのインストール

```
pip install huey
pip install redis
```

- ブローカーに使うRedisの起動

お手軽にdockerで起動しておきます

```
docker run --rm -d -p 6379:6379 redis
```

# タスクを記述

今回はブローカーにRedisを起動したためRedisHueyを呼び出します。
関数にperiodic_taskのデコレータをつけるだけで定期実行ジョブを登録することができます。

```python:main.py
from huey import RedisHuey, crontab
import time

huey = RedisHuey(host="127.0.0.1")


@huey.periodic_task(crontab(minute="*"))
def test():
    print("process start")
    time.sleep(5)
    print("process end")
```

デコレータの引数として与えたcrontabでジョブの実行時間を指定します。今回は毎分です。

# Wokerを起動

hueyをインストールするとhuey_consumerというコマンドが使えるようになるのでこれでworkerプロセスを起動します。

```bash
$ huey_consumer main.huey

[2020-07-16 23:18:59,827] INFO:huey.consumer:MainThread:Huey consumer started with 1 thread, PID 2744 at 2020-07-16 14:18:59.827805
[2020-07-16 23:18:59,828] INFO:huey.consumer:MainThread:Scheduler runs every 1 second(s).
[2020-07-16 23:18:59,828] INFO:huey.consumer:MainThread:Periodic tasks are enabled.
[2020-07-16 23:18:59,828] INFO:huey.consumer:MainThread:The following commands are available:
+ main.test
[2020-07-16 23:18:59,836] INFO:huey.consumer.Scheduler:Scheduler:Enqueueing periodic task main.test: 30a61be7-903c-4fa7-815f-c5c013074085.
[2020-07-16 23:18:59,841] INFO:huey:Worker-1:Executing main.test: 30a61be7-903c-4fa7-815f-c5c013074085
process start
process end
[2020-07-16 23:19:04,847] INFO:huey:Worker-1:main.test: 30a61be7-903c-4fa7-815f-c5c013074085 executed in 5.005s
[2020-07-16 23:19:59,830] INFO:huey.consumer.Scheduler:Scheduler:Enqueueing periodic task main.test: 8166b273-1b97-427a-a349-a2772ea67fd2.
[2020-07-16 23:19:59,834] INFO:huey:Worker-1:Executing main.test: 8166b273-1b97-427a-a349-a2772ea67fd2
process start
process end
[2020-07-16 23:20:04,839] INFO:huey:Worker-1:main.test: 8166b273-1b97-427a-a349-a2772ea67fd2 executed in 5.005s
```

1分ごとにジョブが実行されているのが確認できます。

以上
Oracle Linux8をOCI インスタンスに構築する

# !!NOTICE!!
この記事の内容は、ほかの手順とまとめて以下の記事に転記しました。
今後は転記先をメンテするためそちらを見てください。

[【証明書自動更新対応版】Oracle CloudとCloudflareとLet's Encryptでつくる！HSTSプリロード対応APサーバクラスタ](https://qiita.com/syakesalmon/items/4639defa14b408121f5c)

# この記事の概要
OCIインスタンスにOracle Linux8をインストールしたあとから初期構築までのメモ。

# 前提
- OCIダッシュボード上の操作方法は省略します

# まずやること
この記事の本編。下記を順番通りに行ないます。
## 1. アップデートする

```
yum update -y
```

## 2. firewalldを止める
OCIのファイアウォールでブロックするためOSのファイアウォールを止めておきます。

```
systemctl disable firewalld
systemctl stop firewalld
```

## 3. SELinuxを無効化する

```
vi /etc/sysconfig/selinux

#SELINUX=enforcing
SELINUX=disabled
```

ここまでできたら一度OSをリブートします。

## 4. SSHを設定する
パブリックIPを設定している場合、デフォルトの22番ポートを開けておくのはリスキーなので、ポートを変更します。
ついでにrootユーザでのログインも禁止します。

```
vi /etc/ssh/sshd_config

#Port 22
Port 10022
#PermitRootLogin yes
PermitRootLogin no
```

設定できたらSSHサーバを再起動します。

```
systemctl restart sshd
```

これ以降はデフォルトの22番ポートではなく変更後のポートでリッスンしているはずです。新規にSSHクライアントを起動して新ポートにアクセスできることを確認してください。（OCIのファイアウォールにも、変更後のポートへのアクセスを許可する設定を行なうのを忘れずに！）

<details><summary>うまくいかない場合</summary><div>
SSH接続にうまくいかない場合は/var/log/secureなどを確認してみてください。
</div></details>

## 5. エイリアスを張る
tailfといった便利なエイリアスは忘れないうちに設定しておきます。
（llのエイリアスってどこに設定してあるんだろう？）

```
echo "alias tailf='tail -f'" >> /etc/bashrc
source /etc/bashrc
```

# まとめ
OCIのAlways Freeサイコーですね。

参考：[私がCentOS 7を入れたら最初にやること](https://qiita.com/fetaro/items/8cf5169dc4d8a7ac9af6)
参考：[CentOS7 minimalをinstallしたあと最低限使える様にする](https://qiita.com/smicle/items/8556fcc820b870db891e)
ABC 079 D Wall

##問題
https://atcoder.jp/contests/abc079/tasks/abc079_d
##見た感じ
最初に全部の場合について、1にする方法への最短路を見つけておいて、あとで全部足していく。ワーシャルフロイド法が実装も楽でいい
##解法
上の通り
##ソースコード
```c++
const int N_MAX=100005;
int h,w,a[201][201],c[10][10];


void Main(){
    int x=0,y=INF10,z=1;
    //入力
    cin>>h>>w;
    rep(i,10){
        rep(j,10){
            cin>>c[i][j];
        }
    }
    rep(i,h){
        rep(j,w){
            cin>>a[i][j];
        }
    }
    //処理
    rep(k,10){
        rep(i,10){
            rep(j,10){
                minin(c[i][j],c[i][k]+c[k][j]);
            }
        }
    }
    ll ans=0;
    rep(i,h){
        rep(j,w){
            if(a[i][j]==-1)continue;
            ans+=c[a[i][j]][1];
        }
    }
    //出力
    cout << ans <<endl;
}

int main(){
    cin.tie(nullptr);
    cout<<fixed<<setprecision(12);
    Main();
}
```
Pythonで聖書の頻出語をカウント

### 0. 実現すること
[前回の記事](https://qiita.com/youichi_io/items/ecba18acd30a293b2d64)のPython版です。

聖書の頻出語をカウントします。
<img width="196" alt="スクリーンショット 2020-07-16 22.45.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/11ad9f55-01a7-7d13-bb52-05a50a30cae2.png">

### 1. 環境
MacbookPro
Python3
Jupyter notebook

### 2. データの取得
Githubに公開されているデータをお借りします。
[bible.txt](https://github.com/mxw/grmr/blob/master/src/finaltests/bible.txt)

フォルダに保存します。

### 3. Jupyter notebookの起動
聖書のデータを保存したフォルダでjupyter notebookを起動します。
jupyter notebookをinstallしていない方は別サイト様を参考にしてください。

[【2019年5月】MacBookにJupyter Notebookをインストールする (macOS 10.14.4/Mojave)]
(https://qiita.com/inai/items/e9da22eb336f7f2cd375)

### 4. Code
```read_bible.ipynb
import re
import collections

path = "./bible.txt"

with open(path) as f:
    s = f.read()

# データの整形
s = re.sub(r'[,.:;"?() ]', " ", s)
s = re.sub('\n', " ", s)
s = s.lower()
s = s.split()
s = sorted(s)

# 頻出語をカウント
counter = collections.Counter(s)
counter.most_common()
```

### 5. メモ
文字列処理の練習でした。
[Rails] HerokuにデプロイしたらGoogleログイン機能が機能しなくなった

##Googleアカウントのログイン機能が動かない

* RubyとRailsのバージョン
 * Ruby: 2.6.5
 * Rails: 6.0.2


* 行なったこと
 * Omniauthを導入し、Googleアカウントでログインする機能を実装
 * .envファイルを作成し、クライアントIDとシークレットIDをこちらに記載
 * .envファイルを.gitignore内に記載し、GitHubから見えないように設定
 * Herokuにデプロイ


DeviseやOmniauthが原因でHerokuにデプロイできない方はこちらの記事をご覧ください
https://qiita.com/TAKO-zhangyu/items/153321ab6b333b614e12



*  行いたいこと
 * デプロイした先の環境で、Googleアカウントを使ってログインできるようにする


##状況

ローカル環境（localhost:3000）では機能していたGoogleアカウントでのログイン機能ですが、Herokuにデプロイしたサイトで見ると機能しなくなりました。

client_idが取得できないと表示されています。

```
Authorization Error

Error 400: invalid_request
Missing required parameter: client_id

Learn more
```

実際の画面↓
![スクリーンショット 2020-07-16 22.23.25（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625905/900d3605-a230-e4ce-f8f5-fe9df4b7f123.png)



##原因
Google oauthを使ったログイン機能の実装には、Google側から発行されたクライアントID （GOOGLE_CLIENT_ID）と、シークレットID （GOOGLE_CLIENT_SECRET）が必要です。

このコードはあまり見えるところに置くべきではないため、私は.envファイルを作成し、その中に書き込みました。
そして、この.envファイルは.gitignoreのなかに記載しているので、GitHubから見えない状態になっています。

しかし、同時にHerokuにも見えない状態になってしまっています。

なので、client_idが取得できないと表示されてしまいました。

##Herokuにclient_idを知ってもらおう

1.　https://dashboard.heroku.com/apps に移動します。

2.　ログインします。

一度デプロイできている場合、そこに自分のアプリの名前が載っていると思います。

3.　自分のアプリの名前をクリックしてください。

すると、ページの上あたりにあるナビバーで確認すると、現在 Overview にいると思います。

4.　そのナビバーの最も右にある Setting をクリックしてください。

5.　上から２段目にある Reveal Config Vars というボタンをクリックしてください。

Config Varsがたくさん並んでいると思います。DATABASE_URLとか、LANGとかが並んでいるところです。

![スクリーンショット 2020-07-16 22.22.29（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625905/f43d50c6-5902-e3bd-4129-ff04fefaf6d9.png)


6.　その中に、Google側から発行されたIDを追加しましょう。

左側のKEY欄にGOOGLE_CLIENT_ID、右側のVALUE欄に発行されたIDを入力し、Addをクリックしてください。
シークレットIDも同じ要領で入力しましょう。

そうすると、治りました。

GitHubに見えないようにしているからHerokuからも見えないのは当たり前か、と腹落ちしました。参考になると嬉しいです。

プログラマーとしての就職活動中です。もしよければTwitterのフォローお願いいたします！
Twitter : https://twitter.com/tako_guangzhou
konoha VPS サーバー とkonoha VPSのDBサーバーをローカル接続をする

## サーバーについて
CentOS 7.7
- WebServer（東京リージョン）用を一台借りる
-- test-web-serverとする
- DBServer(東京リージョン)用を一台借りる
-- プライベートネットワークは private.vvvv.vvvv.vvvv.vvvvとする
* サーバー > 該当データーベースサーバー > 接続ホスト名 > プライベートネットワークで確認できる。
## プライベートネットワークの設定
konohaコントロールパネル（管理画面）から
ネットワーク > プライベートネットワーク ページへ 
DBサーバー接続用ネットワーク > 東京リージョンネットワーク > 契約中VPS から
test-web-serverの接続状況を「接続する」に変更する

## konohaVPSの設定の確認
サーバー > test-web-server >ネットワーク情報 > 表示NIC に
「shared-zzz-zzz-zzz-zzz-zzz」が追加されているはずなので選択そこに表示される、下記情報を使用する

```
IPアドレス: xxx.xxx.xxx.xxx
ゲートウェイ: yyy.yyy.yyy.yyy
```

* 「ext-www-www-www-www-www」を選択して表示されるものとは別なので注意

## サーバー内での設定

test-web-serverにターミナル等でログインする

```
ssh root@~~~~~ 
```

```
# nmcli d

DEVICE  TYPE      STATE                     CONNECTION         
eth0    ethernet  接続済み                  eth0               
eth1    ethernet  接続中 (IP 設定を取得中)  Wired connection 1 
lo      loopback  管理無し
```

```
# nmcli c modify "Wired connection 1" connection.interface-name eth1 connection.id eth1
```

```
# nmcli c modify eth1 ipv4.method manual ipv4.addresses xxx.xxx.xxx.xxx/24 connection.autoconnect yes
```

```
# nmcli c modify eth1 ipv4.gateway yyy.yyy.yyy.yyy
```

```
# ip route add 172.29.92.0/23 via yyy.yyy.yyy.yyy
```

繋がるか確認

```
# ping -d private.vvvv.vvvv.vvvv.vvvv
```

繋がるはず。

## 設定の永続化について

再起動すると

```
# ip route
# systemctl restart network
# ip route
```

繋がらない

```
# ping -d private.wwww.wwww.wwww.wwww
```

### 永続化

/etc/sysconfig/network-scripts配下にroute-{interface}を作成する
（今回の場合はroute-eth1）

```/etc/sysconfig/network-scripts/route-eth1
ip route add 172.29.92.0/23 via 172.29.96.1
```

再度接続

```
# ping -d private.wwww.wwww.wwww.wwww
```


繋がるはず。




参考
https://support.conoha.jp/v/dbnetwork/#01

https://qiita.com/mtitg/items/a4fa30cf1615bac196a4

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_static_routes_with_ip_commands
テスト自動化の8原則について

個人で細々と書いていたブログ記事をQiitaに移行しております。
もしかしたら、既に読んだことがある人がいるかも知れないですね

***

ここに書くのはあくまでも私自身の解釈であり、所属する組織などとは一切関係ございません。
*むしろ違っていたりしたら教えてほしいです。

詳しくは、テスト自動化研究会の記載されているページでご確認ください。
[テスト自動化の8原則 - テスト自動化研究会](https://sites.google.com/site/testautomationresearch/test_automation_principle)


# テスト自動化の8原則

#1. 手動テストはなくならない
自動化が優れていても、人間でしか出来ないテストはもちろんある。
例えば、ユーザビリティテスト。
自動テストで不具合が見つからなくても、使い勝手とかは人間でないと判断できない。


#2. 手動でおこなって効果のないテストを自動化しても無駄である
これは書いてある通りではないでしょうか。
意味のない手動テストを自動化しても、自動化するのにお金と時間がかかるだけで、
なんの効果もないでしょうし。

 

#3. 自動テストは書いたことしかテストしない
書いてある通りで自動テストは人間とは違い、書いてある通りの動きしかしない。
これが人間であれば、「ログイン画面でIDとPASSを入れてログインできること」とあれば、5人いれば5通りのことをするかもしれない。
だけど、自動テストでid:User PASS:Passwordと書けば、この通りにしか動かない。
（まぁ人間だと、たまにとんでもないことをやらかすこともあるけどねぇ。。）

 

#4. テスト自動化の効用はコスト削減だけではない
何度も同じテストを実行する場合、コスト削減はもちろんできる。
例えば、既存システムに新機能を導入したいと言った場合、既存のテストは自動化。
新たに実装した箇所は手動+新しい自動化テスト。
こうすれば新たにバグが発生したときに、実装済みの自動テストを流せば、
同じ結果を返してくれるのでバグの修正にかかる日数や工数などが削減できる...はず

#5. 自動テストシステムの開発は継続的におこなうものである
テストを自動化したから終わり！手動はやらないから人間は全員解雇！
**なんてことには絶対にならない**
自動化することで、新しい仕事が生まれる。

機能の追加・削除、新しいテストケースの追加、実行結果の確認などなど
せっかく自動にしても、メンテしてないとかだと意味ない気がします。
「殺虫剤のパラドックス」と同じで自動でやるところの質は上がるかもしれませんが、それ以外がおざなりになってしまいますし。
なにより、そのうちせっかく作った自動テストを使わなくなる未来が見えます。

 

#6. 自動化検討はプロジェクト初期から
これは本当にそう思います。。
すでに手動でずっとやっているプロジェクトだと、既存のものに対して自動化するのって大変なんですよ。。
最初から自動化を前提として設計していればもっと楽になるのに。

#7. 自動テストで新種のバグが見つかることは稀である
これは「3. 自動テストは書いたことしかテストしない」にも関わっていると思います。
既存の今まで動いていたシステムに対して、自動テストを流すことで、その機能がコピペミスで動かないとかは結構早く見つけ出すことは可能だと思います。
でも、多くの現場だと手動テストを自動化すると思うので、そうなると新種のバグが見つかる可能性は低くなるかと思います。

#8. テスト結果分析という新たなタスクが生まれる
5のところでも書きましたが、自動テストを使うと、新しくテスト結果分析という仕事が生まれます。
自動テストを流した結果を人間が確認し、Passしているかを確認する。
Failedだとなぜ失敗したのかを調べます。
それが単純にシステムが落ちていたのか、バグなのか、それとも自動テスト自身に問題があるのか。これらの結果を分析しする必要が生まれます。
これが数件程度ならいいんですけどね....
*結果はFailedだけど「それはFailedになることが正しいから、FailedだけどPassだよ！」 っていうものもあったり。。。

 

**ソフトウェアテストの7原則と同じで、テストに関わる人なら知っていないとダメな原則だと個人的に思っています。 **
SendGrid の Net::SMTPAuthenticationError: 535 Authentication failed: Bad username / password 解決方法

# 概要

SendGrid で `Net::SMTPAuthenticationError: 535 Authentication failed: Bad username / password` というエラーが発生したときの解決方法をご紹介します。

# エラーメッセージ

```
Net::SMTPAuthenticationError: 535 Authentication failed: Bad username / password
```

# 解決方法 SendGrid API の場合 `user_name` は `apikey`

> APIキーで送信するときにハマったのですが、APIキーを使って送信する場合にはユーザー名にapikeyを指定しないとSMTPAuthenticationErrorのような認証エラーがでます。
> 引用元: [SendGridを使ってSMTPでメールを送信する方法 \| Simple is Beautiful\.](https://blog.kozakana.net/2018/05/rails-sendgrid-smtp/)

`smtp_settings` が下記のような場合 `SMTP_USER` は SendGrid API key を発行したページにある情報ではなく `apikey` という文字列を指定する必要がありました。

```ruby
  ActionMailer::Base.smtp_settings = {
    user_name:             ENV['SMTP_USER'],
    password:              ENV['SMTP_PASS'],
    domain:                ENV['SMTP_DOMAIN'],
    address:               'smtp.sendgrid.net',
    port:                  587,
    authentication:        :plain,
    enable_starttls_auto:  true
  }
```


以上、SendGrid で `Net::SMTPAuthenticationError: 535 Authentication failed: Bad username / password` エラーが発生して困り果てた、現場からお送りしました。
[Rails] DeviseとOmniauthを導入したらHerokuにデプロイできなくなった

##Googleアカウントログインのでつまずいた

* RubyとRailsのバージョン
 * Ruby: 2.6.5
 * Rails: 6.0.2


* 行なったこと
 * Deviseを使ってログイン機能を実装
 * Omniauthを使ってGoogleログイン機能を実装


*  行いたいこと
 * Herokuにデプロイする

##Heorkuにデプロイする
```ruby:ターミナル
$ git push heroku master
```

Herokuにデプロイしようとすると、エラーが出てしまい、デプロイに失敗しました。

エラーメッセージ(抜粋)↓

```
rake aborted!
NameError: uninitialized constant Devise
```

##それに対しての解決
Gemfileの一番下に

```ruby:Gemfile
group :development, :production, :test do
  gem 'devise'
end
```

を追加し、

```ruby:ターミナル
$ bundle install
```
を実行。

##もう一回デプロイ

```ruby:ターミナル
$ git push heroku master
```
しかし今度はOmniauthに対してエラーが出てしまいました。

エラーメッセージ(抜粋)↓

```
Could not load 'omniauth'. Please ensure you have the omniauth gem >= 1.0.0 installed and listed in your Gemfile.
```

##それに対しての解決
Gemfileの一番下に

```ruby:Gemfile
group :development, :production, :test do
  gem 'devise'
  gem 'omniauth-google-oauth2'  ⇦これを追加しました!
end
```

を追加し、

```ruby:ターミナル
$ bundle install
```

##もう一回デプロイ 

```ruby:ターミナル
$ git push heroku master
```

デプロイに成功しました！
【リファレンス】Go

# データ型

|データ型|意味|
|:--|:--|
|int|数値|
|string|文字列|
|bool|真偽値|
|float64|浮動小数点|

# 繰り返し

```go:無限ループ
for {
    処理
}
```

```go:カウンタ付きループ
for i := 0; i < 10; i++ {
    処理
}
```

```go:オブジェクトループ
fruits := [5]string{"りんご", "バナナ", "いちご", "もも", "ぶどう"}

for i, s := range fruits {
    処理
    // iはインデックス番号
    // sはオブジェクト
}
```

# 日付関連

## タイムゾーン設定

```go
const location = "Asia/Tokyo"
loc, err := time.LoadLocation(location)
if err != nil {
    loc = time.FixedZone(location, 9 * 60 * 60)
}
time.Now.In(loc)
```
SAS/RでSQL エピソードⅢ : Cross Joinでデカルト積を作成

# SASやRでもSQL構文を使える!
SAS/RでSQLを使ってみるのシリーズ3
今回はデータのクロス結合(デカルト積)

パラメータ×時点など,ダミーデータの作成などによく使う

# SAS SQLプロシジャ

```sas
proc Sql;
  create table work.CLASSDATA as
    select *
    from DATA1 , DATA2;
quit;
```

from DATA1 , DATA2のかわりに
from DATA1 cross join DATA2でもOK


# ちなみにdataステップの場合

```sas
data work.CLASSDATA;
  set DATA1;
  do i = 1 to N;
    set DATA2 nobs = N point = i; 
    output;
  end;
run;
```

point=オプションで読み込み開始の行を指定している


# R sqldf

```r
CLASSDATA <- fn$sqldf( "select * from DATA1 , DATA2" )
```

# ちなみにdplyrの場合

```r
# cross join用に適当なキー変数作成
DATA1$DMY <- 1
DATA2$DMY <- 1

CLASSDATA <- full_join( DATA1 , DATA2, by = c( "DMY" ) ) %>% select( - "DMY" )
```
SAS/RでSQL エピソードⅡ : Left Join, Inner Join, Full Joinを使ったデータの結合

# SQLを用いたデータのハンドリング
SASやRでSQLを使うシリーズ2

※以下はgroup byの紹介
https://qiita.com/saspy/items/2829fdf6ab21ce9d9ce0

今回はleft joinなどデータの結合を紹介

# SAS SQLプロシジャ

```sas
proc Sql;
  create table work.DATA
    select 残す変数 A.VAR1 , A.VAR2 , B.*など
    from DATA1 as A
    left join DATA2 as B
    結合条件 on A.VAR1 = B.XXX and A.VAR2 >= 100;
quit;
```

left joinで左結合(DATA1がベースとなり、DATA2にしかない行は残らない)
left joinをright joinにすると右結合(DATA2がベースとなる)
inner joinだと両方ともにある行を残す(数学でいう積集合)
full joinだとどっちかにある行を残す(数学でいう和集合)
差集合にしたいなら、where=うまく使うとか、except使うなど

dataステップでのやり方は、以下を参照
https://qiita.com/saspy/items/7f61d4e733a952cd83e7


# R sqldf
```r
DATA <- fn$sqldf(
 " select A.VAR1 , A.VAR2 , B.*
   from DATA1 as A
   left join DATA2 as B
   on A.VAR1 = B.XXX and A.VAR2 >= 100
 " )
```

full join使ったら、
エラー: RIGHT and FULL OUTER JOINs are not currently supported
と出たのでleft joinとinner joinしかダメかも
まぁそしたらdplyr使えばいい


結合しながら処理ならsqldfの方がいいかもしれないが、dplyrの方がきれいかもね
Python3で@staticmethod 付けなくてもクラスのmethodを直接呼べる

# Python3で@staticmethod付けなくてもクラスのmethodを直接呼べて驚いた話:scream:

通常classのmethodをコールするには、オブジェクトを生成してコールする。
もしくは、@classmethod、@staticmethodを付けて直接コールするのどれかかと思います。

でも、タイトル通り直接呼べました。

## 環境
Python 3.8.2

## @staticmethodつけないでコールする
簡単なサンプルを用意してみましょう。
下記コードでは、@staticmethodを付けていませんがfoo()メソッドが直接呼べちゃいます。

```python
>>> class A:
...     def foo():         # @staticmethodつけない
...         print('Hello foo')
...
>>> A.foo()
Hello foo       <=== なぜか直接呼べる
>>> A().foo()
Traceback (most recent call last):   <=== オブジェクトからは呼べない 
  File "<stdin>", line 1, in <module>
TypeError: foo() takes 0 positional arguments but 1 was given
>>>
```
## @staticmethodつけてコールする
では、今度はつけてみましょう。
@staticmethodを付けてるので直接呼べるのはもちろんですが、オブジェクトからも呼べちゃいます。

```python
>>> class B:
...     @staticmethod      # @staticmethodつける
...     def foo():
...         print('Hello foo')
...
>>> B.foo()
Hello foo
>>> B().foo()
Hello foo       <=== オブジェクトからも呼べる
>>>
```

## @staticmethodつける、つけないの違い
上記見てもらった通り、**オブジェクトからも呼び出せるかどうか**しかないように思えるのだけど、ちょっと分からないです。

つい最近まで、python3がこんな仕様だなんて知らなかった。
でも、@staticmethod付けた方が分かりやすいから、自分はこれからも付けます。

## 参考までに
では、Python2 ではどうだったか確認
### 環境
Python 2.7.16
### 確認
```python
>>> class A:
...     def foo():               # @staticmethodつけない
...         print('Hello foo')
... 
>>> A.foo()
Traceback (most recent call last):   <=== 直接呼出しはダメ
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with A instance as first argument (got nothing instead)
>>> A().foo()
Traceback (most recent call last):    <=== オブジェクトからも、もちろんダメ
  File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)
>>>
>>>
>>> class B:
...     @staticmethod             # @staticmethodつける
...     def foo():
...         print('Hello foo')
... 
>>> B.foo()
Hello foo           <=== @staticmethod つければ呼び出せる
>>> B().foo()
Hello foo
>>>
```
これを見るとPython2ではやっぱりダメですね。
でも、なんでPython3からOKになったんだろう？気になる。

## 参考にしたURL
https://stackoverflow.com/questions/43587044/do-we-really-need-staticmethod-decorator-in-python-to-declare-static-method
https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod
Unity 3D入門 #1 [3Dゲーム作成テスト]

Unityで3Dゲームを作る備忘録です。

基本の作り方などはhttps://qiita.com/2kyym/items/47e0e18bbb1442bf688c#を参照

使用アセット：Nature Starter Kit2 , unity-chan

フィールドはNature Starter Kit2に任せて、次は自分でキャラクターを作って動かしたいと思います。


Unityのゲーム画面をキャプチャする方法としてUnity Recorderを使用しました。
https://dkrevel.com/unity-explain/unity-recorder/

以下、今回の進捗GIF
![ezgif-4-007b70238e05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670403/a25b503d-e7cd-9ed6-7a25-423bbc5f79da.gif)


https://ezgif.com/video-to-gif
上のサイトを使用してmp4をgifに変換して貼り付けた
【Laravel】DBから取得したcreated_atに->formatを使うと「Call to a member function format() on string」が出てしまう時の対処法

# 現象
DBから取得した`create_at`をviewファイル(blade)に表示する時に

```php
{{ $data->created_at->format('Y/m/d')}}
```

上記のように`format`メソッドで年月日（2020/07/16)の形式に変換したところ、

**Call to a member function format() on string**

というエラーメッセージが出た。

ちょっとハマりかけたが解決することができた＆この内容の記事が見つからなかったので残しておく。

# 結論
`Eloquent(ORM)`ではなく`QueryBuilder`でDBからデータを取得をしていたことが原因。

`Eloquent(ORM)`でコードを書き直したら解決！

#理由
`QueryBuilder`でデータを取得した場合、取得した値は**文字列**になっちゃうから。

エラーメッセージである

**Call to a member function format() on string**

は「文字列に対してformatメソッドを使っちゃってますよ〜」という意味（だと思う）


**Eloquentを使うと`created_at`と`update_at`は`Carbon`クラスのインスタンス（DateTime型を拡張したものと書いてた）で取得することができるので`format`メソッドが使える**というわけ。

参考：[Laravel 6.x Eloquent：ミューテタ](https://readouble.com/laravel/6.x/ja/eloquent-mutators.html)
※「日付ミューテタ」という項目に記載あり


今回は4つのテーブルからデータを取得する処理だったのでEloquentが使えないのかなと勝手に思ってQueryBuilderを使ったが、Eloquentでもできることがわかった。（しかもめっちゃ簡単w）

# Modelに$dateを宣言してもダメ
**Call to a member function format() on string**

でググるとほとんど**「Modelファイルに`$date`を宣言する」**という対処法が出ますが、この場合はそれもダメ。

というか先程も書いたがそもそもLaravelでは`created_at`と`updated_at`はデフォルトでDateTime型のメソッドが使えるから$dateに書いても意味がない。

余談だが、初め「これだっ！！」と思って

```php
protected $date = [
    'created_at'
];
```
って書いたけど、無意味だった。

#最後に（というか余談）
`QueryBuilder`でも取得したデータを**string→DateTime**に変換する処理を記載すればできたと思うが、せっかくLaravelを使っているのでEloquentを使う処理にしてみた。

ちなみにデータ取得の処理は`QueryBuilder`で書いてたら**7行**だったが、`Eloquent`を使うとなんと**1行**。

すげえ。
Rails6:Action Text内にある画像を取り出す

# 前提

Rails:6.0.3.2
使うモデル名:Article 
リッチテキストのフィールド名:body

# 実際に画像を取り出す
 
```ruby

@article = Article.first
@images = @article.body.embeds
ActionText::RichText Load (0.5ms)  SELECT `action_text_rich_texts`.* FROM `action_text_rich_texts` WHERE `action_text_rich_texts`.`record_id` = 1 AND `action_text_rich_texts`.`record_type` = 'Article' AND `action_text_rich_texts`.`name` = 'body' LIMIT 1
```
一つめの画像を取り出したいとき

```ruby
@images.first.blob
ActiveStorage::Attachment Load (0.6ms)  SELECT `active_storage_attachments`.* FROM `active_storage_attachments` WHERE `active_storage_attachments`.`record_id` = 1 AND `active_storage_attachments`.`record_type` = 'ActionText::RichText' AND `active_storage_attachments`.`name` = 'embeds' ORDER BY `active_storage_attachments`.`id` ASC LIMIT 1
ActiveStorage::Blob Load (0.4ms)  SELECT `active_storage_blobs`.* FROM `active_storage_blobs` WHERE `active_storage_blobs`.`id` = 1 LIMIT 1
=> #<ActiveStorage::Blob id: 1, key: "rt0856j7x8btuev1ncbuurjgjyq4", filename: "1_xxo_q17kxed6bI9O_E8ZcA.png", content_type: "image/png", metadata: {"identified"=>true, "width"=>512, "height"=>512, "analyzed"=>true}, byte_size: 14483, checksum: "5qx1/QPniLbLvo07uUFsOw==", created_at: "2020-07-16 11:40:19">

```

存在確認

```ruby
@images.present?
ActiveStorage::Attachment Exists? (0.6ms)  SELECT 1 AS one FROM `active_storage_attachments` WHERE `active_storage_attachments`.`record_id` = 1 AND `active_storage_attachments`.`record_type` = 'ActionText::RichText' AND `active_storage_attachments`.`name` = 'embeds' LIMIT 1
=> true
```
【Unity】EnumでUnityEventに引数を渡す

# 2022/10/25追記
こちらの記事内容はUnity2021以降のバージョンでの動作が確認できていないため以下に掲載させていただくリンクにあるファイルを使用していただくと記事内容を再現できるかと思います！

リンク先 -> https://forum.unity.com/threads/ability-to-add-enum-argument-to-button-functions.270817/page-4#post-7745919

# UnityEventにEnumを渡したい。

今回はこちらの方の記事を参考にさせていただきました。
[ほっぽこ開発 Androidゲームアプリの個人開発者「ほっぽこ開発」のウェブサイト](http://hoppoco.blogspot.com/2017/01/unitybuttononclick.html)
そのまま使用すると、多量のエラーがコンソールを埋め尽くしますが、たった一行で使えるようになります。

※ MRTKでもUnityEventの拡張を行っているのでその影響でコンフリクトを起こしているようなエラーも出ているため、自己責任でご利用ください。

## 準備

まずはソースのダウンロード
以下のファイルをダウンロードしてください。
(ダウンロード先はUnityのプロジェクトフォルダ内にそのまま入れてください。)

 1 Editor拡張
インストールDir => UnityProject/Asset/Editor/
[UnityEventDrawer.cs](https://forum.unity.com/attachments/unityeventdrawer-cs.358765/)

2 UnityEventの拡張
インストールDir => UnityProject/Asset/***
(どこでもいい)
[EnumActionAttribute.cs](https://forum.unity.com/attachments/enumactionattribute-cs.358762/)

ソースコードの修正
75行目付近のソースコードを一行編集してください。

```UnityEventDrawer.cs

	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
	{
        // 追加 ---------------------------------------------------------------------- /
		if (property.FindPropertyRelative("m_TypeName") != null) m_Prop = property;
        // --------------------------------------------------------------------------- /
        // 削除 ---------------------------------------------------------------------- /
        // m_Prop = property;
        // -------------------------------------------------------------------------- /
		m_Text = label.text;
		var state = RestoreState(property);
		OnGUI(position);
		state.lastSelectedIndex = m_LastSelectedIndex;
	}
```

以上で使えるようになります。

## 使い方

※使い方はサイトから添付しています。

```sample.cs
// GameManger -> class名
// WeponType -> Enum名
[EnumAction(typeof(GameManager.WeaponType))]
    // ※int型で引数を定義する
    public void hoge(int type)
    {
        // Inspectorで設定したEnumを受け取れます。
        GameManager.WeaponType enumType = (GameManager.WeaponType)type;
    }
```

## サンプル

![コメント 2020-07-16 222613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363822/9d0a989d-7447-cdf7-21c3-206f92a3e95c.png)

定数管理したい項目が多いHoloLens開発でもそのままEnumの値をunityeventに登録できるのは大変ありがたいです。
Stateで管理するような項目ではほぼほぼ使えると思うのでぜひお試し下さい。
EclipseにPayaraを設定する方法

- 環境
    - Windows 10 Pro 64bit バージョン1909
    - Eclipse Version 2020-03

# Payara Toolsをインストールする
1. [Help] > [Eclipseマーケットプレイス]からダイアログを表示する
2. [Find]に「Payara Tools」を入力して検索する
1. 検索結果に表示された「Payara Tools」を[Install]ボタンでインストールする
2. 再起動を促されるのでEclipseを再起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/d84ddc0d-2314-a8b1-5c4d-4ee9e1de6d32.png)

# Payaraをサーバーに設定する
1. [Window] > [Show View] > [Servers]で[Servers]タブを表示する
2. コンテキストメニュー > [New]からダイアログを表示する
3. [Select the server type:]で[Payara] > [Payara]を選択し、[Next]ボタンで進む
4. [Payara location:]にPyaraをインストールしたディレクトリを設定し、[Next]ボタンで進む
    - 今回の場合は、`C:\apps\payara5`
    - [Java location]も自動で設定される(と思う)
1. [Finish]ボタンで設定を完了する
【PowerShell】コマンド実行の成功/失敗を取り出す方法

# はじめに
コマンド実行の成功/失敗を取り出す方法についてアウトプットします。
※最近、業務でPowerShellスクリプトを書く中で使用している手法になります。

# コマンド実行の成功/失敗の結果を取り出す

こちらのコマンドを利用します。

```powershell:command
echo $?
```

## 成功の場合の出力

```powershell:成功
PS C:\Users\owner> Get-Host


Name             : Windows PowerShell ISE Host
Version          : 5.1.18362.752
InstanceId       : ae3418e2-425d-473d-aa82-c44f35743808
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : ja-JP
CurrentUICulture : ja-JP
PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

PS C:\Users\owner> 
PS C:\Users\owner> echo $?
True ←「True」はコマンド実行に成功したという意味
```


## 失敗の場合の出力

```powershell:失敗
PS C:\Users\owner> aaa
aaa : 用語 'aaa' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ aaa
+ ~~~
    + CategoryInfo          : ObjectNotFound: (aaa:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
 

PS C:\Users\owner> 
PS C:\Users\owner> echo $?
False ←　「False」はコマンド実行に失敗したという意味
```

# 使用方法(例)

## ①「if」にて条件式にしてみる

- code

```powershell:例1
Get-Host | Out-Null
$result = echo $?

if($result -eq "True"){
  Write-Host "コマンドの実行に成功しました。"
}else{
  Write-Host "コマンドの実行に失敗しました。"
}
```

- 実行結果

```powershell:実行結果
PS C:\Users\owner> C:\Users\owner\Desktop\scripts\command.ps1
コマンドの実行に成功しました。

PS C:\Users\owner> 
```

## ②「foreach」でやってみる

- code

```powershell:例2
$commands = @("Get-Host","Get-NetAdapter","Get-DnsClientServerAddress")
$results = @()

foreach($command in $commands){
  powershell $command | Out-Null
  $results += echo $?
}

foreach($result in $results){
  Write-Host $result
}
```

- 実行結果

```powershell:実行結果
PS C:\Users\owner> C:\Users\owner\Desktop\scripts\command.ps1
True
True
True

PS C:\Users\owner> 
```
Ubuntu の apt-get で `Undetermined Error` が出たら mirror site を変える

# 背景

- Ubuntu イメージをベースとした Dockerfile 内でパッケージのインストールを行っていた
- あるパッケージだけインストールに失敗する
  - `Undetermined Error` というエラーメッセージ

# 現象

```text:error_log
Step 8/15 : RUN apt-get update     && apt-get install -y --fix-missing curl locales git openssh-server
  :
Get:101 http://archive.ubuntu.com/ubuntu bionic/main amd64 libwrap0 amd64 7.6.q-27 [46.3 kB]
Err:101 http://archive.ubuntu.com/ubuntu bionic/main amd64 libwrap0 amd64 7.6.q-27
  Undetermined Error [IP: 91.189.88.142 80]

Unable to correct missing packages.
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/t/tcp-wrappers/libwrap0_7.6.q-27_amd64.deb  Undetermined Error [IP: 91.189.88.142 80]
E: Aborting install.
```

# 原因と対策

フェッチに失敗している URL
> http://archive.ubuntu.com/ubuntu/pool/main/t/tcp-wrappers/libwrap0_7.6.q-27_amd64.deb

をブラウザから叩いたら問題なくダウンロードできた (2020/07 現在)。よって、リンク切れなどではなさそう。

調べてみると

- セキュリティソフトの問題
- Ubuntu のバージョンの問題 (bug?)

など様々な要因が挙げられるようだが、今回のケースにおける原因はわからなかった。
ひとまず対応として、リポジトリ URL を以下のようにミラーサイトへ切り替えることで問題解消できた。

```bash:apt-getの直前に追加
sed -i'' 's/archive.ubuntu.com/jp.archive.ubuntu.com/' /etc/apt/sources.list
```

# 副次効果

通信が海を飛び越えなくなったことで、インストール速度が大幅にアップした。特に今回のようなインストールするパッケージが 100 を超える場合には効果が高かった。

とはいえ、 jp.archive.ubuntu.com は日本語版の Ubuntu における標準的なリポジトリらしいので、タイミングによってはここも負荷増大で重くなることがあるらしい。よって、日本国内のミラーサイトを用いるほうがより効果的とのこと。

- https://www.ubuntulinux.jp/ubuntu/mirrors

# 参考

- https://midorigame201845.hateblo.jp/entry/2018/06/13/003238
- http://blog.shun-ichiro.com/howto/vagrant-docker-undetermined-error/
- https://dockerquestions.com/2019/12/29/failed-to-fetch-http-archive-ubuntu-com-undetermined-error-docker-run-apt-install/
- https://ykore.hatenablog.com/entry/2018/02/16/181532
[随時更新]お世話になってるリンク集

お気に入りやQiitaのLGTM一覧だと必要な時に探しにくいので、ここでまとめる
随時更新予定です。無くなることもありますので、ご了承ください。

# Git
[基本的なGitコマンドまとめ](https://qiita.com/2m1tsu3/items/6d49374230afab251337)
[色々な git stash](https://qiita.com/akasakas/items/768c0b563b96f8a9be9d)

# Ruby
[[Ruby入門] 14. 日付と時刻を扱う（全パターン網羅）](https://qiita.com/prgseek/items/c0fc2ffc8e1736348486)

# Rails
[Rails sのプロセスが切れない時](https://qiita.com/motty93/items/d22c1eb8f5128f8cd7f8)

# ショートカット
[Mac のキーボードショートカット](https://support.apple.com/ja-jp/HT201236)
[Chrome のキーボード ショートカット](https://support.google.com/chrome/answer/157179?hl=ja)
[VSCode のキーボード ショートカット](https://qiita.com/naru0504/items/99495c4482cd158ddca8)
[【VSCode】キーボードショートカットの設定とおすすめを紹介](https://b1tblog.com/2019/10/16/vscode-shortcut/)
[ターミナル 作業効率化 tips集](https://qiita.com/shizuma/items/86470203ac8ea6b4d53f)

# mac設定
[【Mac】マウス・トラックパッドカーソルを限界突破で早くする設定](https://suwaru.tokyo/%E3%80%90mac%E3%80%91%E3%83%9E%E3%82%A6%E3%82%B9%E3%83%BB%E3%83%88%E3%83%A9%E3%83%83%E3%82%AF%E3%83%91%E3%83%83%E3%83%89%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%82%92%E9%99%90%E7%95%8C%E7%AA%81/)

```terminal

defaults write -g com.apple.mouse.scaling 16
defaults write -g com.apple.trackpad.scaling 16
*実行後PC再起動
```

## マウスで複数のウィンドウをまとめて閉じる
[Macで複数のウィンドウをまとめて「閉じる」「隠す」「しまう」方法](http://inforati.jp/apple/mac-tips-techniques/system-hints/how-to-close-multiple-windows-at-once-in-macos.html)

```
閉じたいウィンドウをアクティブにして、「Option」を押しながら、「ファイル」メニューから「すべて閉じる」を選択
または「Option」を押しながら、ウインドウの左上の赤い閉じるボタンを押す
```

# その他
[初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9)
[[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか](https://qiita.com/jnchito/items/dedb3b889ab226933ccf)
[プログラミングでよく使う英単語のまとめ【随時更新】](https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923)