OmniAICreator/Qiita-1.07M huggingface dataset:
【heroku】herokuのセットアップ【Rails Tutorial 1章まとめ】

herokuのセットアップ方法🐳

##heroku用のジェムを用意

```Gemfile
group :production do
  gem 'pg'
end
```

本番環境用のグループにpgを追加する。
pgはherokuでPostgreSQLデータベースを使用するためのジェム。

##開発環境用のジェムを用意

```Gemfile
group :development, :test do
  gem 'sqlite3'
end
```

開発環境ではSQLiteを使用するため、開発用のグループにsqlite3を追加する(多分元からある)。

##本番用以外のジェムをインストール

```
$ bundle install --without production
$ git commit -a -m "Update Gemfile for Heroku"
```

--without productionを付けて、本番用以外のジェムをインストールする。
ここでコミットをしておく。

##herokuにデプロイ

```
$ heroku create
$ git push heroku
```

createでアプリケーションのサブドメインを作成して、プッシュしたら完了。
なお

```
$ heroku rename アプリケーション名
```

でアプリケーション名を変更できる。
cssメモ

# memo
~~~
//スクロールしてもついてくる要素の設定
position: -webkit-sticky;
position: sticky;

//要素寄せ
//左
float: left;
//右
float: right;
//クリア
clear: both;

//要素の重なりの優先順位をつける
//優先順位1の場合
z-index: 1;

//アイコンの円形化
border-radius: 50%;

//text中央寄せ
text-align: center;

~~~

# diplay:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382669/f97bb9be-1c6f-1296-9290-8734767ae8f3.png)
Tensorflow.js を Typescript で compile error なく動かす


tensorflow.js を typescript で楽に扱いたかっただけなんです．

## 要約

- typescript: 3.5.3
- @types/webgl2: 0.0.5
- tsconfig.json は tfjs 本家をベースにする


## 当時の環境

- vue: 2.6.10
- typescript: 3.6.2
- vue-property-decorator: 8.1.0
- tensorflow: 1.3.2

## 発生したエラーと解決法

原因までは分かんないです．誰か解説してください．

### tensorflow.js

```
Subsequent variable declarations must have the same type.  Variable 'WebGL2RenderingContext' must be of type '{ new (): ...

582 declare var WebGL2RenderingContext: {
                ~~~~~~~~~~~~~~~~~~~~~~
```

WebGL2RenderingContext で前のと違う型が宣言されているらしいです．探してany にしてるStackoverflowもあった気がします．

私は [公式の tsconfig](https://github.com/tensorflow/tfjs/blob/master/tsconfig.json) をコピペしました．
また vue-property-decorator を使っていたので

```json
{
  "compilerOptions": {
    "module": "esnext",
    "target": "esnext",
    "experimentalDecorators": true
  }
}
```

あたりを書き換え／加えました．

### WebGL
```
Interface 'WebGL2RenderingContext' incorrectly extends interface 'WebGL2RenderingContextBase'.
```
のようなエラーが3種．

WebGL2RenderingContext が 2 じゃないほうを正しく継承できていないそうです．これも無理やり書き換えてもいいと思います．私は趣味のプロダクトだったので typescript をダウングレードしました．

```
yarn upgrade typescript@3.5.3
yarn add -D @types/webgl2: 0.0.5
```

もしやと思って typescript のバージョンを公式と揃えたらたまたまうまくいっただけです．3.4.3 や3.6.3 だとエラーが出ました．

「 typescript のダウングレードはきついっす......」というときは，該当箇所を any にするとか継承せずにそれっぽい型を書き上げるか，ファイル自体をignoreすればいいと思います．たぶん．




．
【Swift】UserDefaultsを使って、日付更新ごとに処理する方法

#UserDefaultsとは？
UserDefaultsとは簡単に言うとキーバリュー型のDB(データベース)にアクセスするために用いるもので、これを用いることで、アプリの起動時にキーと値のペアを永続的に保存することができます。その他の特徴を下記に記しておきます。

**・< Key, Value >形式の辞書型でアクセス可能。**
**・各iOSアプリは、1端末に対して1つのUserDefaultsを保持している。**
**・アプリを削除するとUserDefaultsも消えるため、同じアプリを再インストールしてもUseDefaultsはリセットされる。**

UserDefaultsは以上のような特徴を持っていて、主な使用目的としてはユーザーの設定情報（Preferences）を永続的に保存することが目的として挙げられます。


#日付更新ごとの処理
今回はこのUserDefaultsを使って、日にちが変わるごとに何かしらの処理を実行してくれるようなプログラムを組んでいきます。
下記が全体コードになります。

```
import UIKit

// userdefaultsを用意しておく
let UD = UserDefaults.standard
 
//日付判定関数
func judgeDate(){
    //現在のカレンダ情報を設定
    let calender = Calendar.current
    //日本時間を設定
    let now_day = Date(timeIntervalSinceNow: 60 * 60 * 9)
    //日付判定結果
    var judge = Bool()
    
    // 日時経過チェック
    if UD.object(forKey: "today") != nil {
         let past_day = UD.object(forKey: "today") as! Date
         let now = calender.component(.day, from: now_day)
         let past = calender.component(.day, from: past_day)
        
         //日にちが変わっていた場合
         if now != past {
            judge = true
         }
         else {
            judge = false
         }
     }
     //初回実行のみelse
     else {
         judge = true
         /* 今の日時を保存 */
         UD.set(now_day, forKey: "today")
     }
     
     /* 日付が変わった場合はtrueの処理 */
     if judge == true {
          judge = false
　　　　//日付が変わった時の処理をここに書く
     }
     else {
      //日付が変わっていない時の処理をここに書く 
     }
}
```
まずUserDefaultsが使えるように定数に代入します。

```
// userdefaultsを用意しておく
let UD = UserDefaults.standard
```
そしてcalender定数に現在のカレンダー情報を代入、now_dayに現在の日本時間を代入、最後に日付判定を行うBool値の変数を定義します。

```
func judgeDate(){
    //現在のカレンダ情報を設定
    let calender = Calendar.current
    //日本時間を設定
    let now_day = Date(timeIntervalSinceNow: 60 * 60 * 9)
    //日付判定結果
    var judge = Bool()
```
次にif文でUserDefaultsのtodayキーに値があるか判定します。
あったらif文内の処理へ、なかったら後ほど解説の初回起動時の処理へ進みます。
if文内の処理ではまず最初にpast_dayにすでに保存してあった日時情報を代入し、nowに現在の日付を代入、そしてpastにpast_dayの日時情報を使って過去の日付を代入します。

```
 if UD.object(forKey: "today") != nil {
         let past_day = UD.object(forKey: "today") as! Date
         let now = calender.component(.day, from: now_day)
         let past = calender.component(.day, from: past_day)
        
```
次に先ほど代入したnowがpastと異なる場合はjudgeにtrueを、同一であればfalseを代入します。

```
if now != past {
            judge = true
         }
         else {
            judge = false
         }
     }
```
次に初回起動時の処理としてjudgeにtrueを代入し、現在日時をUserDefaultsに設定します。

```
 //初回実行のみelse
     else {
         judge = true
         /* 今の日時を保存 */
         UD.set(now_day, forKey: "today")
     }
```
最後にif文で初回起動時・日付変更時にする処理を記述し、else内で日付が変わっていない時にする処理を記述します。

```
 /* 日付が変わった・初回起動時の場合はtrueの処理 */
     if judge == true {
          judge = false
　　　　//日付が変わった時の処理をここに書く
     }
     else {
      //日付が変わっていない時の処理をここに書く 
     }
}
```
【Git】Gitの基本的なコマンドと流れ【Rails Tutorial 1章まとめ】

Gitによるバージョン管理とコード保存のコマンドと流れを整理🐳

##Gitの初期化
アプリケーションごとに最初に一回だけ行う。

```
$ git init
```

##add→commit→push

```
$ git add -A
$ git commit -m "comment"
$ git push
```

addでコミットするファイルを選択する。
-Aは全てのファイルを選択するオプション。
個別のファイル・ディレクトリを選択する場合は、addの後にファイル名・ディレクトリ名を置く。
特定の拡張子のファイルのみを選択する場合は、*.jsのようにする。
コミットの前に$ git statusで状態を確認できる。

commitで選択したファイルをローカルレポジトリ（要は自分のパソコン）に保存する。
-m "comment"のようにしてコメントを付ける。
コメントは命令形で書くのが慣例。
コミット後は$ git logでコミットメッセージの履歴を確認できる。
ちなみに-aをつけることで新規ファイル以外の全ての変更をcommitできるため、addは不要。

pushでGithubにファイルを保存する。
最初はGithubでレポジトリを作成した際に表示される「…or push an existing repository from the command line」のところにあるコマンドをコピペして使用する。
以降は$ git pushのみでOK。

##トピックブランチの使い方
作業の大枠ごとにブランチを作って作業する。

```
$ git checkout -b ブランチ名
$ git checkout master
$ git merge ブランチ名

$ git branch -d ブランチ名
```

checkoutでブランチを切り替える。
-bを付けてブランチ名を入力することで、ブランチの作成と切り替えを同時に行える。
コードを書き終わったらmasterブランチに戻る。
mergeでブランチの変更をmasterブランチに適用する。
トピックブランチが不要であれば、-dを用いてトピックブランチを削除できる。
ちなみに-Dとすると、マージ前でもブランチを削除できる。
ブランチの一覧と、今どのブランチを使用しているかは$ git branchで確認できる。

##herokuへpush
```
$ git push heroku master
```
本番環境のherokuにコードをプッシュする。
masterは省略可。
マイナスと丸の全角文字の話

# ソースコードに全角記号を使う

プロデル言語では、文字列定数以外の場所で、記号に全角文字を使うことを許容しています。プログラムのほとんどで日本語文字(漢字,ひらがな,カタカナ)を使ってプログラムを記述し、IMEをオンにする状態が多く、全角文字で入れられる方が都合が良いためです。
今回は、プロデルとは直接関係がない話ですが、プロデル言語で使われるマイナスと丸の記号の話をしようと思います。

## マイナス記号

プロデル言語では他の言語と同様に負の数を表す「マイナス」記号を使います。マイナスは全角文字も半角文字と同様に扱われます。例えば-10と書いても－１０と書いても同じ値を表します。

Unicodeには、ハイフンマイナスやダッシュ、長音記号など、マイナスに見た目が似た記号がたくさん定義されています。最近まで私自身知りませんでしたが、日本語キーボードで入力できるマイナス記号は、実際はハイフンマイナス(-－)と呼ばれるもので、Unicodeでは「マイナス」(−)を意味する記号は別に用意されています。
また、ダッシュについては半角文字と全角文字がそれぞれ用意されており、さらに罫線を表す文字も含めて、見た目が同じ記号を4種類ぐらいは挙げることができます。
プロデル言語では、ハイフンダッシュ(-－),マイナス(−),ダッシュ(–—)を「マイナス」と扱い、長音「ー」(記号)や「─」(罫線)はマイナスとしては見なさないことにしました。

##真(true)を表す○

同じような問題が「まる」○でも起こります。プロデル言語には真偽を表す記号として○と×があります。当初、プロデルでの真偽値の表記には、「真」と「偽」だけを用意していましたが、より身近な記号である「○」と「×」も後から対応することにしました。
ところがその後、掲示板で「〇」が真として扱われないというご指摘を頂きました。よく見ると「○」ではなくて「〇」です(違いが分かりますでしょうか...)。

試しにIMEで「まる」と入れて変換すると、確かに○以外にも、それらしい記号が沢山表示されます。よく調べてみると、掲示板にあった「〇」は、漢数字のゼロを表す文字であると分かりました。IMEで変換候補の記号の名前が表示されますが、気が付かずに選んでしまうケースもあるかと思います。

言語仕様を決めるに当たり、見た目が同じ記号について、どの記号,文字を有効と認めるかが問題になってきます。記号の意味の厳密さを取るか、入力時の利便性を取るかのどちらかの基準で決めないといけません。
結局、「まる」については○(記号)と〇(漢数字)をどちらも認めることにしました。
理由としては、プロデルが日本語プログラミング言語であるという特徴からPCに扱いに慣れない方が使うことも想定しているので、入れ間違いはある程度許容したいため、また、元々言語仕様で漢数字をリテラルの数字として認識せず、ゼロと意味が重ならなかったためです。

逆に言えば、漢数字をリテラルの数字として認めてしまうと、〇(漢数字のゼロ)が数値の0と同じ値なので、偽(false=0)を表すことになり、見た目が類似する記号が全く逆の意味を表してしまい、深刻な問題になる可能性がありました。(数字をわざわざ漢数字で入れることは考えにくいので漢数字は無視しても困らないでしょう...)

##まとめ

今回は、見た目が酷似するマイナスと丸の全角文字をプロデル言語ではどのように扱っているかの話でした。こういった記号の違いが問題になるのは日本語プログラミング言語特有な話であり、多くのプログラミング言語では問題にすらならならないのではないかと思います...

ただ、マイナスについては日本語プログラミング言語に限らず、ソースコードにUnicodeをサポートする処理系では問題になることと思います。調査はしていませんが、プログラミング言語によって扱いに違いがありそうです。言語処理系を作る方は、調べてみると面白いかも知れません。

Qiitaに書くには場違いな気がしますが、折角の機会ですので書いてみました。
web(java)の制作必要なもの練習メモ　作成中

#web(java)の勉強をしているときに使ったものです


###maven
Java用プロジェクト管理ツールでApache Antに代わるものとして作られた
ウィッキペディアページ https://ja.wikipedia.org/wiki/Apache_Maven
参考ページ　https://qiita.com/tarosa0001/items/e5667cfa857529900216
これがあるといろいろな機能を追加するとき楽

###SQL
#####sql

#####jdbc 
 Java と関係データベースの接続のためのAPI
ウィッキペディアページ　https://ja.wikipedia.org/wiki/JDBC

######hibernate  
Java のためのオブジェクト関係マッピング (ORM) ライブラリでオブジェクト指向のドメインモデルを関係データベースにマッピングするためのフレームワーク
ウィッキペディアページ https://ja.wikipedia.org/wiki/Hibernate
操作参考 https://qiita.com/Maruo110/items/4dc4a49aedd6323ebfdb

###フィルタ
javaリソース->srcにパッケージを作成
EncodingFilter(フィルター)を作成しdoFilterに
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
を設定することにより各サーブレットとjspに記述する必要がなくなる

ログを残すフィルタ
doFilterに
System.out.println( ((HttpServletRequest)request).getRequestURI() + ":" + new Date() );
に記述するとコンソールにアクセスログを残す
[メモ] SQL学習2 (DISTINCT, 四則演算, SUM, AVG, COUNT, MAX / MIN, GROUP BY, HAVING)

# DISTINCT

「DISTINCT」は、指定のカラムの検索結果から重複するデータを除くことができる。
以下例はuserテーブルからnameカラムの重複するデータを省略して取得している。

```sql
SELECT DISTINCT(name)
FROM user;
```

# 四則演算

SQLでは四則演算を使って取得結果を加工することができる。
以下例はfoodテーブルのfood_nameカラムとpriceカラムに100掛けたデータを取得している。

```sql
SELECT food_name, price * 100
FROM food;
```

# SUM

数値の合計を計算したい時は「SUM」を使う。
指定したカラムの合計を計算して取得する。
WHEREと併用可能。
以下例はuserテーブルのnameカラムの山田さんの支払い額の合計を取得している。

```sql
SELECT SUM(pay_money)
FROM user
WHERE name = '山田';
```

# AVG

数値の平均を求めるには「AVG」を使う。
指定したカラムに保存されているデータの平均を計算する。
WHEREと併用可能。
以下例はuserテーブルのnameカラムの山田さんの睡眠時間の平均を取得している。

```sql
SELECT AVG(sleep_time)
FROM user
WHERE name = '山田';
```

# COUNT

「COUNT」は指定したカラムのデータの合計数を計算する。
**COUNTはNULLデータの数を計算しない。**
例えば、全5件のデータ中3件がNULLの場合、取得結果は全部で2件となる。

**NULLデータも含めて計算したい場合は「\*」で全カラムを指定する。**
「\*」を使った場合、特定のカラムのデータの数ではなく、レコードの数を計算する。

WHEREと併用可能。

以下例はWHEREによって山田さんがいくつボールを買ったかを取得している。

```sql
-- ballカラム内のNULLデータを含んで取得する場合
SELECT COUNT(*)
FROM toy
WHERE name = '山田';

-- ballカラム内のNULLデータを含まずに取得する場合
SELECT COUNT(ball)
FROM toy
WHERE name = '山田';
```

# MAX / MIN

指定したカラム内のデータで最大のデータを取得したい場合は「MAX」を、最小のデータを取得したい場合は「MIN」を使う。
WHEREと併用可能。
以下例は山田さんが買った一番高い金額を取得している。

```sql
SELECT MAX(price)
FROM shop
WHERE name = '山田';
```

# GROUP BY

「GROUP BY」を用いると、データをグループ化することができる。
「GROUP BY カラム名」とすることで、指定したカラムで完全に同一のデータを持つレコードどうしが同じグループとなる。
グループ化するには、今までの集計関数を取得する**FROMの後ろ**に「GROUP BY カラム名」を追加する。

**GROUP BYを用いる場合、SELECTで使えるのはGROUP BYに指定しているカラム名と、集計関数のみ。**

**SELECTで集計関数を使っていない場合、日付ごとに集計された値が取得できない。(*A)**

```sql

SELECT SUM(price), shop_date
FROM shop
GROUP BY shop_date;

-- *A
SELECT price, shop_date
FROM shop
GROUP BY shop_date;
```

## GROUP BYに複数のカラムを指定する

「GROUP BY」は複数のカラム名を適用させることができ、その場合は、カラム名同士をコンマ(,)で区切る。
以下例のように日付と名前ごとに合計金額を取得できる。そのほかにも、日付と名前ごとに来店回数を取得することもできる。

```sql

SELECT SUM(price), shop_date, name
FROM shop
GROUP BY shop_date, name;
```

## GROUP BYとWHEREを併用する

GROUP BYはWHEREと併用することができ、**WHEREの後に記述**する。

実行順序は上から

1. WHERE (条件検索)
2. GROUP BY (グループ化)
3. COUNT, SUM, AVG, MAX, MIN (集計関数)

```sql

SELECT 集計関数
FROM テーブル名
WHERE 条件
GROUP BY カラム名A, カラム名B;
```

以下例は「帽子」のレコードを検索して、日付と名前でグループ化している。
最後にグループ化した結果に関して集計関数(今回はSUM関数)で計算している。

```sql

SELECT SUM(price), shop_date, name
FROM shop
WHERE category = "帽子"
GROUP BY shop_date, name;
```

# HAVING

GROUP BYでグループ化したデータを更に絞り込みたい場合には「HAVING」を用いる。
「GROUP BY カラム名 HAVING 条件」のようにすることで、条件を満たすグループを取得することが可能。
グループ化された後で条件を元に検索される。

実行順序は上から

1. WHERE (条件検索)
2. GROUP BY (グループ化)
3. COUNT, SUM, AVG, MAX, MIN (集計関数)
4. HAVING 

**WHEREはグループ化される前のテーブル全体を検索対象とするのに対し、HAVINGはGROUP BYによってグループ化されたデータを検索対象としている**

HAVINGの注意点として、**グループ化された後のテーブルから検索するため、条件文で使うカラムは必ずグループ化されたテーブルのカラムを使う。**

以下例は日付でグループ化して集計、そして合計額1000円以下を条件にデータを取得している。

```sql

SELECT SUM(price), shop_date
FROM shop
GROUP BY shop_date
HAVING SUM(price) <= 1000;
```
Gitでローカルリポジトリを作成して、Salesforceソース管理する

１．[Gitインストールする](https://git-scm.com/downloads "Git")
２．[TortoiseGitインストールする](https://tortoisegit.org/download/ "TortoiseGit")

３．ロカールでフォルダを作成する（例として：Sampleフォルダ）
４．Sampleフォルダ下に、[git init]コマンドを実行して、ロカールリポジトリを作成する
　　```C:\Sample>git init```

５．VSCodeでSalesforceソース取得して、Sampleフォルダ下に保存する
６．下記のコマンドでSalesforceソースをロカールリポジトリに追加する
　　**C:\Sample>git add .**
　　**C:\Sample>git commit -m メッセージ**
７．または、**フォルダ**選択して、右クリックして、TortoiseGitでコミットする
　　**TortoiseGit　⇒　追加　⇒　Gitコミット(C)**
８．修正・追加があれば、上記の**６OR７**を実行する
お手軽なサンプルデータ作成手順

ホームページ：https://program-board.com


##モチベーション
今回色々、サンプルデータを使って遊びたいと思ったが、お手軽に作れるAPIは存在するが自由度が低いと感じたため、自作で作ることを決めました。

##モジュール
モジュールのインストールを行います．ここではpandas,numpyと偽データを簡単に生成できるfakerというモジュールを使います．

```
pip install faker
```
##fakerについて
fakerの基本的な使い方を記述します．Faker(‘ja_JP’)で日本語用の偽データを生成する準備をします． あとは，好きな種類のデータを生成してみてください．英語ですが，以下のサイトにFakerが生成できるデータが載っています．
https://www.nblog09.com/w/2019/01/24/python-faker/

ここでは，名前，都道府県，会社，生年月日，職業を生成します．

```python
# 日本語偽データの設定
from faker import Faker

# 日本語偽データの設定
fakegen = Faker('ja_JP')

print(fakegen.name())#名前
print(fakegen.prefecture())#都道府県
print(fakegen.company()) #会社
print(fakegen.date_of_birth()) #生年月日
print(fakegen.job()) #職業
```

##偽データの生成

まず，名前，生年月日，住所(都道府県)，職業，会社の偽データを生成します．

```python
import numpy as np
import pandas as pd
from numpy.random import *
from faker import Faker

# 日本語偽データの設定
fakegen = Faker('ja_JP')
faker_list = []
for i in range(1000):
    name = fakegen.name() #名前
    pref = fakegen.prefecture() #都道府県
    company = fakegen.company() #会社
    birth = fakegen.date_of_birth() #生年月日
    job = fakegen.job() #職業
    faker_list.append([name,pref,company,birth,job])

# データフレーム化
df = pd.DataFrame(faker_list,columns=['名前','住所','会社','生年月日','職業'])
```

こんな感じで、簡単に作成することが可能です。

###年齢
年齢の偽データを生成します．ここでは，numpyを用いり15〜85の一様分布の乱数からデータを生成します．欠損値を考慮してここでは800しか作りません．また，他の項目で欠損値を生成する際に同じ行で重ならないよう，データの並び方をごちゃにします．

```python
age_list = randint(15,85,800) # 一様分布(下限,上限,生成数)
# データフレームに追加
df['年齢'] = pd.DataFrame(age_list)
# データの並び方をごちゃにする．
df = df.sample(frac=1)
```

###年収・身長

年収・身長の偽データを生成します．ここでは，numpyを用いり平均値と分散の値を適当に決め，正規分布からデータを生成します．

```python
# 身長
height_list = normal(170,6,900) # 正規分布(平均,分散,生成数)
height_list = np.round(height_list,decimals=0) # 整数止め
# データフレームに追加
df['身長'] = pd.DataFrame(height_list)
# データの並び方をごちゃにする．
df = df.sample(frac=1)

# 年収
income_list = normal(400,8,850) # 正規分布(平均,分散,生成数)
income_list = np.round(income_list,decimals=0) # 整数止め
# データフレームに追加
df['年収'] = pd.DataFrame(income_list)
# データの並び方をごちゃにする．
df = df.sample(frac=1)
```

###婚姻
婚姻偽データは，numpyのnp.random.choiceで用意した選択肢を決まった割合で乱数生成します．

```python
#性別
mariage = ['未婚','既婚','離別'] #選択肢
Weight = [0.4,0.3,0.3] #割合
mariage_list = np.random.choice(mariage,700,p=Weight) #np.random.choice(選択肢,生成数,割合)
# データフレームに追加
df['婚姻'] = pd.DataFrame(mariage_list)
# データの並び方をごちゃにする．
df = df.sample(frac=1)
```

<img width="512" alt="スクリーンショット-2019-11-19-3.53.49-1024x432.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504780/fe4b7a9a-672e-4d46-a970-487ee5e70d72.png">

##おわりに
データ分析の練習用に偽データの生成を行いました．ただし，分析練習用にデータを生成するためには，生成に用いる分布の種類やパラメータを確認して実行する必要があります.

##参考
https://www.nblog09.com/w/2019/01/24/python-faker/
https://qiita.com/ogamiki/items/4821173ca713a6b77510
Javaのポリモーフィズム super()について

ポリモーフィズムを改めて調べたのでまとめておく
今回はsuper()を深ぼって理解したい


**対象**  

- なんとなくでJavaを書いている人

## super()とは、親クラスのコンストラクタである
**結論**である

具体例で試していこうと思う

## 具体例
```Person.java
public class Person {
    Person() {
        System.out.println("人間です。" + );
    }
}
```
```Student.java
public class Student extends Person {
    Student() {
        System.out.println("学生です。");
    }
}
```
```Main.java
public class Main {
    public static void main() {
        new Student();
    }
}
```
```result
人間です。
学生です。
```

## 解説
Studentクラスのコンストラクタに「人間です。」を出力する記述をしていないが表示される。
つまり、Personを継承したStudentクラスのコンストラクタは

```Person.java
public class Student extends Person {
    Student() {
        super();
        System.out.println("学生です。");
    }
}
```
このようになっている。
> （実際になっているわけではないが明示的に書くとこんな感じ。継承クラスのインスタンスを生成すると親クラスのコンストラクタが自動で呼ばれる）

このsuper()こそが親クラスのコンストラクタ。

## 引数を追加
次に親クラスのコンストラクタに引数を追加する

```Person.java
public class Person {

    private String name;

    Person(String name) {
        this.name = name;
        System.out.println(name + "です。");
    }
}
```
```Main.java
public class Main {
    public static void main() {
        new Student();
    }
}
```

はい。コンパイルエラーです。Personクラスのコンストラクタが引数を要求しているからです。
こういう場合はStudentクラスでsuper()に引数を入れて呼んであげる必要があります。

```Student.java
public class Student extends Person {
    Student(String name) {
        super(name);
        System.out.println("学生です。");
    }
}
```
```Main.java
public class Main {
    public static void main() {
        new Student("山田");
    }
}
```
```
山田です。
学生です。
```

StudentはPersonを継承しているので、nameフィールドも持っています

```Main.java
public class Main {
    public static void main() {
        Student student = new Student("山田");
        System.out.println(student.name);
    }
}
```
```
山田です。
学生です。
山田
```
OSインストール時のエラー「Setting up standard PCI resources」への解決方法

#OSをインストールする際に発生するエラー

OSをインストールする際、コンソールに以下の文が出力されてから全く進まなくなりました。

```
Setting up standard PCI resources
```

私の場合はXPの解析ツールのインストール時でしたが、解決策を模索しているとCentOS等でも発生しているようなので、広義の「OS」と書きました。

結論として、
インストーラを起動する際にオプションを指定できる場合は、次を入力してください。

```
boot: linux acpi=off
```

#原因の考察
ACPI(Advanced Configuration and Power Interface)とは、OS側から電源制御を行うための規格のことです。
おそらく、原因はコンピュータとOSのバージョンの互換性がないからではないかと考えています。
（私の盛大な推測ですので、原因究明できたら追記します）

WindowsなんかでACPIをoffにした状態で起動すると破損する可能性があるらしいので、使用には注意が必要です。
aliasの便利コマンドを教えてほしい話

UNIXやLINUX上でコマンドを省略した形で登録することのできるaliasについて紹介する

alias:コマンドの省略形が作成できる

## bash  
``` bash
$ alias 登録したい単語='登録したいコマンド'  
```
```bash
$ alias histail='history | grep curl | tail'
$ histail
 3295  curl "http://localhost:8080"
 3296  curl "http://localhost:8080"
 3297  curl "http://localhost:8080"
 3298  curl "http://localhost:8080"
```

## zsh
~/.zshrcにbashと同じように記述することでaliasを登録できる

```bash
$ vi ~/.zshrc

alias histail='history | grep curl | tail'
alias rezsh='source ~/.zshrc'
alias redoc='docker-compose stop && yes | docker-compose rm && docker-compose up -d'
alias -g @b64='| base64 '
alias -g @d64='| base64 -D'
alias -g g='|grep '
alias vish='vi ~/.zshrc'
```

zshにはグローバルエイリアスと呼ばれるエイリアスが登録できる
グローバルエイリアスは普通のエイリアスと違い、呼ばれる場所を問わない（普通のエイリアスは文頭限定）

なので  

```
$ echo aaaaaaa @b64
```

とすることでbase64エンコードをかけることなどができる
（あまり省略できてないとは言わないでください）

## aliasメモ
便利だと思ったaliasをメモ的に列挙しておきたいので、教えてください（他力本願）

|alias  |元のコマンド  |操作説明  |
|---|---|---|
|rezsh |source ~/.zshrc |zshの設定ファイルを再読み込みさせる |
|redoc |docker-compose stop && yes &#124; docker-compose rm && docker-compose up -d &#124;docker-composeの再起動を行う |
|sd|docker-compose stop|docker-composeを止める|
|rd|docker-compose rm|docker-composeの設定を削除する|
|ud|docker-compose up -d|docker-composeを立ち上げる|
|vish |vi ~/.zshrc |zshの設定ファイルを編集する |
|@b64|&#124; base64 |base64エンコーディングを行う|
|@d64|&#124; base64 -D|base64デコーディングを行う|
踏み台サーバーを超えていけ

踏み台サーバーを踏み倒すときに使えるコマンド

**ProxyCommand**：文字の通りにプロキシ上で動作するコマンドを指定できる

## scp接続

```bash
$ scp -o 'ProxyCommand ssh -A fumidai.co.jp nc %h %p' hoge,txt honban.co.jp:/home/hogehoge
```

本来の目的：honban.co.jpにhoge.txtをscpする
ProxyCommandがはたらき、踏み台サーバーを通り越してscp接続することができる

**利点**
- コピーが1回しか動かないので踏み台を通すより早い
- 踏み台サーバーに余計なファイルが残らない
- scpコマンドが使えない踏み台サーバーを超えられる
- はやい

## ssh接続

```bash
$ ssh -oProxyCommand='ssh -W %h:%p fumidai.co,jp' honban.co.jp
```

## 2段以上の多段接続

~/.ssh/configに接続情報を記録しておくことで何段階でも多段接続することができます

```bash
$ vi ~/.ssh/config

Host fumidai-first
    HostName fumidai-first.co.jp
    User hogehoge
    IdentityFile ~/.ssh/id_rsa

Host fumidai-second
    HostName fumidai-second.co.jp
    User hogehoge
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh fumidai-first -W %h:%p

Host honban
    HostName honban.co.jp
    User hogehoge
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh fumidai-second -W %h:%p
```

このように設定しておけば「ssh honban」で本番に接続することができます。
Firebase App Distribution で App Distribution found more than 1 output file for this variant のエラーが出たときの対応

# はじめに
Firebase App Distribution の `appDistributionUpload` の Gradle task を実行した際に

```
== BUILD FAILED ==

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:appDistributionUploadXxxYyy'.
> App Distribution found more than 1 output file for this variant. Please contact firebase-support@google.com for help using APK splits with App Distribution.

```
が表示された場合の解決方法です。
（APK splits を行っている Android project で再現します。）

# 原因
ビルドを行うと複数の apk ファイルが生成され、どの apk ファイルがアップロード対象かどうかが特定できないためです。

# 対応
`build.gradle` の distribution properties に `apkPath` を指定する。

例）

```Groovy
buildTypes {
    release {
        ...
        firebaseAppDistribution {
            apkPath = "app/build/outputs/apk/xxxYyy/debug/xxx.apk"
        }
    }
}
```

productFlavors を設定している場合は、もう少し工夫が必要そう。。。

※仕様に明記されていないので、サポートされなくなる可能性もあります。
【追記：2020/05/11】
英語のドキュメントには `apkPath` が記載されていました。
https://firebase.google.com/docs/app-distribution/android/distribute-gradle?hl=en#step_3_configure_your_distribution_properties
（日本語はまだでした…）
※Gradle Plugin 1.2.0 で動作確認済み
【ポエム】三ツ星をめざす開発チームの新人育成法

【注意】 本記事はポエムです。ポエムを求めていない方は、そっとページを離れてください。

### 新人には ~~料理を作らせない~~ コードを書かせない。

### ~~料理道具~~ 開発環境 は選んで与える。

### 業務時間外の ~~修行~~ プルリク はあたりまえ。

### ~~まかない~~ ツール作成 を通して指導する。

### 与えすぎずに考えさせる。評価は適切に行う。

### ~~レシピの流出~~ ソースコードの公開 を気にしない。
docker-composeメモ（MySQL、FTPサーバ）

完全に自分用のメモ書きです

## mysql 

ディレクトリ構造

```
project
 ├─ docker
 │    └ mysql
 │        ├─ conf 
 │        │    └─ my.cnf
 │        ├─ initdb.d
 │        │    ├─ 101_profile.sql
 │        │    ├─ 102_branch.sql
 │        │    └─ 103_price.sql
 │        └─ Dockerfile
 │
 └─ docker-compose.yml
```

```docker-compose.yml
version: '3.3'
services:
  db:
    build: ./docker/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: user0101
      MYSQL_PASSWORD: password
      MYSQL_DATABASE: human
      TZ: Asia/Tokyo
    ports:
      - "3301:3301"
    volumes:
      - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
      - ./docker/mysql/conf:/etc/mysql/conf.d
```

```my.cnf
[mysqld]
character-set-server=utf8mb4
explicit_defaults_for_timestamp=1
general_log=1
general_log_file=/var/log/mysqld-query.log
wait_timeout = 60

[client]
default-character-set=utf8mb4
```
## ftp
ディレクトリ構造

```
project
 ├─ docker
 │    └ ftp
 │        ├─ etc 
 │        └─ home
 │            └─ hoge.txt
 │
 └─ docker-compose.yml
```

```docker-compose.yml
version: '3'
services:
  ftp-server:
    image: stilliard/pure-ftpd:latest
    container_name: ftp-server
    ports:
      - "21:21"
      - "30000-30009:30000-30009"
    volumes:
      - ./docker/ftp/home:/home/ftpusers
      - ./docker/ftp/etc:/etc/ssl/private
    environment:
      - PUBLICHOST=localhost
      - FTP_USER_NAME=ftpuser
      - FTP_USER_PASS=12345678
      - FTP_USER_HOME=/home/ftpusers
      - ADDED_FLAGS="--tls=2"
    restart: always
```
SSHについてまとめてみた

GithubやEC2に接続する際になんとなく行っていたSSH接続について簡単にまとめてみた。

#SSHとは?
SSH(Secure Shell)の略称で、遠隔地のサーバーなどを操作するために作られたプロトコルである。
Telnetも同じような仕組みだが、暗号化されないので、SSHが主流となっている。
SSHの認証方式として、「パスワード認証」と「公開鍵認証」の２つが用意されている。

#パスワード認証
サーバー側のユーザー名とパスワードで認証する方式。
**メリット**
　サーバー側のユーザー名とパスワードを知ってさえいれば良いので、クライアント側で特別な操作が不要。

**デメリット**
　パスワードがネットワーク上に流れるため、第三者に盗まれる可能性がある。
　そもそもパスワードがソーシャルエンジニアリング等で第三者に知られてしまえば効果がない。

#公開鍵認証

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451305/38417a8a-2ade-1830-5b01-59aaed3effb7.png)

①(受信者)が公開鍵と秘密鍵をあらかじめ準備する。
②(送信者)が公開されている公開鍵を取得する。
③(送信者)が取得した公開鍵を使ってデータを暗号化する。
④(受信者)が秘密鍵を使ってデータを複合化する。

**メリット**
　データが暗号化されているため、パスワード認証よりも安全である。
　また、秘密鍵へのアクセスもパスフレーズが必要なので、万が一端末を盗まれても安全。

**デメリット**
  前もって鍵ペア(公開鍵、秘密鍵)を作成しておく必要があるので、最初の設定が少しめんどくさい。

#鍵ペア(公開鍵、秘密鍵)の作成
```
$ cd ~/.ssh

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
```
上記を実行すると、以下２つの鍵が生成される。

- id_rsa(秘密鍵)     
- id_rsa.pub(公開鍵)

[こちら](https://euske.github.io/openssh-jman/ssh-keygen.html)にオプションの詳しい説明も載っていますので、参考にしてみてください。

以上。

#参考
- [.3 Git サーバー - SSH 公開鍵の作成](https://git-scm.com/book/ja/v1/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90)
- [インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識](https://qiita.com/tag1216/items/5d06bad7468f731f590e)
- スラスラわかるネットワーク&TCP/IPのきほん 第２版
SDWebImage5にcacheMemoryOnlyオプションがいない

## 概要

SDWebImageを4系から5系にアップデートする必要があったのですが、
ディスクキャッシュを使用しない`cacheMemoryOnly`オプションが`options`から消えたようです。
contextが使えない方向けのピンポイントなマイグレーションガイドです。

## 経緯

StackOverFlowで秒殺だと思ったのですが、意外に簡潔なSwift用サンプルが見つからず。

公式GitHubで同じ質問をしてる人がいましたが、ちょっと分かりづらい気がしたので記事にしました。
https://github.com/SDWebImage/SDWebImage/issues/2729

一応、issueにある回答としては以下になります。

```swift
imageView.sd_setImage(with: url, 
  placeholderImage: nil, 
  context: [.storeCacheType : SDImageCacheType.memory.rawValue])
```
contextに辞書でいれるだけですね。
ただ、ホントに`rawValue`まで記載するの？と気になることばかりです。

## reference

これだけだとPRを通す根拠に欠けるのでリファレンスを探しました。

### SDWebImage - 5.0 Migration guide
https://github.com/SDWebImage/SDWebImage/wiki/5.0-Migration-guide

#### SDWebImageOptionsの項目から引用
> SDWebImageCacheMemoryOnly removed, use @{SDWebImageContextStoreCacheType : @(SDImageCacheTypeMemory)} context option instead. For Swift user, using [.storeCacheType: SDImageCacheType.memory.rawValue] (rawValue is important, same for other scalar type context option).

冗長に見えますが先程の回答の実装で問題なさそうです。

## Migrationつまづきポイント

SDWebImage4系のときのコード▼

```swift
imageView.sd_setImage(with: url, 
  placeholderImage: UIImage(named: "hoge"), 
  options: [.cacheMemoryOnly, .retryFailed], 
  completed: {(image, error, ctype, url) in
```

5系だとこんな感じか？▼

```swift
imageView.sd_setImage(with: url, 
  placeholderImage: UIImage(named: "hoge"), 
  options: [.retryFailed], 
  context: [.storeCacheType: SDImageCacheType.memory.rawValue], 
  completed: {(image, error, ctype, url) in
```

上記にするとコンパイルエラーで変更案が表示され、従うとcontextがprogressに...
→ progressに辞書を渡してももちろんダメ:frowning2:

#### 原因

ライブラリの中を追えば分かるのですが、`UIImageView+WebCache.h`を見ると
`sd_setImage()`メソッドは、`placeholderImage`, `options`, `progress`, `completed`全ての組み合わせを網羅しているわけではありません。
一番近いオーバーライドが以下だったので、contextがprogressに提案されたのでしょう。

```objc
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable SDExternalCompletionBlock)completedBlock;
```

以下を利用すれば大丈夫そうですね。

```objc
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable SDExternalCompletionBlock)completedBlock;
```

修正したコード ▼

```swift
imageView.sd_setImage(with: url, 
  placeholderImage: UIImage(named: "hoge"), 
  options: [.retryFailed], 
  context: [.storeCacheType: SDImageCacheType.memory.rawValue], 
  progress: nil,
  completed: {(image, error, ctype, url) in
```

## おわり

完成されたライブラリだと思っていたので、ここにきてなかなかの変更ですね！
SDWebImageのポテンシャルをフル活用するのだけが目的のアプリつくるのも楽しそうですｗ
Ginのミドルウェアを使ったエラーハンドリング

# はじめに

ginでAPIなんかを書いていると、エラーを返すとき、

```go
if err != nil {
	log.Print(err)
	c.AbortWithJSON(http.StatusInternalServerError, gin.H{
		"Error": "Request failed"
	})
}
```

のようなコードが（気をつけないと）あちこちに散らばってしまいます。
このままだと、例えばログの表示方法や保存方法が変わることになったときなどに一つひとつ手直ししないといけません。
そこで、ミドルウェアを使ってエラー時の処理をまとめたいと思います。

## バージョン

Go : v1.12
[gin](https://github.com/gin-gonic/gin) : v1.5

# ミドルウェアについて

ginではミドルウェアを設定でき、通常のハンドラーの前後に任意の処理を入れることができます。

例えば、

```go
func main() {
	r := gin.Default()
	r.Use(someMiddleware())			// ミドルウェアを登録
	r.GET("/", func(c *gin.Context) {
		log.Println("2nd")
		c.JSON(200, gin.H{"Message": "Hello"})
	})
	r.Run()
}

func someMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		log.Println("1st")
		c.Next()					// ハンドラーを実行
		log.Println("3rd")
	}
}
```

とすると、ログは、`1st`, `2nd`, `3rd`の順番で出てきます。
見ての通り、`c.Next`の前に書いたものはハンドラーの前に、後に書いたものはハンドラーの後に実行されます。

# エラーハンドリング
## エラーの投げ方

gin のコンテキストは、`Error`メソッドを使ってエラーが設定できます。
さらにこのメソッドは、元のエラーとTypeやMetaなどの追加情報を含むgin.Error型を返します。
Typeには、`gin.ErrorTypePublic`、`ErrorTypePrivate`などがあり、デフォルトでは`ErrorTypePrivate`です。
Metaの方はinterface{}型なので任意のデータを設定できます。

```go
c.Error(err)		// simple error
c.Error(err).SetType(gin.ErrorTypePublic)
c.Error(err).SetType(gin.ErrorTypePrivate).SetMeta("more data")
```

リクエストの処理中に何かエラーが起きたときは、`AbortWithJSON`などとする代わりに、次のようにコンテキストにエラーを設定して一度ハンドラーから抜けます。

```go
if err != nil {
	c.Error(err).SetType(gin.ErrorTypePublic)
	return
}
```

## エラーミドルウェア

エラーがセットされたコンテキストをミドルウェアで処理するようにします。

次のようなミドルウェアを作成して、`r.Use(errorMiddleware())`というように登録してください。

```go
func errorMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Next()

		err := c.Errors.ByType(gin.ErrorTypePublic).Last()
		if err != nil {
			log.Print(err.Err)

			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"Error": err.Error()
			})
		}
	}
}
```

ここでは、コンテキストにセットされたエラーの中でも、TypeがPublicで、最後のものを取得しています。
エラーを取得した後には、ログの出力やSentryへの送信などといった任意の処理を入れることができます。

また、MetaにHTTPのステータスコードやレスポンスを入れたり、TypeのPrivateとPublicで処理を分けたりなどといったこともできます。

これで、エラーの処理をミドルウェアにまとめることができました！

# 参考リンク

- エラーハンドリングについて https://github.com/gin-gonic/gin/issues/274
- ミドルウェアについて https://qiita.com/tobita0000/items/d2309cc3f0dd32006ead
- ドキュメント https://godoc.org/github.com/gin-gonic/gin
npmパッケージをGitHubで公開する

# はじめに
なんと、2019年5月10日からGitHub上でパッケージの公開ができるようになっていたみたいです（2019/11/13より正式版に）。
そのプロダクト名は、 [GitHub Packages](https://github.com/features/packages) です。
さらには、[GitHub Actions](https://github.co.jp/features/actions) を使い、GitHub上でパイプラインを構築でき、CI/CDを動かせるようになってきました。
これにより管理しなければならないTOKEN情報を減らすことができ、WebUIも共通のものを使うことができるようになるなどのメリットがあります。
そんなメリットを享受すべく、GitHubでnpmのパッケージを公開する方法を学びました。

# 事前準備
## npmコマンドでGitHubにログインする
まず、以下のページからnpmレジストリ用のTOKENを発行してください。
https://github.com/settings/tokens/new

必要な権限は、 `repo` `read:packages` `write:packages` です。
この3つは最低限付けてください。
![キャプチャ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183540/e7f00c21-a3f7-df7a-8efb-4b9f609a65bb.jpeg)

この発行したTOKENを使って、npmコマンドでログインします。
そのコマンドは以下になります。

```.sh
npm login --registry=https://npm.pkg.github.com/ --scope=(GitHubのユーザー名)
> Username: (GitHubのユーザー名)
> Password: (先ほど作成したTOKEN)
> Email: (レジストリの連絡先メールアドレス)

# 確認方法
npm whoami --registry=https://npm.pkg.github.com/ --scope=(GitHubのユーザー名)
# GitHubのユーザー名が出力されればOK
```

npm v9以降は、ログイン時に `--auth-type=legacy` を付ける必要があります。

## npmコマンドにレジストリを登録する
```
npm config set @(GitHubのユーザー名):registry https://npm.pkg.github.com/
```

# 公開する
```.sh
npm publish
```

# 他のリポジトリに追加する
```.sh
yarn add @(GitHubのユーザー名)/(パッケージ名) --update-checksums
```

もし異なる環境でパッケージを追加する場合は、[事前準備](#事前準備) を参考に、npmコマンドでのログインやレジストリ登録を行ってください。

## 追加時にエラーが発生する。
普通に `yarn add` しても追加することができません。
以下のようなエラー文が表示されます。

```.txt
error https://npm.pkg.github.com/download/@(GitHubのユーザー名)/(パッケージ名)/(バージョン)/(ハッシュ値): Integrity checked failed for "@(GitHubのユーザー名)/(パッケージ名)" (none of the specified algorithms are supported)
```

そこで使用するのが、 `--update-checksums` というオプションです。
上記のエラーは、ローカルとリモートの間で、chucksum値が異なる場合に発生するようです。
そのため、 `--update-checksums` を使い、ローカルのchucksum値を更新することでこのエラーは解決します。

なお、このエラーはnpmコマンドでパッケージを追加する場合では、発生しないようです。
この記事では、yarnコマンドでパッケージ管理を行っている場合は気を付けてください。

# おわりに
GitHubがMicrosoftに買収されたときは、あちこちであれこれ騒いでいましたが、実際にはアップデート速度が高まり、Microsoftの『OSS推進』と『開発者を支援する』という考えにより、より開発者に優しいプロダクトになったように感じます。
『GitHub Packages』と『GitHub Actions』の2つを使うことで、誰でも簡単にCI/CDを行えるようになりました。これは個人に対しても中小企業に対しても大きな影響を及ぼすでしょう。
モバイル側でもGitHubに動きがあるので、今後も「Microsoft」のGitHubが楽しみです。

# 参考資料
- [Configuring npm for use with GitHub Packages](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-npm-for-use-with-github-packages)
【C++】クラステンプレートでパラメータパックを複数もらう

#こんな状況に出くわした
複雑なテンプレートを書いているとこんな状況に出くわす

```cpp
// 2つ以上のパラメータパックが欲しい!
template<typename... Components, typename... Events>
class ComponentManager
{
	// ・・・
};
```

でもこれは当然コンパイルエラーになる
なぜならパラメータパックは**最後の引数にしか使えない**からだ

```cpp
// できたとしても区切りがつかなくなる
ComponentManager<Component1, Component2, Event1, Event2> comp;
```

そこでタプル**`std::tuple`**さんに活躍してもらうことにしましょう。[^1]

#std::tupleを使ってパラメータパックをまとめる

`std::tuple`を使うとこのようにまとめることができます。

```cpp
// templateの中にタプル
using Components = ComponentManager<
	std::tuple<
		Component1,
		Component2
	>,
	std::tuple<
		Event1,
		Event2
	>
>;
```

それでは実装してみましょう。

少し不思議な書き方ですがとてもシンプルです。

```cpp
template<typename Components, typename Events>
class ComponentManager;

template<typename... Components, typename... Events>
class ComponentManager<std::tuple<Components...>, std::tuple<Events...>>
{
	// ・・・
}
```

ぜひ、試してみてください。

#応用

これを応用すればパラメータパックの2重ループが作れます

```cpp
// 出力
template<typename Event, typename Component>
void PrintEventComponent()
{
	std::cout << "Event:" << typeid(Event).name() << ", "
		<< "Component: " << typeid(Component).name() << std::endl;
}

template<typename Components, typename Events>
class ComponentManager;

template<typename... Components, typename... Events>
class ComponentManager<std::tuple<Components...>, std::tuple<Events...>>
{
private:
	// 内側のループ (Components)
	template<typename Event>
	static void InitializeEvent()
	{
		using accumulator_type = int[];
		accumulator_type accumulator = { 0, (PrintEventComponent<Event, Components>(), 0)... };
		(void)accumulator;
	}

public:
	// 外側のループ (Events)
	static void InitializeEvents()
	{
		using accumulator_type = int[];
		accumulator_type accumulator = { 0, (InitializeEvent<Events>(), 0)... };
		(void)accumulator;
	}
};
```
```cpp
struct Component1 {};
struct Component2 {};
struct Event1 {};
struct Event2 {};

int main()
{
	// usingを使えば何度も使うことができる
	using Components = ComponentManager<std::tuple<Component1, Component2>, std::tuple<Event1, Event2>>;
	Components::InitializeEvents();

	return 0;
}
```
```
Event: struct Event1, Component: struct Component1
Event: struct Event1, Component: struct Component2
Event: struct Event2, Component: struct Component1
Event: struct Event2, Component: struct Component2
```




[^1]: パラメータパックがまとめられるクラスなら何でもいいです。
docker-composeでサクッとCassandraをたてる


docker-composeでお手軽にCassandraを立ち上げるサンプルとその簡単な説明

まずは下記のようなディレクトリ構造でファイルを作成していく

```
sample
 ┣━ docker
 ┃   ┗ cassandra
 ┃       ┗ initdb
 ┃           ┗ schema.cql
 ┗ docker-compose.yml
```

次にdocker-compose.ymlを記述していく

```docker-compose.yml
version: '3.3'
services:
  cassandra:
    image: cassandra:latest
    ports:
      - 9044:9042
    environment:
      - CASSANDRA_USER=user
      - CASSANDRA_PASSWORD=pass
      - MAX_HEAP_SIZE=256M
      - HEAP_NEWSIZE=128M
    container_name: cassandra
    restart: always
    volumes:
      - ./out/cassandra_data:/var/lib/cassandra

  cassandra-load-keyspace:
    container_name: cassandra-load-keyspace
    image: cassandra:latest
    depends_on:
      - cassandra
    volumes:
      - ./docker/cassandra/initdb/schema.cql:/schema.cql
    command: /bin/bash -c "sleep 60 && echo loading cassandra keyspace && cqlsh cassandra -f /schema.cql"
```

**cassandra**コンテナはそのままCassandraを立ち上げるコンテナ
**cassandra-load-keyspace**コンテナは立ち上がった**cassandra**コンテナに対してテスト用schemaを流し込むコンテナ
cassandraは起動に時間がかかるので60秒まったあとにcqlをたたいている

```schema.cql

DROP KEYSPACE IF EXISTS test;

CREATE KEYSPACE test WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor' : 1
};

USE test;

CREATE TABLE test_table (
                            id text PRIMARY KEY,
                            data text,
                            update_time timestamp
) WITH default_time_to_live = 31536000;

INSERT INTO test.test_table (id, data, update_time)
 VALUES('test_id', 'text', '2019-09-10T11:21:59.001+0000');
```

コンテナに直接アクセスしてcqlshを立ち上げるコマンド

```bash
docker exec -it cassandra cqlsh
```
GitHubへのgit pushで怒られた時の対処（同一リモートリポジトリを多重でcloneしてしまった場合）

こちらの記事作成の過程で、ローカルリポジトリがあるにもかかわらず、同じリモートリポジトリを別ディレクトリにcloneしたところ、git pushするときに怒られた。


[GitHubリモートリポジトリをローカルにcloneする](https://qiita.com/kanazwk/items/65595343a8c9bb622e12)


```
k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$ git push
To https://github.com/kanazwk/dev.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/kanazwk/dev.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$
```

・fetch firstがいるからpushできません
・another repository pushingしてんじゃないの
・git pullしてからやってみたら

ここでgit fetchをためすといいらしいので以下の通り実行。

```
k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$ git fetch
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/kanazwk/dev
   f41d5ac..c968ccd  master     -> origin/master

k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$
```

通ったのでローカルリポジトリをgit mergeする。
カレント以外の同じローカルリポジトリは消え、統合されるので注意が必要。

```
k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$ git merge origin/master
Merge made by the 'recursive' strategy.
 QIITAARTICLE.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 QIITAARTICLE.txt

k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$
```

merge完了後、git pushを実行すると成功。

```
k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$ git push -u origin master
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 1.02 KiB | 131.00 KiB/s, done.
Total 7 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/kanazwk/dev.git
   c968ccd..4b9413d  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

k_kanazawa@MyComputer MINGW64 /c/kana/dev (master)
$
```

#まとめ
本来ならbranch切るなり、リポジトリをforkするなりしてローカルリポジトリにcloneするのが使い方なのだろうけど、うっかり多重でcloneして開発を進めてしまった場合には使えそう。
[UE4]UE4.23からBehaviorTreeの中で簡単にコメントブロックを足せるようになってる！

UE4.23からBehaviorTreeの中でノードを選択して `C` キーで何不自由なくコメントブロックが追加できるようになっています！

#Behavior tree

ノードを選択して、、、

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/271d9a75-5cc9-8e9f-64c7-bd429ee8ef21.png">

**C!!!!!!**

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/2e864151-9c3d-a049-a628-690fd6f1cbef.png">

最高！
<font color=LightGray>なんかうまい事するとそれ以前でもコメントブロック足せるはずなんですが方法不明・・・</font>

#niagaraも
UE4.24に追加されているナイアガラのOverviewにもコメントを追加できます。
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/4663e4b7-6df5-9f29-0677-cdfa7a38538c.png" >

色とかはこれからですかね。
【Laravel】メール送信失敗時のログを残す

Laravel で複数のメールアドレスへの送信処理を書いた時、メール送信が失敗したアドレスの一覧を取得したかったが、ドキュメントには載っていなかったのでメモとして残しておく。

## 環境
Laravel 6.X


## やり方
`Mail::failures()` で送信失敗メールアドレスが配列で取得できる。（[参考](https://github.com/laravel/framework/blob/6.x/src/Illuminate/Mail/Mailer.php#L541)）
例えば、Mailable クラスの設定後、送信処理をコントローラに書く場合、下記のような感じ。


```MailSendController.php
namespace App\Http\Controllers;

use App\Mail\SampleMailableClass;
use Illuminate\Support\Facades\Mail;
use Illuminate\Http\Request;
use Log;

class MailSendController extends Controller
{
    public function send()
    {
    	$emails = ['hoge@example.com', 'huga@example.com']
        Mail::to($emails)->send(new SampleMailableClass());
        if (count(Mail::failures()) > 0) {
            Log::channel('slack')->warning(Mail::failures());
        };
    }
}
```

 Slack へのログ投稿の方法は [こちらの記事](https://liginc.co.jp/436328) に詳しく書かれていました。

## 参考
- [PHP Illuminate\Support\Facades Mail::failures Examples](https://hotexamples.com/examples/illuminate.support.facades/Mail/failures/php-mail-failures-method-examples.html)
テンプレート文字列について

コードレビューでテンプレート文字列を知ったのでめも :pencil: （JavaScript初歩的なことをわかってなすぎる... 勉強になりました :pray: ）

### 変更前

- テンプレート文字列のことを知らずに使ってて以下のコードを書いていた

```html
<nuxt-link :to="'/sample/request/' + `${book.id}`">
  詳細
</nuxt-link>
```

### 変更後

- テンプレート文字列使うならこんな感じで書いた方が良さそうとアドバイスしてもらった

```html
<nuxt-link :to="`/sample/request/${book.id}`">
  詳細
</nuxt-link>
```

### 参考

[テンプレート文字列 \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/template_strings)
windows server 2012 R2にZabbix agentをインストールした

#◆環境
　・ホスト側
　　　CentOS Linux release 8.0.1905 (Core)
　　　サーバ（GUI）だけでインストールを実施
　　　Zabbix server 4.0LTSをインストール済み。操作言語は日本語にしている

　・クライアント側
　　　Windows server 2012R2　投稿日時点の最新パッチまで更新済み

#◆やったこと
・クライアント側での操作
1.agentのダウンロードを実施する
https://www.zabbix.com/jp/download_agents#tab:40LTS
amd64をダウンロード。あれ　msiなん？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/5dec1b5e-d86b-226c-5713-3ffb711d5728.png)

2.ダウンロードしてきたファイルをインストールしたいPCに配置して実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/a8cc946b-aa38-48e3-99fc-d84c8c98a0c4.png)

3.「Next」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/624dbdf9-d552-2bd4-4289-e3bdde2e50eb.png)

4.「I accept・・・」にチェックを入れて「Next」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/ca06ea40-3a45-b784-046e-72558005ec7c.png)

5.「Zabbix server IP/dns」「Server or Proxy・・・」にzabbix serverをインストールしているPCのIPアドレスを入力して「Next」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/8885b749-3f92-b3b6-5a39-1916115d2b0d.png)

6.そのまま「Next」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/7b07035b-957a-d3d7-b78e-f8ae7532bf78.png)

7.「Install」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/f7b649f2-a903-12ca-3764-d8a85cce12f7.png)

8.「Finish」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/52b25c07-a70f-0bd4-2995-85e20b4494ca.png)

9.コントロールパネル＞管理ツール＞サービスから「Zabbix Agent」が存在して「実行中」であることを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/c0305f2e-d422-8d95-70a6-0f31471b5291.png)

10.ブラウザでzabbixのコンソールへアクセスする

11.設定＞ホスト　を選択して右上にある「ホストの作成」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/be7aa347-190e-33d9-78c0-b095df7a47b5.png)

12.以下の項目を入力して「テンプレート」タブを選択する
　・ホスト名：agentをインストールしたクライアントのホスト名
　・表示名：任意で自分が分かりやすい名前
　・グループ：右側の「選択」を選ぶと最初から設定されているグループを選べる。直接入力で任意のグループを作成することも可能
　・エージェントのインターフェース
　　・IPアドレス：agentをインストールしたクライアントのIPアドレス
　　・DNS名：名前解決しているなら入力。普通にホスト名を入れてもいいと思われる
　　・接続方法：どちらか選択する※今回はIPアドレスにしました
　　・ポート：初期設定のままなら変更しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/38e33e12-2b84-e9fd-8038-37246e0c2f71.png)

13.新規テンプレートをリンクの右側にある「選択」を選び、表示される一覧からテンプレートをにチェックを付けて「選択」を選択する
　　※今回は「Template OS Windows」を選択しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/09aa9e98-45bf-c8ea-32f0-199e35990ae3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/74ae4a5a-fdf9-1cdc-e0c2-50e445ab3f01.png)

14.新規テンプレートをリンクの右下の「追加」を選択して追加したテンプレート名が表示されていることを確認し、
　「追加」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/6b33d692-1c00-6b30-681e-4424a643c6fb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286981/cc4dd852-427b-90b5-bc98-49e7c1120cc6.png)

15.ホストが追加されるのでしばらく待って情報が上がってきていればOK




参考サイト
https://www.server-world.info/query?os=CentOS_7&p=zabbix42&f=8
PowerShell スクリプト作成Tips

個人向けにPowerShellスクリプト書く時のノウハウをまとめておく。
いかんせん突貫で作っているところで、細かい指摘が頂けるととてもうれしい。

**随時アップデート予定**

# 引数を渡す

$Args[0]
[]内は一つ目の引数を0と数えて指定する。

```test.ps1
Write-Host $Args[0]
Write-Host $Args[1]
```

実行例

```
PS C:\work>.\test.ps1 hoge huga
hoge
fuga
```

# 指定回数ループする
いろんなやり方はあるので、これは一例。
とある回数に達するまでループする方法。

以下のスクリプトは、1秒間のsleepと "<ループ回数> times."のメッセージ出力を10回繰り返す抜ける処理。

```loop.ps1
$exec_run_count = 10
$run_count = 1

    do{
        Start-Sleep 1
        write-host $run_count times.
        $run_count++
    }while($run_count -ne $exec_run_count)

exit
```

#日付 時間（yyyy/mm/dd HH:mm）を変数に入れる
```
$v_DATE = (Get-Date -Format "yyyy/MM/dd HH:mm")
```

実行例

```
PS C:\work> $v_DATE = (Get-Date -Format "yyyy/MM/dd HH:mm")
PS C:\work> Write-Host $v_DATE
2019/11/25 23:25
```

#キー入力を受け付けるまで待機する（バッチでいうpause）

```reply.ps1
Write-Host "終了するには何かキーを押してください..."
$host.UI.RawUI.ReadKey()

Write-Host "終了します"
```

実行例（キー「a」を入力）

```
PS C:\work> powershell .\reply.ps1
終了するには何かキーを押してください...
a
終了します
VirtualKeyCode Character ControlKeyState KeyDown
-------------- --------- --------------- -------
            65         a               0    True

PS C:\work>
```

#コマンドの件数取得 ().Count 
便利で驚いたのがこれ。コマンドの出力結果をヘッダなしで件数を取得してくれる。

例えばget-jobはこの結果だが、"State”が"Completed"のジョブを表示する、`get-job -state Completed`コマンドの表示件数を取得し、変数に入れることが出来る。

```
PS C:\kana\dev> get-job

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      Job1            BackgroundJob   Completed     True            localhost             $CMDLINE
3      Job3            BackgroundJob   Completed     True            localhost             $CMDLINE
5      Job5            BackgroundJob   Completed     True            localhost             $CMDLINE
7      Job7            BackgroundJob   Completed     True            localhost             $CMDLINE
9      Job9            BackgroundJob   Completed     True            localhost             $CMDLINE
11     Job11           BackgroundJob   Completed     True            localhost             $CMDLINE
13     Job13           BackgroundJob   Completed     True            localhost             param($CMDLINE) $CMDL...
15     Job15           BackgroundJob   Completed     True            localhost            param($CMDLINE) $CMDLINE
17     Job17           BackgroundJob   Completed     True            localhost            param($CMDLINE) "$CMDL...
19     Job19           BackgroundJob   Completed     True            localhost            param($p) "`$p is $p"


PS C:\kana\dev>
PS C:\kana\dev> $exec_run_count = (get-job -State Completed).count
PS C:\kana\dev> Write-Host $exec_run_count
10
PS C:\kana\dev>
```
Heroku PostgresにDBeaverで接続する

# はじめに
DBeaverを使い始めて、Herokuにデプロイしたアプリのデータベース（Postgres）
をみたい人向け。
他の記事の焼き直しですが、最新のDBeaver対応の記事です。

# 使用するDBeaver
バージョン 6.2.5

# 流れ
1. Database Credentialの確認
2. DBeaverへ入力


# Database Credential確認
- herokuのページより、データベースをみたいアプリを選択して、データベースを選択
<img width="670" alt="check-me-share___Heroku.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/68d32dca-4e2a-0e6b-d11a-ab804a021e92.png">
- settingsを選択
<img width="858" alt="postgresql-fitted-69133___Heroku_Data.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/88974530-f5f6-e6e8-55ac-792ed4e348e8.png">
- View Credentialsをクリック
<img width="1435" alt="postgresql-fitted-69133___Heroku_Data.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/2f58e3f4-6cfe-0417-22fe-27dbb3fce134.png">
- DatabaseのCredentialsが表示される。
<img width="881" alt="postgresql-fitted-69133___Heroku_Data.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/4087cc05-eaee-51d0-6720-1ca8a7a227d8.png">

# DBeaverへ入力
- DBeaverのメニューバーで、データベース　→　新しい接続を選択
<img width="843" alt="データベース_と_Menubar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/59b6e107-85ba-2482-3a3a-9b9624d8ff5d.png">
- PostgreSQLを選択して次へをクリック
<img width="892" alt="新しい接続を作成する_と_DBeaver_6_2_5_-_d9c2rfc4eoq2t8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/d9c7c208-950b-c635-c374-280b3efb71c2.png">
- 各項目に上記で確認した内容を入力する
<img width="886" alt="新しい接続を作成する.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/83531414-a213-96ba-8727-458ecb9cef48.png">
- テスト接続をする
<img width="740" alt="Connection_Test_と_接続__PostgreSQL_-_d9c2rfc4eoq2t8_構成.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/d2efe768-aafa-941e-daea-b92fead5d3ac.png">
- SSLを使用するようにする
<img width="733" alt="接続__PostgreSQL_-_d9c2rfc4eoq2t8_構成.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/787d0898-e21f-9714-c979-6e29716ba64b.png">

テスト接続がうまくいけば、これで終了です。

# 参考
http://umi-uyura.hatenablog.com/entry/2017/10/18/235842
http://thebar.cc/connecting-dbeaver-to-a-heroku-postgres-database/