OmniAICreator/Qiita-1.07M huggingface dataset:
Docker Toolboxでローカルホストにアクセスする

Docker-Toolboxを使っているとき、localhostにアクセスできずに少し詰まったのですが、意外と忘れてしまうのでメモしておきます。

#　環境
* windows 10 home
* Docker-Toolbox 

# Docker-Toolboxとは
macやwindows 10 ProではないPCにdockerを導入する際に利用するもの。
詳しくはこちらの記事がわかりやすいです。
[windows 10 home で docker を導入するメモ](https://qiita.com/idani/items/fb7681d79eeb48c05144)

# localhostへアクセス
Docker-Toolboxは他のDockerと違い、localhostへアクセスする際にはひと手間必要です。
コンテナを立ち上げたあと、localhostでアクセスしようとしてもアクセスできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485956/a01a7229-c210-a9c6-be29-4de6d38099f9.png)

# docker-machineのIPを確認する
`docker-machine ip`で自分が今コンテナを動かしている仮想マシンのIPを確認します。

```
$ docker-machine ip
192.168.99.102
```

#取得したIPとポートでアクセス
今回はコンテナに3000ポートでマッピングしているため`http://192.168.99.102:3000`でアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485956/48c4df50-1415-31ea-54cd-bb387e567b5d.png)

コンテナで起動しているRailsが無事表示されました。

# まとめ
**Docker-Toolbox上のコンテナにアクセスする場合は、仮想マシンのIPを確認する。**

何度やってもたまに忘れてしまうので、気をつけたい。。。
そのサイトアプリ化しませんか？といわれても

#モバイルファースト

最近の日常的にインターネットを利用する環境の比率をみると

- スマホのみが54%（全体）
- 女性の方が男性よりスマホのみの割合が多く約7割
- 年齢でへ10代のスマホのみが８割超え
- 30代、50代についてもスマホのみの利用が増え続けている

![net.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/9a22fa71-622d-66d5-e5cb-cd4897d5982d.png)
(line統計 https://www.line100.com/sumaho-riyoutyosa2019/)
自分に置き換えても会社以外ではPCを使うことはありませんし、なんでもスマホですませてしまう派です。

WebサイトのUI/UX設計ではモバイルファーストが主流となり、スマホから操作しやすいWebサイトをつくるのが通常です。

- AMP(Accelerated Mobile Pages)モバイルページを高速に表示させるための手法
- SPA(Single Page Application) 動作性の向上より高度なWeb表現

などの導入も進み、スマホで操作しやすいWebサイトがどんどん増えています。
その次に考えるのは、スマホがターゲットならWebよりアプリ？となります。

#ネイティブアプリについて

導入までが大変なイメージがありました。

- ネイティブアプリはApp StoreやGoogle PlayからアプリをDLする必要がありプロモーションが大変
- 日本人が持っているアプリは平均で80個、使っているのは25個であることを考えるとDLさせるハードルが高い
- iOSとAndroidで２重開発となりコストがかかる

など。。
でも最近では、テレビCMなどでも「Webで検索」より「アプリを検索」のほうがよく見かけるようになったように、昔ほどアプリダウンロードの敷居は高くなく、逆にアプリがないサービスはユーザーが離れてしまうように感じます。

最近のユーザー動向（予想）

1. Webで検索
2. アプリがあればアプリをDL
3. アプリが使いやすければサービスを継続利用

では、アプリ開発はいままでどおり大変なのでしょうか？

#アプリ開発について

簡易的なのは出来合いのサービスに自社のWeb一部を組み込んで表示する、なんちゃってアプリ（WebViewアプリ）ですが、ユーザーがアプリを使いたい理由は、操作性の向上やレスポンスなどの使い勝手にあるため、ただたんにWebサイトをアプリ上で表示しているだけのではユーザーは満足できません。実際アプリStoreの評価欄で、中身がWebと変わらないとか、遅いとかの、コメントをよくみかけますし。。

やはりネイティブアプリを準備すべきでしょう。

あまり難しい機能やデザインでなければ、クロスプラットフォームのフレームワーク（ReactNative、Fultter）などを利用できiOS,Androidのダブル開発は不要です（動作検証、申請など、２重作業部分もかなりありますが。。）

![flutter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/6a71eb89-ffba-47c3-e1c5-a41b90d47493.png)
（渋谷女子も大好きな言語Dartで実装GoogleのFlutter https://flutter.dev/）

また、Webサイトをアプリのようにつくり、アプリのように使う
PWA：Progressive Web Appsという方法もあります。
昨年話題になった日本経済新聞社のページが爆速で逸品というのもPWA関連の技術です
googleDevelopersサイトでも紹介されています
https://developers.google.com/web/showcase/2018/nikkei

![nikkei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/352ae899-71bb-c3ba-f1ea-fde2b707bf75.png)



#まとめ

今後はWebサイトもどんどんスマホで使い勝手がよいものにかわっていくとおもいますが、

- アプリ＝便利
- Webサイト＝昔っぽいし不便

のイメージがユーザーとしてもまだ大きいのではないかと思います。
ECも含めサービス提供サイトの場合、Web+アプリを準備することは必須とおもわれるのですが、実際にもとめられているのは、実はアプリ自体ではなく、スマフォで操作性が高くレスポンスが早いなどの使い勝手です。

1. まずはWebサイトをモバイルで操作しやすいものに改善（SPA、AMPに対応、PCはこのさえ捨てる）
2. アプリ化するならクロスプラットフォームフレームワークでローコストをめざすが、WebViewアプリではなくてちゃんとつくる
3. アプリにこだわらなければPWAにしてみる
CentOS7(最低限インストール)へのGUI&VNC導入手順メモ

# 環境
CentOS7.5
とあるクラウド上のVM、Gnome等はインストールされていません。
# インストール
yumのアップデート,GUI環境,VNC

```
$ yum -y update
$ yum -y groupinstall "GNOME Desktop" 
$ yum -y install tigervnc-server 
```

# 設定
## VNC Serverのパスワード設定
遠隔でログインするためのパスワードを設定。

```
$ vncpasswd
 Password:
 Verify:
```
Read onlyのパスワードは必要に応じて。

## VNC Serverのサービス設定
CentOS7なのでサービスの起動はsystemctl。
サービス起動のためのファイルをcpで持ってきます。
**ここでcpではなくln(シンボリックリンク)でcopyしてしまうと、正常にvncが起動できない場合があります**

```
 $ cd /etc/systemd/system
 $ cp /lib/systemd/system/vncserver@.service vncserver@:2.service
```

vncserver@:2.serviceを編集する。
＜USER＞と記述されている箇所をすべてログインするユーザ名に書き換える。
2箇所のはず。
今回はrootで入るので以下の様にする。

```
[Service]
Type=forking
 # Clean any existing files in /tmp/.X11-unix environment
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
ExecStart=/sbin/runuser -l root -c "/usr/bin/vncserver %i"
PIDFile=/root/.vnc/%H%i.pid
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
```

## VNC Serverの有効化

```
$ systemctl daemon-reload
$ systemctl enable vncserver@:2
$ systemctl restart vncserver@:2
```

3行目を実行すると、VNC Serverのサービスが設定した通りに起動するはず。
エラーが出る場合は何か設定し忘れがある可能性大です。
GNOMEの実行のために、下記コマンドを実行。

```
$ startx
```
ただし、リモート環境だと正常に実行されない。

```
touch: cannot touch ‘/root/.cache/imsettings/log’: No such file or directory
^Cxinit: connection to X server lost
waiting for X server to shut down (EE) Server terminated successfully (0). Closing log file.
xinit: unexpected signal 2
```
Ctrl-Cで止めちゃってOK。

## VNC Serverへ接続
macだと移動→サーバへ接続をクリック
<接続先VMのIP>:5902 でVNC接続できるはずです。

以上
参考:http://www.plan0213.com/blog/20151202_1/
シンボリックリンク張るやり方だと`$ systemctl restart vncserver@:2`でエラー出ちゃったので。
稼働中の商用ネットワークでVRRPの切替検証を実施しちゃった話

# ご挨拶
初めまして @moriya-snj です。
この記事は「[本番環境でやらかしちゃった人 Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/yarakashi-production)」の15日目の記事です。
みなさん盛大にやらかしている様で安心しております。
今回は私が社会人3ヶ月目でやらかした重大事故の記録を包み隠さず暴露するとともに当時フォローしてくださった先輩や上司お陰でなんとかこの業界で生き抜くこと出来ていることの感謝をお伝えすべく、キーボードに手を伸ばしております。

# 何をしでかしたか
顧客AがIP電話を導入するため、新たにVoIP用ネットワークを構築することとなった。
機器の設置等は別部署が行うため、設置依頼を出し、完了の報告をもらったため、ネットワーク機器のコンフィグなどを流し込み疎通確認などを行うこととなった。

疎通確認が完了し、お次はVRRPの切替確認を行おうとしたが、ここで誤って稼働中の顧客Bのネットワークで作業してしまった。
何故その様なミスを犯したかというと、別顧客向けの同一サービスであったため、IPアドレス管理表が共用でかつ顧客名による絞り込み機能が存在しなかったのである。
当然機器名称の頭に顧客がわかる略称が記載はされていたが、完全にそちらを見落とし、日本語で書かれた説明文を見て判断してしまったのである。
また、想定ではPINGが一瞬NGで帰ってくるはずであったが問題なく疎通し続けていた。
たまたま復帰するタイミングとPINGの間隔が噛み合わなかったのかな？と判断し、何度か切替のための作業を行なってしまった。
これによりネットワーク切断を何回か発生させてしまった。

そのネットワークは前述の通りVoIPネットワークであり数秒のネットワーク断がかなり致命的な環境であった。
その結果顧客Bの業務が一時停止し、損害賠償物の大事件へと発展してしまった。

# 事件発覚と後処理
顧客から問い合わせを受けた営業チームから私の所属するチームへエスカレーションが来たのはやらかしから5分後くらいであっただろうか。
当時の課長が即座に状況調査をベテランのエンジニアに指示、ふと私が顧客Aのネットワーク検証を行っていることを思い出したのだろう。
「今はなんの確認をしているの？」と聞いてきたため、「VRRPの切替試験をしています。」と返答。
「それだ！すぐに中止しなさい！！！」課長の大声が室内に響き渡った。

その後すぐに状況は収束し、私のやらかしであったことは間違いなかった。
汗がだらだらと流れるもやたらと寒く感じたのは初めての経験である。

その後、課長に個室に呼び出される。
どんな叱責を受けるのか恐くてたまらなかったのを覚えている。
しかし、課長は私に怒鳴りつけることなく淡々と事態収束のための指示を出してくれた。
思い出せる限りの言葉を羅列してみよう。
「既に起きてしまったことをとやかく言っても仕方がない。」
「先方に謝罪しなくてはいけないが、頭を下げるのは俺たち上の人間の仕事だから気にしなくていい。」
「先方への報告のために何故起きてしまったのか？何をすれば防げるのか？をまとめて俺に報告してほしい。」
こんな感じのことを言われたと思う。

当時私の教育担当だったH先輩とともに課長に指示された原因報告と対応策を考える会議を行った。
その時最初に先輩に言われた言葉でだいぶ肩に乗った重圧が下がったのでその言葉も挙げておきたい。
「検証だからって稼働中の商用環境にログインできる環境で独り作業させたのは俺のミスだね。」
「日中帯に作業させちゃったのも不味かったね。」
「こんな感じでキミのミスはなんだったのか？どうしたら防げたか？一緒に考えて行こうか。」
こんなことを言われたと思う。
あぁ、自分一人の責任ではないのかと当時の私が心が救われる気持ちになり、前向きに原因と対策を考えられたのを覚えている。

既に転職してしまい、かつスマホ水没により連絡先も不明になってしまったN課長・H先輩、当時のお二人の言葉のおかげで今もこの業界でなんとかやってこれております。
この場をお借りしてお礼申し上げます。

# 結論
この事件で私が学んだとこをまとめておきたいと思います。

## 作業者として
- ログインしたリモートホストが本当に正しいのかよく確認すること！
    - 環境名とかがプロンプトに出てるはずなのでコマンドを打つ前に確認しましょう
- 手順はしっかり事前に確認すること！
  - テキストベースでも構わない。できればコマンドなどは作業中コピペで完結する様にしておくと良い
- 想定する挙動をしなかった場合は直ちに作業を中断し周囲にヘルプを求めること！
  - 報・連・相は大事だよ！

## 先輩・上司として
- 後輩・部下の責任は自分の責任。そのことを本人に伝えてあげてください
  - 本人を過剰に責めてはならない。何故なら本人が最も自分を責めているのだから
- 落ち着いて状況確認と事態収集のための指示出しを
  - やらかした本人はパニックに陥り何をすべきか判断できない状態であることが多いので
- 事態収集後のケアもしっかり
  - 一緒に予防策を考えるなど、後のケアもしっかりと行ってあげてください
    - 考えるのは本人にさせましょう。自ら考えることで身につくのです

# 終わりに
やらかし暴露というより先輩・上司に助けられたハートフルな話になってしまいました。
私も最近部下を持つ立場になり、当時のことを思い出しながら彼らに接する様にはしているつもりですが、なかなか難しいですね。
当時の先輩・上司には頭が下がる思いでいっぱいです。

明日は @n_takehata さんによる「rootユーザーのshell設定を変えてしまいサーバーにログインする方法がなくなってしまった話(予定)」です。
既に胃が痛くなってくるタイトルですねw
とても楽しみにしております。

ところで、本当は昨日のうちに記事をまとめて本日の0時丁度に記事を書こうと思っていたんですが、なんと障害が発生し調査・対応で記事を書く余裕がなくこんな時間になってしまいました。
障害っていつ起こるか分からないから恐ろしいですね。
まじ心臓に悪いわー（愚痴
Dockerのコンテナ内で設定したエイリアスがログアウトしたら無効になってしまう件について

Dockerで開発環境を構築してTDDを用いて個人開発をしてたのですが、テストを実行する度に

```
$ vendor/bin/phpunit
```
と入力するのめんどくさいですよね。

そこでエイリアスを設定して、puと入力したらテストを走らせるようにしようとしたのですが、コンテナ無いから抜けたらエイリアスが使えないという現象に出くわしたので忘備録として残しておきます。

```
// ashでAppコンテナ内に入る
$ docker-compose exec app ash

// ルートディレクトリに移動
＄ cd 

// .profileファイルをviコマンドで開く
$ vi .profile

#.profileファイル内に下記を追加
alias pu="clear && vendor/bin/phpunit"
alias pf="clear && vendor/bin/phpunit --filter"

// ファイルの読み込み直し
＄ source .profile

// ドキュメントルートに移動
$ cd /work/

// エイリアスで設定したコマンドを実行
$ pu   ←ここでは実行できる

// 一旦コンテナを抜ける
$ exit

// ashでAppコンテナ内に再び入る
$ docker-compose exec app ash

// エイリアスで設定したコマンドを実行
$ pu 　　←ここではエイリアスで設定したコマンドが実行できない
ash: pu: not found
```

原因として、コンテナ内に入った時はデフォルトでは非ログインシェル状態だそうです。
そのためユーザーを変更して上げる必要があるみたいです。

```
// ashでAppコンテナ内に入る
$ docker-compose exec app ash

// ashユーザーにスイッチ
$ ash -l

// エイリアスで設定したテストを走らせる
$ pu
```

間違ってたら優しくご指摘お願いします。
Ubuntu 18.04をHyper-V Server上で使うときに、Hyper-V daemonをインストールする方法

# 概要
Ubuntu on Hyper-V Serverでホットバックアップする際には、仮想マシン側にhyper-V daemonがインストールされているべきです。
ところが、それはなぜかubuntuのリポジトリにはありません。
ですので、直接debをインストールすればよいと思いました。

# 環境
Ubuntu 18.04 on Hyper-V Server 2016を想定

# 手順
dpkgをそのままインストールすれば問題ありません。

```bash
wget http://ftp.jp.debian.org/debian/pool/main/l/linux/hyperv-daemons_5.3.15-1_amd64.deb
dpkg -i hyperv-daemons_5.3.15-1_amd64.deb
```

また、依存関係がubuntuで問題になることはないでしょう。[^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/2a4fea25-781e-7fc5-4391-31d13ea35a11.png)




# 参考文献
https://yun-craft.com/software-crafts/hyper-v-server-2016-6#4

# 注釈
[^1]: Sidのパッケージ https://packages.debian.org/ja/sid/hyperv-daemons
Netlifyを利用してみる

# 概要
### 困っていること
* プロジェクトメンバーにナレッジや自分のソースを共有したい
* QiitaやGitHubのアカウントは共有したくない
* 裏タク作るのは管理が面倒なので嫌だ

### やりたいこと
* 共有サイトの作成
* 認証・認可（閲覧制限）
* リアルタイム反映
* ソース管理はしたいが、サイト管理はしたくない

# Netlify
Netlifyは静的コンテンツのホスティングサービス
コンテンツはGitHubのリポジトリを指定
ソースをGitHubにプッシュすると自動反映
無料枠で以下の利用が可能

* 無料SSL
* 転送量: 100GB/月
* lambda関数
* ストレージ: 100GB
* リクエスト制限: 500 requests/分

`参考：Netlifyの無料枠と料金に関してのまとめ`

## Netlifyの利用手順
以下の手順で利用可能。超簡単

1. Gitリポジトリ準備（GitHub/GitLAB/BitBucket)
2. [Netlify](https://www.netlify.com/)でアカウント登録（GitHub/GitLAB/BitBucket/EMail)
3. サイトの作成
4. 公開

以上！

あとは、Gitリポジトリにソースをプッシュするだけで自動反映されます。
ドメインが自動生成されますが、サイトの設定でドメイン指定が可能です。

## 認証・認可
Identityの指定でアクセス制限が可能なようです。
（2019/12/24追記）
Identityの指定で外部の認証サービスを利用できる。
サイト閲覧の制御をするようなBasic認証は有料プラン。

# まとめ
無料枠でここまで手軽にサイト公開ができるのは驚きです。
GitHubアカウントは隠蔽されるため、気兼ねなく、
プロジェクトメンバー用のサイトが構築できます。

# 参考サイト
[Netlifyで静的サイトのホスティングをする](https://qiita.com/sugo/items/2ee64887d682b0dae635)
[Netlifyの無料枠と料金に関してのまとめ](https://www.suzu6.net/posts/92-netlify-monthly/)
[徹底比較！Firebase vs Netlify (2018年版)](https://techblog.kayac.com/netlify-vs-firebase-2018)
Macでjupyter-notebookが起動できない時の対処法（エラー：No such file or directory）

## 現象
AnacondaをインストールしてJupyter-notebookを起動してみたが動かない。
エラー内容は以下

```
usage: dirname path
/opt/anaconda3/envs/base (root)/bin/jupyter_mac.command: line 3: /jupyter-notebook: No such file or directory

```

## 環境
- anaconda3
- macOS : Catalina 10.15.1

## 解決策
この現象はjupyter-notebookをインストールした際に、エラーによりインストールに失敗し、新しい環境を作り直す時に「base (root)」を選択してインストールしてしまうと起きるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260272/9c14379c-2bd0-1d30-c69a-503ded819911.png)

このエラーは**Pythonのバージョンで2.7**を選択して環境構築した際に発生しました。
なので**新しくPython3.7で環境を作り直して**jupyter-notebookをインストールし直せば問題なく動作するはずです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260272/9fe9e6b9-2188-804a-4203-bf32838e538b.png)

jupyter-notebookをインストールして実行する。
するとブラウザにjupyter-notebookが開きます。

## それでも治らない時に
自分がこの解決策を見つけるまでに色々試した過程を載せておきます。

### 1. シェルスクリプトの修正
とりあえず何が起こっているのか調べるために、jupyter_mac.commandを見てみます。

`/opt/anaconda3/envs/base (root)/bin/jupyter_mac.command`を開きます。

```jupyter_mac.command
DIR=$(dirname $0)

$DIR/jupyter-notebook
```
.command拡張子はシェルスクリプトですが、知識がなかったので調べてみると

- $0：このファイルの絶対パスを取得
- dirname : パス名からディレクトリパス名部分の文字列を取り出す

つまり、$0で`/opt/anaconda3/envs/base (root)/bin/jupyter_mac.command`が取得され、dirnameの引数に入れることでファイル名が取り除かれ、`/opt/anaconda3/envs/base (root)/bin/`になる。それを変数DIRに入れているようです。

しかし、これが上手く動かず、`usage: dirname path`とエラーが出ているので以下のように変更します。

```jupyter_mac.command
DIR=$(dirname "$0")  # $0を""で囲む

$DIR/jupyter-notebook
```

これで再度jupyter-notebookを実行。

```
/opt/anaconda3/envs/base (root)/bin/jupyter_mac.command: line 3: /opt/anaconda3/envs/base: No such file or directory
```

とりあえず`usage: dirname path`というエラーは消えます。
しかし、パスに空白スペースがあるため、途中で途切れてしまっています。

### 2. 環境名を変更
改めて環境名を空白スペースの含まないものに変えて実行してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260272/9fe9e6b9-2188-804a-4203-bf32838e538b.png)

jupyter-notebookをインストールして実行する。
するとブラウザにjupyter-notebookが開きます。


## まとめ
まとめると、
1. `dirname $0`を使うときは`dirname "$0"`にする。
2. 環境名に空白スペースを入れない

そもそもbase (root)の環境が何なのかすら理解していないのが良くなかったのかな。状況によって解決策も変わると思いますので、１つの参考程度に利用ください。

## 参考サイト
http://itdoc.hitachi.co.jp/manuals/3021/3021313330/JPAS0332.HTM

https://stackoverflow.com/questions/1308823/os-x-bash-dirname
ターミナルって？だったけどGitの鍵設定できた話

<h2>やったこと</h2>
<ul>
<li>Githubのアカウント作成</li>
<li>SourceTreeの設定</li>
<li>SSHキーの生成</li>
</ul>
※この記事は解説ではなくあくまで自身が参考になった記事やつまずいた事を書いているだけなので決してためになるものではありませんので悪しからず。


<h2>Githubのアカウント作成</h2>

つまずいた点：　パスワードの設定←そこから？笑

まず英語は雰囲気で流してはいけなかった（笑）
そのワードはすでに使われていますよ的なメッセージが出ているのに無理にenterenterと作成したらできてしまったので大丈夫と思っていたら、後々パスワードの入力が求められる場面でエラーエラーでパニクる。まさかと再設定してみたらあっさりと（苦汗）

<h2>SourceTreeの設定</h2>

つまづいた点：　UIデザインがちょくちょく更新されているようでネットの記事の画像と合わない。ただ得意のenterenterでなんとなくは進めた

<h2>SSHキーの生成</h2>
ここが一番苦戦。ターミナルを触った事ないからクリックとかしてみちゃうし。。。
下の記事をみながらなんとか出来た

<p>参考になった記事↓</p>
<a href="https://qiita.com/unsoluble_sugar/items/14bea376d8e6fce82eb3">新しいMacでGitHubのSSH接続をするまでの環境構築手順</a>
<a href="https://qiita.com/shizuma/items/2b2f873a0034839e47ce">GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~</a>

<h2>終わりに</h2>
あとはひたすらググっていった感じ。
あとは、自分のMacがUserファイル非表示になっていてどこにあるの？とひたすら探して
Finderの環境設定でまずは表示に切り替える必要があった事に気づくまでもやや苦戦。こういうところってあまり記事に書いてない→つまり誰もつまずかないのか・・・そんな私でも無事設定できたのでなんとかなるのもですよね。
GitHubチートシート

# [gitでUntracked filesを削除する](https://www.write-ahead-log.net/entry/2016/05/27/102233)

# マージにおいて片方のファイルをそのまま取り入れる
[２つのブランチ間でコンフリクトしているファイル fileA.txt と fileB.txt があるとする](https://qiita.com/nantekkotai/items/2ed17c3d774211d234a4)

```
# fileA.txt を現在チェックアウトしているブランチ側の対応に合わせる場合
$ git checkout --ours fileA.txt
$ git add fileA.txt    # add を忘れずに

# fileB.txt をマージさせたブランチ側に合わせる場合
$ git checkout --theirs fileB.txt
$ git add fileB.txt

$ git commit
```
https://qiita.com/shisho/items/c1075d394f1edf1a5928


# [git resetを取り消す](https://qiita.com/shosho/items/1f53b1fcf5fd876f309b)

# git addのを取り消す

```
# 全てのファイルを取り消し
$ git reset HEAD
# 特定のファイルのみ取り消し
$ git reset HEAD file_name
```
saveとupdate_attributes　チュートリアル6章　3.2.4演習3

railsチュートリアル６章3.2.4演習3でハマった部分を投稿します。

saveがうまくいかない理由が分かりませんでした。

調べた結果、

saveをすることで全てのカラムを更新しようとする。
↓
saveの実行にはname以外の入力（保存）の保存を要求するようになり、検証で失敗する。
↓
update_attributesなら特定の属性だけを更新することができます。

以上です。
ActionCable + Nginx + Redisの設定

## はじめに

このごろSPAでフェッチというマッチングアプリを作っている阿部です。
マッチングアプリと言えばチャット。
ということでチャット機能を作りました。

下手にSPAなんかに手を出したので、
WebSocketを本番で使うのに、Redisが必須になってしまいました。

備忘録がてらActionCableをデプロイするための記事を書きました。

## 前提
Rails 5.2.3
Ruby 2.5.1
Puma
Nginx
Vue
Amazon Linux AMI release 2018.03

## 説明すること
- Redisのインストール、実行
- Rails側の設定
    - Production.rb
    - cable.yml
- Nginxの設定
    - /etc/nginx/conf.d/*.conf

## Redisのインストール、実行
サーバー上でコマンドを叩き、Redisをインストール

```
sudo yum install redis --enablerepo=epel
```

サーバー上でコマンドを叩き、Redisを実行

```
sudo service redis start
```

## Rails側の設定
リクエスト元を設定してあげる。

```Production.rb
  config.action_cable.allowed_request_origins = [ 'http://ドメイン', /http:\/\/ドメイン.*/]
```

WebSocket通信時のadapterを設定

```Production.rb
development:
  adapter: async

test:
  adapter: async

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: example_production
```
`Redisをstartした時のデフォルトのポートが6379の為、redis://localhost:6379。ポート変えたらここも要変更`
`channel_prefixは複数のアプリケーションでRedisをしようする為に必要らしい。一つのアプリケーションでしかRedisを使用しない場合は不要`


## Nginxの設定

``` /etc/nginx/conf.d/exemple.conf
    upstream puma-example-api {
        server unix:///home/user/htdocs/example/tmp/sockets/puma.sock;
    }

    location /cable {
        proxy_pass http://puma-example-api;
        proxy_http_version 1.1;
        proxy_set_header Upgrade websocket;
        proxy_set_header Connection Upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
```

## 参考
[Action Cable の概要] (https://railsguides.jp/action_cable_overview.html)
[Rails5のActionCableをCapistrano経由でデプロイ] (https://qiita.com/ueokande/items/8d00d7658259221c4a3f#nginx%E3%81%AE%E8%A8%AD%E5%AE%9A)
[Rails5のActionCableをNginxとPumaの環境にデプロイする] (https://qiita.com/maggam/items/5259543569093689d6e4)
UnityでAndroid実機で実行したときに一部環境で画面が乱れる問題と対処法

# 発生した問題
UnityでAndroidスマートフォン向けの2Dゲームを開発していてゲーム画面のアスペクト比を統一させようとした。
方法はスクリプトでスマホ画面のアスペクト比が基準となるアスペクト比(今回は16:9)と異なる場合、ゲーム開始時にメインカメラのrectを変更してゲーム画面のアスペクト比を統一して余ったところは黒帯を表示させることで対応した。
エディタ上でゲームを実行したところ下の写真のようにカメラ外の左右の余った部分は黒帯が表示されている。
![New Unity Project - test - Android - Unity 2019.2.13f1 Personal _DX11_ 2019_12_15 14_30_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/53181803-4b75-9767-b936-36b0763c60fa.png)
しかし、ビルドして手元のPixel 3aで実行したところ、下の写真のように左右のカメラの表示外の部分が黒帯にならず表示が乱れる現象が発生した。
![Screenshot_20191215-142906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/6c02f5e7-8bd9-4a6d-cb22-ebd153f6fd41.png)
他の実機端末で実行するとエディタ上で実行したように、余った部分は黒く表示されて同じ現象は発生しなかった。

# 原因
調べたところ下の記事に書いてあるようにカメラの描写外の部分はメモリ上のゴミが残されているかららしい。
[Android の特定機種で画面が乱れたら……](https://helpdesk.unity3d.co.jp/hc/ja/articles/204456334-Android-%E3%81%AE%E7%89%B9%E5%AE%9A%E6%A9%9F%E7%A8%AE%E3%81%A7%E7%94%BB%E9%9D%A2%E3%81%8C%E4%B9%B1%E3%82%8C%E3%81%9F%E3%82%89-)

# 対処法
画面全体を映す二つ目のカメラを用意してメインカメラの描写外を表示させることによって一番下の画像のように問題が起こってた端末でもエディタ上と同じく表示されるようになった。全体を映す二つ目のカメラの描写の上にメインカメラを描写してるイメージ。二つ目のカメラはCulling Maskをすべてのレイヤーのオブジェクトを表示しない設定にして黒帯の部分にオブジェクトが映るのを回避している。二つ目のカメラのDepthをメインカメラより小さくしないと二つ目のカメラが上に表示されて全体真っ黒な画面になるので注意。(今回の場合だとBackgroundの色を変えることでほかの色の帯にすることが可能)
ゲームでどのようにカメラを使用しているかによって対処法も変わりそう。
![New Unity Project - test - Android - Unity 2019.2.13f1 Personal _DX11_ 2019_12_15 14_32_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/3892098b-51fa-5a7f-12e7-7d656d066c34.png)

![Screenshot_20191215-143323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/2398a4d2-c086-76bd-2e4a-be3e07f9e79e.png)

# さいごに
もし間違えている箇所などがありましたらコメント等で教えてください

# 参考
- [Android の特定機種で画面が乱れたら……](https://helpdesk.unity3d.co.jp/hc/ja/articles/204456334-Android-%E3%81%AE%E7%89%B9%E5%AE%9A%E6%A9%9F%E7%A8%AE%E3%81%A7%E7%94%BB%E9%9D%A2%E3%81%8C%E4%B9%B1%E3%82%8C%E3%81%9F%E3%82%89-)
- https://docs.unity3d.com/jp/460/Manual/class-Camera.html
AWS Cloudwatchチートシート

# [アラームを評価する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)

- [期間]アラームの各データポイントを作成するためにメトリクスや式を評価する期間です。これは秒単位で表されます。期間として 1 分を選択した場合、1 分ごとに 1 つのデータポイントが存在します。

- [評価期間] は、アラームの状態を決定するまでに要する直近の期間 (データポイント) の数です。

- [Datapoints to Alarm (アラームを発生させるデータポイント数)] は、アラームが ALARM 状態に移るためにしきい値を超える必要がある評価期間内のデータポイントの数です。しきい値を超えたデータポイントは連続している必要はありませんが、すべてが [評価期間] に相当する直近のデータポイント数に含まれている必要があります。
Ruby & Rails チートシート

# Rubyの論理値の評価

* A && B  
true(nil, flase以外)が現れたら終わりでそれが論理値になる
* A || B  
false(nilかfalse)が現れたら終わりでそれが論理値になる

# 特定のtest methodのみを走らせる

```
$ rails test test/integration/users_login_test.rb   TESTOPTS="--name test_login_with_valid_information"
```

# 本番デプロイ先のURLを確認できる

```
$ heroku info
```
パーミッションエラー(permmision error) の時、オールラウンドに使える解決手順

#最初にツールをインストールした場所を特定します。
例.npm

```
npm config get prefix
```

#その場所の所有者をあなたに変更します。

chown : チェンジオーナー 所有者を変更
-R : ディレクトリと配下全てを変更
whoami : ログイン中のユーザ名を取得
{DirA,DirB,...,DirN}: ディレクトリを複数指定する場合

```
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
```

[コマンドの直訳]
**所有権変更 　ディレクトリを変更 　ログイン中のユーザ 　ディレクトリの場所**

こちらの記事を参考にしました→[https://qiita.com/okohs/items/ced3c3de30af1035242d](https://qiita.com/okohs/items/ced3c3de30af1035242d)
CUDA_STANDARD is set to invalid value '17'

初心者すぎて変なところで詰んでいたので今後のためにもメモ。

# 何が起きていたか
CUDAは現状C++11にしか対応していないことは周知の事実とします。

以下のような`CMakeLists.txt`を作って作業をしてました。

```cmake
cmake_minimum_required(VERSION 3.10)

if(NOT DEFINED CMAKE_CUDA_COMPILER)
    set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
endif()

project(sample LANGUAGES CXX CUDA)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 11)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${sample_SOURCE_DIR}/bin)

cmake_policy(SET CMP0079 NEW)

find_package(CUDA REQUIRED)
include_directories("${CUDA_INCLUDE_DIRS}")

if(NOT DEFINED CMAKE_CUDA_STANDARD)
    set(CMAKE_CUDA_STANDARD 11)
    set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()

add_executable(sample main.cpp)
target_sources(sample
    PRIVATE
        cuda.hpp
        gpu_functions.h
        gpu_functions.cpp)

target_link_libraries(sample ${CUDA_LIBRARIES})
```

`gpu_functions.h`

```cpp
#pragma once

#include "cuda.hpp"

__global__ void kernel(void);

void proxy(void);
```

`gpu_functions.cu`

```cpp
#include <cstdio>
#include "gpu_functions.h"

__global__ void kernel(void) {
  printf("Hello from CUDA kernel.\n");
}

void proxy(void) {
  kernel<<<1,1>>>();
}
```

`cuda.hpp`というのは、以下記事に載っていた有益なコードを拝借してます。が、今回は特にGPUメモリへデータを転送するということはしていないのであくまで`cuda_runtime_api.h`用
https://proc-cpuinfo.fixstars.com/2019/02/cuda_smart_pointer/

さてビルドをしてみると以下のエラーが。

```
CUDA_STANDARD is set to invalid value '17'
```

このメッセージでググっても記事が出てきません。冷静に考えてみると、いくらCMakeにCUDAが統合されたからとはいえ、どれがCUDAのソースかはCMakeにはわかりません。

当然分けないといけないわけなんですが、上記のCMakeLists.txtは通常のC++ソースファイル類と同じターゲットに加えてしまっていました。これではCUDAのソースもg++へ投げられてしまいます。
（`CUDA_STANDARD`の値が17になっていた原因がさっぱりですが、`CXX_STANDARD`が17になっていたため、`CUDA_STANDARD`も17にセットされてしまっていたのでしょうか…わかりません）

# 解決

ちゃんとターゲットを分けてリンクしましょう。

```cmake

cmake_minimum_required(VERSION 3.10)

if(NOT DEFINED CMAKE_CUDA_COMPILER)
    set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
endif()

project(sample LANGUAGES CXX CUDA)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 11)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${sample_SOURCE_DIR}/bin)

cmake_policy(SET CMP0079 NEW)

find_package(CUDA REQUIRED)
include_directories("${CUDA_INCLUDE_DIRS}")

if(NOT DEFINED CMAKE_CUDA_STANDARD)
    set(CMAKE_CUDA_STANDARD 11)
    set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()

add_executable(sample main.cpp)

add_library(cudalib
        cuda.hpp
        gpu_functions.h
        gpu_functions.cu)
set_target_properties(cudalib PROPERTIES
        CUDA_SEPERABLE_COMPILATION ON)

target_link_libraries(sample cudalib)

target_link_libraries(sample ${CUDA_LIBRARIES})
```

# 参考

https://cliutils.gitlab.io/modern-cmake/chapters/packages/CUDA.html
TwilioのAuthyの2FA（電話番号認証）機能をnode.jsから使う


呼び出し方は本家のAPI使う方法や[先人のnpmパッケージ](https://www.npmjs.com/package/authy)使う方法とかあるが、今回は先人のnpmパッケージを利用してみる。

>ちなみにTwilioでは2つの電話番号認証機能があり、どちらを使うかはケースバーケースのようです。

## Authy API

Authyが提供するAPIはSMS送信以外での2FAに対応していますが、今回はSMS送信による認証を試してみます。

## 準備

### Twilioに登録

Twilioに登録して利用できるようにしておく。無料枠もあるがすぐに消費してしまいます・・・。

### Authyのプロジェクト作成とAPIの取得

左メニューからAuthyを選択肢、新規プロジェクトを作成、設定にてPRODUCTION API KEYを取得します。

## APIの機能（利用の流れ）

利用方法は簡単で、主な利用APIは下記の２つ。

* verification_start()でSMS経由でCode送信
* verification_check()でCode検証

あとは、

* verification_status()というAPIで状態を確認

することもできる。

## 実装

まず、モジュールをインストールします。

```bash
npm install --save authy
```

で、実装。

以下のコードではめんどくさいの一気に記述していますが１）と２）は同時に実行することはできません。
まず、２）をコメントアウトして実行し、SMSが届くか見ましょう。そして、１）をコメントアウトして、Codeを設定した状態で２）をコメントインして実行します。

```js
//取得したAPIで初期化
var authy = require('authy')('MswmXqxxxxxxxxxxxxxxxxxxxxxxxxxxx');

const phoneNumber = '9012345678';
const countryCode = '81';
const verificationCode = '000000'; //受け取ったものを入れる

//１）smsでcode送信
authy.phones().verification_start(phoneNumber, countryCode, { via: 'sms', locale: 'ja', code_length: '6' }, (err, res) => {
    if (err) throw err;
    console.log(res);
});

//２）受け取ったコード認証
authy.phones().verification_check(phoneNumber, countryCode, verificationCode, (err, res) => {
    if (err) throw err;
    console.log(res);
});

//３）ステータス確認
authy.phones().verification_status(phoneNumber, countryCode, (err, res) => {
    if (err) throw err;
    console.log(res);
})
```

スムーズにうまく動きました。

## レスポンス

それぞれ、下記のようなレスポンスがあります。

send時。キャリアとかも見える。

```
{
  carrier: 'NTT DoCoMo',
  is_cellphone: true,
  message: 'テキストメッセージは、+81 111-222-0000 に送信',
  seconds_to_expire: 439,
  uuid: '74dff830-0f49-0138-219c-12b9a9198221',
  success: true
}
```

check。

```
{ 
  message: 'Verification code is correct.',
  success: true
}
```

checkがOKならverified。チェックが終わってないないとpenddingとなる。

```
{
  message: 'Phone Verification status.',
  status: 'verified',
  seconds_to_expire: 305,
  success: true
}
```

## その他

テストするなら上記コードでも問題ないのですが、関数化するときなどcallbackがやっかいなので、そういう場合はラップしてasync/awaitで利用できるようにしてやる。

例えばFirebase Functions内で利用するときなど下記のようにしてみました。

```
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const authy = require('authy')('MswmXqxxxxxxxxxxxxxxxxxxxxxxxxxxx');

const verification_start_wrapper = (phoneNumber) => {
    return new Promise((resolve, reject) => {
        authy.phones().verification_start(phoneNumber, '81', { via: 'sms', locale: 'ja', code_length: '6' }, (err, res) => {
            if (err) {
                reject(err);
            } else {
                resolve(res);
            }
        })
    });
}

//sendCode
module.exports = functions.https.onCall(async (data, context) => {

    //受け取り
    const tel = data.tel;

    //authy
    const res = await verification_start_wrapper(tel);
    return res;
    
});
```

## メモ

* 一度認証しても、再度送信するとstatusはpendingになるようです（まあ、当然ですが）。
* 料金は国内3キャリア向けに$0.08円（まあ10円）。
* あくまで電話番号の実在確認なので、会員管理システム等は別途用意しておく必要がある。
* 専門サービスだけあって090と記述しても送信してくれる。090-1234-5678とハイフンがあっても処理してくれる。
mockmockのデータテンプレートで生成タイプ"バルク"を使ってみる

この記事は、[mockmockアドベントカレンダー](https://qiita.com/advent-calendar/2019/mockmock)15日目の記事です。

今回はデータテンプレートのちょっとマイナーな生成タイプ"バルク"を使ってみます。

## バルクとは？
1秒ごとのデータが10個入った配列を10秒おきに送るような、1データ内に複数回の計測データを入れるようなケースを想定したものです。
データテンプレート, 最大/最小送信間隔を指定することで、配列中にデータを入れてくれます。

## 使ってみよう
例として、1秒ごとに計測した温度計の値を10個入れたデータを10秒おきに送ってみましょう。

### 計測データを生成するデータテンプレート
温度と計測時刻だけのデータテンプレートです。
（グラフバリュージェネレーターは別途作っておきます。）

<img width="813" alt="スクリーンショット 2019-11-28 13.05.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39565/bba0d836-c6c0-4b96-fdc0-f89a88179200.png">

### 計測データをまとめるデータテンプレート
シリアル番号と送信時刻、そして計測時刻を入れた配列を作っています。
生成タイプ"バルク"で、送信間隔が1秒です。これを10秒ごとに送ると、配列の中に10個の計測データが入るという寸法です。

<img width="805" alt="スクリーンショット 2019-11-28 13.05.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39565/fa8eb168-bc3e-7985-9dd5-633c1c2e3c4b.png">

### mockステータス
送信間隔を10秒にしました。

<img width="811" alt="スクリーンショット 2019-11-28 13.17.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39565/0ea6839f-e9c3-49bc-ea12-4002939a9b9c.png">

### データ送信
以下のようなデータが送信されます。
1秒ごとの計測データが10個入っていますね。

```
{
    "serial_number": "12345",
    "time": "2019-11-28T04:06:11Z",
    "temperatures": [
        {
            "val": 11.724744018415981,
            "time": "2019-11-28T04:06:01Z"
        },
        {
            "val": 11.906567695655506,
            "time": "2019-11-28T04:06:02Z"
        },
        {
            "val": 13.458312351934037,
            "time": "2019-11-28T04:06:03Z"
        },
        {
            "val": 13.58706491420987,
            "time": "2019-11-28T04:06:04Z"
        },
        {
            "val": 13.990795146462386,
            "time": "2019-11-28T04:06:05Z"
        },
        {
            "val": 13.242849686697905,
            "time": "2019-11-28T04:06:06Z"
        },
        {
            "val": 13.384880669895342,
            "time": "2019-11-28T04:06:07Z"
        },
        {
            "val": 15.244839141202288,
            "time": "2019-11-28T04:06:08Z"
        },
        {
            "val": 11.558284588460122,
            "time": "2019-11-28T04:06:09Z"
        },
        {
            "val": 14.507298715125948,
            "time": "2019-11-28T04:06:10Z"
        }
    ]
}
```

## まとめ
IoTでは通信コストを気にしなければならないケースが多く、今回のように計測データをまとめて送信することもよくあります。そんなときは、この"バルク"を使ってみてください！

明日は@yukabeokaです。
データ送信間隔をランダムにする方法についてです！
Redisとredis-pyを使って、緯度経度での位置情報検索を実装する

レコメンドのプロジェクトで「緯度経度で最寄りの市区町村を検索し、その市区町村に紐づくアイテム（物件）を提案する（それを機械学習アルゴリズムで再ソートする）」ような実装が必要なことがありました。

ちなみに、元々はもっと複雑な特徴量を使って近似最近傍探索のようなロジックを考えていたそうなのですが、上記のような比較的シンプルな方法で早く試そうという方針に決まりました。（レコメンドアルゴリズムは別のメンバーが検証し、私は実装担当として関わっています）

その際に「最寄りの市区町村を検索する」アルゴリズム部分で、Redisの位置情報系の機能を使うと簡単に実装できたのでメモしておきます。…ここまでの情報で、あとは[redis-pyのドキュメント](https://redis-py.readthedocs.io/en/latest/)を読めば実装できると思いますが、他メンバーの類似プロジェクトでも利用検討することがありそうなので、共有のために書いておきます。


# Redisのクライアントライブラリ

Pythonではredis-pyというライブラリが用意されています。

https://github.com/andymccurdy/redis-py


```python
import redis

client = redis.Redis(host='{Redisのエンドポイント}', port="6379", decode_responses=True)
```

ここで `decode_responses=True` のオプションをつけていないと、レスポンスが全て `bytes` 型で返ってしまい、それを `.decode("utf-8")` し続けるので大変になります。


# アイテムの追加

このように追加します。第一引数(name)で登録先のkeyを指定します。

```python
client.geoadd("restaurants", 139.741072, 35.684266, "LIFULL TABLE")
```

※[LIFULL Table](https://table.lifull.com/)は弊社半蔵門オフィスにあるカフェです。弊社にいらっしゃった時はぜひいらっしゃってください。


# 緯度経度による検索

近い順で1件取得します。

```python
response = client.georadius("restaurants", 139.741072, 35.684266, 10, "km", "ASC", count=1)

print(response)
# => [['LIFULL TABLE', 0.0002]]
```

同じ点なのに距離が出てしまっているのは、おそらく浮動小数点かなにかの誤差なんじゃないかと思います。


# アイテムの削除

```python
client.zrem("restaurants", "LIFULL TABLE")
```

また `geodel` コマンドじゃないのは、緯度経度の実態が[Sorted set](https://www.tutorialspoint.com/redis/redis_sorted_sets.htm)で、そちらで用意されている `zrem` コマンドで十分だからのようです。[公式ドキュメント](https://redis.io/commands/geoadd)では次のように説明されています。

> Note: there is no GEODEL command because you can use ZREM in order to remove elements. The Geo index structure is just a sorted set.

ちなみにSorted setを使えば[リアルタイムのランキングの実装も簡単](https://qiita.com/niisan-tokyo/items/170ef3ac47ee39cfb46c)だそうです。


# 制限

Sorted setで、valueとして入れられる値は文字列のみに制限されているようです。そのため緯度経度で近い「レストラン名」は管理できても、これ単体でそれ以上（例えばレストランのメニューも入れてupdateさせるとか）はできないようでした。

実は「緯度経度で指定し、その最寄りのランドマーク周辺の `json` オブジェクト（最新の物件情報）をレスポンスとして返す」という実装をしたかったのですが、valueの値が物件情報が変わるたびに毎回変わり、挿入するたびに過去の値が消えずに残っていきます。そのため実は別の方法で実装しています。

また、[極地付近のデータは利用できない](https://redis.io/commands/geoadd)ようです。

> The command takes arguments in the standard format x,y so the longitude must be specified before the latitude. There are limits to the coordinates that can be indexed: areas very near to the poles are not indexable. 

# 参考

* [Redis公式ドキュメント](https://redis.io/)
* [Welcome to redis-py’s documentation!](https://redis-py.readthedocs.io/en/latest/)
* [Redisで位置情報を扱うコマンド(GEORADIUS, GEORADIUSBYMEMBER)](https://blog.shimar.me/2016/11/21/redis-georadius.html)
プリメイドAI ハック

# 初めに
プリメイドAIは、DMM.COMから15万で売られている、ダンスロボットです。
専用のアプリでしか動きませんが、PC(Windows10)から操作できるようにしました。
<img width="120" alt="pmait0.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551517/51a489a3-a50e-57f7-d924-e9829982cfff.jpeg">
# 機能概要
・基本モーションの実行（20個)
  ・サーボモータ情報の取得
  ・電源監視
  ・個別サーボモータの角度指定
  ・脱力モードの設定
  ・サーボモータのミラーリング動作
  ・取得情報のログ出力
  ・モーションファイルの保存
  ・モーションファイルの実行

(1)基本モーション

|No|動作|No|動作|No|動作|No|動作|
|:---|:---|:---|:---|:---|:---|:---|:---|
|0|ホーム|5|おねがい|10|敬礼|15|もんきー|
|1|どうぞ|6|バイバイ|11|えーん|16|応援|
|2|ワクワク|7|右にキス|12|ハート|17|エアギター|
|3|コシニテ|8|左にキス|13|キラッ|18|右にターン|
|4|ようこそ|9|ピストル|14|あなたへ|19|左にターン|

(2)サーボモータ情報の取得
   以下の情報が、定期時(ユーザ指定 *=500msec)に更新される。

サーボID　　：2～28
エンコード値：サーボ現在位置(0=脱力)
オフセット値：機体固有値(エンコード値－オフセット値＝指令値相当)
指令値　　　：コマンド指示で受け取った値(脱力＝0 又は 3500 ～ 11000)、この角度に向かった動作する
有効フラグ　：128(0x80)=有効,0(0x00)=無効
ジャイロ方向：-1(0xFFFF)=対象外,1282(0x0502)=ピッチ,1794(0x0702)=ロール
ジャイロ倍率：1(0x0001)=対象外,20=20倍,-20=-20倍
スピード　　：0(0x00)～127(0x7F)モーター・スピード
ストレッチ　：0(0x00)～127(0x7F)モーター・ストレッチ

(3)電源監視
   ロボット内の電圧値を、定期時(ユーザ指定 *=10000msec)に取得する事ができます。

(4)個別サーボモータの角度指定
   コマンドおよび、GUIでの指定サーボによる、角度指定を行う事ができます。

(5)脱力モードの設定
   コマンドおよび、GUIでの指定サーボによる、脱力指定を行う事ができます。
   脱力指定したサーボは、手動で回す事ができ、その角度を取得する事ができます。
   (モーションファイル用に利用できます)

(6)サーボモータのミラーリング動作
   手・腕・肩・足等の対になっている、サーボを手動で動かす事(脱力モード)で、対応する
   サーボを同じ動きにします。

(7)取得情報のログ出力
   送受信のコマンド、およびサーボ情報等を、ログに出力します。

(8)モーションファイルの保存
   サーボモータ情報の取得タイミングでID/エンコーダ値/オフセット値/指令値をタイムスタンプを
   付加して、CSV形式で保存します。


※詳しくは、下記のURLを参照してください。(プログラムがダウンロードできます）
http://www.wtoy.net/static/pmait/index.html
React-Draggableで<Draggable>内のインプットから勝手にフォーカスが外れる問題

React-Draggableを使ったコンポーネントでテキスト入力ができなくなる問題が発生したので対処法をメモ

## 環境
Chrome 78.0
React 16.8.6
React-Draggable 4.1.0

## 起きた問題
タイトルのまんまですが

```jsx
<Draggable>
  <div>
    <input type="text" />
  </div>
</Draggable>

```

上記のコンポーネントで、inputに文字を入力しようとしてフォーカスを当てても瞬時にフォーカスが外れて文字が入力できない問題が発生。

## 解決方法

https://github.com/mzabriskie/react-draggable/issues/314
こちらのissueに解決方法がありました。

Draggableに``cancel``というプロパティでdraggableの対象外にする要素のセレクタを渡せばいける。

```jsx
<Draggable cancel="input[type=text]">
  ...
</Draggable>

```

どうやらドラッグ中に意図せぬテキストの選択が発生しないようにフォーカスをすぐに外す処理が入っているのが原因のようです。
なのでテキスト入力部分だけはdraggableの適用対象外とすることで解決できます。

過去には
``enableUserSelectHack={false}``というプロパティを渡す必要があったようですが、
現在のバージョン(4.1.0)ではcancelだけでいけるようです。

## 参考
https://github.com/mzabriskie/react-draggable/issues/314
Windowsでgcloudコマンドを実行したら unknown encoding: cp65001 というエラーが出て使えない時の解決方法

# 内容

`gcloud`コマンドを実行したらいきなり`ERROR: gcloud crashed (LookupError): unknown encoding: cp65001`という内容のエラーが出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248810/96b48af6-e45c-6fbf-cc25-f88ea85b9ea2.png)

なにぃと思って`gcloud feedback`を実行しても同じエラーが出る。

# 実行環境

- Windows 10 Insider Preview 19037.1 (vb_release)
- Google Cloud SDK 273.0.0
- PowerShell 5.1.19037.1

# 原因

これはPythonのエラーらしい

## 解決方法

`PYTHONIOENCODING`という環境変数に`UTF-8`を設定することでエラーを解決できた。

### PowerShellの場合

```powershell:PowerShell
$env:PYTHONIOENCODING="UTF-8"
```
### コマンドプロントの場合

```shell:コマンドプロンプト
set PYTHONIOENCODING="UTF-8"
```

# 参考にしたサイト

- [Google Cloud App SDK crash → cloud crashed (LookupError): unknown encoding cp65001
](https://stackoverflow.com/questions/52540622/google-cloud-app-sdk-crash-%E2%86%92-cloud-crashed-lookuperror-unknown-encoding-cp650)
AWS環境構築（実装編）~VPC~

##概要
AWSについての設定の備忘録。今回はVPCの実装を試みる。
そもそもVPCって何って人は[こちら](https://qiita.com/ryuryu52868475/items/ce93d746991742a516a0)（今回使用する用語の解説もあります。）。

##実装
###VPC作成
<img width="1078" alt="スクリーンショット 2019-12-15 16.00.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551477/30bf2837-7a9e-2916-db60-8817a6c291ee.png">

1. コンソールからVPCを選択。
2. VPCの作成。

<img width="1650" alt="スクリーンショット 2019-12-15 16.03.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551477/26c0d27c-1b98-07db-a482-19f80d3783cb.png">

CIDRに10.0.0.0/16
テナンシーはデフォルト
このテナンシーは専有にすると料金上昇。

###サブネット作成
1. コンソールからサブネットを選択。
2. サブネットの作成。
3. 先ほど作ったVPC内にサブネット作成。
<img width="1654" alt="スクリーンショット 2019-12-15 16.14.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551477/70ee1e79-fa01-43c1-3766-04df6e64616a.png">

VPCに先ほどのVPC
Availability Zoneにap-northeast-1a
CIDRに10.0.0.0/24

さらにもう一つサブネットを追加
VPCに先ほどのVPC
Availability Zoneにap-northeast-1c
CIDRに10.0.1.0/24

###インターネットゲートウェイ作成
1. コンソールからインターネットゲートウェイを選択。
2. インターネットゲートウェイの作成。

<img width="1339" alt="スクリーンショット 2019-12-15 16.20.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551477/4fade52c-8b99-7bef-f8e0-68fca1a6bea0.png">

1. このままだとVPCがattachされてないので、attachする。
2. 作成したインターネットゲートウェイを選択して、アクションから「VPCにアタッチ」を選択

###ルートテーブル作成
1. コンソールからルートテーブルを選択
2. ルートテーブルの作成
3. 先ほどのVPCを選択して作成。
4. 画面下のルートの部分からルートの編集を選択。

<img width="1340" alt="スクリーンショット 2019-12-15 16.24.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551477/5caf5994-7fa9-ae1c-2200-507156f94b32.png">

5. アドレス0.0.0.0/0, ターゲットにインターネットゲートウェイを選び、先ほど作成したものを選ぶ。
6. アクションからサブネットを関連づける

以上で設定を完了。
エディタ　ショートカットキー・便利な機能一覧　Mac&&VScode

時間短縮したいけど・・・それを調べるのにめちゃ時間かかってる！
そのための備忘として。ただし、完全『自分』仕様です。
網羅して書かれた記事は結構あったのですが、自分がよく動作＆自分が使うエディタのみ＆自分の環境に適したものは流石になさそうだったのでまとめてみました。全く同じ状況の人は（いればですが）ぜひ参考にしてください。Mac前提です。

⌘ Command
⌥ Option
⇧ Shift
^ Control


### Visual Studio Code
####ショートカットキー(これで時間短縮できます。慣れれば。)

| キー | キー詳細 | 動作 |
|:--|:--|:--|
| ⌥⇧↑ | Option+Shift+↑ | 行のコピーを上に追加 |
| ⌥⇧↓ | Option+Shift+↓ | 行のコピーを下に追加 |
| ⌥↑ | Option+↓/↑ | 行の移動 |
| ⌘X |Command+X | 行の切り取り (未選択時) |
| ⌘C | Command+C | 行のコピー (未選択時) |
| ⌘⇧K　| Command+Shift+K | 行の削除　|
| ⌘] | Command+ ] | 行にインデントを追加 |
| ⌘[ | Command+ [ | 行のインデントを削除 |

<br>
#### その他便利な機能（最初知った時感動しました）



***`.クラス名`*** 
12秒から3秒に時短できました!!
わお！便利！VScode様様！あれ、ちょっと待てよ…クラス名でできるということはもしかして…？？

```.html
<div class="クラス名"></div>
```

***`#id名`*** 
やっぱりこれでもできた！！
11秒から3秒に短縮できました:)

```.html
<div id="id名"></div>
```

***`html:5`***
実はこう打つだけで・・・
え？ 

これは何分時短？？超便利！！！！


```.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  
</body>
</html>
```

### Atom
また追加します
文字列を画像に変換する

# 概要
PythonとPILを使って，文字列から，その文字列が描かれた画像を出力する方法をまとめました．単に背景画像を用意し，文字を描画しているだけです．

# PIL
PIL(Python Image Library)はPythonの画像処理ライブラリです．現在は開発が停止しているようで，その後継であるPillowを使った方がよいのでしょうが，AnacondaにはPILが標準でインストールされていること，PILの機能で実現可能だったことの2点から，PILを用いています．

# 画像の出力
文字列を画像に変換するという題目のページは見つかりませんでしたので，画像処理ライブラリの使い方を見ながら，文字を描く方法を調べて流用しました．そもそも，文字列を画像に変換するという需要がないのだろうと思いますが，迷惑メール対策として，メールアドレスを画像に変換するなど，細々とした用途はあると思います．そのため，題目はあえて「文字列を画像に変換する」としました．

作業に際して，[Pythonの画像処理ライブラリPillow(PIL)の使い方](https://note.nkmk.me/python-pillow-basic/)を参考にしました．

`PIL.Image.new()`でImageオブジェクトを作成した後，`PIL.ImageDraw.Draw()`でDrawオブジェクトを作成しています．`PIL.Image.new()`では，引数に色モード，画像サイズ，背景色を指定しています．

`PIL.ImageFont.truetype`で用いるフォントとそのサイズを指定します．その後，`draw.textsize()`で描画されるテキストのサイズ（ピクセル数）を取得して，テキストが所望の場所にくるよう調整し，`draw.text()`で描画しました．

```Python
import PIL.Image
import PIL.ImageDraw
import PIL.ImageFont

# 使うフォント，サイズ，描くテキストの設定
ttfontname = "C:\\Windows\\Fonts\\meiryob.ttc"
fontsize = 36
text = "暗黙の型宣言"

# 画像サイズ，背景色，フォントの色を設定
canvasSize    = (300, 150)
backgroundRGB = (255, 255, 255)
textRGB       = (0, 0, 0)

# 文字を描く画像の作成
img  = PIL.Image.new('RGB', canvasSize, backgroundRGB)
draw = PIL.ImageDraw.Draw(img)

# 用意した画像に文字列を描く
font = PIL.ImageFont.truetype(ttfontname, fontsize)
textWidth, textHeight = draw.textsize(text,font=font)
textTopLeft = (canvasSize[0]//6, canvasSize[1]//2-textHeight//2) # 前から1/6，上下中央に配置
draw.text(textTopLeft, text, fill=textRGB, font=font)

img.save("image.png")
```

# 出力された画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/94a3b66f-c0bf-1cdc-a35e-1b0e5a1e78f5.png)

無事に画像が出力されました．
p5jsでPokémon GOっぽいUIを作る(3)

3回目です。今回はボタンを作ってみましょう。とりあえず位置合わせも何も考えずに、circle()で書いてみましょう。

```js
function draw() {
  background(0);

  rotateX(1)

  // 地図を描く
  push();
  texture(img);
  plane(1000, 1000);
  pop();

  // 箱人間を描く
  drawBoxman();

  // ボタンを描く
  fill(64,64,64,128);
  circle(0,0,100);

}
```
こんな感じで書いた丸がこちら。地図の面に張り付いてますね。

<img width="490" alt="スクリーンショット 2019-12-15 9.59.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33389/38bce438-69da-8230-2150-de92ed3859e4.png">

というわけでrotate(-1)として面を戻してみます。

```js
  rotateX(-1);
  fill(64,64,64,128);
  circle(0,50,100);
```

すると、おやおやボタンは正面を向いてるようですが、地図にめりこんじゃってますね。

<img width="493" alt="スクリーンショット 2019-12-15 10.26.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33389/8dee384d-55fe-d2aa-63b5-3b966f9188c5.png">

というわけで、ボタンを描く面をtranslateで離し、ここにボタンを描くことにします。


```js
  rotateX(-1);
  translate(0,0,300);

  noStroke();

  fill(255,0,0,128);
  circle(-40,120,20);
  fill("white");
  text("A",-40,120);

```

地図からどれだけ話すかとか、どの位置にボタンを置くかは「適当」です。。。

<img width="491" alt="スクリーンショット 2019-12-15 16.32.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33389/e1980065-acd9-89f5-593a-0e3c849035d4.png">

次回はボタンを押したら何かアクションが起こるようにしてみましょう。
【Unity】シーンをロードするとき、スマートにパラメーターを渡す方法

こんにちは！
ねこじょーかー（[@nekojoker1234](https://twitter.com/nekojoker1234)）と申します。

Unityで開発をしていると、シーンをロードする処理は必須ですよね。
そのときに、「パラメーターを渡してロードしたいな」と考えている人も少なくないはず。

しかし、調べてもなかなか方法が出てきません。

Qiitaで探してみると、[[Unity] シーン切り替え時にパラメータを渡す](https://qiita.com/tkyaji/items/361bd3d3d296516658f5)という記事が出てきました。

こちらの内容でもできそうですが、少し難易度が高い印象。

もっと簡単にやる方法はないか、と調べてみたところ、いい方法があったので記事にしておきます。

## シーン間でパラメータを渡す方法

**結論から言うと、直接パラメータを渡すのではなく、「間に一つクラスを挟んであげて、お互いにそのクラスを参照する」という方法を取ります。**

では、具体的に見ていきましょう。

### 1.中継役となるクラスを作成する

```csharp
public static class SceneParameter {
    public static string CrossSceneInformation { get; set; }
}
```

`MonoBehaviour`を継承しないクラスなので、`GameObject`にアタッチすることはできませんが、そのまま使うことができます。

`GameObject`にアタッチしていないので、シーンが変わっても値が保持されている、という仕組みです。

### 2.ロード前にパラメータをセットする

今回は`SceneB`を読み込む例としました。

```csharp
using UnityEngine;
UnityEngine.SceneManagement;

public class ScriptA : MonoBehaviour {
    void Start()
    {
        SceneParameter.CrossSceneInformation = "Hello World!";
        SceneManager.LoadScene("SceneB");
    }
}
```

### 3.ロード先でパラメータを取得する

ロード先（SceneB）で、セットしたパラメータを読み込みます。
`static`なので、インスタンス化することなく、そのまま参照できます。

```csharp
using UnityEngine;
public class ScriptB: MonoBehaviour {

    void Start () {
        Debug.Log(SceneParameter.CrossSceneInformation);
    }
}
```

実行したら、ちゃんと値を渡せていることが確認できます。

```:Console
Hello World!
UnityEngine.Debug:Log(Object)
ScriptB:Start() 
```

これだけです。
かなりスッキリしましたね!!

すてきなシーンロードライフ(?)を送りましょう！

### 参考

[Load scene with param variable Unity](https://stackoverflow.com/questions/42393259/load-scene-with-param-variable-unity)

##あわせて読みたい

- [【Unity】Airtableを使って簡易的なDB管理をする方法【SQLは不要】](https://qiita.com/nekojoker/items/b309a13138a054d0f88e)

運営している PlayFab 専用ブログ
https://playfab-master.com
leapjs+johnny-fiveでクレーンゲームを操作する

はじめまして、@ufoo68です。普段はAWSとかReactを触る業務をやっておりますが、Qiitaでは色々と雑多なことを書いたりしております。

# はじめに
今回は今更ながら[Leap Motion](https://www.leapmotion.com/ja/)を買ったのでこれをNode.jsのライブラリで遊んだりしておりました（何年前の記事だよと思われるかもしれませんが）。きっかけは私が[とあるイベント](http://wiki.nicotech.jp/nico_tech/index.php?NT%E4%BA%AC%E9%83%BD2019)でここ２年くらい前から展示している改造クレーンゲームがありまして↓

![iOS の画像 (11).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/42e8cf0e-fdd3-4932-6132-1bf8a3f22fe8.jpeg)

こいつは[市販のやつ](https://item.rakuten.co.jp/goldstar/r300-12-86353/?gclid=Cj0KCQiArdLvBRCrARIsAGhB_sxQfBipA6Vv8yEBRVoS-u-1ezb8omFKldLB05KPmRyxIMST0wzd8AIaAsr1EALw_wcB&scid=af_pc_etc&sc2id=af_113_0_10001868)に[Arduino Nano](https://www.switch-science.com/catalog/2554/)を仕込んだものになってます。Arduinoの中には[Firmata](https://ashitani.jp/wiki/index.rb?p=Arduino%2FFirmata)を書き込むことで、PC上で動くのプログラミング言語で操作することができます。今まではPythonとOpenCVを使って、手のオブジェクト検出を使って操作するものを展示していたのですが、どうも照明とか外の光加減とか手の形の個人差とかで認識精度が左右されて調整とかが難しかったのでここは思い切って、Leap Motionを買うことにしました。

# まずは動画

以下が実際に動作したものになります。

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/G8_YqshXMzA/0.jpg)](https://youtu.be/G8_YqshXMzA)

# Leap Motionについて

Leap Motionを操作するために[leapjs](https://github.com/leapmotion/leapjs)というライブラリを用いました。今回は`palmPosition`という手のひらの位置を検出するメソッドを用いました。あと、注意点として、Leap Motionのドライバが認識しないという問題で躓いたりしたので[こういった情報](https://qiita.com/yuta0218/items/8b9f08d7e51cbbf6b7a3)を参考に調べるといいと思います。

# クレーンゲームについて

クレーンゲームというよりは、中に仕込んだArduinoについてですが、Firmataを書き込んでいるのでArduinoに毎回新しいソフトウェアを書き込む必要が無いです。このFirmataを書き込んだArduinoとUSB経由でPCと通信するわけですが、今回は[Johnny-Five](http://johnny-five.io/)というライブラリを用いてNode.jsとArduinoを連動させました。

# Leap MotionとArduinoを連動させる

今回は[ここ](https://junni.co.jp/release/46/)のサイトを参考に実装しました。と言ってもまずは動くもの、という感じで書いたので以下のような雑な感じの実装になりました。

```js
const Leap = require("leapjs")
const five = require('johnny-five')

const motor = { right: 6, left: 5, down: 2, up: 3, forward: 8, back: 9 }

const board = new five.Board()
board.on('ready',  () => {
    const up = new five.Led(motor.up)
    const down = new five.Led(motor.down)
    const forward = new five.Led(motor.forward)
    const back = new five.Led(motor.back)
    const right = new five.Led(motor.right)
    const left = new five.Led(motor.left)

    const stop = () => {
        back.off()
        forward.off()
        down.off()
        up.off()
        right.off()
        left.off()
    }

    const controller = new Leap.Controller()
    controller.connect()
    controller.on('hand', hand => {
        console.log(hand.palmPosition)
        hand.palmPosition[0] > 0 ? right.on() : left.on()
        hand.palmPosition[1] > 150 ? up.on() : down.on()
        hand.palmPosition[2] < 40 ? forward.on() : back.on()
        setTimeout(stop, 500)
    })
})

```

一応johnny-fiveはモーター動作をサポートしたライブラリもあるのですが、今回は単純なON/OFFでいいかなと思ったので`five.Led`を使っちゃいました。


# さいごに

もう少しソフトウェアとハードウェアのアップデートをして今年のNT京都2020に挑みたいと思います。一応今回はこのアドベントカレンダーへの間に合せということで。。。
一応ソースは[GitHubで公開します。](https://github.com/ufoo68/crane)ではこのへんで、次は@kimamulaさんの投稿です。お楽しみに！
MacでGithubAPIを使用してリポジトリ一覧を出力する

# 目的
MacでGithubAPIを使用してリポジトリ一覧を出力した際の備忘録です

# 準備

PyGithubをインストール

```
$ pip install PyGithub
```

加えて、GitHubアカウントのアクセストークンを取得（Settingsから取得できる）

# コード

リポジトリ一覧を出力する

```
#!/usr/bin/env python
from github import Github
 
token = 'xxxxxxxxxxxxxxx' # your access token
 
# or using an access token
g = Github(token)
 
for repo in g.get_user().get_repos():
    print(repo.name)
```

実行

```
（リポジトリ一覧が出力される）
```

# Error対策

```
$ python github.py
Traceback (most recent call last):
  File "github.py", line 2, in <module>
    from github import Github
  File "/Users/seigo/Desktop/python/burger/github.py", line 2, in <module>
    from github import Github
ImportError: cannot import name 'Github' from 'github' (/Users/seigo/Desktop/python/burger/github.py)
```

サンプルコードをgitHub.pyという名前にすると上記エラーが出る。
sample.pyにリネームして解決。

# 参考
[PyGithub](https://pygithub.readthedocs.io/en/latest/introduction.html)
[GithubAPIについて色々とまとめてみた](https://qiita.com/syossan27/items/dd3bd152792360c29d01)
[PyGithubを使って、GitHubの情報を取得してみた](https://dev.classmethod.jp/etc/get-github-info-using-pygithub/)
[Python 2.7 Error - ImportError: cannot import name Github](https://github.com/PyGithub/PyGithub/issues/472)
いつのまにかzshでもないbashでもないshになってた話

こないだ[何も知らずにchshした](https://qiita.com/masajiro/items/4f0965c40fc941942311)後の続きで
しらーんまに~~KP~~バッシュっぽくなってて、コナンくんよろしく「あれれーおかしーぞー？」って思って、
<img width="181" alt="スクリーンショット 2019-12-15 16.17.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181863/4f98afb7-a7fd-74d5-e596-cceb62925093.png">
↑試行錯誤してたあとによーくターミナルみたら....
おまえ"sh（シェル）"やんwww

結局前と全く同じコマンドを打ってからウィンドウ開き直したら直りました

```Bash:terminal
chsh -s /bin/zsh
```

完
エラーメッセージを日本語で表示したい！-機能実装方法について

個人アプリ作成中にエラーメッセージを日本語で表示したい！と思いましたが、想定よりも苦戦したので、以下に記載します。
（想定よりも苦戦した原因はymlファイルの設置と内容の編集です。。笑）

#はじめに
-背景：
Tweet機能を持たせたアプリを作成中、文字数制限をValidationで設定していたため、
Tweet時、文字数制限をオーバーしたときにValidationエラーメッセージを出そうとしていました。
この機能自体は、無事実装できましたが、出てくるエラーメッセージのデフォルトは英語になってます。
そこで、今回エラーメッセージを日本語にする方法を調べましたので、以下にまとめます。

#機能実装方法
##1.rails-i18n（gem）実装
日本語化するにはrails-i18nというgemを使用します。

```:Gemfile
gem 'rails-i18n'
```
忘れずにbundle installします。

```:terminal
bundle install
```
##2.application.rbを編集
次にconfig/application.rb内に以下を追記しましょう。

```rb:config/application.rb
#デフォルトのlocaleを日本語(:ja)にする
config.i18n.default_locale = :ja

#複数のロケールファイルが読み込まれるようpathを通す
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
```
これで、各フォルダにおけるymlファイルを読み込めるようになりました。

##3.ymlファイルの設置＋編集
まず、ymlファイルを設置します。
今回はpostモデルに関する内容だったので、models配下に設置します。

```
config
└── locales
      └──models 
           └──ja.yml
```

続いて、ymlファイルを編集します。

```:models/ja.yml
ja:
  activerecord:
    models:
      post: 投稿
    attributes:
      post:
        address: メールアドレス
        content: 投稿内容
```
ymlの記載はインデント量で構造を表すので、注意が必要です！
（自分はそれで、何度か引っかかりました。。。笑）

これで、エラーメッセージが日本語で表示できるようになりました！
今回記載しきれなかった内容もございます。
気になる方がいらっしゃいましたら、参考のページをご確認いただけますと幸いです！

以上となります。最後までご覧いただき、ありがとうございました！
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします！
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。



#参考
Ruby on Railsでエラーメッセージを表示する方法【初心者向け】
https://techacademy.jp/magazine/10024

[初学者]Railsのi18nによる日本語化対応
https://qiita.com/shi-ma-da/items/7e5c3d75c9a9f51abdd5#4-configlocales%E4%BB%A5%E4%B8%8B%E3%81%AB%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E9%85%8D%E7%BD%AE

Ruby on Rails モデルのエラー表示が日本語にならない
https://ja.stackoverflow.com/questions/38880/ruby-on-rails-%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E8%A1%A8%E7%A4%BA%E3%81%8C%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84
passwordとpassword_confirmation in rails チュートリアル

この記事はRailsチュートリアル６章の内容です。

２つの属性はhas_secure_passwordメソッドをモデルで呼び出した時に

自動的に追加される仮想的な属性です。

また、値が一致するかどうかのvalidationが追加されます。

```app/models/user.rb
 has_secure_password
```
この状態でテストを行うとredになります。

なぜなら、@userでpasswordとpassword_confirmationの値が設定されていないからです。

```
def setup
  @user = User.new(name: "Example User", email: "user@example.com")
end
```
なので、以下のように書き換えます。

```
def setup
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end
```

passwordとpassword_confirmationに同じ値を代入することでテスト結果がgreen
になります。

以上です。
> rails チュートリアル６章