OmniAICreator/Qiita-1.07M huggingface dataset:
C++を使った基本入出力 

競技プログラミングを始めて2か月。私のC++経験歴も2か月になり、そろそろ文章に書くほどの内容を身に付けたと思うのでぼちぼち書いていきます。今回は基本入出力のお話をします。
##基本入力
C++で入力を行うときは、cinを使ってあげる。演算子>>とかとても直感的かつ書きやすいので良い。それ以前にCを少し書いていたことがあったので、この楽さに初め感動した。

```c++
cin >> n; //入力を変数nに格納
```
こんな感じに連続して入力を受け取ることもできる。

```cpp
cin >> input1 >> input2;
```

int型だろうと、char型だろうと、string型だろうと基本何でもこの形で入力を受け取れる。注意は空白で前の入力と次の入力を区切っていること。なので、競技プログラミング以外の場面などで空白以外の例えばカンマでの区切りの入力を受け取るのに苦労したり、入力の文字列に空白が含まれてたりすると思わぬ結果が出る。カンマ区切りで受け取りたい場合は、string型で受け取ってあげて、splitとかしてあげるといいらしい。（知らんけど）

```c++
cin >> string; //入力が"abc def"だと受け取るのは"abc"のみ

cin >> a >> b; //入力が1,2のときa=1,b=0とかになる
```

幸運なことにC++はCとの互換性があるので、Cでのようにscanfを使ってあげるとカンマ区切りも受け取れる。こんな感じ。

```cpp
//入力が1,2など(整数),(整数)で与えられる場合
int main(){
  int a, b;
  scanf("%d,%d",&a,&b); //a=1, b=2
  return  0;
}
```

ただこれにも面倒くさい点はあって、この入力方式は入力されるものの型だったり、変数のアドレスを意識していないと詰むことがある。今回だったら%dみたいな%(入力の型に応じた文字)だったり、アドレス演算子&だったり。

複数の入力をまとめて入力したいときには配列を作ってあげて、for文をぶん回す。例えば、数値配列だとこんな感じ。

```c++
int main(){
  int n, i;
  cin >> n;
  int a[n];
  for(i=0; i<n; i++){
    cin >> a[i];
  }
  return 0;
}
```

実はこれC++のルール的にはアウトな書き方らしい。どうも配列の要素数の定義に変数を使うとまずいらしい。が、そんな事細かいことは競技プログラミングでは関係ない。実務ではまずいが。
##基本出力
出力をするときにはcoutを使うこのときの演算子<<の向きに注意。
特に何も考えずに出力できるのはいい。

```cpp
cout << n; //変数nの値を出力
```

このときに複数の出力をしても、空白などで区切られない。文字列の出力には便利だが、数値の出力には不便といった感じ。

```cpp
a = 1;
b = 2;
cout << a << b; //出力結果:12
cout << a << ' ' << b; //出力結果:1 2
cout << a+b; //出力結果:3
```

coutも同様に面倒くささ回避のために、代わりにprintf()を使ってあげることもできる。

```cpp
//a=1, b=2のとき
printf("%d %d",a,b); //出力結果:1 2
printf("%d,%d",a,b); //出力結果:1,2
printf("%d",a+b); //出力結果:3
```

これも出力の型に気を付けないといけないのはscanfと同様。だけどこっちは、アドレス演算子&がいらない。これはC言語が値渡ししているのに関係しているのだと思う。(詳細は割愛) 
##終わりに
今回はC++での基本入出力のお話でしたが、暇とネタがあれば言語に関わらず投稿していきたいと思います。ではでは。
#Mac で #django を始める最小手順のコマンドを羅列する ( #python )

# pyenv

`$ brew install pyenv`

`$ pyenv install 3.7.3`

`$ eval "$(pyenv init -)"`

必要なら .zshrc .bashrc などに追記

`$ python --version`
Python 3.7.3

# pip

`$ pip install django`

# django

`$ django-admin startproject example`

`$ cd example`

`$ ./manage.py runserver`

# http

http://127.0.0.1:8000/ にアクセス

![image](https://user-images.githubusercontent.com/13635059/56872405-a8ee3200-6a63-11e9-8083-35662b931222.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1505








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
msbuild


# msbuildの場所
ビルドするvisual studioによって、使うmsbuildを変える。
  https://qiita.com/ryo2i/items/f2028c62a03b8b0b9d85
  
  vs2017:
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin
  
# .netのバージョン
* "TargetFrameworkVersion"を指定して、msbuildを実行する。
  http://orzmakoto.hatenablog.com/entry/2015/05/17/143832
* 指定しなければ、プロジェクトファイルの"TargetFrameworkVersion"で決まる。

# msbuild 使用例
```bat
msbuild VSTest.csproj /p:Configuration=Release /p:TargetFrameworkVersion=v4.6 /t:Rebuild
```

# Jenkinsでの自動ビルド
* 環境変数の追加
  Jenkinsの管理>システムの設定>グローバル プロパティ>環境変数
  キー: msbuild
   値: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe
* 設定>ビルド>Windowsバッチコマンドの実行
　"%MSBUILD%" /vesion
 
# JenkinsでWindowsの環境変数を使う
* Jenkinsサービスのログオンアカウントを「ローカル システム アカウント」から「アカウント(インストールアカウント)」に変更する。
 https://blog.kakakikikeke.com/2013/08/windowsjenkins.html
 
 # リモートからビルド
 * ブラウザやcurl、wgetコマンドで下記urlにアクセスする。
 http://localhost:8080/job/build/build?token=vstest
【Xcode】実機で動かそうとしたらこんなエラーが出た時

Xcode10.1 / 2019.4.29作成

　Xcodeで実機で動かそうとしたらビルドはできてもエラーメッセージが出て動かない…ということでハマることがある。こんな時の対処法。
#Could not locate device support files
　これは、iPhoneやiPadのiOSのバージョンが今のXcodeに対応していないことを示すエラーである。iOSをアップデートすると直面しやすいことだろう。対処法は以下の通り。

1.サポートファイルをダウンロードする
　
　まずは以下のURLに行く。
https://github.com/filsv/iPhoneOSDeviceSupport
 ここにはサポートファイルが置かれている(下の画像)。この中から欲しいiOSのバージョンをクリックし、Downloadを押してダウンロードする。
![Qiita_Xcode20190429.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261325/a8456dd6-2bab-71b0-b578-4e794c789582.png)

2.サポートファイルを指定の場所に置く

　ダウンロードしたサポートファイルはフォルダ(ディレクトリ)ごと次の場所に置く。
/アプリケーション/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
![Qiita_Xcode20190429-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261325/314c5783-a704-862e-fbfe-7e2c0a07493c.png)

3.Xcode起動中の場合はアプリ再起動
　
　もし、Xcodeを起動しているならば、アプリの再起動が必要。左上の赤いボタンで閉じるのではなく、Command+Qなどでアプリを終了させよう。もう一度起動するとそのサポートファイルが読み込まれ、エラーが解消される。

＊もし、ダメだったらXcode自体のアップデートを試みたほうがいいかもしれない。時間がかかるから気が進まないが…。

参考サイト
[【Swift】エラー「Could not locate device support files（iOS 12.2）」の対処方法](https://pippi-pro.com/swift-error-could-not-locate-device-support-files-12-2)

#Development cannot be enabled while your device is locked
　文面上では、iPhone/iPadにロックがかかっているから外してくれと言っている感じだが、ロックを外しているのにこのエラーが出ることがある。

1.Cleanをやってもう一度
　
　キャッシュを消去することで意外にどうにかなることも多い。重いアプリだと時間食うけれども、やってみる価値はある。
＊多くのサイトでは2番目の方法について書かれているが、まずCleanは常識すぎて書かれてない？筆者はこのエラーに直面した時、2番の方法ではなく1番の方法で解決した。

2.iPhone/iPad側でプライバシー関係をリセットする

　サイトを回ると、この方法が書かれている所が多い。一旦接続を外し、
設定＞一般＞リセット＞位置情報とプライバシーをリセット
でリセットしてみよう。もう一度Runすると信頼するかどうかを聞かれるので、そこは「信頼」で。

参考サイト
[Development cannot be enabled while your device is locked.](https://qiita.com/ukandori/items/ea2554d18ae480d43741)
[CTC] コネクショニスト時間分類

#リカレントニューラルネットワーク
この記事ではリカレントニューラルネットワークについての知識が必要です。 あなたがこの種のニューラルネットワークに慣れていないのであれば、私はあなたがそれらについての[私の記事](https://qiita.com/hungph_dev_ict/items/f591532221f9e9d56973)をチェックすることを勧めます。
RNNをよりよく理解するために、通常の（フィードフォワード）ニューラルネットワークとはどう違うのかを調べなければなりません。 次の画像を見てください。
<img width="368" alt="screen-shot-2018-09-05-at-09-10-06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344186/356d87f3-173e-043a-e70c-0ab183b9f431.png">
FFNNでは、情報は一方向（入力から隠れ層を経由して、出力層を経由する方向）にのみ移動するため、情報がノードに2回接触することはありません。 これがフィードフォワードニューラルネットワークが入力として受け取ったものを思い出せない理由です - 彼らは彼らが訓練されたデータを思い出すだけです。

対照的に、RNNはループを介して情報を循環させます。 決定を下すとき、RNNは現在の入力とそれが以前の入力から何を学んだかを考慮に入れます。
#基本RNNと音声認識
![jzgh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344186/e071aeed-07aa-d892-1ebc-2de7296c7de6.png)
音声認識は、話し言葉をコンピュータでテキストに翻訳する作業です。問題は、あなたが音響観測（あるオーディオファイルとしての録音）を持っていて、手動でそれを作成せずにそれの転写をしたいということです。

ご存知のとおり、リカレントニューラルネットワークはシーケンシャルデータを含むタスクに非常に適しています。そして、スピーチはシーケンシャルデータなので、理論的には、音響観測とそれに対応する転写のデータセットを使ってRNNをトレーニングすることができます。あなたがおそらくすでに推測したように、それはそれほど簡単ではありません。これは、基本的な、標準的リカレントニューラルネットワークとも呼ばれるデータが整列データを必要とするためです。つまり、各単語（各単語ではありません！）をオーディオファイル内のその位置に合わせる必要があります。下の画像を見て、すべてのキャラクターをその正確な位置に合わせる必要があることを想像してください。
![picture1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344186/900048cd-3136-1e54-fdf4-e0b7adb656a5.png)
もちろん、これは誰もやりたくない面倒な作業であり、それを実行するのに十分な人数の従業員を雇う余裕がある組織はごくわずかであるため、このようなデータセットが非常に少ないのはこのためです。
#コネクショニストの時間的分類
幸いなことに、私たちはコネクショニスト主義の時間的分類（CTC）を持っています。これは入力と出力の間のアライメントを知らないということです。 CTCは、クロスエントロピーなどのニューラルネットワークのトレーニングに使用される単なる損失関数です。 音声認識のように、データを整列させることが問題となる問題で使用されます。

私が言ったように、CTCでは、整列データは必要ありません。 それは、入力が与えられると、それが任意のラベルの確率を割り当てることができるからです。 これは入力としての音声ファイルとそれに対応する書き起こしだけが必要であることを意味します。 しかし、CTCは、入力が与えられたときに、どのようにして任意のラベルに確率を割り当てることができるのでしょうか。 私が言ったように、CTCは「アライメントフリー」です。 これは、入力とラベルの間のすべての可能な整列の確率を合計することによって機能します。 それを理解するために、この単純なアプローチを見てください。
![img_2639.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344186/349bee51-a3e1-0753-d655-e66f4ff8b612.jpeg)
ここではサイズ9の入力があり、それを正しく表記したものが「Iphone」です。システムに各入力ステップに出力文字を割り当てるよう強制してから、繰り返しを折りたたむと、結果として出力が得られます。しかし、この方法には2つの問題があります。

入力内の無音も考慮する必要があるため、すべての入力ステップをある出力に強制的に合わせることは意味がありません。 「Kaggle」という単語のように、1行に2文字の単語を出力として生成する方法はありません。このアプローチを使用すると、出力として「Kagle」しか生成できませんでした。

###空白のトークン
これを回避する方法があります。これは「空白トークン」と呼ばれます。それは何も意味せず、最終的な出力が生成される前に単に削除されます。現在、アルゴリズムは各入力ステップに文字または空白トークンを割り当てることができます。 1つの規則があります。出力で二重文字を許可するには、それらの間に空白のトークンを入れる必要があります。この単純な規則では、2文字を続けて出力することもできます。

これがどのように機能するかの実例はこれです：
![img_2640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344186/13cb24ec-6ca1-ee07-a4e3-73f780a3ff54.jpeg)
1.）CTCネットワークは、すべての入力シーケンスに最も確率の高い（または文字がない）文字を割り当てます。

2.）間に空白のトークンを入れずに繰り返しがマージされます。

3.）そして最後に、空白のトークンが削除されます。

CTCネットワークは、各タイムステップの文字のすべての確率を合計することによって、特定の入力に対するラベルの確率をユーザーに提供します。
#結論
この記事では、リカレントニューラルネットワークに関する主な事実を概説し、なぜ正規のRNNがシーケンス問題に実際には適していないのかを説明しました。 次に、コネクショニストリストの時間的分類とは何か、それがどのように機能するのか、またなぜRNNが音声認識のようなタスクに取り組むことができるのかを説明しました。
「Long Life RailsApps」というテーマで登壇した話 (後編)

Reproさんのイベントで登壇させていただいた件の後編です。
ビシバシ振り返っていきます。

# スライド
[![thumbnail](http://image.slidesharecdn.com/reprotechlongliferailsapps-190206014652/95/slide-1-1024.jpg)](https://www.slideshare.net/yamasakidaisuke/long-life-railsapp-in-the-case-of-rejob)

# Problem

## マルチドメイン・シングルリポジトリでカオス
リジョブでは、「求職者向け画面」「企業向け画面」「リジョブ用管理画面」の3ドメイン体制で運用しています。
3ドメインですがデータベースは一つなので、Railsプロジェクトも一つで運用しています。

よくある構成なのですが、長期運用していると肥大化に次ぐ肥大化で雪だるま式にコードが増えていきます。
肥大化したコードは可読性が下がり、開発着手時に仕様を把握することに時間を取られ開発速度の低下を招きます。
また、3ドメインが絡むので必然的に複雑度も上がり、不具合の温床となりやすいです。

結果、コードに手を入れることに消極的になったり、工数見積がバッファ盛り盛りでスピード感が極端に下がったりします。
スピード感が出ないので人員を増強するも、複雑度が高いので思ったように進まずオーバーヘッドのみ増えていく。という負のスパイラルが発生します。

## 歴史が長く、属人化しているので仕様変更がきつい
LongLifeという名の通り、8年ほど運用していますので過去の仕様に引きずられることが多々あります。
また、ドキュメントも細かいものは無く、動作しているコードから読み解いていくという地道な手順が各工数にのしかかってきます。
当時のコードや経緯を知る人がほぼ居ないのでコードも正しいのか判断できない場合もあります。
そういう時は現状に合わせて一部作り直したりと、地味に工数が膨れていきます。

## テストのカバレッジが極端に低い
ソースコードの量が多いというのもありますが、10%程度だと思います。
主要なところは押さえているのでなんとかなっていますが、テストが無いところに手を入れる恐怖感は拭えません。

## 見積もりの精度を上げられない
いくつかのProblemをまとめると、見積もりやスケジュールの話になります。

- ドキュメントが散らかりまくり
- 当初の要件が不明なので設計が理解不能
- 暗黒期のコードが理解不能

自然に難読化されたコードが点在するため、思わぬ落とし穴があります。
読みづらい、理解しづらいコードはリファクタリングをしましょう！

## 決めたルールを守り、守られているかチェックする機構がない
コーディング規約を守っているか？決めた仕様通りの実装になっているか？

現在は上記のようなチェックをコードレビュー時に行っています。
しかしレビュアーも実装者であるため、まとまった時間を確保できない場合の方が多いです。

そうすると、必ずと言っていいほど漏れが発生します。
この漏れに気づかずにいると、漏れた箇所を参考に新しい機能が作成されたり、仕様の不具合が発生する場合があります。

仕様の不具合はかなり深刻で、障害として通知が来る訳でも無く、
「なんかおかしい...」「変なデータが飛んでるんだけど？」といった声でようやく気付くので、
機会損失額が大きくなる傾向にあります。

## 保守に対してコストを割きづらい
自社サービスではよくある話ですが、施策に対して投資という側面があるのでリファクタリングやテストといった保守施策に手が回りにくいです。
障害が出た時に初めて問題を認識し、対策を練ろうとしますがその時にはコストが膨大に...というのはそう先の未来ではないと思います。

## ビジネスロジックに対する学習コストが高すぎる
200近いテーブルを駆使したビジネスロジックを把握しておくのは人間の脳では限界があります。
新しくエンジニアを採用しても学習するのに2ヶ月〜3ヶ月は学習のためパフォーマンスが50%以上下がる傾向にあります。

## 部分的に疎結合なアプリケーションがあったりして忘れる
これもあるあるですが、Wordpressをリバースプロキシで表示している場合など、メインリポジトリに入っていないので忘れます。リリースしてから気付くのでバタバタしてしまうので注意が必要。

## Gemを大量に使っていて身動きが取れない
Railsあるあるです。Gemfileが300行ぐらいあります。
絶対使っていないgemが紛れています。


# Try
イベントでは時間があまり無かったので懇親会で知見を溜めるというtryにしましたが、まじめに振り返ります。

## ドキュメントに向き合う
ドキュメントが無いと何が正しいのかわからない。何が正しいのかわからないのでテストが書けない。
テストが書けないから不安になる。見積もりも曖昧になるし、動作確認コストが跳ね上がる。

ドキュメントは偉大だったという話です。
という訳で、ドキュメントとの向き合い方は、二通りあると考えられる。

1. 常に向き合う
2. 何か大きな変更を加える時だけ向き合う

### 常に向き合う
サービス要件定義書、仕様書、設計書、画面遷移図、ガイドライン、画面操作手順書、etc...
をまとめる人や、チームを据えて品質管理部門として置く。

### 何か大きな変更を加える時だけ向き合う
例えば、メイン機能のリニューアルや、全体的なリプレースの際に、現状をまとめたドキュメントをまとめて作る。
そこから変更点を加えていき、要件定義書としたり仕様書として活用していく。

### どっちが良い？
スポットでの対応が安く済む。
常に向き合う方はかなりのコストと担当者の熱量が必要。

個人的には、常に参照できるドキュメントがあるだけで開発スピードの向上や、
ブラックボックスに手を入れなくて済むという安心感を得られるので常に向き合いたい。


## まとめ
サービスが大きくなってから慌ててドキュメント整備やテスト作成を行うのは本当に大変です。
ドキュメントを書く文化やテストを書く文化を取り入れるなら早い段階の方がハードルが低いです。
初期段階なら記述量も大したことないはずです。ほんの少し手間をかけるだけで引き継いだ人の苦労が変わります。

自分がもし初期段階からジョインできるサービスが今後あるなら、
土台をしっかりと作っていきたいと心から思うようになりました。
Rails 5.2 & WebpackerにBulmaを導入する

# 環境

- `Rails 5.2.2`
- `ruby 2.5.1p57`
- `psql (PostgreSQL) 10.4`

# 前提条件

本記事では、Rails、ruby、PGのインストールの内容を含みません。

- ruby のインストールは、[こちら](https://qiita.com/Alex_mht_code/items/d2db2eba17830e36a5f1)の記事がわかりやすかったです。
- Ruby on Rails のインストールは、[こちら](https://qiita.com/yoshiokatsuneo@github/items/d75d4fef9e75afb65126#rails%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)の記事がわかりやすかったです。


[Rails 5.2 で簡単なWikiサイトを作る - Part1](https://qiita.com/fukmaru/items/625845471df2110cc718) の続きです。
ここで作ったアプリにBulmaを入れて行こうと思います。

## Bulmaってなんですか？

[Bulma](https://bulma.io/)は、FlexboxをベースとしSassで構築された無料のオープンソースCSSフレームワークです。モジュールされており、使いやすいです。無料で利用可能です。

無料のCSSフレームワークでは、Bootstrapがかなり有名ですが、BulmaではJavaScriptを含まないところが大きな違いかと思います。Bootstrapでは、jQueryが必須だったりします。

早速RailsアプリケーションにBulmaを導入していきたいと思います。

## はじめに

[git commit log](https://github.com/fukmaru/wiki/commit/c2caeb8ecdb35965f36fb86deefe40fc9677e200)

# bulmaをインストール

`yarn` でbulmaを入れていきます。

```bash
$ yarn add bulma
```

`./package.json` はこんな感じです。

```js:./package.json
{
...
  "dependencies": {
    "@rails/webpacker": "^4.0.2",
    "bulma": "^0.7.4",
    "normalize.css": "^8.0.1"
  },
...
}
```

# bulma を読み込む

```css:./frontend/init/index.css
@import "normalize.css/normalize.css";
+ @import "bulma/css/bulma.css";

body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 16px;
    line-height: 24px;
}
```

## 確認してみる

ボタンを入れてみます。
<https://bulma.io/documentation/elements/button/#colors>

```erb:./app/views/pages/home.html.erb
<%= render "components/page/page" do %>
  <p>Wiki Top Page</p>
+   <a class="button is-primary">Primary</a>
+   <a class="button is-link">Link</a>
+   <a class="button is-info">Info</a>
+   <a class="button is-success">Success</a>
+   <a class="button is-warning">Warning</a>
+   <a class="button is-danger">Danger</a>
<% end %>
```

<http://localhost:5000/>


こんな感じに表示されます。

<img width="941" alt="スクリーンショット 2019-04-29 11.16.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263973/9e01307f-6cdc-f2e5-8b16-51fe284eb2fd.png">


# 最後に

[git commit log](https://github.com/fukmaru/wiki/commit/c2caeb8ecdb35965f36fb86deefe40fc9677e200)

# [NEXT!](https://qiita.com/fukmaru/items/cca06609157d2223af6f)

Contentテーブルを作っていきます。

# Wikiサービス作りました

(小さく告知させてください:ear:)
簡単なWiki検索を、社内コミュニケーションチャネルから検索できるツールで、「[Poii.io](https://www.poii.io)」と言います。

Poii.ioの名前は、キーボード配列の右上 **P** -> **I** に向けて、押しながらスライドさせるくらい簡単に検索したかったので、POII.IOにしました。

「POI いいお」って感じの親父ギャクです・・・:eyeglasses:
Leetcode #114: Flatten Binary Tree to Linked List

```swift
func flatten(_ root: TreeNode?) {
    var current = root
    for num in preorder(root).dropFirst() {
        current?.left = nil
        current?.right = TreeNode(num)
        current = current?.right
    }
}

func preorder(_ node: TreeNode?) -> [Int] {
    guard let node = node else {
        return []
    }
    return [node.val] + preorder(node.left) + preorder(node.right)
}
```
「argc」と「arvg」の違い

#はじめに
こんにちは。
私は、現在未来電子テクノロジーでインターンを行なっている大学４回生です。
今回は、「argc」と「arvg」の違いについて理解した部分をお話しします。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#「argc」と「arvg」とは
それぞれは、略されています。
「argc」は、argument count、つまり、引数の個数です。
「arvg」は、argument vector、つまり、引数の配列です。
つまり、引数文字列の「配列へのポインタ」です。
「ポインタ」というのは、変数の格納場所を示す変数のことです。
例えば、ある人の住所を知っていて、それを「ここ」と示す人のことを言います。

#実行例

```php
<?php
if( $argc != 3 ){
    echo "数を指定";
    exit(0);
}
 
$num1 = $argv[1];
$num2 = $argv[2];
echo $num1+$num2;

```
コマンドラインから

```
php keisan.php 1 2
```

を記入すると、結果は３と出ます。

#まとめ
私自身、まだまだわからないことが多いです。
しかし、今回のような「argc」と「arvg」の違いのように１つずつ理解していこうと思います。

#参考文献
argc,argvは何の略？（コマンドライン引数の使用例）
https://edu.clipper.co.jp/pg-2-20.html
システムからの警報メールをElasticsearchで可視化する


システムが発行する警報メールがあるのだが、量が多くメーラーで逐一見るのが辛くなってきた。
Elasticsearchにログとして登録して検索、分析できるようにしようと思う。

# 環境
遊びで立てていたElasticsearch環境があったので、これを利用。
バージョンとかは以下。
構築方法とかは省略。

```
elasticsearch.noarch                   6.4.0-1  
filebeat.x86_64                        6.4.0-1  
kibana.x86_64                          6.4.0-1   
logstash.noarch                        1:6.4.0-1   
```

# 作戦
メールを受けるプラグインを探したところimapのプラグインがあったのでこれを利用。
[Logstash-imap input plugin](https://www.elastic.co/guide/en/logstash/6.4/plugins-inputs-imap.html)

警報メールの送信先用に1つアドレスを切ってそのアドレスに送られたメールをElasticsearchに蓄積する。

# やってみる
Logstashのconfファイルをいじる。
host、port、user、passwordあたりはメールサーバへの接続情報なので、特に迷わないはず。
メールBOXが溢れるのは嫌なので、deleteをtrueにして受信したメールをリモートから削除する。
check_intervalで受信行為の間隔を60秒に設定。
あと気になるところがあるとすればfetch_count(何件ずつ取得するか)、folder(受信ボックスの指定。デフォルトINBOX)くらいか。

```bash
input {
  imap {
    host => "pop3.xxxxx.jp"
    port => 993
    user => "test@xxxxxxxx.co.jp"
    password => "test-password"
    check_interval => 60
    delete => true
  }
}
```

警報内容はメール本文に記載されているのでこれをパース。
本文はmessageに格納されるので、良い感じに。
この例は構文の解析を/etc/logstash/patternsファイルに外だしで定義しているので、
これだけ真似しても動きません。messageに本文入るんだな。くらいで。
今回は使ってないですが、件名はsubjectに入るもよう。

```
filter {
  grok {
    patterns_dir => ["/etc/logstash/patterns"]
    match => { "message" => "%{ALARM_PATTERN}" }
  }
  date {
    match => ["time", "MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
    timezone => "UTC"
    target => "@timestamp"
  }
  if "_grokparsefailure" in [tags] { drop {} }
}
```

できた。
![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139625/8fa49d54-556c-eb91-abbc-84e3c9761e82.jpeg)


# おまけ
folderで指定するのって本当にINBOXでいいの？
と思ったので、メールサーバにsshして確認したときのメモ。
INBOXで大丈夫そう。

```bash
openssl s_client -connect pop3.xxxxx.jp:993 -crlf -quiet
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2017 Double Precision, Inc.  See COPYING for distribution information.
a01 login test@xxxxxxxx.co.jp test-password
a01 OK connected to proxy server.
a01 list "" "*"
* LIST (\Marked \HasNoChildren) "." "INBOX"
a01 OK LIST completed
a02 select "INBOX"
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 556500305] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
a02 OK [READ-WRITE] Ok
```
nodejsでExpressをつかってLineボットを作成する

```javascript:index.js
const express = require('express')
const request = require('request')
const bodyParser = require('body-parser');
const crypto = require("crypto");
const app = express()
const port = process.env.PORT || 3000;

app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());
app.get('/', (req, res) => {
  res.send('Hello world')
})
app.post('/hook', function (req, res) {

  if (!validateSignature(req.headers['x-line-signature'], req.body)) {
    return;
  }

  const events = req.body.events;
  const userId = events[0].source.userId;
  const type = events[0].source.type;
  const message = events[0].message;

  if(type == 'user'){
    request.get( getProfileOption(userId), function (error, response, body) {
      if (!error && response.statusCode == 200) {
        const options = {
          url: 'https://api.line.me/v2/bot/message/reply',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}',
          },
          json: true,
          body: {
            'replyToken': req.body['events'][0]['replyToken'],
            'messages': [{
              "type": "text",
              "text": message.text + ' って言ったの？\n' + body['displayName'] + 'さん'
            }]
          }
        };
        request.post(options, function (error, response, body) {
          if (!error && response.statusCode == 200) {
            console.log('success');
          }
        });
      }
    })
  }
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

function getProfileOption(userId) {
  return {
    url: 'https://api.line.me/v2/bot/profile/' + userId,
    json: true,
    headers: {
      'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}'
    }
  };
}
function validateSignature(signature, body) {
  const hmac = crypto.createHmac('sha256', process.env.LINE_CHANNEL_SECRET);
  const data = new Buffer(JSON.stringify(body), 'utf8');
  const result = hmac.update(data).digest('base64');
  return signature == result;
}
```
サイボウズOfficeのメッセージ作成を効率化する

#はじめに
　[サイボウズOffice](https://office.cybozu.co.jp/lp/groupware/)に毎日日報を書く必要があるんですが、いちいち打つのめんどくさい・・・やる作業はこんな感じ。

- タイトルを入力
- 本文を入力
- メッセージの宛先に全員を指名（これはボタンを押すだけ）
- 送信ボタンを押下

そこでjavaScriptを使って手っ取り早くしました。

#環境
- macOS
- chrome

#数式
spreadsheetの表に以下を貼り付けてください。

="document.getElementsByName('Subject')[0].value = '"&*B4*&"';document.getElementById('Data').value = '"&substitute(*B15*,char(10),"\n")&"';document.getElementsByClassName('vr_stdButton')[4].click();document.getElementsByClassName('vr_hotButton')[0].click();"

※セルを指定している箇所は好きなセルに置き換えてください。
何しているかを順番に。

###document.getElementsByName('Subject')[0].value=
タイトルへ入力する値の設定コードです。
###document.getElementById('Data').value=
本文へ入力する値の設定コードです。
###substitute(*B15*,char(10),"\n")
本文は改行が想定されるため、改行を一律"\n"に置換しています。これでサイボウズOfficeに貼り付けたときも改行が保存されています。
###document.getElementsByClassName('vr_stdButton')[4].click();
宛先追加です。サイボウズOfficeでは初期状態、全員が選択されているため、ボタンを押すだけで全員を宛先に指定することができます。
###document.getElementsByClassName('vr_hotButton')[0].click();
送信ボタンを押下します。

#実行
1. spreadsheetに必要事項を入力して、表示されたコードをコピーしてください。
2. サイボウズOfficeのメッセージ送信画面を開き、デベロッパーツールを開きます。

<img width="1280" alt="スクリーンショット 2019-04-29 10.43.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172695/2189bead-45b0-cfc4-952b-2f6f3de43f64.png">

3. Consoleというところにコピーしたコードをペーストすれば、javaScriptが実行されてメッセージが送信されます。

<img width="555" alt="スクリーンショット 2019-04-29 10.47.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172695/0fc1d78a-7295-0b95-9373-034857958783.png">

　これでspreadsheetにいつも書く内容を保存しておくことができ、また日付なども自動算出できるようになります。
　日々のルーティーンは少しでも削っていきたいですね。
expressにJWTを導入してみた


入社研修でツイッターのクローンアプリを作って、その時に初めて使った技術についてまとめていきたい

今回はjwtについて色々書いていきます。
ほとんどJTWとは？みたいな話で、実際に使ってみた的な内容ではありません。


## JWTとは
jwt(ジョット)とは、JSONに電子署名をして、URL-safeな文字列として表現したものです。
電子署名されているので改ざんされているかが検知できるようになります。

## JWTの構造
jwtはHeader、Payload、Signatureの三層構成でできています。
一つづつ解説していきます。

### Header
どんな方法でハッシュ化されるかとかが書かれている場所


```
{
  "alg": "HS256",
  "typ": "JWT"
}
```
上のオブジェクトは適当に発行したJWTのHeaderです。
HS256っていう暗号化アルゴリズムを使ってハッシュ化しますよーってことが書かれている。
typはトークンのタイプを指定している。特に指定する必要がなければデフォルトのJWTでおっけー

jwtのクレームには予約済みクレーム名とパブリッククレーム名、プライベートクレーム名の三種類がある。

### Payload
有効期限とかユーザーIDとか、クライアントとサーバーで共有したい情報を入れる場所
#### 予約済みクレーム名
node.jsで使う時の指定法も一応入れた

| クレーム名 | 説明            | nodeで使う時    |
| ----- | ------------- | ----------- |
| iat   | tokenが発行された時間 | デフォルトで勝手に入る |
| exp   | tokenの有効期限    | expiresIn   |
| iss   | token発行者の名前   | issuer      |
| aud   | どのクライアント向けに発行されたトークンであるかの識別子    | audience    |
| jti   | トークンの固有 ID    | jwtid       |
| sub   | ユーザーの識別子      | subject     |
| nbf   | JWTが有効になる日時   | notBefore   |


#### パブリッククレーム名
[ここ]([url](https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html#ReservedClaimName))から引用
>クレーム名は JWT の利用者によって自由に定義することができる. しかしながら, 衝突をさけるために, いくつかのクレーム名は IANA JSON Web トークンクレームレジストリ Section 9.1 に登録するか, 耐衝突性を持つ名前空間を含むパブリック名にすべきである (SHOULD). それぞれの場合において, 名前あるいは値の定義者は, クレーム名を定義するために用いる名前空間の一部が自身の管理下にあることを保証できるよう, 妥当な措置を講じる必要がある.


#### プライベートクレーム名
 [ここ]([url](https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html#ReservedClaimName))から引用
>JWT の作成者および利用者は, 相互に同意のもとで, 予約済クレーム名 Section 4.1 でもパブリッククレーム名 Section 4.2 でもないプライベートクレーム名を用いてもよい (MAY). パブリッククレーム名とは異なり, プライベートクレーム名は衝突の可能性があり, 慎重に使用する必要がある.

### Signature
HeaderとClaimをハッシュ化したもの。

サーバサイドでしか知らないシークレットキーでハッシュ化する為、HeaderとPayloadの内容が推測できたとしても、Signatureを第三者が生成することは不可能である。サーバサイドではクライアントから送られてきたtokenのSignatureを検証することで、そのtokenが改ざんされているかどうかを判定することができる。



### まとめ
こんな感じですね。
まだまだ理解が甘いところがあるので、実務で実際に使っていって理解を深めていきたいなーと思います。
MacのXAMPPでphpMyAdminにアクセス

Macで[XAMPP](https://www.apachefriends.org/jp/index.html) (VM版)を使った場合の`phpMyAdmin`への接続方法をまとめました。
デフォルトだと`phpMyAdmin`はダッシュボードから直接接続できないのでその対処法です。

![スクリーンショット 2019-04-29 10.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183420/3db8ab80-890e-3fff-b09c-27ad3769b3c8.png)

## バージョン

```config:環境
XAMPP 7.3.4
PHP 7.3.4
Apache 2.4.39
MariaDB 10.1.38
Perl 5.16.3
OpenSSL 1.0.2r (UNIX only)
phpMyAdmin 4.8.5
```

# ホストからアクセス

`XAMMP`の`Network`設定からポート8080を解放してあげる必要があります。
![スクリーンショット 2019-04-29 10.30.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183420/ffbea22a-15cc-d8d6-53b6-12969b22d7d7.png)

これで`http://localhost:8080/phpmyadmin/`から接続できます。

# 外部からアクセス

まずホストマシンで`opt/lampp`をマウントします。
![スクリーンショット 2019-04-29 10.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183420/659b5f86-f996-1d7f-3f86-9ed02b242fe2.png)

次に、`opt/lampp/etc/extra`[^1]を開きます。
その中の`httpd-xampp.conf`を開くと、17行目あたりに下の記述があるはずです。

```config:httpd-xampp.conf
# since XAMPP 1.4.3
<Directory "/opt/lampp/phpmyadmin">
  AllowOverride AuthConfig Limit
  Require local
  ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
</Directory>
```

そして`Require local`を`Require all granted`に書き換えます。


```config:httpd-xampp.conf
# since XAMPP 1.4.3
<Directory "/opt/lampp/phpmyadmin">
  AllowOverride AuthConfig Limit
  Require all granted
  ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
</Directory>
```

`Apache`を再起動するとアクセスできるようになるはずです。
![スクリーンショット 2019-04-29 10.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183420/f44fbca3-ccdb-f99f-6f93-a477f157dfba.png)



[^1]: VM版の場合、ターミナルなら`~/.bitnami/stackman/machines/xampp/volumes/root/etc/extra`からアクセスできる。VM版でない場合は`/Applications/XAMPP/xamppfiles/share/mysql`。
Leetcode #113: Path Sum II


```swift
func pathSum(_ root: TreeNode?, _ sum: Int) -> [[Int]] {
    var paths = [[Int]]()
    var path = [Int]()
    helper(root, sum, &path, &paths)
    return paths
}

private func helper(_ root: TreeNode?, _ sum: Int, _ path: inout [Int], _ paths: inout [[Int]]) {
    guard let root = root else {
        return
    }
    
    path.append(root.val)
    if root.left == nil && root.right == nil && sum == root.val {
        paths.append(path)
    } else {
        helper(root.left, sum - root.val, &path, &paths)
        helper(root.right, sum - root.val, &path, &paths)
    }
    path.removeLast()
}
```
CircleCIを使ってECRへイメージをpushする

[Cloudformationを使ったFargateバッチのデプロイプロセスについて考えてみた](https://qiita.com/nyasba/items/3697a248c60151e11af6)、でやりきれなかったECRイメージへのpushをCircleCIを使って自動化してみます。

CircleCIではAWS ECRを扱うためのOrbが用意されているため、これを使うのが便利そうです。
https://circleci.com/orbs/registry/orb/circleci/aws-ecr

コードはこちら。
https://github.com/nyasba/python-batch-fargate

## 設定

以下のファイルをリポジトリに追加して、一度ビルドを実行します。

```.circleci/config.yml
version: 2.1
orbs:
  aws-ecr: circleci/aws-ecr@4.0.1
workflows:
  build_and_push_image:
    jobs:
      - aws-ecr/build_and_push_image:
          account-url: AWS_ECR_ACCOUNT_URL
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          region: AWS_REGION
          repo: batch
          tag: circleci
```

CircleCIのJobの環境変数画面で4つ追加します

| 環境変数名 | 設定値 |
|:--|:--|
| AWS_ECR_ACCOUNT_URL  |  ECRのリポジトリURL<br>例: 1234567890.dkr.ecr.ap-northeast-1.amazonaws.com |
| AWS_ACCESS_KEY_ID  | アクセスキー  |
| AWS_SECRET_ACCESS_KEY  | シークレット  |
| AWS_REGION  | リージョン  例: ap-northeast-1  |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47589/9db6a311-f934-3b6a-5057-e44f227b40aa.png" width=70%>

## 実行

Orbで設定されていた処理が進んで、ECRへのイメージpushまでできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47589/76cd69c4-3743-ffa5-1f1b-64988b779252.png)

ECRの画面でもタグが表示されています。
<img width="744" alt="スクリーンショット 2019-04-29 10.10.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47589/714a6e76-3006-8633-ba64-5e16086d74c9.png">


CircleCIの環境変数の指定方法に慣れておらず、若干つまづきましたが簡単ですね。ありがたい。
Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile (LoadError)というエラーが出たときの対処法

## Introduction

`rails db:create` した際に発生した下記のエラー対処法。
あまりにもしょうもないミスをしてしまったため、自戒を込めて投稿！！

```bash

Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile (LoadError)
```


## 参考資料（今回は使ってません）

同様のメッセージで苦戦し乗り越えた方々。
今回は使用しませんでしたが、同じようなエラーでハマっている場合はご参考ください。

- Add `gem 'listen'` to the development group of your Gemfile (LoadError)問題
https://qiita.com/kentarothehusky/items/b9179151d12beb3dd6d9

- タスクを実行しようとしたらlistenがないとエラーが出た
https://www.tmp1024.com/programming/rails-task-error-missing-listen/


## 私の対処法

上記のURLからいろいろ試してみて上手く行かなかったため、ダメ元でGemfileの中身を確認したら `listen` がないこと確認。
下記のように `Gemfile` を編集し、 `bundle install` して終わり！！

```ruby

# 省略

group :development do

  gem 'listen'

end
```

ちなみにエラー文をよく読むと。。。書いてありました

```bash

LoadError: cannot load such file -- listen
```
 
## Conclusion

エラー文はよく読みましょう！！
Python + Seleniumでタスク管理画面のキャプチャを取得する

#はじめに
　タスク管理ツールとして[MammothProject](https://app.mmth.pro/)というタスク管理アプリを使用しています。
　さて、私の職場では日報が採用されており、やり残したタスクを書く項目があるのですが、~~なかなかめんどくさい~~のでタスク管理ツールのキャプチャを貼るようにしました。（後々webスクレイピングにしてもいいかもー）
　そこでやっぱり自動化ですよね。
　想定は

1. [ヘッドレスchrome](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)でMammothProjectにログイン
2. 自身のタスク一覧画面をキャプチャ

となります。

#環境
- Python 3.7.3
- mac OS Mojave

後、当コードの実行にあたって以下サイトを参照してSeleniumを実行できる環境を用意しています。
https://qiita.com/memakura/items/20a02161fa7e18d8a693

#コード

```python:taskCapture.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import configparser


# chromeを準備
def initDriver():
    # driverを定義
    options = Options()
    options.add_argument('--headless')
    return webdriver.Chrome(options=options)


# 設定ファイル取得
def getIniFile():
    iniFile = configparser.ConfigParser()
    iniFile.read('./config.ini', 'UTF-8')
    return iniFile


# ログイン
def login(driver,iniFile):

    # マンモスプロジェクトにログイン
    driver.get(iniFile.get('settings', 'URL'))
    driver.find_element_by_id('user_email').send_keys(iniFile.get('user', 'name'))
    driver.find_element_by_id('user_password').send_keys(iniFile.get('user', 'password'))
    driver.find_element_by_name('button').click()


# スクリーンショットを撮る。
def screenCaputure(driver, iniFile):

    # なんか狭かったので固定値を設定
    # page_width = driver.execute_script('return document.body.scrollWidth')
    page_width = 1400
    page_height = driver.execute_script('return document.body.scrollHeight')
    driver.set_window_size(page_width, page_height)
    driver.save_screenshot(iniFile.get('user', 'download'))


# メイン処理
def main():

    # chrome画面を準備
    driver = initDriver()

    # 設定ファイル取得
    iniFile = getIniFile()

    # ログイン
    login(driver, iniFile)

    # スクリーンキャプチャ
    screenCaputure(driver, iniFile)

    # 終了
    driver.quit()
    exit()


if __name__ == '__main__':
    main()


```

```config.ini
[settings]
URL : https://app.mmth.pro/mytask#/list

[user]
name     : （ログインするメールアドレス）
password : （ログインするパスワード）
download : （好きなディレクトリ）/タスク.png

```

#結果
できました。
<img width="216" alt="スクリーンショット 2019-04-29 9.53.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172695/d85738c5-d45d-da03-f8fa-e81583198d01.png">

画面の幅に改善点はあるものの、その他はいい感じ。
後Pythonを初めて触ってみましたが、手軽にかけていい感じー。
【初心者用】 ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to ...

####トラブルメモ
---
```
$ git push origin master
``` 
を実行すると、

```
! [rejected] master -> master (non-fast-forward) error: failed to push some refs to ...
```
 というメッセージが出てpushできない。


色々調べたが、結局、下のコマンドだけで事足りた。

```
$ git reflog
```
コミットしたログ履歴表示

```
$ git reset --hard 'HEAD@{ｘｘ}'
```
履歴から選択した番号をｘｘに入力し、状態を戻す

```
$ git push origin master --force
$ git push heroku master --force
```
強引？にpushする。

今の状態でよければ、下の2つだけで。
MYSQLで「重複行のデータ数」を取得する

SQLといえばSELECTとWHEREが使える程度のSQL初心者の私が、HACKERRANKでSQLの基礎を学んでいた時に直面した問題

> 以下のデータベースから「CITYが重複している行のデータ数」を取得せよ

**STATION テーブル**

|Field |Type|
|---|---|
|ID|NUMBER|
|CITY|VARCHAR|
|STATE|VARCHAR|
|LAT_N|NUMBER|
|LONG_W|NUMBER|

...やばい　意外とわからんかも

### ステップ1 まずは普通のCOUNTのおさらい

SQLで行数を知りたいときは`COUNT(カラム名)`を使う
今回の場合、全ての行数を知りたければこれ

```sql 
SELECT COUNT(CITY) FROM STATION
```

次に「重複していない行数のみ」を知りたい場合、`COUNT(DISTINCT カラム名)`を使う
今回の場合は以下

``` sql
SELECT COUNT(DISTINCT CITY) FROM STATION
```

やりたいこととしては、単にこの差が取りたいだけなんだけど、、、どうやってとればいいんだろう、、、
なんかSQLlってUSER定義の変数指定できたよね？　変数に代入して　えーっとえっと、、、


### ステップ2 素直に引き算する

ごちゃごちゃ考えるまでもなかった　以下でいい

``` sql
SELECT COUNT(CITY) - COUNT(DISTINCT CITY) FROM STATION
```

そう、COUNT関数で得られる値は普通の数字なのでselect文の中で引き算ができる（逆になぜ気づかなかった）
SQLマスターまでの道のりはまだまだ遠そうです、、、
HTMLで構築できるCMS「Vapid」を触ってみた Part1

# What's Vapid
> Vapid is an intentionally simple content management system built on the idea that you can create a custom dashboard without ever leaving the HTML.
https://www.vapid.com

HTML上でほとんどの構築が行えるシンプルなCMSとして登場した「Vapid」ですが、
日本語の情報がほとんど見当たらなかったため、実際に触ってお試ししてみました。
*※Vapid歴１日の時点で記事を書いておりますので、多少の理解不足には目を瞑ってください:bow_tone1:*

# Getting Started
ドキュメントを見よう見まねで進めると、ものの数分で導入が行なえます。
https://docs.vapid.com

```zsh
npm install -g @vapid/cli
``` 
*※node 8.9.0以上の環境が必要ですので `node -v` で確認しておきましょう。*


```zsh
vapid new path/to/project/folder
```
プロジェクトを任意の場所に作成します
筆者環境では `vapid new ~/desktop/project/vapid-test` として作成しています。


```zsh
cd ~/desktop/project/vapid-test
vapid start .
```
作成したフォルダ内へ移動し、 `vapid start .` でデフォルト機能のサーバーを立ち上げます。


```zsh
vapid start .
==> Starting the development server...
==> Watching for changes in /Users/hogehoge/Desktop/project/vapid-test/www
View your website at http://localhost:3000
```
たったこれだけで開発用サーバーの準備が整いました:sunglasses:
早速 `http://localhost:3000` へアクセスしてみましょう！

# How to use
`localhost:3000` へアクセスすると下記のようなページが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/7a642374-9630-3857-afdc-51049e704255.png)

いかにもテンプレートタグらしき怪しいメッセージが表示されていますね:thinking:
`HELLO,{{VAPID}}`
環境を整えたところで、早速CMSとしての機能を確認してみましょう。

LOGINボタンをクリックするとダッシュボードへのログインを求められますので、
あらかじめ登録しておいたEメールアドレス・パスワードでログインをします。
*※登録していない方は[トップページ](https://www.vapid.com)から登録してください！*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/7a367f33-eb7e-62f7-9441-cf3195fdb27a.png)
ログイン後の画面には「**Greeting**」「**Background Image**」の項目がありますね。
今回はGreetingを例に、内部の仕組みを説明していきます。
Greetingへ適当な文字(今回は MAYOMAYO)を入力して「Save」を押すと...。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/c5bfddca-9c80-c10d-c102-2f35ebc3ed24.png)
トップページのメッセージが以下の通りに変化しました！

```text
HELLO,{{VAPID}}  //変更前
HELLO,MAYOMAYO   //変更後
```

該当エリアのコードを確認してみましょう。

```html:/vapid-test/www/index.html
<header class="header" style="background-image: url({{background_image type=image tag=false required=false}})">
  <h2>A New Site</h2>
  <h1><span>Hello, {{vapid label="Greeting"}}</span></h1>
  <div class="container">
    <p>This template already has few tags—visit the dashboard now to edit their content. And when you're done, <a href="https://docs.vapid.com/content-types" target="_blank">add your own content tags</a>.</p>
    <p><a href="/dashboard" class="login button">Login</a></p>
    <p><small>Lastly, submit the contact form below.</small></p>
  </div>
</header>
```
h1タグ内に `{{vapid label="Greeting"}}` という見慣れないコードがありますが、
これがVapidのテンプレートタグになります。
もう少し単純な書き方にして、項目を増やしてみたいと思います。

```html
<h1><span>{{Greeting}},{{YourName}}</span></h1>
```

htmlを変更したから管理画面上でも入力エリア作らないとなぁ...:thinking:
そんなことを思うかもしれませんが、Vapidでは勝手にエリアを作成してくれますので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/36b365d9-5e82-aee7-f298-bc75385c0b22.png)
htmlを保存して上記のように入力するだけで、簡単に表示することができちゃいます:wink:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/2e9f4b5d-9269-8fc1-89da-1a9d122a9ede.png)

今回はVapidの環境構築から簡単な編集作業について解説をしました。
Part2では、Vapidに用意されている様々なコンテンツを紹介していきたいと思います！
(現在勉強中ですのでしばしお待ちを:wink:)
【Unity(C#)】もちろん俺らは抵抗するで？コブシで！(Viveのコントローラーを使ってコブシで抵抗する方法)

##VR空間内でコブシで抵抗する
怖い人(〇学生)に絡まれたとき、みなさんはどうしますか？
コブシで抵抗しますよね。
VR空間でも同じことが言えます。

##再現したい手の動き
![kobushide.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/0867eca0-32c5-fc50-782a-9f0a9f9db307.jpeg)

このように手をよくわからない開き具合にしたいです。

##入力を0~1で受け取る
Viveのトリガーの入力自体はbool値で受け取れるので、
大体のコンテンツはbool値でAnimationが遷移するような作りになっていると思います。

bool値を使った方が簡単ですが、
ゆっくり手を握ったり、手の開き具合を途中で止めることはできません。

そこで、今回はトリガーの入力を0~1の値で受け取る方法で実装します。
※**何もしていない状態を0、完全にトリガーを引いた状態が1**として入力具合を数値で受け取ります。

##準備
まず、手のモデルを拾ってきましょう。
[こちらのサイト](http://zabaglione.info/archives/829)を参考に手のモデルだけ回収します。
アニメーションも入っているので最高です。


あとは`SteamVR plugin`を入れるだけです。
必要なものは揃いました。


##Hierarchyの設定
`SteamVR`から`[CameraRig]`、`SixenseInput`から`Hand`
というPrefabをそれぞれ持ってきて配置します。
![cameraRigHierarcy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/77c4f47a-6c04-2b01-d2f5-1745de58fc13.png)

`[CameraRig]`のModelは消します。


##AnimatorControllerの設定

StateとTransitionはこんな感じです。
holdRateというFloatのParameterを設定します。
![AnimeConHand.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/083880d7-1ae6-9bf6-aa09-7f636bbbeffa.png)


`Default`->`Hand`のTransitionのConditionにhandRateを設定します。
値は0.1です。
![Transition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/19269f8f-9a49-c022-5bdd-36ca34c25365.png)

HandStateに`IdletoFist`というAnimationを設定します。
![HandState.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/40974ed5-c823-be49-bf10-2b9d0c7fa456.png)

以上で準備完了です。


##コード

```C#:Handにアタッチ
using UnityEngine;
using Valve.VR;

public class InputTest : MonoBehaviour
{
    public SteamVR_Input_Sources handType;

    public SteamVR_Action_Boolean inputActions;

    public SteamVR_Action_Single inputActionSingle;

    Animator holdAnime;

    float squeezeVal;

    void Start()
    {
        holdAnime = this.gameObject.GetComponent<Animator>();
    }

     void Update()
    {
        // トリガーの値（0 ～1）
        if (inputActionSingle != null && inputActionSingle.GetAxis(handType) != 0f)
        {
            squeezeVal = inputActionSingle.GetAxis(handType);
            ControllerInputSingle();
        }
    }

   
    //コントローラの入力(0~1)　
    void ControllerInputSingle()
    {
        holdAnime.SetFloat("holdRate", squeezeVal);
        holdAnime.Play("Hold", 0, squeezeVal);

        float animeSpeed = holdAnime.speed;

        if (holdAnime.GetFloat("holdRate") < 0.1)
        {
            holdAnime.speed = 0;
        }
        else
        {
            holdAnime.speed = animeSpeed;
        }
    }

}

```

　　
![HandZeroOne.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/9b18feb2-aee3-762c-0a93-b67bbbd9e8a0.gif)


これでVR空間で怖い人(〇学生)に絡まれても安心ですね。
micro:bitのブロックコードとRaspberry Pi ZEROでIoTしてみた

# 概要
参考リンクをもとにマイクロビットをIoTデバイスとして、明るさ、温度、micor:bitの姿勢（ピッチ角）を計測してみた。マイクロビットのもつ、Bluetoothを使って、取得情報をラズパイZEROのBLEで受信させ、AmibientというIoT可視化サイトにUploadしているだけです。基本的には、参考リンクの内容をトレースしただけですが（苦笑）。マイクロビットで取得したデータをクラウドにUpできる（５秒間隔）ことは、今後の開発には幅を与えてくれると思います。

# IoT取得情報【予告なく計測を停止ことがあります】

- [マイクロビットは窓際に置いています](https://ambidata.io/ch/channel.html?id=10983&private=true)　※2019.05.26 研究室に移設しました。
- 2019.04.28 一日3000件の書き込み制限でAM9:54頃に書き込みがNGになりました。
- 2019.04.29 30秒間隔に修正しました。
- 2019.04.30 DHT11という温度湿度センサーを接続し計測することにした。光センサーはmicrobitのセンサを使用。詳細は別のページに掲載
 
# 公開コードと修正部分

- [発信用マイクロビットのコード](https://makecode.microbit.org/_U7y86rgfWWjj)
- [Ver2:発信用コード](https://makecode.microbit.org/_XDiWCK0xE6z2)
- [Ver3:発信コード：DHT11](https://makecode.microbit.org/_7bmJuU9qvcTi)
- [AmbientData社が公開しているコード：ラズパイで受信してAmbientにUpするためのコード](https://github.com/AmbientDataInc/EnvSensorBleGw/blob/master/src/gw_RPi/env2ambientBS.py)
- 上のコードのなかの変更部分
- 17,18行：チャネルIDとライトキーを自分のアカウントで作成したチャネル情報に併せて書き換える
- 25行:targetをmicrobit + BME280　に書き換えた
- サンプルは外部機器「BME280」で取得データを換算しているので、そこを修正。
- 91行： 行末の /10を削除
- 92行： 行末の　+400を削除

#参考リンク
- [【AmbientでIoTをはじめよう】micro:bitで温度データーをAmbientに送りグラフにする](http://mag.switch-science.com/2018/12/25/letsiot-13-14/)
Windows10 64bit + PIC Kit2 による PIC16F690 マイコン開発

#環境
Windows10 86x64
MPLAB X IDE v5.15
MPLAB XC8 v2.05
PIC Kit2 v2.61
PIC Kit2 PG Writer
PIC16F690

#手順
各種ソフトのインストール。
今回のインストールでは以下の順番だった。
順番が違えば内容が変わる可能性がある。

1. MPLAB XC8 v2.05
2. PIC Kit2 v2.61
3. MPLAB X IDE v5.15

MPLAB X IDEは、筆者の実行時はデスクトップにショートカットが作られなかったため、自前でショートカットを作った。たぶん寝ぼけていたのだろう。


#PIC Kit2 PG Writerの最新化。
PIC Kit2 v2.61を使用し、メニューのToolsより、Download PICkit2 operating systemで最新化する。
注意点として、PICkit2のドライバがインストールされている必要がある。
PIC Kit2 v2.61をインストールし、PIC Kit2を刺してすぐでは、インストールが終わっていない可能性がある。
筆者はMPLAB IDE 8.2を以前にインストールしていたため、ドライバはすでにあった。


#MPLAB X IDEとMPLAB XC8の連携の確認
MPLAB X IDEにてTools -> Options -> Embedded -> Build Toolsの内容が下記の通りになっているか。

Base Directory C:\Program Files (x86)\Microchip\xc8\v2.05\bin
C Compiler C:\Program Files (x86)\Microchip\xc8\v2.05\bin\xc8-cc.exe
Assembler C:\Program Files (x86)\Microchip\xc8\v2.05\bin\xc8-cc.exe


#ソースコードを書くにあたって
XC8なので、XC8に準じた書き方となる。
また、PIC16F690はC90時代のマイコンなので、注意。
コンフィグレーションワードの記述書式はXC8ユーザーガイドに載っている。
場所　C:\Program Files (x86)\Microchip\xc8\v2.05\docs
項目　Specifying Configration Bits
PICマイコンごとのコンフィグレーションについては別途あり。
C:\Program Files (x86)\Microchip\xc8\v2.05\docs\chips\16f690.html
データシートは公式からダウンロード可能。
PORTAやPORTCなどの以下略。


#プログラムの書き込み
プロジェクトをビルドして、プロジェクトのdistフォルダにある
[プロジェクト名].X.production.hex
というhexファイルをPIC Kit2 v2.61でImport Hexして、Writeで書き込む。


#結論
基板が経年劣化により物理的に壊れていたため、回路での動作が確認できなかった。
PIC16F690への書き込みに関しては、問題なく動作していることが確認できた。

以上
【Rails】herokuとAmazonS3を使って画像アップロードができない時の対処法

# やりたいこと
herokuとAmazonS3を利用して、本番環境に画像アップロードをしようと試みて、直面したエラーを解決する

# 使用しているGem

```
gem 'carrierwave'
gem 'fog'
```

# エラー内容の確認

本番環境だとエラーの状況がわかりづらいので、ログを確認します。

```
heroku logs -t 
```

すると、下記の`forbidden=禁止`の部分がエラーの原因のようだとわかりました。

```
2019-04-28T23:11:37.334290+00:00 app[web.1]: :port          => 443
2019-04-28T23:11:37.334292+00:00 app[web.1]: :reason_phrase => "Forbidden"
```

ステータスコード`443`が`forbidden`になっている時は、「アクセス許可権限」周りの設定が誤っている可能性が高いそうな。

## 参考
 
- [Amazon S3 コンソールを使ってファイルをアップロードするときに HTTP 403 Forbidden のエラーが発生するのはなぜですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-403-forbidden-error/)
- [Ruby on Rails チュートリアル 本番環境での画像アップロード](https://railstutorial.jp/chapters/user_microposts?version=5.1#sec-image_upload_in_production)

# 対処

アクセス許可をするべく下記の設定に変更

<img width="1297" alt="スクリーンショット 2019-04-29 8.58.05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331354/d80a8f2c-eeeb-7b0e-6948-555266b3feb9.jpeg">

無事、画像のアップロードが完了。

AWSのコンソール画面は、日に日に新しくなっているので最新バージョンのキャプチャを使用した記事がなく、意外と手こずってしまいました。
CodePenみたいな独立した環境を実現するVueコンポーネントを作った話


# はじめに

[今作ってるアプリケーション](https://github.com/sterashima78/vue-webpage-builder)でCodePenとかで使われているような iframeを使った独立した環境を作る必要があった。
探しても手軽に使えるものが見つからなかったので自作した。
アプリケーション内に入っていたがせっかくなので独立したパッケージにした。

# 作ったもの

[Github](https://github.com/sterashima78/vue-iframe)
[npm](https://www.npmjs.com/package/vue-iframe-sandbox)
[デモ (Storybook)](https://sterashima78.github.io/vue-iframe)

# ほしかったもの

- vueのコンポーネント
- 任意のjsとcssがiframe内に追加できる
    - jsなど追加時は再読み込みする
- body内に任意のコンテンツが差し込める
- コンテンツの再ロードが完了したタイミングをイベントで受け取りたい

# 技術的な話

## iframeの操作

iframe内の要素は基本的に直接DOMをいじるしかない。

iframe内のdocumentには以下のようにしてアクセスできる

```js
const iframe = getIframeElement() //任意の関数
const iframeDocument = iframe.contentWindow.document
```

documentが取れればあとはheaderやbodyも取れるので、好きな要素を追加すればいい

- 任意なスタイルの追加

```js
const style = "p {color: red;}"
const styleElement = document.createElemnt("style")
styleElement.innerHTML = style
iframeDocument.head.appendChild(styleElement)
```
JSもほぼ同様

- 任意の要素の追加

```js
const wrapperElement = document.createElemnt("div")
const p = document.createElemnt("p")
p.innerText = "hoge"
wrapperElement.appendChild(p)
iframeDocument.body.appendChild(wrapperElement)
```

## JSの読み込み

JSを読み込んで、そのJSファイルからグローバルオブジェクトを利用したい場合は以下のようにする。

```js
const script = document.createElement("script")
script.setAttribute("src", "https://code.jquery.com/jquery-3.4.0.slim.js") //jquery
const promise = new Promise(resolve => {
  this.bodyElement().ifPresent(body => body.appendChild(scriptElement))
  script.onload = () => resolve();
})
promise.then(()=>{
   const iframe = getIframeElement() 
   const jquery = iframe.contentWindow.$
})
```

ロード待ちに注意する必要がある

## コンポーネント使用例

[Storybook参照](https://sterashima78.github.io/vue-iframe/?path=/story/vue-iframe--live-editor)

ユーザの入力したHTMLを表示するなどして使うのでXSS対策などをコンポーネント内で行うことは適切でないと思った。
利用者側が責任を持ってエスケープなどすることを注意する。

## 終わりに

jestでユニットテストを書こうとしたがiframeをvdomがサポートしていないので素直な実装だと試験がしにくい。
今後この辺りを改善してテストを書いていくようにしたい。

[今作ってるアプリケーション](https://github.com/sterashima78/vue-webpage-builder)のコア部分とそうでない部分をパッケージレベルで分離することで、アプリケーションの構造を健全にすることも期待している。

このアプリケーションについても[簡単だが記事を書いている](https://qiita.com/sterashima78/items/3d53d0721565a824d5f8)ので、興味があれば見てみてほしい。
Automotive SPICE 3.0 実践ガイドブック　入門編　読み進め　２章

[Automotive SPICE 3.0 実践ガイドブック入門編](https://www.amazon.co.jp/dp/4822200566/)の読み進めです。
自分向けのノートとして記録します。

[１章　概要](https://qiita.com/kcha4tsubuyaki/items/ad80d693e8de74eddc4d)

# 2 基本的な構造と活用方法

## 2-1 基本的な構造
SPICEの目的は「プロセス改善」と「能力評価」。
以下２つの文書から成る。

- プロセス参照モデル（ＰＲＭ）
    - プロセスの目的や、達成するべき成果が書かれており、**開発プロセスを構築**する際の参考となる。
- プロセスアセスメントモデル（ＰＡＭ）
    - ＰＲＭで定義した目的、成果を**評価する仕組み**を定義している。

バージョン云々の話については割愛。

## 2-2 プロセス参照モデル（ＰＲＭ）の概要
合計32個のプロセスが定義されており、「プロセスカテゴリー（ライフサイクルプロセスカテゴリー）」、「プロセス群」で分類される。

例：

- SWE.4 ソフトウェアユニット検証：
    - 主要ライフサイクルプロセスカテゴリー、ソフトウェアエンジニアリングプロセス群。
- SUP.1 品質保証：
    - 支援ライフサイクルプロセスカテゴリー、支援プロセス群。

### 分類

- 主要ライフサイクルプロセスカテゴリー
    - サプライヤーから製品を得る際、または顧客へ納品する際のプロセス
        - 取得プロセス群：発注時に発注者が実施すべきプロセス
        - 供給プロセス群：サプライヤーが製品を供給する際に実施すべきプロセス
        - システムエンジニアリングプロセス群：システム開発プロセス
        - ソフトウェアプロセスエンジニアリング群：ソフトウェア開発プロセス
- 組織ライフサイクルプロセスカテゴリー
    - 事業目標を確立、達成するために必要なプロセス、成果物、資産を発展させていくためのプロセス
        - 管理プロセス群：プロジェクト管理上、重要なプロセス
        - プロセス改善プロセス群：プロセス改善のためのプロセス
        - 再利用プロセス群：開発された資産を再利用するための方針やシナリオを構築するプロセス
- 支援ライフサイクルプロセスカテゴリー
    - 開発ライフサイクルのあらゆる箇所で適宜利用される支援プロセス
        - 支援プロセス群

## 2-3 プロセスアセスメントモデル（ＰＡＭ）の概要
評価の仕組みを定義する、の一言で要約できるので割愛。

## 2-4 プロセスアセスメントモデル（ＰＡＭ）の詳細１
ＰＡＭではＰＲＭに定義した「プロセス目的」と「プロセス成果」に加えて、実施状況を評価する指標として**「基本プラクティス」**と**「作業成果物」**を追加している。

- 基本プラクティス（ＢＰ）
    - 実施すべきこと
    - 基本プラクティスの実行により、関連プロセスの成果を満足させられる
- 作業成果物（ＷＰ）
    - プロセスの実行により成果物が作成され、関連するプロセス成果を満足させられる。

## 2-5 ＰＡＭの詳細２
プロセス座標という二次元モデルが定義されていて、横軸には３２個のプロセスが並び、それぞれの能力値が縦軸にレベル０からレベル５まで存在する。（能力座標）

各レベルの詳細は以下の通り。太字で個人的な要約を付け加える。

- レベル５：革新している
    - 経験の宝庫：定量的なフィードバックを使い、改善活動が立ち上げられている
    - **レベル４の状態を元に改善も実施されている**
- レベル４：予測可能な
    - 定量的：効率、品質が適切かつ統計的に管理されている
    - **過去のプロセス実施の記録の数字を統計的に適切に利用できる（まとまっている）**
- レベル３：確立された
    - ベストプラクティスが選択されている
    - **レベル２に加え、適宜調整もなされる**
- レベル２：管理された
    - 作業成果物が手順に従い作成、計画、記録されている。
    - **ルール通りに行われ、記録もされている**
- レベル１：実施された
    - 直感的：要求された手法は取り入れているが、ＢＰが厳格に文書化／記録されていない。
    - **ルールは知っていてその通りに行っているが、記録を取っていない**
- レベル０：不完全な
    - 混乱：作業成果物が予測できない。
    - **何を作るかのルールが全くない**

ＰＡＭはISO/IEC 33020から「プロセス能力レベル」、「プロセス属性」、「達成成果」を引用しており、加えて「共通プラクティス」と「共通リソース」が追加されている。
共通プラクティス、共通リソースは文字通り、全プロセスで共通な定義だがプロセスの違いに伴う差異は存在する。

## 2-6 主要コンセプト
### 2-6-1 プラグインコンセプト
従来の、「システムエンジニアリング系プロセスはソフトウェアエンジニアリングへブレイクダウンするため」といった解釈でなく、Ⅴ３．０では「システムエンジニアリングは以下のドメインの上位概念」とする。

- メカ（ＰＡＭの範囲外）
- ハードウェア（エレキ）（ＰＡＭの範囲外）
- ソフトウェア（ＰＡＭの範囲内）

これにより、製品としての開発プロセスを俯瞰する。

### 2-6-2 設計系プロセスとテスト系プロセスの１対１対応
従来は

- ソフトウェアアーキテクチャ設計（ＥＮＧ．５）
- ソフトウェア統合テスト （ＥＮＧ．７）
- ソフトウェア詳細設計（ＥＮＧ．５）
- ソフトウェアユニットテスト（ＥＮＧ．６）

以上の項目で関連が横断（またがって）いた。
対して３．０では設計系とテスト系の１対１対応で位置づけの整合性をとった。
〇システム要求分析（ＳＹＳ．２）　　　　　＜＝＝＝＝＝＝＝＝＝＞システム適格性確認テスト（ＳＹＳ．５）
　〇システムアーキテクチャ設計（ＳＹＳ．３）＜＝＝＝＝＝＝＝＞システム統合と統合テスト（ＳＹＳ．４）
　　〇ＳＷ要求分析（ＳＷＥ．１）　　　　　　　＜＝＝＝＝＝＞ＳＷ適格性確認テスト（ＳＷＥ．６）
　　　〇ＳＷアーキテクチャ設計（ＳＷＥ．２）　　＜＝＝＝＞ＳＷ統合と統合テスト（ＳＷＥ．５）
　　　　〇ＳＷ詳細設計とユニット構築（ＳＷＥ．３）＜＝＞ＳＷユニット検証（ＳＷＥ．４）
Windows10上のNetbeans11.0の設定で出てこないフォントがある時の対処

いずれかを実行

1. フォントファイルの右クリックメニューで「すべてのユーザに対してインストール」でインストールする
2. 管理者権限で `cp RictyDiminished-Bold.ttf \windows\fonts` など
Rustのdiesel(r2d2)で初回DBに接続できなくても無視する方法

# 結論

`build_unchecked` で Pool builder を consume してあげる。

# 困っていたこと

Actix-web + r2d2 + diesel なんかを使ってよくある Web システムを作っている前提。
アプリケーション起動時にデータベースに接続に行くのだけれど、タイミングによっては接続に失敗する事もある。
データベースに接続できないからといって起動に失敗するのは困るので、とりあえずは無視をして処理を先に進めたい。
データベースの接続が必要になるまでに接続できていればよい。

```rust:接続に失敗すると先に進めない
use diesel::r2d2::ConnectionManager;
use diesel::PgConnection;
use r2d2::Pool;

fn main() {
// 略...
    let manager =
        ConnectionManager::<PgConnection>::new("postgres://postgres:password@localhost:5432/blog");
    let pool: Pool<ConnectionManager<PgConnection>> = Pool::builder()
        .build(manager)
        .expect("Failed to create pool");
// 略...
}
```

# 解消する

上のコードで `build` としているところを `build_unchecked` に変えてあげる。

```rust:接続に失敗してもとりあえず進む
use diesel::r2d2::ConnectionManager;
use diesel::PgConnection;
use r2d2::Pool;

fn main() {
// 略...
    let manager =
        ConnectionManager::<PgConnection>::new("postgres://postgres:password@localhost:5432/blog");
    let pool: Pool<ConnectionManager<PgConnection>> = Pool::builder()
        .build_unchecked(manager);
// 略...
}
```

# あとがき

このあたりのことをしばしば忘れてしまうので、自分用のメモとして残しています。
Rustは初心者なのでおかしな点があったらツッコミいただけると嬉しいです。
ローカルフォルダをGitHubにあげる

元々ローカルPC上で作成していた資産を
新規でGit管理にしてGitHubにあげる手順

```
# 対象のフォルダ（ディレクトリ）に移動する
$ cd hoge

# git init で ローカルリポジトリを作成する
$ git init
$ git add .
$ git commit -m "Initial commit"

# リモートリポジトリのアクセス先を設定する
$ git remote add origin https://github.com/GitHubのユーザ名/GitHubのリポジトリ名.git

# pushする
$ git push -u origin master

```