OmniAICreator/Qiita-1.07M huggingface dataset:
MacでVRMをPMXに書き出そうとして挫折した話

[前回の記事](https://qiita.com/VirtualDollRio/items/ccd8026617a772d1ee9d)でUnityで踊ってみた動画を作ったので、次はMMDだろう！ということでVRMモデルをPMXに変換しようと思ったのですが、結局Macで変換できずにWin機を引っ張り出した話です。
未解決記事で申し訳……ない……！！

最終的には[VRM to Pmx Converter](https://www.nicovideo.jp/watch/sm34705374)というツールを利用して無事MMD動画を作ることができました。
[![【MMD】[A]ddiction【VTuber月夜莉央】](http://img.youtube.com/vi/Rgb41a91MyU/0.jpg)](https://www.youtube.com/watch?v=Rgb41a91MyU)

##UnityでVRM→PMXへ
UnityにVRMモデルを読み込んだ状態だったので**[VRMtoPMXExporter](https://twitter.com/flammpfeil/status/1032266829597573121?s=20)**というUnityパッケージを使ってさくっとPMXファイルを書き出し。
記事にするほどの手順もないな〜楽勝だな〜と思っていました。この時までは。
MacでMMDは使えないので代わりに**[nanoem](https://nanoem.readthedocs.io/ja/latest/index.html)**というアプリケーションを使ってモデルとモーションを設定、試しに動かしてみると……何かがおかしい……

**眉 毛 な い や ん け**

ヤンキーみたいな見た目になってて笑いました。スクショ撮っておけば良かった。
調べてみたらPmxEditorというもので眉毛やまつげをいじらないといけないみたいです。
しかしPmxEditorはWindowsのみ対応……

##Blenderという魔法のツール
Blenderがあれば3Dモデリング関係はなんでも解決するというイメージがあります（偏見）
Windowsマシンがないというわけではないので素直にPmxEditorを使えば良かったのですが、半ば意地になってMacだけでPMX形式に変換する方法を探しはじめました。
するとBlenderでVRMもPMXもいじれるっぽい記事を見つけたので、Unityを使わずにBlenderでVRM読み込み→PMX書き出しすれば解決するのでは……ということで早速インストールしたばかりのBlenderに**VRM_IMPORTER**と**blender_mmd_tools**を導入。
VRMの読み込み成功！じゃあこれを書き出せばいいんですね、楽勝！と思ったのですが……

**PMX書き出しのメニューが有効にならないじゃないですか。**

試しにPMXファイルを読み込んでみたところ書き出しメニューが有効になったので同形式のファイルじゃないと書き出せないみたいです。
もっと調べれば何かしら方法があったのかもしれませんがここでボクは心が折れました……

##VRM to Pmx Converter
諦めてUnityから書き出したPMXファイルをWindowsマシンにコピーしてPmxEditorで編集しようと思ったのですが、色々調べている時に見つけた**VRM to Pmx Converter**というツールを試してみることに。
VRMをPMXをワンクリックで書き出してくれるツールとのことでまた眉毛消えたりするのでは……と半信半疑になりながら試してみたのですが、別段おかしな箇所もなく書き出しすることに成功しました！！
上記の調査や作業で数時間使ってたんですがWindowsがあればワンクリックで終わるとは……

そんなわけで完成したものが下記の動画です。
[![【MMD】[A]ddiction【VTuber月夜莉央】](http://img.youtube.com/vi/Rgb41a91MyU/0.jpg)](https://www.youtube.com/watch?v=Rgb41a91MyU)

##餅は餅屋というお話
PMX書き出し以降の作業はnanoemを使ってMacでやっていたのですが、どうにもこのnanoemというツールも挙動が不安定でして……プロジェクトを保存してアプリを終了、再度アプリを起動してプロジェクトを開くと音楽ファイルが読み込めないし新規で登録もできないという不具合に悩まされ、結局保存することを諦めてアプリを終了させないよう注意しながら最後まで一気に完成させました。
（もしかするとボクの使い方が悪いかもしれないのでバグです、とは言い切れませんが）

MMD自体がWindows専用のツールである以上、Macでやろうと思うと必要以上の労力がいるな、という感想です。餅は餅屋というやつですね。
次のMMD動画はWindowsで作ると思います！たぶん！！
PushしてもStackがあると前画面がReBuildされる問題

## 今回の問題

ある日のこと、
`Navigator.pushNamed(context,route)`
で気持ちよく遷移してたところ、なぜか前画面のbuildが走ることに気づいた！
なぜ気づいたかは後ほど話します。

どうやらFlutterでは、Stackされてる画面については全てrebuildされるらしい。
↓記事参照
https://github.com/flutter/flutter/issues/11655

これって普通なんでしょうか？
rebuildされても大丈夫なようにコーディングしていけばいい話ではあるんですが、、、
※詳しい方いたら教えてください。

## なぜ気づいたのか

FirstView
↓
↓任意のタイミングでダイアログを表示
↓
Dialog
↓
↓OKならSecondViewへpushする
↓
SecondView

みたいな遷移を実装していて、
DialogのOKを押した時に 前画面に戻りたくなかったので
`Navigator.pushReplacementNamed(context,'/second')`
みたいな感じで消そうとしたんですが、AppBarのLeadingに戻るボタンが付与されて
戻れる状態になっていたので、なんでだろうと思って好奇心で前画面のbuild直下に
printをしたのがきっかけです。


コードで書くと↓みたいな感じです。

```main.dart
class FirstView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("firstViewBuild")
    return Scaffold(
        body: Center(
          child: FlatButton(
                onPressed: () {
                  errorDialog(context);
                },
                child: Text("Start"),
              )
        )
    );
  }
}

class SecondView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("secondViewBuild")
    return Scaffold(
        body: Center(
          ///省略
        )
    );
  }
}

void errorDialog(context) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (_) {
        return AlertDialog(
          title: Text("Warning!!!!"),
          content: Text("ダイアログです"),
          actions: <Widget>[
            FlatButton(
              child: Text(
                  "Cancel",
                  style: TextStyle(
                      color: Colors.black54
                  )
              ),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            FlatButton(
              child: Text(
                  "OK",
                  style: TextStyle(
                      color: Colors.black54
                  )
              ),
              onPressed: (){
                Navigator.pushReplacementNamed(context, '/second');
              } ,
            ),
          ],
        );
      },
    );
  }
```

これでダイアログから遷移した時にこうなりました。

```
I/flutter (15474): secondViewBuild
I/flutter (15474): firstViewBuild
```

なんでPushしてるのに前画面もBuildされてるねん！！！！
となりました。

## 解決策

StackされてるのがBuidされてしまうなら消すしかない！とおもったので
なんとか消す方法を考えたところ、
`Navigator.pushNamedAndRemoveUntil(context, nextRoute, removeUntilRoute);`
がありました！（なんだかんだできるのはFlutterいいですね）

↓公式ページ
https://api.flutter.dev/flutter/widgets/NavigatorState/pushNamedAndRemoveUntil.html

今回は

```
Navigator.pushNamedAndRemoveUntil(context, '/second', ModalRoute.withName('/'));
```

これをダイアログのOKのイベントに差し込むことで、FirstViewのStackを消すことに成功しました。

ダイアログからの遷移って結構あるあるなので、できてよかったです。

## 最後に

結構前画面のBuildとかって勝手にされると怖いです。
まぁいつビルドされても問題ないようにコーディングするべきだとは思いますが……

という感想です。
PSTをOffice 365にインポートする方法は？

PSTをOffice 365にインポートするための完璧なソリューションをお探しですか？はいの場合は、正しいページに着陸しました。この記事の最後で、PSTを問題なくOffice 365にインポートできます。

次に、PSTファイルとOffice 365について説明します。

Office 365は、マイクロソフトが提供するサブスクリプションベースのサービスです。 Office 365には、電子メール、カレンダー、ファイルストレージ、データ保護、サイバー脅威保護などのさまざまなサービスが含まれます。Word、Excel、One Note、Outlookなどのソフトウェアが含まれます。

コンピューティングにおいて、パーソナルストレージテーブル（.pst）は、メッセージ、カレンダーイベント、およびMicrosoft Exchange Client、Windows Messaging、Microsoft OutlookなどのMicrosoftソフトウェア内の他のアイテムのコピーを保存するために使用されるオープンな専用ファイル形式です。

PSTをOffice 365に直接インポートする公式のソリューションはありません。 PSTファイルをOffice 365アカウントにインポートするには、信頼できるソリューションを使用することを強くお勧めします。ここでは、Windows用の**[Advik PSTからOffice 365](https://www.adviksoft.com/pst/office365.html)**へのインポートウィザードをご覧ください。このソフトウェアは、OutlookアーカイブをOffice 365アカウントにアップロードするように特別に設計および開発されています。

ダウンロード : https://www.adviksoft.com/dl/advik-outlook-pst-converter.exe

## Outlook PSTをOffice 365にインポートする手順：

ステップ1：Advik PSTからOffice 365への移行ツールを実行します。

ステップ2：[ファイルの選択]をクリックして、PSTファイルを追加します。

ステップ3：目的のメールボックスフォルダーを選択し、「次へ」をクリックします。

ステップ4：保存オプションの選択メニューからOffice 365を選択します。

ステップ4：Office 365のログイン資格情報を入力し、[変換]をクリックします。

できた！ソフトウェアは間もなくOutlookアーカイブ（.pst）をOffice 365アカウントにエクスポートします。これで、Office 365でPSTファイルを開くことができます。

概要
この素晴らしいテクニックを使用して、Office 365 OnlineアカウントにPSTをインポートし、時間の消費と長い構成を回避します。したがって、このソフトウェアは、メールフォルダーをOutlookオフラインデータベースからOffice 365に直接転送する究極のソリューションです。
人間行動の計量分析　東京大学出版　柳井晴夫・岩坪秀一・石塚智一先生

```{r}
#人間行動の計量分析
#p.44

#確認中

library(dplyr)

X=data.frame(a=c(rep(0,8),rep(1,8)),s=c(0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1),t=c(0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1),g=c(0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1))

f=data.frame(sc=c(38,4,29,9,22,5,35,8,14,3,11,2,9,6,19,10),md=c(69,36,0,0,8,9,0,2,80,45,1,2,10,16,0,1),ax=c(6,0,0,0,1,0,0,0,92,3,0,0,14,1,0,0))

R=nrow(X);C=ncol(f)

A=2

D_C=diag(apply(f,2,sum))

Y=matrix(sample(1:20,R*A,replace=T),ncol=A)/100

M=solve(D_C)%*%t(f)%*%Y

d=array(0,dim=c(R,C))

for(i in 1:R){
for(j in 1:nrow(M)){  

d[i,j]=sqrt(sum((Y[i,]-M[j,])^2))   

}
}


W=rep(1,C)

log_lik=function(w){

w2=abs(w)/sum(abs(w))

p=(exp(-d^2)*c(w2))

sum_p=apply(p,1,sum)

for(j in 1:length(sum_p)){

p[j,]=p[j,]/sum_p[j]  

}  

log_lik_val=sum(f*log(p))

return(log_lik_val)

}




h=0.001

ite=1000000;eta=0.0000001

log_lik_vec=c()

for(l in 1:ite){

vec=W  

for(j in 1:length(W)){

vec_sub=vec;vec_sub[j]=vec_sub[j]+h  

W[j]=W[j]+eta*(log_lik(vec_sub)-log_lik(vec))/h

}  

print(log_lik(W))  

log_lik_vec=c(log_lik_vec,log_lik(W))

}

```

```{r}


#人間行動の計量分析

#p.77 因子分析として使われる主成分分析

library(dplyr)

data=data.frame(num=1:20,y=c(0.20, 0.10, 0.49, 0.26, 0.92, 0.95, 0.18, 0.19, 0.44, 0.79, 0.61, 0.41, 0.49, 0.34, 0.62, 0.99, 0.38, 0.22,0.71,0.40),x1=c(84,87,86,85,82,87,92,94,88,84.9,78,90,88,87,82,84,86,83,85.2,82),x2=c(61,55.5,57,57,50,50,66.5,65,60.5,49.5,49.5,61,59.5,58.4,53.5,54,60,58.8,54,56),x3=c(24.5,24,23,22.5,22,24,25,26,25,24,23,21,26,25.5,24,23,24,24,24,22))

X=as.matrix(data);N=as.numeric(nrow(data)-1)

D=diag(diag(cov(X)))

Z=solve(sqrt(D))%*%((t(X)-c(apply(X,2,mean))))

R=cor(X)

#Rと一致

Z%*%t(Z)/(nrow(data)-1)



ite=1000000

n=ncol(X);m=10;lambda=0.00001

A=array(sample(1:10,n*m,replace=T),dim=c(n,m))

f=solve(t(A)%*%A+diag(lambda,m))%*%t(A)%*%Z


cost_vec=c()

for(l in 1:ite){

f_pre=f;A_pre=A  

A=Z%*%t(f)/N;f=solve(t(A)%*%A+diag(lambda,m))%*%t(A)%*%Z  

costs=(sum(diag((Z-A%*%f)%*%t(Z-A%*%f)))/N)

cost_vec=c(cost_vec,costs)

E=Z-A%*%f

#print(costs)

}

plot(cost_vec)

#print(sum(abs(A_pre-A))+sum(abs(f_pre-f)))


```
勉強記録　6日目 〜クラスの持つ定数〜 - Effective C++ 第3版 -

#　はじめに

Effective C++ 第3版の2項4ページから勉強していきます。
今回は、「クラスの持つ定数」についです。

# Effective C++ 第3版 - 2項　#defineより、const, enum, inlineを使おう -

## クラスの持つ定数

### クラスのメンバ変数に定数を持つ場合

クラスで使う定数のスコープを限定するために、その定数をクラスのメンバ変数とすることがある。
その定数が実際に1つだけ存在するように、static(静的)にしなければならない。

static(静的)なメンバ変数とは？
通常の(非staticな)メンバ変数はクラスのインスタンスを生成する度に確保されるが、
static（静的な)メンバ変数はクラス1つ毎に1つだけと定義される。

そのため、クラスに定数を用いる場合は、

```cpp
class GamePlayer {
 public:
  GamePlayer(){};

 private:
  static const int NumTurns = 5;
  int scores[NumTurns]; 
};
```

のようになる。
注意：
上のコードであるのは、NumTurnsの宣言であって、定義ではない。
staticな整数型である「クラス定数」だけは、定数の宣言になる。
そのため、

```cpp
class GamePlayer {
 public:
  GamePlayer(){};

 private:
  static const int NumTurns = 5;
  int scores[NumTurns]; 
  static const double x = 5;
};
```
のようなコードの場合、

```cpp

static const double x = 5;
```

の部分でコンパイルエラーとなる。
ただし、

```cpp
class GamePlayer {
 public:
  GamePlayer(){};

 private:
  static constexpr int NumTurns = 5;
  int scores[NumTurns];
  static constexpr double x = 5;
};
```
のように書くと、コンパイルエラーがでなくなる。
constexprは、constと違い、変数の値がコンパイル時に確定しているためなのか、、、

下にクラスのメンバに定数を持つ場合のサンプルコードを示します。

### サンプルコード

```cpp:2_const_static.cpp
#include <iostream>

class GamePlayer {
 public:
  GamePlayer(){};

 private:
  static constexpr int NumTurns = 5;  // 定数の宣言
  int scores[NumTurns];               // 定数の使用 
  static constexpr double x = 5;  // static const だとコンパイルエラー
};

int main(int argc, char* argv[]) {
  std::cout << "2_const_static.cpp" << std::endl;
  GamePlayer g1;
  GamePlayer g2;
}
```

### 実行結果


## 参考文献

・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0
稼働中のコンテナのシェルに入りたい～attachとexecの違い～

###環境

・windows 10
・Docker version 19.03.5

#目的とゴール
・attachとexecの違いが分かるようになる
・起動中のコンテナのシェルに入れるようになる

#attachとexecの違い
###attach

稼働中のコンテナに入るコマンド。
コンテナで実行中のプロセスが開始される。
つまり、`docker ps`で表示される`COMMAND`のコマンドが実行される。



###exec

現在稼働しているコンテナで新たなプロセスを開始できるコマンド。
シェルに入りたい場合は下記コマンドを実行する。
`docker exec -it XXXXXXXXXX /bin/bash`



つまり稼働中のシェルに入りたい場合は、
**①docker psでCOMMANDが`/bin/bash`の場合**
**②それ以外の場合**

の2パターンに分かれることになります。


#パターン１：docker psでCOMMANDが/bin/bashの場合

```
docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
72a12e05690c        ubuntu              "/bin/bash"         29 hours ago        Up 8 seconds                          　hungry_bassi
```
実行中のプロセスは`/bin/bash`となります。
こういう時は`attach`してあげればシェルに入れます。

```
> docker attach 72a12e05690c
root@72a12e05690c:/#  
```

ちなみにSTATUSが`Exited`の場合は、`docker start -ai XXXXXXXX`で入れますね。
attachはあくまで稼働中のコンテナのプロセスに入るものであって、止まっているものについては再度スタートしてあげる必要があります。



#パターン2：それ以外の場合

docker psでCOMMANDが`/bin/bash`以外の場合はどうでしょうか。

```
>docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                      PORTS                NAMES
205974b714d2        httpd               "httpd-foreground"   20 hours ago        Up 5 seconds                0.0.0.0:80->80/tcp   nostalgic_maxwell
```

この場合、attachしてもダメです。
稼働中のコンテナのコマンドは`"httpd-foreground"`であって、シェルではないからです。

こういう時は`exec`コマンドを使って新たにプロセスを開始します。
/bin/bashを指定してあげるわけです！

```
>docker exec -it 205974b714d2 /bin/bash
```




#おまけ：稼働中"ではない"コンテナのシェルに入るには

###パターン1　そもそもコンテナがない場合

```
docker run -it 【コンテナID】/bin/bash 
```

`/bin/bash`を指定して、イメージから新たに立ち上げてあげればいいですね。

###パターン2　コンテナがあるが、Exitedの場合


```
docker start -ai 【コンテナID】
```

スタートしてあげる必要がありますね。
もちろん`COMMAND`が`/bin/bash`であることが前提となります。

`COMMAND`が`/bin/bash`以外の場合には、一旦スタートしてその後
`docker exec -it XXXXXXXXXX /bin/bash`
でシェルに入りましょう！
フリーランスになります！

みなさんこんにちは。
12月からSEとしてフリーランスになるたつぞーです。

今回私が書く内容はフリーランスになるまでの話をしていこうと思います。
※長文となる為、お暇な時に読んで頂ければ幸いです。

まず私の経歴から
・大学卒業後、SEとして中小企業に就職。
・2年半して退職。
・その後1年弱、アルバイトの日々。
となります。

・使用言語
　　Java、HTML,Javascript,CSS
・ざっくりとした業務内容
　印刷機の画面開発(機能と画面)
　関わったアプリは15個ほど、主にアプリの機能追加。
　検証作業。新規案件に向けて技術調査。

～～～～～～～退職について～～～～～～～

退職理由は日々成長することを期待される職場で、わがままではありますが
毎日プレッシャーに押しつぶされそうになり、やめる1年前までずっとうつに
なるんじゃないかってくらいネガティブになっていました。

そして、転職のことを考えることより「この場から早く逃げないと死んじゃう！」と
思い気づいたら退職をしていました。

退職後は2,3ヶ月SEではなく、インフラ系の仕事を探し、面談を受けて内定もいくつかもらっていました。
しかし、1,2個目の内定をもらった時は「俺ってまだ市場価値があるんだな」と思っていたのですが、
それよりも「前職での職場環境(だれがどう見たって良い環境だが俺には無理だった)と同様だったらどうしよう。」
という考えが一歩踏み出す私を邪魔していました。

結局内定はお断りして、アルバイトをして食いつないでいました。
(ちなみに実家暮らしなのでそこまで生活には困らなかったです。)

アルバイトをしている間、どんな仕事をしようかと考えました。
例えば、バスの運転手、鍵屋、小売業、etc....
そして、接客業で面接を受けていく中で私はフリーランスを目指すきっかけがあったのです。
～～～～～～～～～～～～～～～～～～～～


～～～～～～～フリーランスを目指すきっかけ～～～～～～～

私はパチンコ、スロットをよく友人と打っていました。
そこで安直でしたがパチンコ業界で大手の会社の面接を受けました。
3次面接まであったのですが、最終面接が私の考えを変えたのです。

最終面接の面接官は人事部長でした。
話しを聞くと、心理学の資格を持っている方で、私の一挙一動をくまなく
みて、私をこんな人間だなと話して下さりました。

・メンタルが弱い
・人に興味がない、ロボットみたいだ。
・一つの目標に愚直に努力できる
etc...

まず、素直な感想として、
「これ面接なのか？今後頑張れって意味？」
と思いました。
しかし、面接官は
「だが、あなたはまだ変われる。ダメなところから目を逸らさず
　愚直に努力して改善できる。将来やりたいことをよく考えてみて！」
と励ましてくださりました。

この言葉から私は、正直SEという仕事から逃げてしまいましたが、
自分のやりたいことはなんだろうと考えた時、
「生活が豊かになる。そんなものづくりをしたい。」
と心の底から思い、SEの仕事を探し始めました。
～～～～～～～～～～～～～～～～～～～～～～～～



～～～～～～～フリーランスになるまでの話～～～～～～～

ここからは私がフリーランスになるまでのお話しをします。
いざ転職活動をしようと思っても、
「経験値がすくないこんな私をどこが雇ってくれるんだ。」
となかなか行動に移さなかった自分がいました。

そんな時、前職の会社の先輩からフリーランスになった
というお話しを聞き、食事に行きました。
話しを聞いていると、
・職歴は長かろうと短かろうと関係ない。
・見られるのは実際に経験した業務の経験年数。
・仕事はいくらでもある。
・自由度が高い。
とのことでした。

そこから
「地団駄踏んでるのはもったいない。会社員と違ってもし仕事内容が
いやだったらやめれるから！試しに3ヶ月くらいやってみない？」
とお誘いを頂きました。ちょうどSEの仕事をどうしていくか考えていた為、
二つ返事でお願いしました。

そこからその先輩がお世話になっているフリーランス紹介エージェントの方を
ご紹介して頂き、お話しを聞いて仕事を紹介してもらいました。

面接は2つしか行っていませんが、そのうちの一社が未経験の私でも
育てると行って下さりました。
業界は金融系で激務必至であろう現場ですが、一から学ばせて頂ける職場が見つかり
安心しました。
～～～～～～～～～～～～～～～～～～～～～～～～～～～

～～～～～～～最後に～～～～～～～
フリーランスになっていない私がいうのはおこがましいですが、
フリーランスになるメリット、デメリットを感じた中でお伝えしようと思います。

■メリット
　・案件ごとに仕事の契約を行う為、タイミングがよければ様々な技術に触れ合う
　　チャンスがある。
　・時に職場が転々とすることがある為、交友関係が広がる。
　・契約期間での業務になる為、人間関係に悩まなくて済む(個人的にここがすごくメリットに感じた)
　・節税ができる。(当たり前)


■デメリット
　・会社員とは違い、保険や年金などの公的手続きをすべて自分でやらなくてはならない。
　・着実にスキルをつけていかなければ紹介される仕事も少なくなる。
　・契約期間中に企業側が契約を切ることも可能な為、仕事がいきなりなくなる可能性がある。


～～～～～～～～～～～～～～～～



とても長くなりましたが以上、フリーランスを目指すたつぞーのお話しでした。
ここまでご一読して頂いた方、ありがとうございました。
もしこの記事をみてフリーランスを目指すきっかけになったら
嬉しいです。
teachablemachineを使って、なんかやってみた

こんにちは。ジョンです。

昨日の@shin27さんの
[AWS認定ソリューションアーキテクト – アソシエイト試験を受験してきた](https://qiita.com/shin27/items/1efe51c5a646b9ad1ec7)
読ませて頂きました。

自分もAWSの勉強をしているので参考になりました。
では、ニフティグループ Advent Calendar 2019の2日目の記事始めます。
<h1>はじめに</h1>

いつも通りの出社中

[こういう記事](https://www.itpro.co.uk/machine-learning/34782/google-tool-teaches-machine-learning-to-six-year-olds)を読みました。

まとめますと6歳の子供にAIを教えるGoogleのツールの内容です



https://teachablemachine.withgoogle.com/train

Web基盤の機械学習ツール、ポチポチですべてできます。

面白いと思ってやってみることにしました。

<h1>teachable machine</h1>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/70ef60f9-56b9-499b-45dc-fef9c2335862.png)


teachable machineでできる機会学習は　画像分析、サウンド分析、モーション分析の三つです。

画像をやってみることにしました。

使い方はどても簡単です。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/6ad1a72d-d374-0e77-f84e-d7b4abe8c715.png)

- 1で画像を登録する
（カメラ・アップロード両方できます。複数のClassを登録可能）
- 2で訓練ボタンポッチット
- 3で判別したい画像を登録
- 4で結果
- 6で作った訓練モデルをエクスポートできる

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/d8f25e34-c017-43c4-5726-d5241687f012.png)
tensorflowの学習データです。


エクスポートでを押すと
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/8ef64908-1988-2691-1a24-6a95f5564fdd.png)


こんな風にジャバスクのコードも提供しているので、コピペすると

コーディングなしでカメラで画像の判別ができる静的ウェブページを作ることができます。



このままで終わると面白くないので、さらに何か作ることにしました。



<h1>コーディングなしでポケモン図鑑サイトを作ろう</h1>
ポケモン画像をカメラに移すと判別してくれる図鑑を作ることにしました。

必要なものは以下

- 上のソースコード
- 画像クロールのChrome拡張機能（fatkun）
- 図鑑テンプレートファイル
- ホスティングサイト（netlify）

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/e69c603e-e889-6edc-7fd5-ebfc44095f34.png)

まずfatkunで判別したポケモンの画像を収集します。





その後、ポケモン図鑑テンプレートソースをググッて探します。

https://codepen.io/Bidji/pen/MYdPwo

ありました。



teachable machineのコードと図鑑テンプレートコードをコピペし、合わせます。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/570840a1-7cc5-14e7-236f-c5ce6fd2935c.png)





合わせた後、各ポケモンごとのパラメータを設定します。
こればかりはコーディングせざるを得ないですね・・

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/76a000ce-2d67-b3c7-1bb7-b740a19e4a73.png)
終わりました。
~~めんどかった~~



作ったファイルたちをnetlifyにアップロードして、ホスティングします。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/e3fbc87e-3d3e-dea5-5e9f-9c616040e815.png)




できました。

![9_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/a61ac152-5e70-e2b7-cdb9-958e2d0edcc8.png)


https://happy-nobel-722acb.netlify.com/html.html

startボタンを押すと、カメラが起動して、ポケモンを判別し説明してくれるポケモン図鑑を完成しました。

しかし今はピカチュとフシギタネのデータしか入っていませんので、
ピカチュかフシギタネかだけを判別してくれます。![deal_with_it_parrot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541333/b8af24fb-a74c-596d-3202-6e29b45a7c3b.gif)


<h1>感想</h1>
ポケモンパラメータ設定以外はコード全然書いてないし、
あとの作業は全部ポチポチで一時間程度で作ったので、子供にもできるものかと。

次は@y_konoさんの[AWXの通知をカスタマイズする](https://qiita.com/y_kono/items/8234e094c193baf9ee43)の方よろしくお願いします。
インスタのような感じのアプリを作るスパイラル仕様

１．文字投稿サイト
ヘッダーのパーシャルを使う。
文字投稿はRESTfulな入力フォームを使う。

２．ユーザー登録機能
ヘッダーにifでログイン状態のときに表示を変える。
投稿に対して名前が付与される。この時に関連付けが利用される。
postテーブルの関連付けからuser.nameをひっぱる。postにはuser_idを追加

簡略化のために名前とメールアドレスだけで認証を行う。
パスワードはあとでok

２．５投稿に○○さんの投稿と名前をつける
ログインしていない投稿にはifでゲストさんにしておいた。

３．画像機能
画像が投稿で追加される。
取得できればそんなに難しくない。

３．５　いいね機能
そんなに難しくはないと思う。

４．関連付けでフォロー
できないことはないと思う。

これ以降
細かい機能を取り付け
・投稿、ユーザーの検索
・投稿への返信機能
・ユーザーへのメッセージ機能
・フォロワー通知
・バリデーション
・デザイン
・Restfulな書き方、美コード化
・各機能等のテスト方法考案
・フォロー機能
・いいね機能
・基本的なログイン（パスワード仕様）
・発展的ログイン（クッキー）
・sns紐付けログイン
・投稿詳細ページ
・ユーザー詳細ページ
・アカウント有効化メール
・パスワード再設定機能（メールなし・あり
・投稿の削除・編集
・ユーザーの削除・編集

1203　ここから取り付ける機能厳選考
●ログイン機能強化　地味
⇒idがごちゃついている ほどくのは時間かかる
●登録機能強化　地味
⇒メールで送る 外部要因で動かないと困る
●フォロー機能追加　華麗　採用
⇒テーブル関連 ほどくのは難しいが配線するだけならいけると思う。

今回はできるだけたくさんの機能を搭載して
粗削りであっても見所のある作りができることを証明するのが大事だと思う。

12/06 まで隈なく取り組めるように細かいところは後で作れるようにしてある。
フォロー機能でいこう。
flycheckのツールチップ表示を抑制する

**注:flycheck-pos-tipやflycheck-popup-tipとは異なります**

flycheckではエラーや警告メッセージが[GUIツールチップ](https://www.gnu.org/software/emacs/manual/html_node/emacs/Tooltips.html)を介して表示されます。しかし、`lsp-ui-sideline`などを使っていると情報が二重に表示され、邪魔くさくなります。

これを抑制するには

```emacs-lisp
(setq flycheck-help-echo-function nil)
```
としてやればよいです。[^1]

参考: 
[Interact with errors — Flycheck 32-cvs documentation](
https://www.flycheck.org/en/latest/user/error-interaction.html#variable-flycheck-help-echo-function)


[^1]: defcustomにsetqを使うことの是非についてはここではスルー。
ワンコマンドで複数行にわたるテキストファイルを作成する

毎回忘れるのでメモ

```sh
cat <<-EOF > /tmp/hogehoge.json
{
   data: "hogehoge"
}
EOF
```
結果

```sh
[root@754ec3e9caec /]# ls -l /tmp/hogehoge.json
-rw-r--r-- 1 root root 24 Nov 29 09:19 /tmp/hogehoge.json
[root@754ec3e9caec /]# cat /tmp/hogehoge.json
{
   data: "hogehoge"
}
```

手順書作るときに便利
以上。
SCMの別の見方

# SCM
この記事では、SCM（構造的因果モデル）の別の見方を提示します。
SCM自体の説明はおこないません。

# 例
（この例は、Bernhard Schölkopf. Causality for Machine Learning. arXiv:1911.10500. から取っています。）
二つの変数$X,Y$だけを含む、次のような$X \to Y$というSCMを考えます。

```math
\begin{align}
X & = U \\
Y & = f(X, V).
\end{align}
```

ただし、$U$と$V$は外生変数で、独立とします。

さらに、このSCMが、以下のようなものであるとします。

- $X$と$Y$は、${0,1}$の2値変数。
- $U$と$V$は、一様なベルヌーイ変数。
- $V$の値によって、関数$f$が$f(x) = x$となるか、$f(x) = 1 - x$となるかが決まる。

このSCMは、興味深い性質を持っています。
それは、観測データからは$X \to Y$という関係性を得られない、という性質です。
理由は次の通りです。

$X$は、$X=U$という式より、一様なベルヌーイ変数となりますが、
$Y$も一様なベルヌーイ変数となり、しかも$X$とは独立になります。
このように、$X$と$Y$が独立になってしまうので、これらの値のペアをいくら観測しても、
$X \to Y$という関係性を観測データから得ることはできません。

# 例の別の見方

上の例と全く同じSCMについて、別の見方を提示します。

$\Omega = \\{a,b,c,d\\}$について、$P(\\{a\\})=P(\\{b\\})=P(\\{c\\})=P(\\{d\\})=1/4$であるような確率空間$(\Omega, 2^\Omega, P)$を考えます。

$\\{0,1\\}$に値をとる確率変数$X$を、次のように定義します。

```math
X(a)=0 \\
X(b)=0 \\
X(c)=1 \\
X(d)=1 \\
```

関数の集合$\\{f_1, f_2\\}$に値をとる確率変数$\xi$を、次のように定義します。

```math
\xi(a)=f_1 \\
\xi(b)=f_2 \\
\xi(c)=f_1 \\
\xi(d)=f_2 \\
```

なお、$f_1(x) = x$、$f_2(x) = 1 - x$とします。

このとき、$X$と$\cal{F}$は独立となります。ひとつのケースについてだけ示すと、

```math
P(\{\omega : X(\omega)=0\} \cap \{\omega : \xi (\omega)=f_1\}) = P(\{a\}) = 1/4 \\
P(\{\omega : X(\omega)=0\})P(\{\omega : \xi(\omega)=f_1\}) = P(\{a,b\})P(\{a,c\}) = 1/2 \cdot 1/2 = 1/4
```

となります。他の3つのケースについても同様です。

そして、確率変数$\xi$の値である関数を、$X$の値で評価した結果を$Y$とします。
このように$Y$を定義すると、以下の結果が得られます。

```math
Y(a) = \xi_{X(a)}(a) = f_1(0) = 0 \\
Y(b) = \xi_{X(b)}(b) = f_2(0) = 1 \\
Y(c) = \xi_{X(c)}(c) = f_1(1) = 1 \\
Y(d) = \xi_{X(d)}(d) = f_2(1) = 0 \\
```

このとき、$X$と$Y$は独立となります。先ほどの例と同じ結果です。

# おわりに

任意のSCMについて、上のように外生変数を無くしてしまい、
確率変数と確率過程（関数空間に値を取る確率変数）の言葉だけで書き直すことは、できるのでしょうか？

残念ながら、私にはこの問題に答えるための数学力がありません・・・。
チーム内で不要とされたremote branchを消すコマンド

#はじめに
gitを利用している場合
油断するとチリツモの如く溜まっていくremotebranch。

見通しが悪くなったりするので
PRが通ったタイミングで消すのがベストかもしれませんがうっかりなんてことありますよね:disappointed_relieved:

ちょうど試してみたのでその方法の共有になります。

# コマンド

```
git branch -r --merged | egrep -v "\\*|release|master|develop|feature/xxx" | awk '{ print substr($0, 10)}' | xargs -I branch git push origin :branch && git fetch --prune
```
 
`git branch -r --merged`
merge済のbranchリストを取得

`egrep -v "\\*|release|master|develop|feature/xxx"`
merge済であっても消して欲しくないbranchを指定

消して欲しくないremotebranchについてはしっかりチームメンバーに聞きましょうね！
アクシデントの元になる恐れがあります:scream:

`awk '{ print substr($0, 10)}'`
 egrepの出力結果では`origin/`が文字列に含まれており後に控えるremotebranchを消すコマンドで都合が悪いため文字を`oridin/develop` -> `develop`となるように整形

`xargs -I branch git push origin :branch`
整形された文字列を引数としてremotebranchを消す

`git fetch --prune`
remoteで削除されたbranchをlocalに反映

# 実行前にどのremotebranchが削除対象なのか確認
```
git branch -r --merged | egrep -v "\\*|release|master|develop|feature/xxx" | awk '{ print substr($0, 10)}' | xargs -I branch echo branch
```
# 最後に

remotebranchを消す方法については何個もやり方はあると思いますが、
一例としてみてもらえると幸いです:relaxed:
リアクティブな書き方、アロー演算子アレルギーを克服する

#例えば「Vuex」の「getters」の書き方。

お恥ずかしながらイキって「ES6」で書いた結果、自分で読めなくなってしまう事があるんです。
いろんな書き方あると思うんですが、結論コレが一番意味が分かりやすいと思います。

```store.js
export default new Vuex.Store({
  state: {
    test: 'initial state',
  },
  getters:{
    test(state) {
      return state.test;
    },
  },
});
```
```App.vue.js
computed: {
  test() {
    return this.$store.getters['test']
  },
},
```

##Javascriptの昔の書き方を今風に変換する

これは大昔の書き方です。配列に入れてリターンで返すやつ。

```js
function test(state){
  var array = new Array();
  array = state['test'];
  return array;
};
test(state);
```

　↓　最近のES5ってこんな感じですよね。

```js
var test = function( state ){
  var array[] = state.test;
  return array;
};
test(state);
```

　↓　それをリアクティブな感じにすると、Vueで使えます。

```js
test: function(state) {
  return state.test;
},
```

　↓　もっと省略した書き方ができます。

```js

test(state) {
  return state.test;
},
```

　↓　ES6のアロー演算子。

```js
test: (state) => state.test,
```

##アロー演算子・・・

`function{ return }`を `=>` と、省略して書けるのは分かるけど、
なんとなく、気分的にですが `return` 書いてないから左の変数に値が返ってきてないような気になるんですよね。

誰かが
「アロー演算子は（〜の中の）って読むと意味が分かる」って言ってました。
ダイレクトに値を取り出せる的な意味なんだそうですが、個人的には矢印を逆方向して欲しかったッスね〜

```js
test <- state.test
```
こっちのほうが、変数に値がリターンされてる感あるじゃないですかｗ
以上です。
WafCharmを始めるときに知っておきたいTips

最近WafCharmを導入したのですが、公式以外にあまり情報がなかったので、公式サイトに記載がないTipsなどをまとめることにしました。

# WafCharmとは何？
[WafCharm公式](https://www.wafcharm.com/)
サイバーセキュリティクラウドが提供する、**AWS WAF運用を支援してくれるサービス**です。WafCharm自体は**WAFではありません**。Managed Rulesとも違います。
あくまでAWS WAFの支援サービスなので、利用できるのはAWS WAFに対応しているCloudFront, ALB, API Gatewayのみです。
WAF Classic, v2いずれにも対応しています。

# 導入の注意
## WafCharm以外の費用
WafCharmの利用コスト以外に、

 - AWS WAFの利用費用
 - CloudFront, ALB, API GatewayアクセスログログのS3保存費用

がかかります。
さらに、攻撃通知メールを受信するために

- Kinesis Data Firehose
- Lambda

を設定する必要があり、こちらも費用がかかります。参考までに1.7億リクエストでKinesis Data Firehoseのコストは25USD程度でした。
AWS WAFに限らず、WAF運用は誤検知や検知漏れの対応が鍵になるため、攻撃通知メールの受信は実質必須といってよいでしょう。
## 導入作業
作業ドキュメントはありますが、自分でCloudFrontやAWS WAF, Kinesisなどの設定が必要です。基本的にAWSを自分で設定できることが導入の前提になります。

## Cyber Security Cloud Managed Rules for AWS WAFとの違い
同じサイバーセキュリティクラウドが提供しているCyber Security Cloud Managed Rules for AWS WAFは全く別のサービスで、OWASP Top 10に準拠したAWS WAF v2/Classic対応のマネージドルールです。なお、WafCharmとの共存も可能で、WafCharmのProfessional以上に契約すると、このマネージドルールのサポートも受けられます。

# 導入
導入方法は[マニュアル](https://www.wafcharm.com/blog/check-wafcharm-setting-jp/)を参照してください。
攻撃通知や月次の統計情報設定方法は契約者向けページに記載されているので、ここではリンクしません。

# Tips
## ACLセットはまとめるべきか?
ACLセットはリージョン単位（CloudFront用ACLはus-east-1（バージニア北部）扱い）で使い回せます。ACLセットごとにAWS WAF, WafCharmそれぞれ課金が発生するので、なるべく使い回したいところ。
現在はサービスごとに1ルールにまとめて運用しています。（本番環境、ステージング環境などすべて1ルール）
## 脆弱性診断との兼ね合い
WafCharmがブロックモードになっている場合、脆弱性診断を行ってもブロックされてしまい、アプリケーションに脆弱性があるかどうか調べられません。
しかし仮に脆弱性が見つかった場合、WAFでブロックされることの確認が必要です。そこで基本的に脆弱性診断環境はWAFを設定せず、脆弱性が見つかった場合は有効化して攻撃がブロックされることを調べる方針にしています。
## 攻撃通知と誤検知の対応
WAFによくある現在の攻撃ステータスをリアルタイム表示する機能はありません。月次レポート表示はできますが、月単位で更新されるためリアルタイム性はありません。
リアルタイムな攻撃通知はメール通知で行われます。
メール通知は登録アドレスと、通知用のメールアドレスに送られます。初期は登録したアドレスのみでしたが、今は別に通知用アドレスを設定可能になっています。Slackの投稿用アドレスを指定して、Slack通知を行っています。

## ルールの更新
WAF運用で一番大変なルールのチューニングは、アクセスログを分析して自動的に行われます。誤検知があれば、サポートに連絡することで修正してもらえます。幸い今のところ誤検知は起きていませんが。
ルールのチューニングは概ね1日ごとに行われるそうですが、通知はありません。更新を確認したい場合はCloudTrailが使えます。

## Web Site ConfigにあるS3 Validationって何?
<img width="394" alt="スクリーンショット 2019-12-02 13.31.36.png" src="https://qiita-image-store.s3.dualstack.ap-northeast-1.amazonaws.com/0/19807/4f211c8e-81e5-05d4-c08d-1e4a8dda5aee.png">

ドキュメントには何も記載がないこの項目。空欄だったりnormalだったりしますが、実は現在何も意味がありません。
本来は何か機能があるらしいのですが、今は正常に動作していないそうです。
SumoLogicを始めてみる

#はじめに

今回はサンプルとしてApache形式ログをSumo Logicへアップロードし取り込むところまで実施します。

#Sumo Logicとは
Sumo LogicはSaas上でサービスされているセキュリティにフォーカスシアタマシンデータの分析、オペレーションやBIなどのユースケースを持っているサービスです。


#無料トライアルに申し込む
https://www.sumologic.jp/sign-up/jp/

- メールアドレス（Gmailなどの無料メールアドレスは登録不可なので気をつけてください）
- 地域（Sumo Logicが動作しているAWSのリージョンを選択）今回は「アジア太平洋ー東京」を選択
- プラン「Enterprise-無料トライアル」を選択
- サービス使用許諾契約に同意します。サービス使用許諾契約の内容を確認し問題がなければチェック
- はい、Sumo Logicからの連絡を希望します。（任意）

![スクリーンショット 2019-11-28 15.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/4a359351-7ddf-5f29-ddf6-08fcfd12ca64.png)


#アカウントのアクティブ化

Sumo Logic から届いたメールに従って、アカウントをアクティブ化します

![スクリーンショット 2019-11-28 15.20.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/39508785-d5d5-e543-c268-044de8ec556c.png)

[Activate Your Account (アカウントのアクティブ化)] フォームに必要事項を入力します。 

![スクリーンショット 2019-11-28 15.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/6503d75b-1ad9-7724-2417-dbc7cdf9336a.png)

[Activate (アクティブ化)] をクリックします。
これで無料トライあるの登録は完了しました。
次に、実際にSumo Logicを触っていきます。

#セットアップ ウィザード
まずサンプルとなるデータをこちらからダウンロードします。
https://help.sumologic.jp/@api/deki/files/151/apache_access_logs_tutorial.txt?revision=1
画面からUpload Fileを選択
- Upload Files (ファイルのアップロード):  静的なローカル ファイルをアップロードして、Sumo Logic の機能を試用できます。

![スクリーンショット 0001-11-29 14.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/d2f3475d-1330-0061-827e-f7b31a955e39.png)

1. 次に、アップロードするログ ファイルのタイプを[Apache]を選択
2. 後でログの検索に使用する [Source Category (ソース カテゴリ)] は自動的に入力されます。
3. アップロードするファイルをドラッグ アンド ドロップするか、ブラウズ ボタンを使用します。ファイルは合計で 20 ファイル、サイズは 100MB 以内に制限されています。
4. 使用するタイム ゾーンを選択します。
 - Use time zone from log file. If none present use を選択
    - (UTC)Etc/UTC を選択
5. [Continue (続行)] をクリックします。

![スクリーンショット 0001-11-29 14.50.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/43d1930e-e309-ae64-5909-363efb0f7e05.png)

![スクリーンショット 0001-11-29 14.50.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/f8c072e9-4b3a-73ac-2b18-4be527ff9ffb.png)

Uploadが完了すると、[Start Searching My Logs]が選択可能となります。


![スクリーンショット 0001-11-29 14.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/390d279d-6f09-e9d6-366e-18e4f7209a6b.png)
#Dashboardsで、取り込みデータの確認

クリックすると、[Search] ページに移動して取り込まれたLogが表示されます。

![スクリーンショット 0001-11-29 14.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/d47e15fa-68e8-020b-cc40-53959057181e.png)

注）サンプルのログファイルが[ 19:39:27 UTC 2018]と言ったフォーマットとなっており日付が入ってませんので、アップロードした当日の[19:39:27] + 0900 = [04:39:27 JST]のログとなることを気をつけてください。
検索する際は右上の検索時間を指定する箇所を[Last 24 Hours]　などへ変更するとアップロードされたログが検索しやすくなります。

![スクリーンショット 0001-11-29 17.40.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88887/b57e87df-c4e2-d01e-e4d7-3a58455e6c8b.png)


#まとめ
今回はログの取り込みを、Webからアップロードをしましたが、実際は各サーバにエージェントを導入したり、Fluentdからログを転送することによってリアルタイムにログの取り込みを行います。
次回は、今回取り込んだデータをApp Catalog機能を使って、実際可視化を行っていきたいと思います。
レビューあるあるとモブプロ

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%82%E3%82%8B%E3%81%82%E3%82%8B%E3%81%A8%E3%83%A2%E3%83%96%E3%83%97%E3%83%AD/)をご覧ください😀

## はじめに

みなさん、コードレビューしてますか？
上手くいかない！つらい！もうレビューやだ！と思ってたりしませんか？

**そこでモブプロですよ！**

## レビューあるある

レビューではいろいろな問題が発生しがちです。

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-8-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/8)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-10-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/10)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-12-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/12)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-14-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/14)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-15-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/15)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-16-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/16)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-17-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/17)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-18-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/18)

[![thumbnail](https://image.slidesharecdn.com/reviewmob-191129054719/95/slide-19-1024.jpg)](https://www.slideshare.net/naoqoo2/ss-199199291/19)

上記どれかひとつでも「あるあるー」と思ったらぜひモブプロをやってみてください。

## モブプロで解消できるの？？

モブプロではつねに議論（レビュー）をするので、これらが発生することはありません。
※事象自体は発生するものもありますが口頭でその場で解決するので問題にならない。

## さいごに

レビューに限らずチーム開発でモヤモヤしたら

**『そこでモブプロですよ』**

を合言葉に一緒に作業してみることをオススメします。きっと幸せになれますよ。

## おまけ

「でもモブプロって生産性悪いんでしょー？」と思った方は[こちら](https://qiita.com/naoqoo2/items/ec89af8d1f3f6af4babb)。
【swift】var geometry: [MKShape & MKGeoJSONObject] という定義を見てビックリした

小ネタですが、１時間ぐらい調べてしまったので、書いときます。

# あなたはわかりますか？
AppleのMapkitにGeoJSONを処理するクラスがあって、それを仕事でゴニョゴニョしています。
そんな中、こんなプロパティを見つけました。

```swift:
var geometry: [MKShape & MKGeoJSONObject] { get }
```

これを最初見たとき、「え？　型２つあるやん！」（誤解）と焦りました。

# 答え
正解は、**MKGeoJSONObjectはprotocolで、型はMKShape**だけです。
MKShapeはClassなので、MKGeoJSONObjectに従うClass=MKShapeという指定でした。

[プロトコルコンポジション](http://www.studiogalago.com/the-swift-programming-language/language-guide/protocols/protocol-composition/)というカッコいい名前があるみたいです。
プロトコルコンポジションするときは、だいたい下記みたいに、カンマで区切るのが多いので、
今回みたいに＆でつなぐパターンもあるのか〜と新発見しました。

```swift:
class hoge: protocolA, protocolB,…
```

これをプロパティの型に指定して書いてやると、

```swift:
var any: [hoge & protocolA & protocolB]
```

こんな感じになるわけですね。
「,」区切りのときも継承クラスとの区別がわかりづらいな〜と思っていましたが、
「＆」区切りだと完全に型とプロトコルが同列に並んでるように見えて、僕にはわかりづらく感じます。
慣れなんですかね？
YouTube広告のメリットとデメリット

#はじめに

YouTubeに表示する広告って効果あるの？ 再生前に出る広告って逆効果になったりしない？ など、日々進化するYouTube広告に疑問はつきものです。

私は個人的にゲーム実況のYouTubeを運営していて、主に人気ゲームの発売前後に
Google Adwordsを通して広告を出していたことがあります。

今回は、そのとき調べた諸々のおさらいと備忘録としてYouTube広告についてまとめました。

WebサービスにてYouTubeを活用する事例も増えていると思うので、知っておくと役立つかもしれません。

#1. TrueView
YouTubeの主な広告として「TrueView」という広告があります。
これには、動画視聴前に流せる動画広告、YouTubeページ上に表示できる広告の2種類があります。

広告はパソコン、モバイル（スマホ、タブレット）ともに表示されます。

1-A. TrueViewインストリーム広告
TrueViewインストリーム広告は、動画の視聴前に流せる動画広告です。その特徴は3つあります。

・冒頭の5秒間はかならず表示→その後ユーザーがスキップ可能
・5秒後スキップできない設定もアップロード側（広告設定側）で可能
・30秒以上視聴orリンクをクリックされると料金発生・視聴回数が＋1回
（30秒未満の動画の場合は最後までの視聴で発生）

cf.標準インストリーム広告（TrueViewインストリーム広告の前身で、現在はこの形式のものはありません）
最大15～20秒までのスキップできない広告
最後まで動画を見てもらえる反面、スキップできないので動画を閉じて離脱などの可能性も。

1-B. TrueViewインディスプレイ広告
動画の再生ページ上やYouTube検索結果などに表示される広告です。

ユーザーが見ているコンテンツと関連性の高い広告を表示
サムネイル画像・最大3行の広告文を表示
クリックすると動画再生ページやチャンネルへのリンクが表示される
クリック再生されると料金発生

#2. YouTube広告のメリット・デメリット

2-1. YouTube広告の効果・メリット
○費用対効果が高い
インストリーム広告はスキップされれば料金は発生しないので、興味をもつユーザーにのみ動画を届けられます。

○ターゲットを絞って配信できる（セグメント機能）
［地域・性別・年齢・好み・キーワード・時間帯・曜日］などを設定できるので、潜在顧客層に絞って配信可能。
より効果を出しやすいです。

［例］
若者向け女性ファッション中心ショッピングサイトの場合
→20代女性のみに配信

○興味をもつユーザーを自社サイトへ直接誘導できる
動画内にサイトへのリンク（CTAボタンなど）を表示でき、ユーザーが商品サイトなどにすぐアクセスできます。
テレビCMなどと異なり、視聴者の行動を促しやすいです。

○スキップまでの数秒は必ず見てもらえる
TVのようにCM中はチャンネルを変えたり、録画で早送りされたりすることがありません。

○興味をもつユーザーを追跡できる（リマーケティング）
YouTube広告はGoogle　AdWordsと連携しているため、より効果の高いユーザーへ配信ができます。


［例.］
購入したことのあるユーザーへ、リピート購入のための広告配信をする
未購入のないユーザーにのみ広告配信する
○圧倒的に多いユーザー数
YouTubeの視聴者は世界中におり、その数は増え続けています。最近はスマートフォンでの視聴者が伸びてきています。

○「YouTubeはテレビよりも80％以上の広告効果あり」とGoogleが発表
Googleは2016年4月時点で上記の内容のレポートを発表しました。欧州8か国56の事例から出た結果で、「広告主は現在の6倍の予算をYouTubeへの広告出稿に回すべき」、2015年には「若者へリーチするには、テレビへの広告予算の24％をYouTube広告にシフトすべき」と発言しています。


#2-2. YouTube広告のデメリット・注意点
○動画を見てもらえない可能性
インストリーム広告は5秒後にスキップできるので、最初の5秒で心をつかめなければ、そもそも動画を見てもらえません。
そのため、動画制作に時間と費用が予想より多く必要な可能性も当然あります。

○逆効果になる恐れ
目当ての動画を見る前に強制的に再生される動画広告は、ターゲット選定のズレや動画内容によっては不快感をもたれ、商品・企業のイメージダウンにつながる恐れがあります。

スキップできないストレスでひとたびマイナスイメージを持たれると、回復は用意ではありません。慎重に検討しましょう。
また、当然ですが、配信対象を広げすぎると、費用が高くなる可能性があります。

○審査に時間がかかる場合がある
YouTubeやAdWordsのポリシーに準ずるかどうかの審査時間を含めて準備する必要があります。

広告掲載禁止の商品、動画の表現については[広告に関するポリシーの概要](https://support.google.com/youtube/answer/6162278?hl=ja)を必ず確認するようにしてください。

参考：
・https://support.google.com/youtube/answer/2467968?hl=ja
・https://support.google.com/google-ads/answer/2375464?hl=ja
・https://anagrams.jp/blog/basic-knowledge-of-trueview-video-ads/
日本語版GitLab CIリファレンスを技術書典7に出品した！ 話

本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 技術書典7に出品した話

# ことの発端
ある時のI氏との会話(注:脚色されています)

## 2019年7月10日頃の話
I氏：「いやね、技術書典に応募したんですよ」
私：「お、ほうほう」
I氏：「そうしたらですね。当選しちゃったんですが(注：技術書典7は会場が2フロアになったので当選しやすかった)」
私：「いいじゃないですか！」
I氏：「出品するネタがなくて、どなたか本を書いていただける方はいらっしゃらないですか(注：I氏は某技術系出版社の元編集者さん)」
私：「そういうことですか！折角当選したのに出品するものがないとよくないですよね」
私：「某パーフェクト本を書いた人に相談してみましょうか」
I氏：「よろしくお願いいたします」

## CNDT2019
某パーフェクト本著者を発見！

私：「かくかくしかじかで、文章を書いていただける方を探しています」
I氏：「意欲のある方であればどなたでも構いません」
某パーフェクト本著者：「いいですよ！xxxはyyyなのでzzzがいいかな」
(いつもナイスガイな著者さんでした。その節は誠にありがとうございます。)

一段落して
I氏：「ああ、よかった、紹介していただけるそうです」
私：「よかったですね！そういえば、最近私のQiitaの記事でGitLabのリファレンス翻訳したのが結構人気なんですが、これって書籍のネタになりますか？」
I氏：「！！？？」
私：「2017年にGitLabのCIを使おうと思って自分で翻訳したネタをQiitaにアップしてあるんですよ。それからほったらかしにしてたのですが、2019年7月に新しいバージョンに追従して更新したんですね。よければそれを使って本の形になりませんか？」
I氏：「それはいいですね。ネタは沢山あった方がいいですし、今回の出品にならなくても今後のネタにもなるかもしれませんし」


# QiitaのGitLab CIのリファレンス翻訳記事について
## そもそも
元々は、自分の勉強用資料でした。
社内でGitLabを動かしていて、Ver.8からCI周りが新しくなったのは知っていたのですが、GitLabのバージョンアップに疲れており社内向けGitLabのバージョンは7で止まってしまっていました。
これではいかんとGitLab 10を入れ直して社内のプロジェクトを全て移行、Runnerを動かし始めたのはよいのですがよい資料がないので困っていました。
GitLab 10の.gitlab-ci.ymlのリファレンスを翻訳をしました。

Qiitaの編集履歴を見たら2017年9月17日から翻訳を開始したようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/19ddb698-b0aa-5f74-17c4-4f5d6cb201ef.png)

一旦2017年10月にはこのバージョンで一旦Fixしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/3b99533e-b032-ee85-d757-ca75e2c264da.png)

## 月日は流れて
最初の翻訳のバージョンが10だったのでそれから2年経っていました。GitLab 12が発表されており資料が古くなってきていたのは知っていました。そこで、2019年に翻訳内容をバージョンアップしようとリブートしました。

修正を開始したのが2019年5月で完了しているのが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/23d9bfc1-7e13-b19a-3ff4-29517e669386.png)
7月でした。

そういう意味では、タイミングがよかったと思います。

# 書籍の編集について

書籍の編集作業は、I氏に任せっきりで何もする必要はありませんでした。
編集作業から印刷の手配、技術書典への搬入、電子版の作成、BOOTHへの出品など全てI氏にやっていただきました。

できあがりもパーフェクトなもので修正点も殆どなく、流石に長年編集をやられているだけあり非常に品質よくまとめていただきました。
ありがとうございます。

# 技術書典 7

技術書典には何回か参加していますが、出品者として参加することになるとは思いませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/f1a87dc6-7bc9-5b73-e354-f2131ec3a1a4.png)

おかげさまで100冊弱当日は売れたようです。

# 宣伝

I氏がやられているBOOTHのページが以下になります。
techiemedia - BOOTH
https://techiemedia.booth.pm/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/a0830767-be1d-5613-b830-5e3d1d1eaba3.png)

よろしければ、電子書籍版お買い求めください。

【電子書籍版】日本語版GitLab CIリファレンス - techiemedia - BOOTH
https://techiemedia.booth.pm/items/1579669
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/97a9ee4b-0fbd-d02e-ed4b-8aa1aa45b9db.png" width=30%>

# まとめ

技術書典に出品すると「〆切が！」とか「原稿が！」「印刷が！」となることが多いと思いますが、
[テッキーメディア](https://techiemedia.co.jp)さんにお願いするとその辺りの苦労をまるっとお任せできたのは、非常に助かりました。
※その辺りも技術書典への出品の醍醐味だったりもするので善し悪しですが、私は助かりました。
注：売り上げはテッキーメディアさんで、原稿料だけいただく形になります。

紙媒体になると感激もひとしおです。
今は自分で書いた内容を参照しながら、.gitlab-ci.ymlを書いています。
さらに出店者の気分も味わえるので、楽して楽しいところだけを味わえたのではないかと思います。
備忘録：Python3でMySQLに接続する in CORESERVER

#前書き
レンタルサーバーを使ったことがない上、ロクに使えるプログラムも書いていない人間が、CORESERVERでMySQLサーバーを借りた時の備忘録。MySQLに接続するPython3のプログラムを記載するとともに、詰まりがちであった箇所を載せている。
先に言い訳をすると、サーバーに入れたファイルが文字化けするやら、最初から使える外部ライブラリがわからないやら、改行コードの置換に手間取るやらで問題がごちゃまぜになっていた。
だからここにあるのは「とりあえずこうすればうごくよ」という初心者の感想でしかない。ご注意を。

#やりかた
順番は好きなように。ただしSSH接続は、現在のIPアドレスに対して許可が必要。
##MySQLにデータベースを作る
コントロールパネル「データベース」→「MySQL」からデータベースの新規作成。
この「DB名」と「パスワード」は、プログラムからデータベースに接続するのに必要。

##ファイルをサーバーにアップロードする
コントロールパネル「サイト設定」→「FTP/SFTP接続情報」からファイルマネージャーを開いてアップロード。とりあえず/public_htmlにファイルを置く。
以下ファイルの中身

```Python:sqltest.py
import mysql.connector # 最初からインストールされているmysql-connector-python
config = {
    'host':'localhost' # 原文ママ
    'user':'「DB名」'
    'password':'「パスワード」'
    'database':'「DB名」'
}
conn = mysql.connector.connect(**config) 
print(conn.is_connected()) # => Trueと出れば接続できている
```
[このプログラムはこの記事のコードを改変して作られている](https://qiita.com/skokado/items/caa31d3845df23bc0913)

これはデータベースに接続し、接続を確認するだけのプログラムである。ここからデータベースを動かすには、この記事が参考になるだろう
[Python + mysql-connector-python の使い方まとめ](https://qiita.com/valzer0/items/2f27ba98397fa7ff0d74)

##現在のIPにSSH接続の許可を出す
コントロールパネル「サイト設定」→「ツール/セキュリティ」→「SSH接続IP許可」でSSH接続できるようにする。
SSH接続とは、TeraTermやPUTTYを使ってサーバーにアクセスすること。多分。

以上３つをやった上で以下の手順を行う。

##SSH接続する
ここではPUTTYを例に出す。
接続先の指定「ホスト名（またはIPアドレス）」には「***.coreserver.jp」（「FTP/SFTP接続情報」参照）、ポートは22に設定する。
ユーザーIDとパスワードを求められたら、「FTP/SFTP接続情報」のアカウントとパスワードを入力する。

##プログラムを実行
このようになれば問題なく成功している

```
[user@*** public_html]$ python3 sqltest.py
True
```


#Q&A
- **Q. エラー出るんだけど！わかんない！**
    - A. エラー文をそのままググれ、それで改行コードの違いが原因だった、かつ君がAtom使いならこの記事を見るんだ_ [Atomエディタ上からファイルを新規作成する際のデフォルトの改行コードを設定する（Windows環境）](https://qiita.com/nyoro_712/items/8c80e32aa49f7a2d2eaf)
- **Q. Python3プログラムをコマンドとして実行できないよ！**
    - A. プログラムの一行目に「#!usr/local/bin/python3」を入れて、パスを通す。詳しくは[公式のサーバー仕様](https://www.coreserver.jp/support/faq/server.php#severSpec)とこの記事を見てほしい_ [#!/bin/sh は ただのコメントじゃないよ！ Shebangだよ！](https://qiita.com/mohira/items/566ca75d704072bcb26f)
- **Q. PUTTY使ってて、viコマンド打ったら文字化けした！**
    - A. PUTTYの場合、ファイルの中身がEUC-JP以外で書かれていると文字化けを起こす。この記事を見よう_ [puttyの文字化け問題～解決編～](https://qiita.com/kawaty/items/ee96d92847422eac9c8e)
- **Q. CORESERVERで最初から使えるPython3モジュールの一覧が見たい**
    - A. このコマンドを打とう「python3 -m pip freeze」_ [value-domainの質問記事](https://help.value-domain.com/f_tech_cgi/index.cgi?read=1039&ukey=0)
- **Q. PUTTYでいちいちIDパスワードを打つのは面倒くさい？ならこれを見るんだ...**
    - A. [PUTTYで、ユーザID/Passwordをいちいち入力しないで接続](https://web.plus-idea.net/2012/10/putty-id-password/)
kubernetes on minikubeで、DockerイメージがPullできない件について

# Minikubeとは
ローカル環境で（比較的）簡単にkubernetes環境を構築できるツール・仮想環境で、VirtualBoxなどの上で動作します。
詳しくは、公式ドキュメント等をご確認ください

# どハマりしたポイント
今回、なんと丸２日ハマった問題への対応策と、何をチェックすべきなのかの備忘録として記載します。
なので、説明不足とかあります。　追記の希望等々はコメント欄までよろしくお願いしますmm

# 環境
- Minkube (with inside Docker) feat. Kubernetes
- MacOS Catalina
- Docker for MacOS

# やりたかった事
1. Minikubeを起動し、 `eval $(minikube docker-env)`
2. ローカルディスク上にDockerイメージをbuild(docker build ...)
3. `kubectl apply ...`
4. `kubectl get pod`でRunningになってればOK

###のはずだった。。。 `PullError` なんてみたくなたかった

# うまく行かないポイント
### 1. docker build ... `-t xxxx`のxxxxが間違ってる
- これは単純でわかりやすいです。名前が不一致なので探しきれず、リモートを探すもさらに見つけきれず。。。って言う状態
- pruneコマンド等でイメージを削除して作り直しましょう

### 2. imagePullPolicyがAlwaysになってる
- `kubectl edit deployment xxxxx`でチェック
- これがAlwaysになってると、ローカルのDockerイメージが古いかもしれないからと、リモートを検索してエラーになります。
- `IfNotPresent` (ローカルになかったらリモート探してね)。または`Never`(ローカルが正だ！)を設定する事で回避

### 3. `eval $(minikube docker-env)`が無効になってる
- 意外と気づかない
- 契機はわからないけど、PCがスリープに入ったりしたくらいでも無効になる模様
- イメージ名も合ってる、IfNotPresentも設定したのにPullエラーが起きる様なら疑うべき
- 対応策
    1. `kubectl delete deployment xxxx`
    2. `kubectl delete service xxxx`
    3. kubectl get pod / service / deploymentでお亡くなりになっている事を確認
    4. `minikube stop`
    5. `minikube start`
    6. `eval $(minikube docker-env)`
    7. `kubectl apply ...`
 
# 終わり
仮想化技術はトラブルにずば抜けて強く、チーム開発でも導入にもたつかないメリットがとっても魅力的ですが、目に見えないしログにも現れない’繋がり’の問題が発生すると厄介だなと思い知らされました。。。

この問題は今回の様にローカルの開発環境だからこそ発生する問題で、通常通り稼働しているkubernetes環境では発生しないものと思われます。

トラブルシューティングツールか何か合ったら嬉しいけど、、、大体のケースでは上手くいくはずって事なのかな

作成した方がいたらコメントで教えてください（笑
【OCI Compute】Invalid ssh public key type "----" エラー

# 環境

* putty genで鍵を作成
* ローカルPCはwindows

OCI Computeを作成する際に、公開鍵の指定で「Invalid ssh public key type "----"」が発生した場合の解決策

# Invalid ssh public key type "----"　の解決策

OpenSSH形式のカギをコピーして、.pub拡張子でファイルを保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532975/da999cc4-4139-28f8-ca18-5abf5d2f7539.png)



## pem形式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532975/1dccc927-0f64-593d-09fa-4f582767b76a.png)
Save Public Keyで作成した場合は、pem形式になっているので注意。

# おまけ
# 鍵系のエラー
* InvalidKey - Invalid PEM format

pem形式に対して以下のような形式

```
ssh-rsa XXX...

```

解決策(mac)

```
pem形式の秘密鍵作成
openssl genrsa -out ~/.oci/oci_api_key.pem -aes128 2048 

pem形式の公開鍵作成
openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem

フィンガープリント 取得
openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c

```
参考

* [Required Keys and OCIDs](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#How)
スマホアプリのバグ調査Tips（勉強会用）

## はじめに

バグ調査のやり方が人それぞれ違うなと感じている

私がやってることの共有と、他の知見を集めたいという目的

設計/実装に求められる能力と、バグの原因特定に求められる能力は、別物である

バグ調査は推理ゲーム

---

## 例えば、印刷してもプリンターが動かない場合

* 同じ端末から**別の**プリンターで印刷してみる
* **別の**端末から同じプリンターで印刷してみる
* プリンタのプロパティからテスト印刷してみる

まずはこのように原因特定を始める

* いきなりプリンタドライバーを再インストールしてみる

みたいな闇雲な始め方は望ましくない

> 参考: [「原因が特定されました！」などと言うのは10年、、いや5ステップほど早い](https://blogs.itmedia.co.jp/noubiz/2014/08/post_149.html)

---

## 強制終了する場合

以下は基本

* Stack trace
* BreakpointとDebug実行
* printf的ログ出力を細かく仕込む

以下も使えると良い

* [Crashlytics](https://console.firebase.google.com/project/_/crashlytics)
* [Build Scan](https://scans.gradle.com/?_ga=2.131930959.1550494474.1570447026-1415319631.1570447026#gradle)
* 例外にBreakpointを貼る

> 参考
> [Xcodeでデバッグ実行中にクラッシュした時に捗るブレークポイント設定](https://qiita.com/mono0926/items/bf70c7ef15db046ee163)
> [Gradle Build Scanを使ってみる](https://qiita.com/knagauchi/items/be93308ab324e4d8319f)

---

## エラーメッセージが出る場合

以下は基本

* そのメッセージで全文検索
* ユーザーに聞く
  1. ユーザーは何をしていたか
  1. ユーザーは何を期待していたか
  1. 実際に何が起きたか

以下も使えると良い

* Layout Inspector

> 参考: [Layout Inspector を使用してレイアウトをデバッグする](https://developer.android.com/studio/debug/layout-inspector)

---

## 動作が遅い、重い、固まる

以下は基本

* [ANR](https://developer.android.com/topic/performance/vitals/anr)から推測する
* メモリリークを調査する
    * [LeakCanary](https://square.github.io/leakcanary/)、[Xcode memory graph](https://developer.apple.com/documentation/xcode/improving_your_app_s_performance/reducing_your_app_s_memory_use/gathering_information_about_memory_use)

以下も使えると良い

* [System trace](https://developer.android.com/studio/profile/systrace/on-device)

> 参考: [Android PからのSystem TracingとPerfettoを使ってパフォーマンスを確認しよう](https://qiita.com/takahirom/items/0fc9b1e7fba397c8ae18)
> 参考: [iOS — Identifying Memory Leaks using the Xcode Memory Graph Debugger](https://medium.com/zendesk-engineering/ios-identifying-memory-leaks-using-the-xcode-memory-graph-debugger-e84f097b9d15)

---

## 共通していること

* 現象を再現させる
* 実装を理解する
  * 人のコードを読む癖をつけておく
  * デバッガーの呼び出し履歴を使う
* 原因を推理する
  * ケアレスミス（Null、範囲外Index、定数の間違い、演算子の間違い(=/==)）
  * 考慮してない入力値
  * 意図しない型キャスト（小数→整数）
  * 複数スレッド非同期実行
  * サーバーレスポンス異常

> 参考: [How to fix bugs, step by step - Software Engineering Tips](https://sites.google.com/site/yacoset/Home/how-to-fix-bugs-step-by-step)

---

## 共通していること

* わからなければ二分探索しよう！
  * 一部をばっさりコメントアウトして実行
* めんどくさければモックを書こう！
  * 同じレスポンスをサーバーで用意するのはとっても非効率
  * 実体←→モックの差し替えが容易かどうかはアーキテクチャー次第
* 上手くいってる修正方法を探そう！
  * GitHubはオープンソースの集まりで、トラブルシューティングの宝庫
* 英文に慣れよう！
  * トラブルシューティングは大体英文
  * 言語の壁が、探せる範囲の壁を作る
  * 知らない言語でもそこに唯一の解決策があるかもしれないので、Translatorを使おう（Chromeアドオンおすすめ）
  * とはいえ、怪しいサイトには注意
  * Forumの回答で"same problem"はNGワード扱い

> 参考: [【バグ発見のコツ】二分探索でバグ発生個所を特定する](https://qiita.com/mtanabe/items/91f93b236b89cf11057a)
> 参考: [クリーンアーキテクチャーでスマホアプリ開発した感想](https://qiita.com/knagauchi/items/8c9fb93520b56fd3a564)

---

## まとめ

バグとの戦いは開発言語の知識よりも、頭の中に引き出しがどれくらいあるかの方が大事だと思っています。

> ちなみに僕はF1とかのモタスポが好きですが、F1でも車が予想外の挙動を示した時に、引き出しが多くて対応できるドライバー（どんな車でもそこそこ速いタイプ）と、そうじゃないドライバー（車を完璧に仕上げることが必須のタイプ）がいると思って見てます。どちらを目指すかは人それぞれ自由ですが、個人的には前者がいいな〜と思います。

---

## さいごに

若手エンジニア向けの発表でしたが、私も今のお仕事は2年目でまだまだ無知な若手エンジニアなので、足りない観点があればぜひ教えてください！
こんな人は伸びない！プログラミング初学者がやりがちなダメ勉強法について



##はじめに

私は現在、社内で新人達のメンターを勤めているのですが、
プログラミング学習には向かないダメ勉強法を選択している人が多い気がします。

正しい勉強法で学習すれば成長も早いのにもったいないなと思い、この記事を書いてみました。
※この記事には私の独断と偏見が含まれています。

##1.技術書を丸暗記する
初学者の方にかなり多いのが、とりあえず技術書を丸暗記しようとする人です。
知識だけ詰め込めば上達するわけでは無く、
プログラミングはどちらかと言うと、ロジックや構成などを考えられる力を重視します。

テストで良い点を取りに行く勉強方法は、
プログラミングの勉強にはあまり向いていないと考えた方が良さそうです。

ゲームで例えると、
とりあえずゲームをプレイ(プログラミング)しつつ、詰まったら攻略サイト(技術書やネット)で攻略に必要な情報を検索すればいいだけの話です。

そのうちゲームが楽しくなってきたら、自然と勝手に攻略サイト見ると思いますし、そうなれば最高です。

##2.質問できる環境を作らない、質問できる環境を活用しない
プログラミングをしていると必ず詰まる時がきます。

そんな時のために、社内外で開催している勉強会や交流会で、プログラマーと仲良くなっておくと良いです。
自分の師匠(メンター)を探すと言うことですね。

そういうところに参加している人は、個人的に結構面倒見いい人が多い気がします。

いい人に巡り合えたら、◯◯先生と呼ぶといいでしょう。
プログラマーは先生呼びされるのに弱いので、きっと可愛がってくれると思います。
多分。

LINEやSlackとか何かしらで繋がっておくといいでしょう。

[SOFT SKILLS](https://www.amazon.co.jp/SOFT-SKILLS-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E8%80%85%E3%81%AE%E4%BA%BA%E7%94%9F%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB-%E3%82%B8%E3%83%A7%E3%83%B3%E3%83%BB%E3%82%BD%E3%83%B3%E3%83%A1%E3%82%BA-ebook/dp/B01GDS0994)という本でもメンターを探すことを勧めています。

プログラマーというと、ひたすらPCに張り付いてコードを書いてるイメージがあって、コミュ力が必要ないと思われているのか、勘違いしている人も多いんですが、プログラマーにもコミュ力は大切です。

##3.インプットばかりでアウトプットしない
これは一般的な勉強法でも言われていますが、
インプットした知識を人に説明できなければ、理解しているとは言えません。

どうアウトプットするかと言うと…、
こうやってQiitaに記事として書いたり、勉強会で他の人に説明したりがお手軽でオススメです。

プログラミング初学者では少々ハードルが高いかも知れませんが、成果物を作成してそれをマーケットに公開したり、
自分が誰かのメンターになっても良いかもしれません。

メンターをこなすと、人に物事を分かりやすく伝える力も身に着くので、ベンダーや上流の人達に仕様説明をする時に役立ちます。

と言うかこの仕事に限らず、人として普通にあると良い力なので是非身につけましょう。

##4.プログラミングを覚えた後の目標がない
「仕事で必要なんでしょ。それ以上は別に良いじゃん。」、まあ別にそれでも良いですが。

何か自分でやりたい事があるとか、開発したいものがある人の方が伸びる傾向がありますし、そっちの人の方が技術力も高いので、結果的に給料もたくさんもらっている人が多いですね。

学習する上で、プログラミングを仕事のための勉強としてやるのか、遊びだと思ってやるのか。
どちらがモチベーション上がりますかね？

##まとまってないまとめ
色々なところで言われていますが、
超重要なのはモチベーションを維持することです。

効率良く勉強して素早く成長していきましょう。

##続編
[続・こんな人は伸びない！プログラミング初学者がやりがちなダメ勉強法について](https://qiita.com/shimajiri/items/095a17c425e77c7420b6)
【Django】SQLを指定してデータを取得する方法。

Djangoで生のクエリを実行したい場合はraw()を使えば簡単に実現できるみたい。
[参考：Performing raw SQL queries](https://docs.djangoproject.com/en/2.2/topics/db/sql/)

# サンプルModel

```python:models/users.py
import django.db from models
class Users(models.Model):
    name = models.CharField()
    age = models.IntegerField()
    sex = models.CharField()
```

# SQLを指定してデータ取得

usersテーブルの年齢が４０以上のユーザーを取得する場合

```python
sql = "SELECT * FROM users WHERE age >= 40"
users = Users.objects.raw(sql)
```

下記と同じ結果となります。

```python
users = Users.objects.filter(age__gte=40)
```

# パラメーターを指定

パラメーターを指定して実行することもできます。

```python
sql = "SELECT * FROM users WHERE age >= %s"
users = Users.objects.raw(sql, [40])
```

辞書型で指定する場合。上記だと、複数のパラメーターがあったときに何個目がどの値だっけ？とわかりにくくなるので、下記がおすすめ。

```python
sql = "SELECT * FROM users WHERE age >= %(age)s AND sex = %(sex)s"
params = {"age": 40, "sex": "male"}
users = Users.objects.raw(sql, params)
```
Laravelでよく使うコマンドまとめ

Laravelを使っていてよくコマンドを使いますが、すぐ忘れてしまうので、
まとめておきます。

#Laravelでよく使うコマンド集

```bash
Laravelの作成
composer create-project laravel/laravel qiita --prefer-dist "6.0.*"　//バージョン指定可

ローカルサーバ起動
php artisan serve --host 192.168.33.10:8000

コントローラー作成
php artisan make:controller ShowProfile

モデル作成
php artisan make:model Flight
php artisan make:model Flight --migration //マイグレーションファイル付

テスト作成
php artisan make:test UserTest
php artisan make:test UserTest --unit　//ユニットテスト

テスト実行
./vendor/bin/phpunit

マイグレーションファイル作成
php artisan make:migration add_votes_to_users_table --table=users //テーブル名指定

マイグレート実行
php artisan migarate
php artisan migrate:refresh　//全てをリセットしてから実行する

マイグレートを戻す
php artisan migrate:rollback　//最後の一回分
php artisan migrate:rollback --step=1 //戻す数を指定する場合
php artisan migrate:reset　//全てをリセット

シーダー作成
php artisan make:seeder UsersTableSeeder

シーダー実行
composer dump-autoload　//シーダー実行前に流す
php artisan db:seed
php artisan db:seed --class=UsersTableSeeder //個別にシーダーを実行したい場合
 
ファクトリの作成
php artisan make:factory PostFactory

キャッシュクリア
php artisan config:clear

フォームリクエスト作成
php artisan make:request PostRequest

認証(一括作成)
php artisan make:auth
```

以上です。
随時追加していきます。