OmniAICreator/Qiita-1.07M huggingface dataset:
ボタンを条件に応じて非活性にする

#いきさつ
ボタンを非活性にする方法はいろいろあるものだなぁと思ったのでまとめておきます。

#非活性の条件
今回は非活性の条件を下記のようにします。

```ruby
CONDITION_DAY = 11
Date.today.day < CONDITION_DAY && hoge.blank?
#hogeは配列
```
今日の日付が1~10日であり、hogeに要素がない場合はボタンを非活性状態にします。

#html.erb

```erb

<%# クラスはbootstrapを使用した場合のもの %>

<%= link_to 'ボタンです', {controller: :hugas, action: :piyo}, class: 'btn btn-primary btn-block', id: 'submit-btn' %>
```


#css
bootstrapを使えばクラスに'disabled'を指定すれば非活性となりますが、
使用していない場合は次のcssを書くものとします。

```css

a.disabled{
    pointer-events: none;
}
```

#本題
###1. JavaScriptで制御する
とっても便利なgem、gonを使用した例です。
gonはコントローラーで

```ruby
#controller
gon.qiita = 'Qiitaに投稿します'
```
とするだけで

```js
//js
console.log(gon.qiita)
//　=>'Qiitaに投稿します'
```
のようにjavascript側で変数を取得できるようになります。

####クラスに`disabled`を追加して非活性に
`gon.condition`に真偽値をつめて・・・

```ruby
#controller
gon.condition =　Date.today.day < CONDITION_DAY && hoge.blank?
```
trueだったら`disabled`をクラスに追加
jQuery使用時の書き方してます

```coffee-script
#js.coffee
if gon.condition == true
  $('#submit-btn').addClass 'disabled'
```

素のjsだとこうなる

```js
//js
if(gon.condition === true){
  document.getElementById('submit-btn').classList.add('disabled');
};
```
`==true `や`===true`はなくてもOK。


####propで要素を追加する方法
propメソッドを使用する場合は`link_to`ではなく`button_to`にしてあげる必要があります。
そのうえで

```coffeescript
#js.coffee
if gon.condition
  $('#submit-btn').prop 'disabled', true
```

素なら

```js
//js
if(gon.condition){
  document.getElementById('submit-btn').prop('disabled', true);
};
```
で要素にdisabledを追加してボタンを非活性にすることができます。


###2.JavaScriptを使わない方法
タイトル通りです。
まずはコントローラーでインスタンス変数に条件の真偽値を詰めてやります。

```ruby
#controller
@condition = Date.today.day < CONDITION_DAY && hoge.blank?
```

次にlink_toの部分を下記のように書き換えます。

```erb
<%# html.erb %>
<%= link_to 'ボタンです', {controller: :hugas, action: :piyo}, class: "btn btn-primary btn-block #{ 'disabled' if @condition } ", id: 'submit-btn' %>
```
`@condition`がtrueなら、クラスにdisabledを追加。
また三項演算子でも書くことができます。

```erb
<%= link_to 'ボタンです', {controller: :hugas, action: :piyo}, class: "btn btn-primary btn-block #{ @condition ? 'disabled' : '' } ", id: 'submit-btn' %>
```


#感想
JavaScriptで書くのも楽しいけど、Rails単体で制御できるのはとっても楽。
「チェックボックスにチェックした時、ボタンを非活性にする」みたいな条件でなければ後者を使っていきたい。
こんな方法もあるよ〜っていうのがあれば教えてください。
#AR・#MR開発まとめ

AR・MR関連の調べ物と試作したもの、作った物のまとめ。


<!--
https://qiita.com/sator_imaging/items/34aa77cbafb54e4bb043
-->


- [ARCore](#arcore)
   - [環境光推定・光源推定（Light Estimation）](#環境光推定光源推定light-estimation)
- [ARKit](#arkit)
- [HoloLens](#hololens)
- [その他](#その他)





## ARCore


### 環境光推定・光源推定（Light Estimation）

- [ARCore とセルシェーダーと環境光推定](https://qiita.com/sator_imaging/items/3c72b53729e28a709feb)


   - <a href="https://www.youtube.com/watch?v=hkKt1A57K6o">【YouTube】Light Estimation with ARCore<br /><img src="https://i.ytimg.com/vi/hkKt1A57K6o/mqdefault.jpg" /></a><br />




## ARKit

- [ARKit 3 気になったところ（WWDC 2019）](https://qiita.com/sator_imaging/items/c6664d544eae9926afc4)



## HoloLens

- [Azure Kinect DK と HoloLens 2 気になったところ](https://qiita.com/sator_imaging/items/114cc54d445c9b51ed2e)




## その他


- <a href="https://www.youtube.com/watch?v=bR1XX4-cgPA">【YouTube】アイドルコネクト AR（仮<br /><img src="https://i.ytimg.com/vi/bR1XX4-cgPA/mqdefault.jpg" /></a><br />
Docker for Macで重たい処理を実行時にメモリ制限に引っかかる

Docker for Macで重たい処理を実行したときに急に `Killed` とかになって「あれれ？」となったので調査したログ。

こけたところは `pip` で重ためのライブラリをインストールしている箇所であった。

```
pip3 install torch
Collecting torch
  Downloading https://files.pythonhosted.org/packages/ae/05/50a05de5337f7a924bb8bd70c6936230642233e424d6a9747ef1cfbde353/torch-1.3.0-cp36-cp36m-manylinux1_x86_64.whl (773.1MB)
    99% |############################### | 773.1MB 9.8MB/s eta 0:00:01Killed
```

色々と調査した結果、メモリ不足でOOM Killerで殺されていると判明。

Docker for Macはデフォルトでメモリ制限が2Gになっている。
Docker runする際に --memory(-m) ではメモリの制限が指定できないらしい。
ref: http://yut.hatenablog.com/entry/2019/04/29/210352

ということで、Docker for Macの `Preference` から `Advanced` でメモリの制限量を増やすことで解決できた。

めでたしめでたし。
最急降下法について

#最急降下法とは
最急降下法とは、目的関数Jを最小化するアルゴリズムです。線形回帰だけではな
く色々な機械学習のモデルで使うことが出来ます。

例えば、以前の記事「線形回帰・最小二乗法について、と、その具体例」で導入した誤差二乗の関数も目的関数の１つでした。

![関数２.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/ee05adeb-ae6e-a7a8-b687-a449b6369808.png)

変数が１つだけの時は横軸に変数、縦軸に目的関数Jをとり点をプロットするなどして比較的簡単に最適解を求めることが出来ましたが、パラメータが２つ、３つ・・・と増えていけば最適解を求めることは容易ではなくなります。そこで、最急降下法という方法を使います。

※誤差二乗、変数が１つの時の話は「線形回帰・最小二乗法について、と、その具体例」（https://qiita.com/aogyt/items/94b0b503a1b5bb5d3485 ）で説明しています。

#視覚的なイメージ
最急降下法は関数の最小値を求める方法ということですが、具体的にはどのような方法なのでしょうか？

![立体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/323eb92c-5643-05d1-089c-5692b3522a85.png)

この図は目的関数とパラメータの関係を表しています。横軸、縦軸に１つずつパラメータが割り当てられ、高さで目的関数の値を表しています。つまり赤い所は目的関数の値は大きく、青い所に行けば行くほど目的関数の値が小さくなる、つまり最適化されるということです。

もちろんこのような立体的な図は見やすいのですが、毎回書くのは大変なので下のような等高線図というものを用いるときもあります。

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/b03e6c4e-4e61-5865-b0a4-cc334891f118.png)

地図と同じように同じ高さの所を線で結んだ図です。ここでも先ほどの立体的な図と同じように真ん中の青い部分に行くにつれて目的関数の値は小さくなっていきます。この記事ではこの等高線図を主に使うことにします。

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/35269afa-dfb0-8b0d-f21c-a3d6df62b94d.png)

あなたが☆の所にいるとします。そしてなるべく低い所に行きたい、そういう場合にはどうすれば良いでしょうか？多分あなたはこのように傾きが一番急な坂を下るでしょう。

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/6c4611d2-e53c-ed7d-e690-661b7d82eef9.png)

そしてある程度下ったところでまた一番急な坂を探して下る。

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/5912e902-1001-a806-c6b0-5b4cc77b56ab.png)

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/34383f1a-fc65-6a67-8005-6dc5df2ea804.png)

![等高線.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/1b90f117-edb2-20f3-87df-02ef699ee873.png)

これを繰り返していけばいつか一番低い所にたどりつくような気がします。確かにこれで最小値にたどり着くときもあります。しかし、たどり着かないときもあります。

![等高線図２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/67a12323-843e-ad05-d033-7ce39dfe8b39.png)

例えばこのような目的関数の時です。もし左の方から下り始めたら左の青い穴にたどり着くでしょう。しかしもし右の方から下り始めたら右側の穴にたどりつきそうです。どちらかが最小値の場合、もう片方の場合は最小値にたどり着かないことになります。実は、これは最急降下法の欠点でもあります。ですから複数の地点から下り始めるなどの対策が必要であると言われています。

関数全体の最小値を大域的最小値、ある部分だけを見た時の最小値（図の青い穴でいちばん低い所）のことを局所的最小値といいます。

#勾配

ここまでの説明から、最急降下法というのは一番急な坂を下る方法であるということがお分かり頂けたかと思います。では、一番急な方向はどのように見つけるのでしょうか？そこで使うのが勾配です。

![勾配.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/19b0550f-a732-b57a-b37b-edbb06c45911.png)

勾配とは各点の値の変化率が最も大きくなる方向への変化率の値を大きさにもち、ベクトルを対応させるベクトル場のことです。

具体例を見てみましょう。

![勾配例.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/64099065-cefa-7636-aee3-3253a0295912.png)

※なぜ偏微分によって表された勾配grad f の向きがｆが最も急激に増加する方向か、という証明は割愛します。

#最急降下法
これで必要な準備は整いましたので、最急降下法の具体的な方法について見てみましょう。
![最急降下法.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520906/e9cc7b23-144a-fe71-d9e3-351c714a116b.png)

（xの右肩にある数字は累乗やn回微分の意味ではなく、何番目のデータセットかを表しています）

一見複雑に見えるかもしれませんが、仕組みはとてもシンプルです。grad fがfの最も増加する向きを持ちます。それに負のある数を掛けることによって、今いる位置からそのfが最も減少する方向に進んでいくことになります。

###学習係数
勾配の係数αは学習率と呼ばれ、１回にどのくらい下るかを決める非常に重要な値です。大きすぎると局所的最小値にたどり着かなかったり、発散してしまったりします。一方小さすぎると局所的最小値にたどり着くまでに時間がかかりすぎてしまいます。
amazon forecastやってみた - 1. 学習データを取得する

# はじめに
今日イベントでAmazon forecastで時系列予測の事例紹介を見たところ
とてもお手軽にできそうな感じがつかめたのでその日のうちにやってみた。
参考：https://dev.classmethod.jp/cloud/aws/amazon-forecast-getting-start/

大きな流れはコチラ。
　1. 学習データを取得する　←今回はココ
　2. 学習データのインポート
　3. amazon forecastの設定
　4. 学習結果の確認

# やってみた元データ
気象庁が公開している平均気温データを使いました。
地元が岡山県倉敷なのでそこのデータを４年分使用。
期間：2016/11/1 ～ 2019/11/1

## 1. 学習データを取得する
自分がとった手順を紹介。
①「気象庁 > 過去の気象データ・ダウンロード」へアクセス
https://www.data.jma.go.jp/gmd/risk/obsdl/index.php

②都道府県を選択する
岡山県をクリック
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/a3e5b44e-6f03-95c4-0091-33da4879c752.png)

②市を選択する
倉敷市をクリックして→ボタンをクリック
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e35b1fca-9d45-2e6f-91f7-417b5fcbc744.png)

③項目を選ぶ
データの種類：日別値
項目＞気温：日平均気温
を選択して→ボタンをクリック
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/c9c4c60f-ad50-114a-764a-b3918cd01cf7.png)

④期間を選ぶ
単年だと季節の周期性が出ないかもと思ったのでまるっと４年分ぬいてみた。
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/fbc83a24-ff4e-df2f-b41e-3dbd890c2ac7.png)

⑤表示オプションを選んでダウンロード
欠損値は省くように選択肢をクリックして、[CSVファイルをダウンロード]をクリック。すると、"data.csv"という名前でダウンロードできた。
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8c054f67-39e8-5270-4145-4e823510ea5a.png)

## データの前処理をする
amazon forecastは複雑なモデル作成やバリデーション等々の処理は全部amazonのナレッジでうまいことしてくれるが
ちゃんと予測してもらうための前処理は各人でやる必要がある。

どんな加工をすればよいのか？についてはポイントがあり、
詳細は他サイトに譲るが、予測をするには最低限下記の項目が必要で特にtimestampはフォーマットが決められている。
　1. item_id
　2. timestamp(YYYY-MM-DD hh:mm:ss)
　3. target_value
このtimestampは必ず合わせないといけないのでここは最低限頑張る。

で、気象庁のデータをどんな感じに加工したのか紹介

```:data.csv(before)
ダウンロードした時刻：2019/11/04 21:55:20

,岡山
,倉敷
年月日,平均気温(℃)
2016/11/1,13.8
2016/11/2,12.1
2016/11/3,11.8
2016/11/4,11.4
2016/11/5,12.6
2016/11/6,12.1
2016/11/7,10.5
```
これを↓↓のように直した。

```:data.csv(after)
item_id,timestamp,target_value
kurashiki,2016-11-01 00:00:00,13.8
kurashiki,2016-11-02 00:00:00,12.1
kurashiki,2016-11-03 00:00:00,11.8
kurashiki,2016-11-04 00:00:00,11.4
kurashiki,2016-11-05 00:00:00,12.6
kurashiki,2016-11-06 00:00:00,12.1
kurashiki,2016-11-07 00:00:00,10.5
kurashiki,2016-11-08 00:00:00,12.7
kurashiki,2016-11-09 00:00:00,9.4
```

# おわりに
今回のデータは欠損値もないのでtimestampのフォーマットをforecast用に合わせるだけですんだけど実際はここが一番大変になるはずの工程。

通常の時系列予測だと、このデータができた後も
頑張ってモデル作成やらバリデーション作成やら
ある意味本来のプログラミングの腕の見せ所なわけだけど
そこをまるっとforecastが面倒見てくれる、というのが最大の売り。
ちょっと寂しい気もするけど、これで時系列予測を実行するハードル
が劇的に下がったのでforecastはすごい！

～次回へ続く～
VScodeでRubyを書くときに設定したこと【初心者】

## はじめに
自分への備忘録こめて書きます。
ただ手伝ってもらったりしたこと多くかなり記憶が曖昧…。
思い出したらその都度追記予定。

## 設定

##### - VSCodeのインデントのスペース数を4→2へ変更

デフォルトだと4になっていてRubyコーディング規約にそぐわないため変更。
これ変更しないと新規ファイル開くたびに設定し直さなきゃいけなくて地味にめんどい。


### 拡張機能編
##### - 日本語にする
`Japanese Language Pack for Visual Studio Code`を追加。
初心者には英語じゃちんぷんかんぷんすぎるので。

##### - RuboCopを追加
Rubyにふさわしい書き方でないところやエラーが出てしまう箇所を波線で示して、カーソルを合わせるとその内容を教えてくれます。
設定など詳しくは他記事をどぞ。
↓
[RuboCop is 何？](https://qiita.com/tomohiii/items/1a17018b5a48b8284a8b)
Unity Packageを使ってみよう

# Packageとは？
すごくざっくりいうと、Assetのデータを外部にエクスポートする仕組み。
Sceneやprefabを.packageというファイルにまとめてエクスポートしてくれる。
ただエクスポートするだけじゃなく、Unity内部で持っている参照関係や、Imageコンポーネントで使っている画像データを自動で検出してまとめてエクスポートしてくれたりするすごいやつ。（例えばSceneをエクスポートすると、Sceneの中に入っている画像やスクリプトだけ取り出してpackageの中に含めてくれる。賢い。）
Unityエディタ内で作成したデータを受け渡す際に必須になる機能。


## なぜPackageを使うの？生のファイルの受け渡しではダメなの？
ダメ。
なぜかというと、Unityエディタ内で紐づいているファイル同士がバラバラになってしまうから。

UnityではmetaファイルとUUID,Sceneビューからの参照情報などを使ってデータの依存関係を管理しているが、手動でファイルを移動させるとこのUUIDが書き換わってしまい、参照が切れた状態になって設定が狂ってしまう。packageを使うとこの参照情報を保った状態で受け渡しを行えるため、packageを使う必要がある。

参照切れは小さなファイルなら手でも直せるが、GameObjectの数が数百に登る大きなファイルであれば参照切れを手で修正するのはほとんど不可能。絶対package使ってね。
※ 興味がある場合は「.metaファイル」「UUID」などでググると有益な情報がヒットするかも。

## Packageを使ってみよう
今回はメッセージウィンドウのprefabを作ってpackageで出力してみる。

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196069/fd51eeec-598a-d253-687a-1878cb8fd9b6.png)

## Unity package の使い方

### パッケージ作成手順
適当なプロジェクトデータを用意して、下記のようなメッセージウィンドウを作成。

Hierarchy ViweからGameObjectのMessageWindowをAsset Viewの任意のディレクトリにD&Dし、Prefab化する。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196069/316cbeb8-ba2c-cbce-21d6-ec81638e7549.png)

ちなみにPrefabというのはインスタンスの情報を保存したテンプレートのようなもの。
画面上部からAssets->Export package...をクリック。このとき、Backgroundに使用した画像が含まれていることを確認。

ダイアログでExportをクリックする。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196069/454f82a9-788f-61b3-2a0b-9341b4cd3a60.png)


package完成！

### Packageをインポートする
Packageは別のプロジェクトにインポートできる。
### Packageインポート手順

別のプロジェクトを開いて、作成したPackageをダブルクリックする。

インポート完了！

## prefab,Package化の単位
基本は共通化する部品をprefabにする（ボタンとか.）
こうすることで、packageを読み込むだけで変更が反映されて欲しい部分全てに変更が反映されるようになる。

### さらなる学習のために
prefabの分け方は勉強すると良い。特に2019以降でprefabのワークフローは今までと大きく変わったので、調べる際には最新の情報を参照すること！

### 関連トピック
Atomic Design：UIを原子、分子などの単位に分けて、それらを組み合わせることで再利用性を高めようという設計パラダイム。webフロントエンドの分野で主流。
コンポーネント志向：コンポーネントという単位で機能を区切り、それらを組み合わせる事でソフトウェアを構成する設計パラダイム。Unityはコンポーネント志向に基づいて作られている。
Unity公式ドキュメント：Unity2019からprefabを入れ子構造にすることができるようになり、再利用性が飛躍的に高まった。知っておくと非常に便利なので、発展的な知識を得たい場合は必読。
Ukeleleでつくったキーボードレイアウトを日本語入力時にも使う

Ukeleleの基本的な使い方とかキーボードレイアウトの作り方はこちらを参考にしてください。

- https://qiita.com/sak39/items/6c24868a7f1ae45f52b9#ここで救世主ukeleleウクレレ

ただしいくつか注意点があって、Ukeleleから出力するときに`*.bundle`ファイルではなく`*.keylayout`ファイルを出力してください（ついでに、これだとログイン画面とかでも使えるようになります）（あとPress&Hold機能が使えなくなるらしい。[このマニュアル](http://iran.clubmgenretraites.paris/Logiciels/Emul/8-16Bits/ZX&Cie/Mac/Spectrum&Cie/Ukulele/Ukelele%20Manual%202.2.pdf)の4.6.をみて）。もしくはすでに保存した`*.bundle`ファイルがあるなら、中から`*.keylayout`を取り出せます。
<img width="419" alt="Screenshot 2019-11-03 at 0.53.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112098/b065692f-6d67-65ac-a200-96a02482bd70.png">
<img width="419" alt="Screenshot 2019-11-03 at 0.50.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112098/9729099c-9dd2-acef-8e32-8042cac07273.png">
そして表題の日本語入力時に使う方法ですが、直接`*.keylayout`をUkeleleで開いて、キーボードレイアウトのスクリプトを`Roman`に変更します（なおこ[^1]の設定は`*.bundle`ファイルを開いて`Roman`に変更してもなぜか次に開くと`Unicode`に戻っていてぁゃιぃので、直接`*.keylayout`ファイルを開いて変更したほうがいいです）。
<img width="498" alt="Screenshot 2019-11-03 at 0.56.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112098/3e695c0b-26eb-5651-ed1d-965bf009bbee.png">
`/Library/Keyboard Layouts/`に`*.keylayout`をインストール（普通にファイルをぶち込むだけです）して再起動します。するとmacOSの日本語入力の設定でそのレイアウトを選べるようになります。
<img width="681" alt="Screenshot 2019-11-03 at 1.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112098/fc6880ee-6a72-541a-0cb9-780ffd6ff2b3.png">
嬉しいですね。

以上の情報のソースはこちらでした。

- https://groups.google.com/forum/#!topic/ukelele-users/agYXlclB-c4

下の脚注は書きかけなわけではなくただ無意味なので無視してください。

[^1]:
#Ruby や #Rails で 西暦 年月日を 自前でバリデーションする的な処理 ( Date.parse )

日付のstringに対して Date.paras する

# Ruby では require が必要

```rb
require 'date'
```

# 成功ケース

8桁の数字でも ハイフン区切りでも スラッシュ区切りでも

なんとドット区切りもできた

```rb
[21] pry(main)> Date.parse('20200229')
=> #<Date: 2020-02-29 ((2458909j,0s,0n),+0s,2299161j)>

[34] pry(main)> Date.parse('2020.02.29')
=> #<Date: 2020-02-29 ((2458909j,0s,0n),+0s,2299161j)>
[35] pry(main)> Date.parse('2020/02/29')
=> #<Date: 2020-02-29 ((2458909j,0s,0n),+0s,2299161j)>
[36] pry(main)> Date.parse('2020-02-29')
=> #<Date: 2020-02-29 ((2458909j,0s,0n),+0s,2299161j)>

```

# 失敗ケース

不正なフォーマットや存在しない日付では例外を起こしてくれる

```rb
[23] pry(main)> Date.parse('2021-02-29')
ArgumentError: invalid date

[39] pry(main)> Date.parse('Wow')
ArgumentError: invalid date
```


# 謎ケース

7桁でもparseできる場合があるが、日付が妙だ

```rb
[28] pry(main)> Date.parse('2020229')
=> #<Date: 2020-08-16 ((2459078j,0s,0n),+0s,2299161j)>
```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
コンテナ学習が無料できるサイト「katacoda」

# コンテナ学習が無料できるサイト「katacoda」

他の方も投稿されていますが、会社の人に教えてもらうまで気づかなかったので、備忘も含めて改めて記載しておきます。

以下のkatacodaというサイトで無料で様々な学習ができます。（正直、これは便利！）

https://www.katacoda.com/

![2019-11-03 01_00_49-Katacoda - Interactive Learning Platform for Software Engineers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/155d499e-a854-8898-affa-868cfc5d804f.png)

コンテナ系の学習
![2019-11-03 01_03_32-Katacoda - Interactive Learning Platform for Software Engineers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/15aebe68-343c-9d1e-fe7d-f25ecce4c1c8.png)

![2019-11-03 01_02_26-Katacoda - Interactive Learning Platform for Software Engineers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/6f012fdf-9bdc-fa34-f190-f0d94fcc978c.png)

##### ↓Deploying Applications From Source

https://www.katacoda.com/openshift/courses/introduction/deploying-python

↓コマンドラインで打てる
![2019-11-03 01_07_45-Deploying Applications From Source _ openshift _ Katacoda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/42383582-57af-9c73-c66d-6d73081bc311.png)
↓Openshiftの画面操作ができる
![2019-11-03 01_08_03-C__Users_EijiNakagawa_Documents_GreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90447/6c02011a-df1d-c89e-9d86-6f7f7ebb6c2c.png)


##### ↓Deploying Applications From Images

https://www.katacoda.com/openshift/courses/introduction/deploying-images

何かしら役立つと思うので、一度触ってみてください。（→自分に言い聞かせる）
VSCodeでOmniSharpのdebuggerが使えない

# VSCodeでC#の拡張機能を入れたのにエラーが出る

困ったことにエラーが消えなかったのです。
全く新しいMacOS(MacBook Pro Catalina 10.15.1)にVisual Studio Code(1.39.2)をいれて、C#の拡張機能（Omnisharp)をいれたところ、次のエラーがでました。
「The .NET CLI tools cannot be located. .NET Core debugging will not be enabled. Make sure .NET CLI tools are installed and are on the path.」
dotnet sdkが入っていないよってことなので、リンク先からダウンロードしてインストールします。
- https://dotnet.microsoft.com/download

だけど、エラーは消えません。
コンソール(OUTPUTを選択して、C#を選ぶ）と「Failed to spawn 'dotnet --info'」と出ています。
ターミナルでdotnet --infoを打ってみたら、ちゃんとでます。

``` bash
bash-3.2$ dotnet --info
.NET Core SDK (global.json を反映):
 Version:   3.0.100
 Commit:    04339c3a26

ランタイム環境:
 OS Name:     Mac OS X
 OS Version:  10.15
 OS Platform: Darwin
 RID:         osx.10.15-x64
 Base Path:   /usr/local/share/dotnet/sdk/3.0.100/

Host (useful for support):
  Version: 3.0.0
  Commit:  7d57652f33

.NET Core SDKs installed:
  3.0.100 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
```
なぜや。

# ためしたこと

## VSCode、拡張機能、dotnet sdkの再インストール

それでうまく行けるなら記事にしません。
なお、VSCodeと拡張機能の削除は下記を参考に完全削除しました。
また、再インストール時には```brew cask install dotnet-sdk```を使ってみました。

* https://codeday.me/jp/qa/20190228/339314.html

## pathの追加

パスが通っていないかと思ったので、パスを通したけどうまくいかず。
ということで、下記を参考にシンボリックリンクをはってみたのですがこれもうまくいかず。。。

- https://stackoverflow.com/questions/50454088/vs-code-error-the-net-cli-tools-cannot-be-located

# うまくいったのは

ダウンロード先を変えたらうまく行きました。
なにこれ。
エラーが出ていたとき（brew使ったとき）は「dotnet-sdk-3.0.100-osx-x64.pkg」というファイルだったのです。
これを下記リンクからダウンロードした「dotnet-sdk-3.0.100-osx-gs-x64.pkg」でインストールしたらうまく行きました。
なにこれ。

- https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/install

比較してみると、うまくいったバージョンは.Net Core SDKのcommitが[02df19ceac]になっていました。
（どっちが新しいのかはわかりませんが）
brewのfomulaもgsなしの.pkgになっていました。
（dotnet-sdkとdotnet両方とも）

結局、なぜdotnetコマンドが通らなかったかは（あと、-gsのありなしの.pkgの違いも）わかりませんでしたが、うごいたのでよしとします。
うまくいっている人と同じやり方をしたほうがいいですよね。。。南無三。
Angularでコンポーネント名を変更するにはWebStormが便利だという話

# コンポーネントのrename辛い
Angularでアプリケーション開発中にコンポーネント名を変更したくなるタイミングが多々あると思います。
Angularでコンポーネント名を変更するとなると、

- `*.component.ts` で定義しているcomponentのclass名
- `*.component.html`, `*.component.scss`, `*.component.spec.ts`, `*.component.ts`の各ファイル名
- `*.component.ts`の@componentデコレーターで指定しているslecector, templateUrl, styleUrls
- 上記のファイル群を包括しているディレクトリ名
- 変更したコンポーネントをimportしているファイル(`*.module.ts`とか)

を変更するという流れになると思います。
普段私が使っているVSCodeの機能[Rename Symbol](https://code.visualstudio.com/docs/editor/refactoring#_rename-symbol)だと、コンポーネントのclass名を変更すると、シンボルの変更をしてくれるだけで、ファイル名、ディレクトリ名の変更は手動で行う必要があります。

https://medium.com/@armno/renaming-an-angular-component-7f3990829e84

# WebStormを使う

そこで[WebStorm](https://www.jetbrains.com/webstorm/)を使うと、コンポーネント名の変更が比較的簡単にできることがわかりました。

以下が BookComponent から ComicComponentに変更する模様です。

![rename.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178093/19cdbd3b-8a64-7883-898b-070a29a864cf.gif)

コンポーネントのclass名を変更するだけで、シンボルを変更するだけでなく、html, scss, spec.ts, tsの全部のファイル名を変更してくれました。
- ディレクトリ名
- selector名

を手動で書き換える必要がありますが、VSCodeで行うときより簡単にできました。
【AtCoder】二分探索の問題を解く

競プロ強くなりたいので、[このサイト(AtCoder 版！蟻本 (初級編))](https://qiita.com/drken/items/e77685614f3c6bf86f44#%E4%BE%8B%E9%A1%8C-2-5-5warshall-floyd-%E3%82%92%E4%BD%BF%E3%81%86%E5%95%8F%E9%A1%8C)を参考に、AtCoderの問題を解いてアルゴリズムの基礎固めしています。今回解いたのは、[この問題](https://www.ioi-jp.org/joi/2007/2008-ho-prob_and_sol/2008-ho.pdf#page=6)（の中のC-ダーツ）です。競プロやるうえで基本となる二分探索（計算量O(logN)）ですが、どこで使うか判断するのがなかなか難しいです。。

### 問題概要
4本の矢を投げて、点数$P_1, P_2, ..., P_N$ の中で当たった点数の合計のうち、$M$ を超えないものの最大値を求めます。矢を「投げない」という選択もOKです。
$S \leq M$
$1 \leq N \leq 1000$ 
$1 \leq M \leq 2 \times 10^8$ 

### 解法
※[ここ](https://www.ioi-jp.org/joi/2007/2008-ho-prob_and_sol/2008-ho-review.pdf)に解説は載っていますが、自分の理解のためにまとめます。

一番最初に思いつくのは、$(N+1)^4$ 通りの全てのパターンを調べることです（「+1」は、「投げない」場合としてP=0の矢を加えている分です）。つまり全探索ですね。4重ループを書くだけで実装できます。しかしこれだと、計算量が$O(N^4)$ となってしまい、$N = 100～200$ 程度でないとACできません。

そこで一工夫して、**二分探索**を使用すると、$O(N^2logN)$ 時間で解くことができます。解説に載っている、解法3のやり方です。
矢を「4回投げる」のではなく、「2回投げるのを2回行う」と考えます。矢を2回投げたとき、得られる点数は$(N+1)^2$ 通り以下です。この結果を、$Q_1, Q_2, ...., Q_r$ として、初めにソートしておきましょう。計算量は$O(N^2logN)$ です。
→「つまり、点数がr通りあった時、矢を2回投げた時の合計がM以下」と言い換えることができます。
最初の2本の矢の合計を$Q_i$ であったとすると、残りの2本の矢の合計$(Q_j)$ の最適解は、
$Q_i + Q_j \leq M$
を満たす$j$ のうち、$Q_j$ が最も大きくなるものを求めればよいです。このような$j$ は二分探索により、$O(N^2logN)$ 時間で求めることができます。
下準備の時間も合わせて、全体で$O(N^2logN)$ 時間で求めることができます。

pythonによる解答例が以下です。ライブラリbisectを使うと簡単に二分探索できます。

```python
import bisect

N, M = map(int, input().split())
p_list = [int(input()) for _ in range(N)]
p_list.append(0)
p_list.sort()
q_list = []

# Qiのリストを作成
for i in range(N+1):
    for j in range(i, N+1):  # 重複がないようにしている・・・★
        q = p_list[i] + p_list[j]
        if q <= M:
            q_list.append(q)
q_list.sort()

ans = 0
for q1 in q_list:
    # 二分探索(合計がMの時に正しく計算するため、rightにする必要あり）
    insert_index = bisect.bisect_right(q_list, M-q1)
    tmp_ans = q1 + q_list[insert_index-1]
    ans = max(ans, tmp_ans)

print(ans)
```

ちなみに、コード中の★の部分を、

```python
for i in range(N+1):
    for j in range(N+1): 
        q = p_list[i] + p_list[j]
        if q <= M:
            q_list.append(q)
```

として計算して後でソートしようとしたらMLEでした。メモリって大事。
日々のプログラミング学習の記録

#html&cssの学習（11月2日）
##html
**brタグ**
改行する際に使う
**アイコンを使う（Font Awesome)**
①Font AwesomeのCSSファイルを読み込む
②<span>タグにfaクラスとfa-アイコン名クラスを指定する

##css
|プロパティ|書き方||
|:---|:---:|--:|
|background-image|bacground-image: url(画像のURL)；|背景画像を表示|
|background-size|background-size: cover;|背景画像の表示範囲を指定（coverは１枚で埋め尽くす)|
|letter-spacing|letter-spacing: ~px;|文字の間隔を指定|
|margin|margin: 0 auto;|**要素**の中央寄せ|
|line-height|line-height: ~px;|行の高さを指定（要素の縦方向の中央に文字を配置するのにも使える）|
🔰初心者向け🔰PythonでYoutubeAPIを叩こう

#初めに
APIという単語はよく聞くし、どんなものかは何となくは理解していたものの使ったことは無かったので触ってみることにしました。

# 本題

###APIキーを作成する
先ずは、何をするんだろう？となりますよね。APIキーがいるって話を聞いたことがあったので、その取得からやっていきたいと思います。以下のサイト[Google Developer Console](https://console.developers.google.com/?hl=JA)から生成します。そして、ここから新しいプロジェクトを選択しプロジェクト名を付けます。進むと、組織を聞かれますがなしで良いと思います。![１.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455271/329b71e7-bc6c-ce9e-2853-e6d55280253d.png)
次に,使用できるAPIが無いと言われると思うので**+APIとサービスを有効化**を押して下さい。すると、APIライブラリへようこそ、と出てきてその下に検索ボックスがありますので、**YouTube Data API v3**と検索してください。検索結果に出てきましたら、それを押して有効にするという青いボタンを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455271/ff798d16-2c6f-d5f0-fc56-a428a3a67eb0.png)
上記のことをすると、下のページに飛ぶと思います。そして、Create Credentialsを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455271/4b24417d-e09e-a8a9-ecf6-a2e49784dd25.png)
すると、下のようなページが開くと思うので下の画像に合わせて設定してみて下さい。今回は、初めてという事で一般公開データに限定してアクセス出来る項目を選択しました。最後に、必要な認証情報をクリックしてください。これでAPIキーを作成することが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455271/2a056beb-4b18-653c-d565-1dddae92e11f.png)
APIキーが作成されましたらメモしておいてください。これを外部には公開しないように注意しましょう。
###APIキーを利用していく
それでは、利用して少しデータを取得してみましょう。下のAPI Keyというものを使います。![Inked2_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455271/d3021b96-20a5-bc85-47d4-1285e9108a35.jpeg)
コピペして以下のコードの**Your_API_Key**に貼り付けましょう。また、タイトルを取得したい動画のURLを**Youtube_URL**に貼り付けましょう。

```python:use_api.py
import json
import urllib.request

class Helper:
    def __init__(self):
        pass
    def id_from_url(self, url: str):
        return url.rsplit("/",1)[1]

class YouTubeStatus:
    def __init__(self, url: str):
        self.json_url = urllib.request.urlopen(url)
        self.data = json.loads(self.json_url.read())
#今回はタイトルのみ取得
    def get_video_title(self):
        return self.data["items"][0]["snippet"]["title"]

api_key ="Your_API_Key"
YT_URL = "Youtube_URL"

helper = Helper()
video_id = helper.id_from_url(YT_URL)
url = f"https://www.googleapis.com/youtube/v3/videos?part=snippet&id={video_id}&key={api_key}"
main_data = YouTubeStatus(url)
title = main_data.get_video_title()

print(title)
```

上のコードを実行すると、動画のタイトルを取得できます。ちなみに、上記のコードの変数urlにapi_key,YT_URLの値を代入したURLに飛ぶと、今回取得したjsonデータをブラウザで見ることができます。
#最後に
今回は、初めて使ってみるという事でタイトルのみを取得してみました。他にもカテゴリや動画の説明など様々な要素が取得できます。Youtubeのリンクをcsvなどで読み込めばより多くの動画情報を得られそうで面白いと思いました。今後、何かに生かせればよいなと思いました。
dockerを使ったlaravelでの「file not found.」エラー


laravelの初期画面が出ず、
file not found.が表示されてしまう時の解決手法のメモです。

![スクリーンショット 2019-11-03 0.30.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244070/1ca84a87-41f9-91ed-4828-e96bffc2a582.png)


初期のlaravelのルーティングを確認。これはあってそう。localhostで動きそうだが。。

```html:routes/web.php
Route::get('/', function () {
    return view('welcome');
});
```

調べていくうちにdockerファイルを作成するときにNginxを規定したconfファイルの
rootの記述が悪いことが判明。
root  /var/www/html/[laravelファイルのルートファイルの名前]/public
に変更しました。

```html:docker/web/default.conf
server {
    listen 80;

    root  /var/www/html/[laravelファイルのルートファイルの名前]/public;
    index index.php index.html index.htm;
```

dockerを停止した後にもう一度起動します。

```
 $ docker-compose down

 $ docker-compose up -d
```


動いた！！！！


![スクリーンショット 2019-11-03 0.16.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244070/d7431846-ff4a-6cca-309a-dd848fcd54ee.png)
お名前.comからGoogle Domainsへの移管で詰まったことまとめ

主に使いやすさ、それからプライバシー保護の設定やDNSレコード追加など、一部の有料機能が無料で提供されていることから、クライアントのドメイン取得・管理を[お名前.com](https://www.onamae.com/)から[Google Domains](https://domains.google/intl/ja_jp/)へ移行してます。一部[お名前.com](https://www.onamae.com/)の気分で使うといくつか詰まることがあったのでまとめ。

#Google Domainsに移管するメリット
## 1. UIがわかりやすい
DNSレコードの設定やgsuiteとの連携(これは当然といえば当然だが)、更新の請求などとにかくわかりやすい。これが一番の動機です。

## 2. Search ConsoleやAnalyticsなどの所有権の確認を大幅に簡略化できる
<img width="1039" alt="Google Search Consoleの所有権確認をGoogle　Domainsで自動的に行なっているスクリーンショット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345976/884ceaf4-24b4-4fd1-48da-6100d98e864a.png">
Google Search ConsoleではあらかじめドメインをGoogle Domainsで管理していればプロパティの登録は１クリックで完了します。
地味に嬉しい業務効率化です。
今後、Googleの様々なサービスとの連携も期待できます。

#詰まった点
##移管に更新料が必要
移管自体は費用がかかりませんが、移管するドメインの残りの有効期限が1年を切っていると、さらに1年の更新を求められますのでGoogle Domainsから追加で1年分支払う必要があります。
##取得から60日未満のドメインは移管できない
Google Domainsでは取得から60日以上経っていないと移管ができません。
60日未満の場合、移管ができるようになり次第メールでアラートを送ってくれるよう設定できます。
##whois情報公開代行を使用していると移管できない
お名前.comではwhois情報公開代行という、whois情報に登録者の情報を載せずGMOの情報を代理で公開してくれるオプションがあります。
whois情報公開代行は無料で、デフォルトでオンになっているので、使用している人も多いかと思います。
しかしながら、whois情報公開代行をオンにしたまま移管手続きをすると、手続き自体は進行するのですが、Google Domainsサイドで移管を申し込んでもGMOから「トランスファー申請不承認のご連絡」というメールが届き、移管できずやり直しになってしまいます。
Googleにも同様のプライバシー設定があるのですが、移管の際は1回whois情報公開代行を外す必要があるようです。
##.xyzや.worksなど格安ドメインは管理できない
.xyzや.worksなどの格安ドメイン(年額1円など)は、[お名前.com](https://www.onamae.com/)では取得できますが[Google Domains](https://domains.google/intl/ja_jp/)では取得も管理もできません。
こういったドメインを使いたい場合は別のレジストラを使いましょう。
ちなみにGoogleの親会社Alphabetのドメインって[abc.xyz](https://abc.xyz)なんですけど、**自分のサイトのドメイン自社サービスで管理できないんですね**。~~ウケる~~。

##他にも管理できないドメインがある
他にも管理できないドメインがいくつかあるようです。
例えば.aiドメイン。AIを連想させるので、やや高額ながら使われているサイトも増えてきましたがGoogle Domainsでは管理できません。
.wikiや.meなどのマイナーなドメインもある程度管理できるので、この辺りは今後の対応を期待したいですね。

##.jpドメインや国のトップレベルドメインのwhois情報を代理公開できない
.jpドメインなど、国のトップレベルドメインは、whois情報代理公開を利用できないそうです。whoisの代理公開は、Google Domainsでは「プライバシー保護」と呼ばれ、.comなどを移行するとデフォルトでオンになっています。
サポートに問い合わせたところ、

>Google Domains では [.jp] のドメインなどの末尾が国になっているドメインはすべてプライバシー保護を無効にさせていただいております。

との返答。
<img width="1092" alt="スクリーンショット 2019-10-16 10.37.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345976/85ce095e-b8ce-ffbc-76d3-026307c88a99.png">
ちなみにドメインのプライバシー保護（お名前.comでいう「whois代理公開」）が有効になっている場合はこのようにドメイン移行プロセスの①が黄色いエクスクラメーションになるようです。
お名前.comでは.jpドメインでも問題なくwhois代理公開が可能なので、移行が向かない場合もあると思われます。

##.jpドメインのREG-IDはわからなくても良い
.jpドメインの移行の時はAuth codeの代わりにREG-IDを求められるのですが、これは
`REG-00-0000-0000`
で大丈夫だそう。
ちなみにお名前だとドメイン情報ページの(.comなどのAuth Codeと同じ)whois情報を確認する欄にあります。

#まとめ
お名前.comの使いにくいドメイン管理画面のUIからすると、Google Domainsの使いやすさはピカイチ。
また、国トップレベルドメインでの情報公開など、徹底してクリーンな運営をしている印象を受けました。
一部やや高いドメインもあるのですが、年間数百円ですので、得られるメリットを考えてどんどん移行していこうと思います。
railsのエラー: テーブル作成

今日はちょっとデータベース作成をやってみた。

まずデータベースの作成の作りかたを細かいところを
省略して説明すると。

⚪️その1
rails d model モデル名

で前提となるモデルを作成

⚪️その2

出来上がったマイグレーションファイルから

[![Screenshot from Gyazo](https://gyazo.com/6ba6c81f013e8a6873db7a31d39c9015/raw)](https://gyazo.com/6ba6c81f013e8a6873db7a31d39c9015)

こんな感じでテーブルの中身のカラムをかく

⚪️その3

rake db:migarate

でテーブルを作成。




それで本題のエラーは

①bundle exec 未使用

その3で bundle exec rake db:migrate
 という形式でやらないとエラーがおきた。

②カラムの追加とrollback

rails generate migration addcolumn+クラス名

で新たにマイグレーションファイルを作成して

def change
    add_column :users, :mobile_phone, :string, after: :phone
end

と書いて行って、

その3を実行しますが

名前の重複でエラーが出る。
rollbackの使用で直そうとしたら混乱したなど。

細かいエラーがでた。


ターミナルの内容をみて細かい内容の把握を必須だと改めて思いました。
Webpackを使って画像をwebpに変換してみた

webp-loaderとimagemin-webpをそれぞれ使ってみました

webpack初心者です。間違っていたら教えていただけるとありがたいです。:bow:

# webp-loader

https://github.com/kavu/webp-loader

↑こちらの設定を参考にし、設定してみました。

```bash
yarn add -D webpack webpack-cli file-loader webp-loader
```


```webpack.config.js
module.exports = {
    mode: process.env.NODE_ENV || "development",
    entry: {
        a: "./images/a.png",
        b: "./images/b.png",
        c: "./images/c.png",
    },
    module: {
        rules: [
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: "file-loader",
                        options: {
                            name: "[path][name].[ext].webp",
                        },
                    },
                    "webp-loader?{quality: 50}",
                ],
            }
        ]
    },
};
```

この設定で`yarn webpack`と実行し、webpackを実行するとdistフォルダ内にwebpが作成されました。
ただ、`dist`フォルダに不要な`a.js`なども一緒にできてしまうのでもうちょっといいやりがないかと思いました。

---

この例では、webpackのentryで直接画像ファイルを指定していますが、jsファイルで
`import image01 from "./images/01.png";`などと読み込んでもwebpに変換するフローで処理してくれるので、jsファイルで読み込むファイルを全部一気にwebpに変換するというのもできました。
↓がやってみたサンプルです。
https://github.com/okumurakengo/webpack-webp-sample

# imagemin-webp

imageminのWebPプラグインでやってみました

ほぼこちらの参考通りですが、試してみるとうまく変換することができました

参考：https://www.smashingmagazine.com/2018/07/converting-images-to-webp/#using-webpack

```bash
yarn add -D webpack webpack-cli imagemin-webpack-plugin imagemin-webp copy-webpack-plugin
```

```webpack.config.js
ImageminWebpackPlugin = require("imagemin-webpack-plugin").default;
ImageminWebP = require("imagemin-webp");
CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
    entry: "./src/index.js", // 空のファイルでOK
    plugins: [
        new CopyWebpackPlugin([{
            from: "./src/images/*.png",
            to: "./images/[name].webp"
        }]),
        new ImageminWebpackPlugin({
            plugins: [
                ImageminWebP({
                    quality: 75
                })
            ]
        })
    ]
};
```

```bash
yarn webpack #distフォルダにwebpに変換した画像が作成されている
```

---


読んでいただいてありがとうございましたm(_ _)m
自分用

###bootstrap
<a href=https://getbootstrap.com/>bootstrap</a>のサイトにアクセスする。
Bootstrapを、そのまま使用するのなら、CDNをコピーするだけで使える。
style.cssを読み込む、直前の部分に貼り付ける。

```html:
（link rel="stylesheet" href="css/style.css"）
```

//htmlに、決められたタグを入れることでBootstrapが勝手に調整してくれる。//

```html:
<body>
 <div class="container">
   <header...>

   </div>
</body>

//全体を,<div class="container">で囲む。//
```

###グリッドシステム

```html:
<div class="row">
```
//class名はrow//

```html:

<div class="col-○○-１~12>
```

//colはカラム、○の部分はxs,sm,md,lg、数字は使うカラムの数//

###オフセット

```html:

<div class="col-sm-8 col-sm-offset-2">
```
//真ん中のカラムを８つ使わず、左右にカラムを２つずつ振り分ける。//

```html:

<div class="col-sm-offset-3 col-sm-offset-3">
```
//前のカラムを３つ確保して、そのあとにカラムを３つ使う。//

```html:

<div class="col-sm-６ col-sm-offset-3">
```

//左右に３つずつカラムを振り分けて、真ん中に６つカラムを使う。//

###ラベル､テキストフィルム

```html:

<label for="name">お名前</label>
<input type="text" id="name" name="name">
```

//ラベルとテキストフィルムを作れる。タイプ属性には色々ある。//

```html:
<class＝”form-control”>
```
//Bootstrapのformsから色んな見た目を作れる。//

###プレースフォルダー

```html:
placeholder="例"
```
//例文を作れる。//

###ドロップダウンリスト

```html:
<div class="form-group">
  <label for="job">ご職業 
  <span class="badge badge-danger">必須</span>
  </label>
  <select id="job" name="job" class="form-control" 
   size="3" multiple>
  <option value="">選択してください</option>
</div>
```

//ドロップダウンリストを作れる。都道府県名など、選択するものが決まっている時に、有効。class="badge badge-danger”は必須アイコン。//

###チェックボックス

```html:
<div class="form group">
     <label>知りたい内容（複数回答可</label>
   <div class="checkbox">
    <label>
   <input type="checkbox" name="q1" value="html"> HTML 
    </label>
   </div>
</div>
```
//チェックボックスを作れる。class=checkboxはBootstrapの指定。name属性は統一する。//

###ラジオボタン

```html:
 <div>
       <label class="radio-inline">
            <input type="radio" name="q2" value="1"> 
       </label>
 </div>
``` 
//ラジオボタンを作れる。radio-inlineで横に並べる。//

###テキストエリア

```html:

<div class="form-group">
        <label for="message">ご意見</label>
        <textarea name="message" rows="10" 
         class="form-control></textarea>
</div>
```
//テキストエリアが作れる。rowsは行数。//

###ボタン

```html:
<button type="submit" class="btn btn-default">送信する</button>
```
//ボタンを作れる。他にも種類がある。primary、success、info、warning、danger、link。//
#docker で SOCKS proxy を利用して ssh サーバー経由の https 接続をする 

# docker run

```
docker run --name=socks-https-proxy -it --rm alpine sh
```

# 必要なライブラリの install

```
/ # apk add --update openssh curl
```

# 必要があれば local から コンテナに秘密鍵をコピーしておく

```
docker cp ~/.ssh/some.pem socks-https-proxy:/
```

# SOCKS で proxy を起動する

起動させっぱなしにしておく

```
ssh -vND 8888 -i some.pem user@host
```


# docker exec

同じコンテナにコンソールの別タブからアクセスする

```
$ docker exec -it socks-https-proxy  ash
```

# curl 

httpbin.orgというサービスで接続元のIPアドレスを確認

```
/ # https_proxy=socks://127.0.0.1:8888 curl -v https://httpbin.org/ip

{
  "origin": "YYY.YYY.YYY.YYY, YYY.YYY.YYY.YYY"
}
```

ssh接続しているサーバーのIPアドレスになっていたら成功。


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
年末まで毎日webサイトを作り続ける大学生 〜15日目 asyncを学ぶ〜

 ##はじめに
初めまして。
年末まで毎日webサイトを作っている者です。
今日はファイルの読み込み順と、非同期を一部勉強しました。
扱う技術レベルは低いですが、同じように悩んでる初心者の方を勇気付けられれば幸いです。
今日は15日目。(2019/11/2)
よろしくお願いします。


##サイトURL
- https://sin2cos21.github.io/day15.html


##やったこと
今日は主に座学的な勉強をしました。主にファイル読み込みの順番(deferとかasyncとかです)と、非同期処理についてです。
学んだことをメモしておいたので載せておきます。↓


- テーマ: ファイル読み込みの違い / 非同期の方法
- defer, async, なし　3つの違い
	js 読み込み	js 実行 (いつ/順番)
defer	非同期	html パース後 /書かれた順
async (完全な非同期)	非同期	html パース中断 / 並列
なし	同期 ( = htmlパースを中断する)	html パースを中断 / 書かれた順

- つまり
defer 利点 → htmlが出来上がっているので、確実にDOMを操作できる
async 利点 → 順番を気にしなくてもいい
なし　利点→ なし？


- 用語
htmlパース・・・htmlファイルを解析すること
非同期・・・同時並行でファイルが処理されること
コールバック関数・・・別の関数に呼び出される関数
アロー関数・・・関数を短くかける（利点: thisが自身を指さなくなった → オブジェクト指向で便利) 
名前あり関数→ 	名前  = () =>  { 処理};
無名関数 →   ()=>{処理};


- 高階関数とコールバック
呼び出す側の関数・・・高階関数
呼び出される側の関数・・・コールバック関数 (非同期で使われること多い)

- 高階関数 例
addEventListener
setTimeout


- その他
- jsは関数も値（変数に入れられる ()つければ処理結果、つけなければ関数自体)

- javascrit 3つの非同期
 promise
 async
 await


- promise 
なぜ作られた? → コールバック関数から抜け出すために

作ったもの ↓ 非同期で読み込まれています
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/be9c5d45-7202-f790-3ec8-79b45928bfba.gif)

scriptタグにasync指定↓
```html
<script src="day15.js" async></script>
    <script src="day15_2.js" async></script>
```

##感想
非同期処理はコールバック関数を使いすぎて、面倒なことになったのでpromiseやら何やらが出てきたということがわかりました。確かにコールバック関数の多用はソースコードがみづらくなると思いました。
明日も頑張ろう。

最後まで読んでいただきありがとうございます。明日も投稿しますのでよろしくお願いします。



##参考
1. スクリプトの非同期読み込み(async, deferの違い) (https://www.wakuwakubank.com/posts/614-javascript-async-defer/)

大変参考になりました！ありがとうございます！(今日はMDNは読んでない）
TensorRTをubuntuにインストールするぞ

ubuntuにTensorRTを入れていきます

今回の環境
* Ubuntu 18.04
* RTX2080
* CUDA10.0

いれるもの
* TensorRT6.0 GA

# TensorRTってなんぞ
TensorRTは、

* ディープラーニングを使った推論高速化ライブラリ。
* NVIDIAが提供しており、CUDAベースで動く
* Tensorflowとは仲良しで相性がいい
* 機械学習ライブラリ共通のオープンモデルフォーマットONNXのパーサも備えている
* なのでpytorch, caffe, chainerのモデルも高速化可能


# インストール手順

### 1. ダウンロード

* [公式サイト](https://developer.nvidia.com/tensorrt)からダウンロード
    1. Download Nowから好きなバージョンのTensorRTを選択（今回はTensorRT 6)
    2. チェックを入れる：☑I Agree To the Terms of the NVIDIA TensorRT License Agreement
    3. TensorRT x.x GA, RC版などが表示されるが、基本GA版(General Availability)
    4. 自分のマシンに合ったファイルを選択、今回は
    ```TensorRT 6.0.1.5 GA for Ubuntu 1804 and CUDA 10.0 DEB local repo packages```
    

### 2. インストール

```bash
sudo dpkg -i nv-tensorrt-repo-ubuntu1804-cuda10.0-trt6.0.1.5-ga-20190913_1-1_amd64.deb 
#sudo dpkg -i 今回ダウンロードしたファイル名前
sudo apt-key add /var/nv-tensorrt-repo-cuda10.0-trt6.0.1.5-ga-20190913/7fa2af80.pub
#このフォーマットで変更する：sudo apt-key add /var/nv-tensorrt-repo-cudax.x-trt6.x.x.x-ga-yyyymmdd/7fa2af80.pub
sudo apt-get update
sudo apt-get install tensorrt

#Pythonから呼び出せるようにする
#Python3の場合
sudo apt-get install python3-libnvinfer-dev
#Python2の場合
sudo apt-get install python-libnvinfer-dev

#Tensorflowと連携させたいなら
sudo apt-get install uff-converter-tf
```

### 3. インストールの確認
```python
python
>>>import tensorrt as trt
#ここでエラーが出なければOK
```

#おわりに
以上がインストール手順です。
しっかり使いこなしてリアルタイムのシステム作りたいですね
TensorRTに変換できる層には限りがあり、変換できないものは自分でCUDA実装する必要もあるらしい、
それでは〜
ApacheでLaravelを立ち上げる手順

ApacheでLaravelを立ち上げる手順をまとめます。

# 実行環境
筆者の動作環境は以下の通りでございます。
- OS: Ubuntu 18.04.3 LTS
- Laravel: 6.2
- Apache: 2.4.29

# 前提条件
以下の手順を済ませている前提で勧めます。
- laravelコマンドをインストールしてある（"laravel new blog"でプロジェクトを作成できるっていう意味)
- Apacheをインストールしてある

# 手順
## 1. 作業ディレクトリにLaravelプロジェクトを作成する
作業しやすい場所にlaravelコマンドでプロジェクトを作成してください。

```
[user@ ~/]$ cd ~/work
[user@ ~/work]$ laravel new laravelapp
```
## 2. Laravelプロジェクト用のドメインをetc/hostsに書き込む
自分自身のアドレス(127.0.0.1)にLaravelプロジェクトのドメインを割り当てるために"/etc/hosts"に以下を追記しましょう。
下の例ではドメインは"my-laravelapp.localhost"になってます。

```shell:/etc/hosts

127.0.0.1 my-laravelapp.localhost
```

## 3. 割り当てたドメインに対するVirtualHostsの設定を書き込む
ApacheのVirtualHostを使って、追加したドメイン(my-laravelapp.localhost)にアクセスしたときに、どのディレクトリを参照するかを設定しましょう。
また、VirtualHostが有効になっていることを確認してください。

```apache:/etc/apache2/sites-available/my-laravelapp.conf

<VirtualHost *:80>
  ServerName my-laravelapp.localhost
  ServerAdmin sample-user@my-laravelapp.localhost
  DocumentRoot /var/www/html/laravelapp/public
  LogLevel debug
  <Directory "/var/www/html/laravelapp">
    RewriteEngine On
    AllowOverride All 
    Allow from All
  </Directory>
</VirtualHost>
```
また、上記で"RewriteEngine On"の設定をしていますが、rewrite_moduleの設定がない場合はその設定をしましょう。

```apache:/etc/apache2/mods-available/rewrite.load
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
```

### 補足
- "ServerName"に追加したドメイン(my-laravelapp.localhost) を設定します。
- "DocumentRoot"はApacheがアクセスするディレクトリです。まだ、"/var/www/html/laravelApp/public"のパスはありませんが、後で設定します。
- "\<Directory "/var/www/html/laravelapp"\>では"/var/www/html/laravelapp"以下の階層のファイルのアクセスできるように設定してあります。
- "RewritEngine On"でLaravelのルーティング(my-laravelapp.localhost/sampleにアクセスすると、対象のファイルを開いてくれる)に対応します。

設定したら、以下のコマンドで反映しましょう。

```
[user@ ~/]$ sudo a2emod rewrite
[user@ ~/]$ sudo a2ensite my-laravelapp.conf
[user@ ~/]$ sudo service apache2 restart
```

## 4. 作業ディレクトリのリンクをApacheディレクトリ配下に作成
VirtualHostに設定したディレクトリパスに対するリンクを以下のコマンドで作成します。

```
[user@ ~/]$ sudo ln -s ~/work/laravelapp /var/www/html/laravelapp
```
## 5. Apacheユーザーでアクセスできるようにアクセス権限を変更
ApacheユーザーでLaravelプロジェクトにアクセスするように設定しましょう。

```
[user@ ~/]$ sudo chown -R :www-data /var/www/html/laravelapp
[user@ ~/]$ cd /var/www/html/laravelapp
[user@ /var/www/html/laravelapp]$ sudo chmod -R 770 storage
```
### 補足
- 1行目はLaravelプロジェクトにApacheグループがアクセスできるように設定しています。
- 3行目はApacheグループがstorage配下(ログファイルや一時的な画像ファイルなどを置く場所)にアクセスできるように設定しています。

# 動作確認
ブラウザで"my-laravelapp.localhost"と入力して、正しく表示されれば完了です。
![Screenshot from 2019-11-02 23-33-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245373/edf0224b-1685-4dce-3b77-b14021d3485e.png)
pybitflyerを使うBotを、Cloud9で動作させる

#概要

pybitflyerを用いたソースをCloud9で動かすときにはまったので備防録

#Python3系への変更

Cloud9 で BitMEX のBotをTESTNETで動かす
https://qiita.com/aisurta/items/8990820f48457bf17cf0

で書いたときはCloud9はデフォルトのPythonは2系ですよといったが、現在（2019/11/02）時点では3系がデフォルトになっているため、~/.bashrcを編集する必要はない

#requests、pyyaml等のインストール

ただし、pipのインストール先はデフォルトが

```sh
/usr/local/lib/python2.7/site-packages 
```

なので単純に

```sh
pip install requests
```

だけだとpythonで呼び出すときに

```sh
ModuleNotFoundError: No module named 'requests'
```
というエラーが出る。そこで以下を入力。

```sh
sudo update-alternatives --config python
```
以下のように表示されるので

```sh
There are 2 programs which provide 'python'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/bin/python2.7
   2           /usr/bin/python3.6

Enter to keep the current selection[+], or type selection number: 
```

2を入力。

あとはsudo pip install ○○で以下をインストールしていく

```sh
sudo pip install requests
sudo pip install pyyaml
sudo pip install pandas
sudo pip install websocket-client
sudo pip install sortedcontainers
sudo pip install matplotlib
```

#参考にしたサイト
[Python] pipで任意のディレクトリにライブラリをインストールする
https://hacknote.jp/archives/27694/
毎日ブログ6日目

只今の時刻23:14

今日のやったことは、昨日の続きである東フリさんのBoootsrapの動画をやりました。

やはり英語だと全然聞き取れませんね。

とりあえずBootstrapは終わりにします。

他にやったことは、https://magazine.krowl.jp/4841/の模写をやったのですが、中々上手くいかずコードを見ながらやりました。

学んだこととしては、CSSのリセットについてですかね。

どうしてもヘッダーの上下左右に8pxができてしまい、何でだろうと思ってましたがCSSのリセットにより消すことができました。

KROWLさんのおかげで分け方がだんだんと分かってきているので、三日に一回は復習したいですね。

11/5までに復習します。

明日からはFlexBoxnについてドットインストールで学びます。

Progateだけだと全然使えませんでした。

昨日なんて、全然応用できなっかたので必ずやります！！

では、明日はドットインストールと模写をやります。

23:27
#Ruby で local に SOCKS proxy を立てて ssh サーバーを踏み台に https 接続をする例 (  faraday + faraday_adapter_socks gem )

# コンソールで SOCSK proxy を起動しておく

```
ssh -vND 8888 user@host
```

# gem Install

```rb
gem install faraday
gem install faraday_adapter_socks
```

# Code

```rb
require 'faraday_adapter_socks'

options = { proxy: { uri: URI.parse("socks://127.0.0.1:8888") } }

url = 'https://httpbin.org/ip'

conn = Faraday.new(url, options) do |faraday|
  faraday.request :url_encoded
  faraday.adapter :net_http_socks  # please assign ":net_http_socks" adapter
end

response = JSON.parse(conn.get.body)
# => {"origin"=>"YYY.YYY.YYY.YYY., YYY.YYY.YYY.YYY"}
```

# 自分のIPアドレスが変わっていたら成功

🎉 

# 元の問題

faraday で proxy を指定しても

`Using socks proxy with auth leads to Faraday::ConnectionFailed: end of file reached`

とエラーが返ってきて使えない。


[Faraday and socks proxy with auth supporting · Issue #787 · lostisland/faraday](https://github.com/lostisland/faraday/issues/787)

# Ruby関係無しで curl で確認する例

```
$ https_proxy=socks://127.0.0.1:8888 curl https://httpbin.org/ip
{
  "origin": "YYY.YYY.YYY, YYY.YYY.YYY.YYY."
}
```

# ところで Faradayの名前の由来ってなに？

>【意味】ファラデー 《1791‐1867; 英国の物理学者》... 

この人？なんだろうか

![image](https://user-images.githubusercontent.com/13635059/68070043-ea152500-fdab-11e9-9aad-ac2427fdf7ae.png)

Faradayに似ているスターバックスを見つけました。めりーくりすま

![image](https://user-images.githubusercontent.com/13635059/68070037-c81ba280-fdab-11e9-9ee4-ca13509e39a9.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
未経験から詳細設計書を書くためのまとめ

#未経験から詳細設計書を書くためのまとめ。


現在の会社に入って良かった点と言えば、詳細設計書の書き方を学べた所だ。
実際それをやったところでまだ、書いても書けてないと言われる所が関の山かもしれないが。
その会社で正しいと言える詳細設計書を書くための手順をこれから書いていく。

##詳細設計書を書くための手順1.執筆編


###①携わるシステムの全体図と詳細設計書を元に設計されてるスクリプトとの相関図を見る。

執筆の前にまずは理解分析が必要。
まずは詳細設計書を元に作られるスクリプトがどんな繋がりで動いているかの全体像が解らないと話にならない。
実際にシステムの全体を管理している端末や、相関図を記してある資料があるはずなのでそれを確認すること。
紙で確認したいのがやまやまだが、SESで来てるような社員だとプリンターを使わせてもらえないことが多い。


###②どういう経緯で詳細設計書を書く必要があるかを記述する資料をすべて読む。

上記の資料はたいてい検討項目資料・基本設計などと呼ばれることが多い。

どの検討資料がどの設計書に該当するかなど、会社の人はいちいち教えてくれない。
資料に相関図が書いてあるものもあれば書いてないものもある、有識者に確認するしかない。
確認する検討資料が多い場合は自分の中で整理して図を作る、WBSを作るなどでまとめること！

そこから詳細設計書を書くための軽いあらすじを各検討項目に書いていく。


##詳細設計書を書くための手順2.執筆編


###①現行で使用している詳細設計書を読んで、文法や言葉遣いを真似る。


詳細設計書は、プログラム処理を日本語に変換したものと考えたほうが良い。
だからと言って、思った通りに文章表現すると必ず間違いと言われる。

なので事前に現行で使用している詳細設計書を読んでどんな文法や言葉遣いが正しいか見る必要がある。

if文やリターンコードの受け取りなどその会社で、パターン化されてることが多いので
その会社ごとの仕様に合わせたほうが良い、そうしないと納得されないパターンが多い。

例としてリターンコードであれば、0だった場合と、それ以外の場合の処理を記述など、
誤りがなくかつ簡易的な文章表現が好まれる。


###②各プログラムの呼出し先、呼出し元を調査して、変更に伴う影響まで説明できるまで理解する。

仮にこのプログラムは使用しなくなったので、そのプログラムの呼出しを削除するだけの場合でも
そのプログラムの呼出し先、呼び出し元があるかないか？を調べ切って、影響の有無を説明できる所まで調査・理解
してから、設計書に記述しないと、上司やお客さんは納得しない。
ここは割り切って時間を割いて一つ一つ調査しよう！


###③一つの設計書でokを貰えたら他の設計書にもその仕様を適応する（水平展開）

一度完全にokを貰える設計書を一つ作ってからそれに似た設計書にも適応するよう水平展開すること。
ヘッダ情報の仕様は基本的に決まっているはずなので仕様理解の意識合わせをしてから書いていく。

あとはその一つの仕様を他の設計書にも適応すべくシステム名、機能名、前提条件、詳細機能、
細かく見るときりがないので抜けがないようにリストを作ってチェックすること！


###④下記に該当するか見直しをしよう！該当していたら、誤りがなくかつ簡易的な処理表現に変えよう。
[表現あいまい][用語未定義][用語多義][記述誤り][記述モレ]
PostgreSQLでテーブルをコピーする方法

# PostgreSQLでテーブルをコピーする方法
PostgreSQLでテーブルをコピーする場合、同DB内でのコピーか別DBへのコピーかでやり方が異なる。

## DB内のコピーであればSQLだけで可能
テーブル内のデータに加え制約、インデックス、権限等もコピーするには下記のようなSQLを実行すれば良い。

```sql
-- コピー元テーブルの定義、制約、インデックス等も含む空テーブルを作成する
CREATE TABLE 先スキーマ.テーブル ( LIKE 元スキーマ.テーブル INCLUDING ALL );

-- 作成した空テーブルの所有者を変更する
ALTER TABLE 先スキーマ.テーブル OWNER TO ユーザー;

-- 上記CREATE文では付与されない権限を付与する
GRANT 権限 ON TABLE 先スキーマ.テーブル TO ユーザー;

-- 元テーブルから先テーブルにデータをコピーする
INSERT INTO 先スキーマ.テーブル SELECT * FROM 元スキーマ.テーブル;
```

ちなみに下記のAS句でのコピーは型とデータのみをコピーするため主キー制約や非ヌル制約などの制約、またインデックスなどは作成されない。

```sql
CREATE TABLE 先スキーマ.テーブル AS SELECT * FROM 元スキーマ.テーブル;
```

## DB間のコピーはダンプ、リストアが必要
あるDBのテーブルを別のDBにコピーする場合、上記のSQLでは対応できないのでいったんテキスト形式でダンプする必要がある。
下記のコマンドでダンプが可能である。

```shell
pg_dump -h ホスト -p ポート -U ユーザー -F p -v -t 元スキーマ.テーブル -f ダンプファイル 元データベース
```

コピー元DBから対象テーブルを指定してテキスト形式の平文SQLファイルとしてダンプする。
出力されるダンプファイルの内容は下記の通りである。

| SQL | 内容 |
|:--|:--|
| CREATE TABE ～ | テーブル作成 |
| ALTER TABLE ～ OWNER TO ～ | テーブル所有者の変更 |
| COPY ～ | データのコピー |
| ALTER TABLE ～ ADD CONSTRAINT ～ | 制約の付与 |
| CREATE INDEX ～ | インデックスの作成 |
| REVOKE ～ | 権限の削除 |
| GRANT ～ | 権限の付与 |

このダンプファイルのSQLにはスキーマ名修飾がないので適宜直す必要がある。
リストアは下記のpsqlコマンドで対象DBに対してSQLファイルを実行すれば良い。

```shell
psql -h ホスト -p ポート -U ユーザー -f ダンプファイル -d 先データベース
```

## 参考資料
[テーブル構造をコピーして新しいテーブルを作成する]
(https://www.dbonline.jp/postgresql/table/index14.html)

[PostgreSQL テーブルのコピー]
(http://mylifeno3.blog.fc2.com/blog-entry-1229.html)
簡易的なウォッチドッグタイマーをRubyで表現できるのか

ryoです。好きなアーティストは「神様、僕は気づいてしまった」です。略称　神僕
神僕の曲で、「ウォッチドッグス」が特に好きです。
そこで今日はウォッチドッグタイマーについてRubyで表現できるか挑戦しようと思います。

**自分の読解力に自信がなくて、ウォッチドッグタイマーの解釈を間違えているかもしれません。
間違えていたらご指摘いただけたらありがたいです。**

## この記事を読んで身につくこと
- ウォッチドッグタイマーが何かがわかる。
- Rubyでウォッチドッグタイマーを表現できるようになる

## 目次
- ウォッチドッグタイマーとは何か
- 作る内容
- 事前準備
- 完成コード
- 各コードの解説
- 終わりに

##ウォッチドッグタイマーとは

システムを定期的に監視して、異常があった場合リセットするためのタイマーのことです。
ウォッチドッグ(watchdog)は番犬という意味だそうです。

[ここで大まかなイメージを説明しています。wikiとかもありますが、リンクは俺の好みで選びました。](https://wa3.i-3-i.info/word16698.html)

## 作る内容

1.秒数を数える
2.３秒ごとに異常がないか確認する。
3.ランダム（４分の１）で寝ている。
4.寝ていた場合、１秒からやり直す
5.１５秒まで起き続けられたら処理終了

## 事前準備
定期実行のプログラムを作成したいので
gemの[Timers](https://qiita.com/pekepek/items/4661ccee67dbecffe595)をインストールします。

```ruby:ターミナル
gem install timers
```

## 完成コード

```ruby:watchdog.rb
require 'timers'

def watchdog
  random = rand(4) + 1
  if random == 1
    @sleep = true 
  end
end

@time = 1
timers = Timers::Group.new
puts @time
timers.every(1) {
  @time += 1
  puts @time
}

timers.every(3) { 
  @sleep = false
  watchdog
  if @sleep == true
    puts "zzzz"
    @time = 0
  else
    puts "ワンワン！"
  end

  if @time == 15
    exit
  end
}

loop { timers.wait }  
```
出力結果

```ruby:ターミナル
1
2
3
ワンワン！
4
5
6
zzzz
1
2
3
ワンワン！
4
5
6
ワンワン！
7
8
9
ワンワン！
10
11
12
ワンワン！
13
14
15
ワンワン！
```

## 各コードの解説

事前準備でインストールしたtimersを呼び出せるようにします。

```ruby:watchdog.rb
require 'timers'
```

１秒経つごとに秒数を出力していきます。

```ruby:watchdog.rb
@time = 1
timers = Timers::Group.new
puts @time
timers.every(1) {
  @time += 1
  puts @time
}
```

３秒ごとに
・起きているか確認。起きていたらワンワンと出力
・寝ていたらzzzzと出力し、タイマーを１からリスタート


```ruby:watchdog.rb
timers.every(3) { 
  @sleep = false
  watchdog
  if @sleep == true
    puts "zzzz"
    @time = 0
  else
    puts "ワンワン！"
  end
```

起きてるかどうか確認（４分の１寝ている）

```ruby:watchdog.rb
def watchdog
  random = rand(4) + 1
  if random == 1
    @sleep = true 
  end
end
```


15秒起き続けてたら処理終了

```ruby:watchdog.rb
  if @time == 15
    exit
  end
```

処理終了するまで繰り返しをする記述

```ruby:watchdog.rb
loop { timers.wait }  
```

## 終わりに
コードを打っているうちに、本当にこれでいいのか不安になってます。。違うってはっきりわかったら作り直すかもしれません。
後、猫派なんですが、番犬じゃなくて番猫とかいないんですかね。
ウォッチキャットタイマー。ちゃんと監視してくれなさそう。
お疲れ様でした。