OmniAICreator/Qiita-1.07M huggingface dataset:
クラウドサーバー上のDockerでインストールしたKali LinuxをGUIで使いたい

#GUIで動かすKali Linux

[以前の記事](https://qiita.com/rui-watanabe/items/5526d7fbfecc43be84f8)でDockerでKali Linuxを導入しました。

しかし、Kali LinuxはGUIで利用することが多く、CUIでは不便だということを知りました。

そこで今回、**クラウドサーバー上のDockerでインストールしたKali Linuxを、簡単にGUIで動かす方法**について紹介したいと思います。(作業自体は簡単でしたが、Dockerの知識不足と情報量の少なさではまってしまいました)

# VNCでGUI接続

今回、GUI接続するためにVNCを使います。

VNCとは、Virtual Network Computingの略で、文字通り**コンピューターを遠隔動作するためのツール**となっています。

今回はVNCを簡単にインストールできるChromeの拡張機能の、[VNC® Viewer for Google Chrome](https://chrome.google.com/webstore/detail/vnc%C2%AE-viewer-for-google-ch/iabmpiboiopbgfabjmgeedhcmjenhbla/related?hl=ja)を使いたいと思います。


# 前提条件
- Dockerインストール済みのクラウドのUbuntu18.04サーバー

# VNCがインストールされたDockerイメージを利用

今回は前回のKali LinuxのDockerイメージと違って、VNCサーバーがインストールされたものを使います。

```
$ wget https://github.com/rringler/kali-vnc/archive/master.zip
$ unzip master.zip
$ cd kali-vnc-master
$ docker build -t kali:latest .
$ sudo docker images
```

# Kali Linuxを起動

ここの起動時がポイントです。

クラウドサーバーからコンテナを起動する場合は、**IPアドレスとポートを指定**してください。

IPアドレスを指定せずポートのみを指定し起動すると、デフォルトの0.0.0.0のlocalhostのIPが割り振られてしまいます。

VNC接続時はIPアドレス:ポートで接続することになるので、ホスト側でこの指定をしないと接続できなくなってしまいます。

```
$ sudo docker run -it --name kali -p IPアドレス:6080:6080 -p IPアドレス:5091:5091 kali:latest
```

コンテナ内に入ったら、初期設定とVNCサーバーを立ち上げます。

```
# apt-get update && apt-get install metasploit-framework　&& apt-get upgrade
# vncserver :1
```

# VNCに接続

その後、VNC® Viewer for Google Chromeを立ち上げ、IPアドレス:5901でconnectを押したら、Kali LinuxのGUI環境が立ち上がります。

これで、Kali LinuxのGUI接続は完了です。

# 参考URL
https://qiita.com/moe-hana/items/14c5d2ecfc054dd12708
http://www.no1497.com/?p=598
Ubuntu 20.04 上の certbot-auto でエラーが出る場合

* [メモ: certbot - Qiita](https://qiita.com/tukiyo3/items/90512149df8e8c7c8c53)のようにdockerを使ったほうが簡単。

## pythonパッケージがない

cert-bot 1.1.0 や 1.2.0 で発生。

```sh:certbot-auto
$ ./certbot-auto certonly --manual \
>  --domain *.sample.jp \
>  --email root@sample.jp \
>  --agree-tos \
>  --manual-public-ip-logging-ok \
>  --preferred-challenges dns \
>  --server https://acme-v02.api.letsencrypt.org/directory
Requesting to rerun ./certbot-auto with root privileges...
Bootstrapping dependencies for Debian-based OSes... (you can skip this with --no-bootstrap)
ヒット:1 http://jp.archive.ubuntu.com/ubuntu focal InRelease
ヒット:2 http://jp.archive.ubuntu.com/ubuntu focal-updates InRelease                                              
ヒット:3 http://jp.archive.ubuntu.com/ubuntu focal-backports InRelease                                            
無視:4 https://download.docker.com/linux/ubuntu focal InRelease                                                   
ヒット:5 http://security.ubuntu.com/ubuntu focal-security InRelease

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
パッケージ python は使用できませんが、別のパッケージから参照されます。
これは、パッケージが欠落しているか、廃止されたか、または別のソース
からのみ利用可能であることを意味します。
しかし、以下のパッケージが置き換えます:
  python2-minimal:i386 python2:i386 python2-minimal python2 2to3

パッケージ python-dev は使用できませんが、別のパッケージから参照されます。
これは、パッケージが欠落しているか、廃止されたか、または別のソース
からのみ利用可能であることを意味します。
しかし、以下のパッケージが置き換えます:
  python2-dev:i386 python2:i386 python2-dev python2

E: パッケージ 'python' にはインストール候補がありません
E: パッケージ 'python-dev' にはインストール候補がありません
```

### 対応

以下のように python3 を指定すれば良い。

```diff:certbot-auto
--- certbot-auto.bak	2020-02-21 12:25:58.472592655 +0900
+++ certbot-auto	2020-02-21 12:30:24.081600015 +0900
@@ -354,8 +354,8 @@
   fi
 
   apt-get install $QUIET_FLAG $YES_FLAG --no-install-recommends \
-    python \
-    python-dev \
+    python3 \
+    python3-dev \
     $virtualenv \
     gcc \
     $augeas_pkg \
```

----

## `./certbot-auto has insecure permissions!`

```sh
sudo chown root certbot-auto
```

## python2が使われるため、python3を使いたい

`USE_PYTHON_3=1` の環境変数を使う。

```sh
$ USE_PYTHON_3=1 \
> ./certbot-auto certonly --manual \
>  --domain *.sample.jp \
>  --email root@sample.jp \
>  --agree-tos \
>  --manual-public-ip-logging-ok \
>  --preferred-challenges dns \
>  --server https://acme-v02.api.letsencrypt.org/directory
```
ChatWorkの[Re]アイコンの横に[返信元]ってボタンがついたことで感じたUIの難しさ

2/20のアップデートで
チャットワークの[返信]をした時のアイコンに[Re]の横に[返信元]なるボタンが表示されるようになりました。
<img width="94" alt="スクリーンショット 2020-02-21 12.20.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/83c45da4-1aeb-4d14-e731-0cd9f3910b21.png">

元々、[Re]はボタンになっていてクリックすると返信元のメッセージが参照できるようになっていました。

![blog_top_image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/d93091df-f04d-5bc1-0517-e455f27aa255.png)

これが
「**ボタンだということがわかりづらい**」や、
「**知る人ぞ知る機能となっていて、知らない人に都度説明しなければならない**」
という声があって今回のアップデートになったそうです。

知っていれば当たり前に便利に使ってましたが、
改めて考えると
[To]の場合はボタンでもないけど[Re]の時はボタンになっているというUIでした。
これは**知らない人はやっぱりいる**のでしょうね。
たしかに、Reで返信してきているのに返信元の[リンク]をわざわざ貼って送ってくれる人がたまにいますし。。

ただ、デザインとしては[返信元]という文字が増えて領域もとるので余計な情報が増えてしまっているのは気になります。
UIとしては前の方がスッキリしていて好きだったのですが、
**ユーザへの直感的な分かりやすさ**と、**ユーザの声に応えて運営していく難しさ**、**スマートなUIでデザインする表現って難しいなぁ**と感じたアップデートでした。

https://blog-ja.chatwork.com/2020/02/re.html
クラス型のArrayListから、要素を順に取り出す

# はじめに
JAVAにおいて、
「クラス型の要素を格納したArrayListから、それぞれの要素のフィールドのデータを順に取り出す」
という処理を、メソッドとして定義する方法がわからなかった。
解決方法を備忘録として書き記しておく。

# 問題となったこと・その解決の鍵になったこと

- メソッドの仮引数にArrayListを指定する方法が分からない

　**->**  `ArrayList<型> 変数名`　とする。

- for文の中で、クラスのフィールドを呼び出す方法が分からない

　**->**　`リストの変数名.get(i).getName()`　などとする。

# 環境
OpenJDK 13 ([dokojava](https://dokojava.jp/)の利用)


# 具体例

自販機のシステムを模したソースコードで、
- Main.java（Mainメソッドと今回問題となったメソッドを含むクラス）
- Drink.java（飲み物を示すクラス）

の2ファイルで構成される。

```Main.java
import java.util.ArrayList;

public class Main {
	public static void main(String[] args) {

        var drinklist = new ArrayList<Drink>();

        // Drinkクラスを格納するArrayListに飲み物を追加
        Drink coffee = new Drink("コーヒー", 1, 130);
        drinklist.add(coffee);

        Drink water = new Drink("水", 2, 100);
        drinklist.add(water);


        // 今回問題となったメソッドの呼び出し
        displayProduct(drinklist);

        }

        // メソッドを定義
        // ArrayListからDrinkクラスのフィールドを順に取り出す
    public static void displayProduct(ArrayList<Drink> drinklist) {
        for(Drink drink : drinklist) {
        System.out.println(drink.getNumber() + "." + drink.getName()
            + drink.getPrice() + "円");
        }
    }
}
```

```Drink.java
public class Drink {
    private String name;
    private int number;
    private int price;
    
    public String getName() {
    return this.name;
    }
    public int getNumber() {
        return this.number;
    }
    public int getPrice() {
        return this.price;
    }
    
    public Drink(String name, int number, int price){
        this.name = name;
        this.number = number;
        this.price = price;
    }
}

```

出力結果

```
1.コーヒー130円
2.水100円
```
Spring Boot で開発環境の組み込みDB(h2)とリリース用データベース(SQL Server)でFlywayを共存させる

# 前提
- Spring Boot でデータベースを使うサーバアプリケーションを作る
- hibernate を使っていて、データベースも初期化している。
  - `spring.jpa.hibernate.ddl-auto=update`
- ローカルの開発環境は h2 を使った組み込み DB をオンメモリで起動
  - アプリを起動する度にデータベースを初期化する
- リリース先ではもちろん永続化が必要なので別のデータベースに切り替える
  - 今回は SQL Server
- データベースのスキーマ変更が必要になったので Flyway で構成管理したい

# 問題点
- Flyway を適用して db/migration に SQL ファイルを置くが、2 種類のデータベースで競合する。
- ローカルでの開発時は h2 を使うのでマイグレーションは不要
  - 毎回作り直しでオッケー
- SQL Server を使う場合はマイグレーションして欲しい

# 解決方法
- SQL ファイルを vendor 毎に分けて配置
- h2 の場合はダミーの SQL ファイルを配置
- Flyway の SQL が先に実行されるので hibernate の初期化は影響を受けない(テーブルが作成済みのため)

```application.properties
spring.flyway.locations=classpath:db/migration/{vendor}
```

```src/main/resources
src/main/resources/
  db/
    migration/
      H2/
        V1_0_0__dummy.sql
      SQLSERVER/
        V1_0_0__Initial.sql
        V1_1_0__AddHoge.sql
```

```sql:V1_0_0__dummy.sql
select 'dummy';
```
if文を用いて出力メソッドを一呼び出し

※初心者向け
※アウトプット練習の為

開発環境
rails 5.2.4.1
ruby  2.5.1

問題内容
---

20時から翌朝7時までにオウムに喋られると問題があるのでその場合は「NG」、
それ以外は「OK」と出力するメソッドを作成します。
オウムが喋る時をture、喋らない時をfalseと入力することにし、時刻も同時に入力します。

---

呼び出し方：
parrot_trouble(talking, hour)


    def  parrot_trouble(talking, hour)
       if (talking  && (hour < 7 || hour > 20))
         puts "NG"
       else
         puts "OK"
       end
    end
erb拡張子をhaml拡張子に変更する

※初心者向け
※アウトプット練習の為、記述しております。

今回は拡張子の変換について記述しております。

開発環境
rails 5.2.4.1
ruby  2.5.1

やりたい事下記のファイルの拡張子(.erb)をファイルの内容も含め全てhamlへ変換したい。

     /view/_form.html.erb
          /item.html.erb
          /new.html.erb   

まずはGemファイルに記述　

     gem 'erb2haml'
ターミナル

     bundle install
     rails haml:erb2haml

----
実行結果拡張子

     /view/_form.html.haml
          /item.html.haml
          /new.html.haml

以上で変換完了です
Vue.jsのテンプレート構文について


⬇️HTMLっぽいこれがテンプレート構文です

```
<div id="app">
  <p>{{message}}</p>
</div>
```

これを、Vue.jsがいろんな処理をして、最終的にHTMLとして出力し、ブラウザがレンダリングしている！

- マスタッシュタグの中に、`message`とか`sayHi`とかのmain.jsのプロパティを記述します

```App.vue
<div id="app">
  <p>{{message}}</p>
 <!--   マスタッシュタグの中身はJavaScriptをそのままかける -->
  <p>{{number + 4 }}</p>
  <p>{{sayHi()}}</p>
 <!-- マスタッシュタグ内に プロパティを記述する -->
</div>
```


```main.js
new Vue({
	//elはクラス,id,divとかも取れる
	el:'#app',
	data:{
		message:'Hello Wold!',
    number:3
  },
  methods:{
		sayHi:function(){
			return 'Hi';
    }  
  }
})
```

### methodsからdataにアクセスするには
インスタンス内のmethodsからdataにアクセスするには、以下のように書きます。




```main.js
new Vue({
	//elはクラス,id,divとかも取れる
	el:'#app',
	data:{
		message:'Hello Wold!',
    number:3
  },
  methods:{
		sayHi:function(){
    //同じインスタンス内のmessageを表示させたい時、
			return this.message;
    }  
  }
})
```
`this`をつけてプラパティである`message`書くことで、
その値の`Hello World!`が表示されます。
UAC有効環境かつ一般ユーザーでも管理者権限＆管理者として実行する方法

AutoItというツールを使用すれば実現可能。

Autoit 入門 （UWSCを超える簡単PC自動化ツール） |
http://take-web.com/cad/2017/10/autoit/#toc2

・au3形式で保存される。exe形式にコンパイルも可能。
・実行内容をbatやps1で外出しする。
　<font color="red">※ローカル固定パスしか実行できないので注意</font>



●作成手順
１．キッカーをpowershellで作成

```powershell:kicker.ps1
$kickProgram = ".\execContent.bat"
$execProgram = ".\verbRunas.exe"

copy-item $kickProgram "c:\temp\" -force

start-process $execProgram -Wait

remove-item c:\temp\execContent.bat -force
```
２．実行内容をbatかpowershellで作成（内容：UAC無効化の例）

```bat:execContent.bat
REG ADD HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
```
３．管理者として実行するプログラムをAutoItで作成、exe形式にコンパイルする

```autit:verbRunas.au3
RunAs("ローカル管理者アカウント", @ComputerName, "ローカル管理者パスワード", 0, "powershell ""Start-Process c:\temp\execContent.bat -Verb Runas""", "", @SW_HIDE)
```
４．PowerGUIで１のpowershellファイルをコンパイル（※２，３を同梱する）
Dockerイメージの管理コマンド集

# 概要
ここでは、タイトルの通りDockerイメージの管理コマンドを備忘録的にまとめます。
後で編集して、もっとわかりやすいように肉付けしていくつもりです。

# Dockerイメージの管理コマンド集

## docker image build
```
docker image build [ -t {イメージ名} [:{タグ名}]] {dockerfileのあるディレクトリ}
```

DockerfileからDockerイメージをビルドする

## docker image history
```
docker image history
```
Dockerイメージの生成時の履歴を表示する

## docker image import
```
docker image import
```
tarアーカイブなどからイメージを生成する

## docker image inspect
```
docker image inspect
```
Dockerイメージの詳細な情報を表示する

## docker image load
```
docker image load
```
tarアーカイブからdockerイメージを読み込む

## docker image prune
```
docker image prune
```
不要なdockerイメージを削除する。
※ タグが付いていないコンテナで使われていないやつ。

## docker image pull
```
docker image pull
```
レジストリからdockerイメージを取得する

## docker image push
```
docker image push
```
レジストリへdockerイメージを送信する

## docker images
```
docker images
```
dockerイメージの一覧を表示する

## docker image rm
```
docker image rm
```
dokerイメージを削除する

## docker image save
```
docker image save
```
dockerイメージをtarアーカイブで出力する
※ ```docker image load```で読めるようになる

## docker image tag
```
docker image tag　[イメージID] [DockerHubのアカウント名/イメージ名:タグ名]
```
既存のdockerイメージに対してタグをつける
C++で二分探索で配列の中の条件を満たす要素の数を求める

# １点

## xより大きい要素の数
```cpp
return distance(upper_bound(begin, end, x), end);
```

## xと等しい要素の数
```cpp
auto er = equal_range(begin, end, r);
return distance(er.first, er.second);
```

## xより小さい
```cpp
return distance(begin, lower_bound(begin, end, x));
```

# 区間

## xより大きくyより小さい
```cpp
if(x > y) return 0;
if(begin >= end) return 0;
return distance(upper_bound(begin, end, left), lower_bound(begin, end, right));

```

## ライブラリ化

```cpp

struct RangeCount {
    int upper, r_equal, between, l_equal, lower;

    friend std::ostream &operator<<(std::ostream &out, const RangeCount &o) {
        cout << endl;
        cout << "upper" << ' ' << o.upper << endl;
        cout << "r_equal" << ' ' << o.r_equal << endl;
        cout << "between" << ' ' << o.between << endl;
        cout << "l_equal" << ' ' << o.l_equal << endl;
        cout << "lower" << ' ' << o.lower << endl;
        return out;
    }
};


// startは含む
// endは含まない
RangeCount range_count(vector<int>::iterator begin, vector<int>::iterator end, int l, int r) {
    if (l > r) return RangeCount{0, 0, 0, 0, 0};
    if (begin >= end) return RangeCount{0, 0, 0, 0, 0};

    if (l == r) {
        RangeCount rc;
        auto it = std::equal_range(begin, end, r);

        rc.upper = distance(it.second, end);
        rc.r_equal = distance(it.first, it.second);
        rc.between = 0;
        rc.l_equal = rc.r_equal;
        rc.lower = distance(begin, it.first);

        return rc;
    }

    RangeCount rc;
    auto it_r = std::equal_range(begin, end, r);
    auto it_l = std::equal_range(begin, end, l);

    auto it_ru = it_r.second;
    auto it_rl = it_r.first;
    rc.upper = distance(it_ru, end);
    rc.r_equal = distance(it_rl, it_ru);
    auto it_lu = it_l.second;
    auto it_ll = it_l.first;
    rc.between = distance(it_lu, it_rl);
    rc.l_equal = distance(it_ll, it_lu);
    rc.lower = distance(begin, it_ll);

    return rc;

}


```

### 使い方
左右の境界値を含めるかどうかは
betweenにl_equalとr_equalを足すかどうかで選べます。

```cpp

// left <= x < rightだったら
RangeCount rc = range_count(left, right);
return  rc.l_equal + rc.between;
```
注意点として、left <= x <= rightを求めたい時に
rc.l_equal + rc.between + rc.r_equal と書きたくなりますが、
left == rightだったらバグるので、その分岐が必要です。
インテリセンスが出ない！静的エラーが出ない！

#いきなりインテリセンスがぶっ壊れた

突然、インテリセンスが壊れてしまい・・・ということがあると困る、何度もあった。
原因は、過去の経緯から考えると、Windowsシャットダウン前に保存がされる・・・ように思えるが、この辺が怪しい。
インテリセンス系がからむ情報のファイルが壊れてしまう印象がある。ncbだけではないようだ。

**しっかり保存終了してからシャットダウン**したほうがいいようだ。このぐらいしか対策を思いつかない。
**保存時に「OK」クリックしてもが消えてからも念のため10～20秒くらい待った方がいい。**（体感）
バックグラウンドで保存処理している可能性があり、画面最下部で保存アイコンが見えないくらい微妙に見える瞬間があり、これを見る限り保存ボタンをクリックした後でもしばらくいろいろ保存していて、終わり際にインテリセンス情報ファイルを保存している可能性を感じる。
これは罠だ。


インテリセンスの調子が悪いと、
**Ctrl+Space** を押してしばらくすると、VisualStudioの画面最下に小さい文字でこういうメッセージが出て、最悪インテリセンスや静的エラーすら出なくなる
![IntelliSence追加情報はありません詳細についてはC++プロジェクトのintellisense.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/be59915f-a6c7-b904-3819-55b1a5765932.png)

#わざとビルドで大量のエラーを出せばいいだけ

ビルドに支障はないので、変な文字を入れて大量のエラーを出させる。インテリセンスのデータファイルを探さなくてもいい。
そうすると出るようになる。

※バックグラウンドで一生懸命ファイルを作っているので、エラーを出した後、キーボードをゆっくり打つとか、ひと単語ごとに深呼吸するとか、
とにかくのんびりやったほうがいいようだ。早く速く！！・・・でやっていて失敗した時もあった。

![インテリセンスを直す- Microsoft Visual Studio 2020-02-21 10.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/7f89540d-6b11-4e18-0c9d-7410002139db.png)


##インテリセンス情報はすべてファイル管理されている

あの多くの情報は、ファイルで管理されいちいちファイル内で検索しつつ表示しているようだ。
クラスの継承やファイル間のやり取りなど、連続したつながりを探しながら行うので、ラグは発生する。
なので、表示するだけでも時間がかかる時がある・・・

ということは変更された時とかもっと時間もかかる場合もある・・・と考えられる。
なので、保存の際は、見た目に終わっているように見えてもしばらく待った方がいい気がする。
保存が完全終了するまで待つのは嫌だと、考慮して開発者は保存はマルチタスクで別処理でやっているとも想像した。
保存直後バックグラウンドで保存処理が行われていることを意識した方がいいかもしれない。

#●追加・別方法


情報を２つ頂いたのでここに追記します。

##ソリューションエクスプローラーからプロジェクト名を右クリック、ソリューションの再スキャン

##ソリューション直下の.vsディレクトリを消す
多重継承を許す場合の循環継承の見つけ方

# 0.目的
クラスの多重継承を許す場合、継承の循環の起こり方が複雑になる。
そのような場合に循環継承を効率的に見つけるアルゴリズムを考えてみる。

# 1.循環継承とは
そもそも循環継承とは何か。
視覚的には図1.1のように、「継承の単方向輪」ができることである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319477/85ac8fc2-e904-573b-4bf0-1c81e1696069.png)

図1.1 単一継承の場合の循環継承の例

これを言葉で説明すると、「自分が自分自身の先祖や子孫となる」関係である。図1.1の例では、AはA自身の曾祖父母あるいは曽孫であるといえる。

多重継承の場合、直系が複数通りになるため、「どの直系で循環継承が起きているか」を考える必要が出てきてしまう。

# 2.考案するアルゴリズム

すべての「子クラスを持たないクラス$c0$」に対して次の方法を適用することで、系内の循環継承を見つけることができる。但し、$ci$は$c0$の直系尊属$i$親等な任意のクラスである。

1. $i=0$とする。
2. $ci$の子孫集合$D_1$を考える
3. $ci$の親の配列$Ci+1$を考える。
4. $Ci+1$の各元$ci+1$の子孫集合$D_2$を考える。
5. $ci+1$の循環参照がないことの真偽は$D_1 \cap D_2 = \phi$と同値である
6. $i$をインクリメントする。

なお、このアルゴリズムには次の2つの定理を採用している。

- すべての「子を持たないクラス」の先祖を辿れば、系内全てのクラスにアクセス可能である (2-1節で詳解)
- 子孫に$d$を持つクラス$c$の任意の親$p$が子孫に$d$を持つことと、$p$が循環継承していることは同値である (2-2節で詳解)

## 2-1.系内全てのクラスに最低1度は確実にアクセスする方法

すべての「子を持たないクラス」の先祖を辿れば、系内全てのクラスにアクセス可能である

全てのクラスは「子を持たないクラス」と「子を持つクラス」に分けられる。
「子を持つクラス」は何かしらのクラスから見た親クラスである。
いま、クラスについて①②に場合分けして考えよう。
「子を持つクラス」の子が「子を持たないクラス」である場合、子の先祖を辿ることでアクセス可能だ。・・・①
「子を持つクラス」の子が「子を持つクラス」である場合、子についてもう一度場合分けして考える。・・・②
②に分類される限り永遠に場合分けが続き、停止するのは①に分類される場合のみ。
循環継承がない限り、卑属の世代数は有限であるため、すべてのクラスは必ずいつか①に分類される。
循環継承がある場合、循環が起きているということは、すでに循環継承に関わるクラスにはすべてアクセス済みであるということである。


## 2-2.循環参照がそこにあるかの判定法

各クラスの親の1次元配列を考えよう。
このとき、各クラスの親もクラスであるため、各々の親の1次元配列を持っている。
そのため、各クラスは祖父母の2次元配列を持っているといえる。
同様に考えることで、一般に各クラスは直系尊属$n$親等の$n$次元配列を持っているということができる。
ここであるクラスを$c$と呼ぶこととする。$c$の先祖の任意の多次元配列に$c$が含まれることは、
$c$が循環継承しているということと同じである。
つまり命題「$c$の先祖配列 $\ni$ $c$ $⇔$ $c$は循環継承している」は真である。
この命題は次のように書き換えられる。
「$c$の先祖配列 $\ni$ $c'$ かつ$c'=c$ $⇔$ $c'$は循環継承している」
ここで「$c$の先祖配列 $\ni$ $c'$ 」とは、$c$が$c'$の子孫といえることと同じである。
$c'$からみて$c$の先祖配列とは、自身を含む先祖配列であり、その配列の少なくとも1つの元について、子孫に$c$を持つものである。
したがって、任意の「$c$を含む先祖配列」において、その元の少なくとも1つが子孫に$c'(=c)$を持つことと、$c'$が循環継承していることは同値だ。
ここで、「子孫に$d$を持つ任意のクラス$c$」の親クラスの先祖配列$P_1(c)$を考えよう。
$c$の任意の親を$p_1(c)$と呼ぶとき、$P_1(c)$は「$p_1(c)$を含む先祖配列」ということができる。
$P_1(c)$の元の少なくとも1つが子孫に$p_1(c)$を持つことと、$p_1(c)$が循環継承していることは同値である。
但し、子孫に$p_1(c)$を持つとき、必ず子孫に「$p_1(c)$の子孫」をも併せ持つ。つまり子孫として必ず$c$や$d$を持つというわけだ。
したがって、次のように言うことができる。

>「子孫に$d$を持つクラス$c$の任意の親$p$が子孫に$d$を持つことと、$p$が循環継承していることは同値である」by 17ec084
Google Spreadsheet API v4 Pivot Table (ピボットテーブル)のサンプルコードをコピペしても動かないし、エラーも吐かない件

# [Pivot Tables][1]

下の方にあるコードサンプル
![Pivot_Tables_ _ _Sheets_API_ _ _Google_Developers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/554712df-428b-c285-2e7c-317fa4d1b1b8.png)

# 問題

適当なデータを用意して、適当なsource範囲なりで設定して実行すると

```rb
Success - #<Google::Apis::SheetsV4::BatchUpdateSpreadsheetResponse:0x00005567c9a9e490
```

などと返ってくるが、実際にはPivotテーブルが作られていない。

# 原因

Pivotテーブルを作るには[batchUpdate][2]の[updateCells][3]を使って更新するが、パラメータのネストが深い。そしてサンプルコードが間違っている。


## UpdateCellsRequest

- rows <= ここが深い
- fields
- start / range (union fieldという事で、どちらかいずれか)


## rows

まず、配列だ

> rows: [RowData, RowData, RowData ...]

### [RowData][4]

valuesが配列

> values: [CellData, CellData, CellData ...]

### [CellData][5]

[pivotTable][6]要素がある

# 総合すると

```rb
requests = []

requests.push(
  {
    update_cells: {
      # 配列
      rows: [
        {
          # 配列
          values: [
            {
              # PivotTableの内容
              pivot_table: {
                source: {
                  ...
                  ...
                },
                rows: [
                  ...
                  ...
                ],
                values: [
                  ...
                  ...
                ]
              }
            }
          ]
        }
      ],
      # pivotTableを指定
      # https://developers.google.com/slides/how-tos/field-masks?utm_campaign=gsuite_series_slidesapi_041317&utm_source=gdev&utm_medium=yt-desc#updating_with_a_field_mask
      fields: "pivotTable",
      start: { 
        ...
      }
    }
  }
)

request_object = Google::Apis::SheetsV4::BatchUpdateSpreadsheetRequest.new
request_object.requests = requests

# request_objectを {requests: requests} で渡すとなぜかエラー
# ArgumentError: unknown keyword: requests
response = GoogleApi.sheet_service.batch_update_spreadsheet(
  your_spreadsheet_id,
  request_object
)
```

サンプルコードは`rows`が配列になっていないので(invalid)、Pivotテーブルは作られない（が、エラーも出ない）。

[Method: spreadsheets.batchUpdate][8]
> Each request is validated before being applied. If any request is not valid then the entire request will fail and nothing will be applied.

1個でも変なのがあれば、全部取り止めって書いてあるように読めるが...

[1]: https://developers.google.com/sheets/api/guides/pivot-tables
[2]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate?hl=ja
[3]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request?hl=ja#updatecellsrequest
[4]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/sheets?hl=ja#RowData
[5]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells?hl=ja#CellData
[6]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/pivot-tables?hl=ja#PivotTable
[7]: https://developers.google.com/slides/how-tos/field-masks?utm_campaign=gsuite_series_slidesapi_041317&utm_source=gdev&utm_medium=yt-desc#updating_with_a_field_mask

[8]: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate?hl=ja
Docker CLIのコマンド一覧

# 概要
dockerのコマンドをよく忘れたり、英語サイトを翻訳するのが面倒なので、ここで整理します。
これは備忘録的なものです。
Windowsの人は、管理者権限なPowerShellからコマンドが打てます。

# インストール後によくチェックするヤツ

## dockerのバージョン確認

```
docker version
```
この意味はそのまま。
実行するとバージョン情報が表示されます。

## docer-composeのバージョン確認

```
docker-compose version
```

これもそのまま。
docker-composeのバージョンが表示されます。

# 子コマンド達

ここからは、後で編集しながら肉付けしています。

## docker attach
```
docker attach
```

## docker build
```
docker build
```

## docker builder
```
docker builder
```

## docker checkpoint
```
docker checkpoint
```

## docker commit
```
docker commit
```

## docker config
```
docker config
```

## docker container
```
docker container
```

## docker context
```
docker context
```

## docker cp
```
docker cp
```

## docker create
```
docker create
```

## docker diff
```
docker diff
```

## docker events
```
docker events
```

## docker exec
```
docker exec
```

## docker export
```
docker export
```

## docker history
```
docker history
```

## docker image
```
docker image
```

## docker images
```
docker images
```

## docker import
```
docker import
```

## docker info
```
docker info
```

## docker inspect
```
docker inspect
```

## docker kill
```
docker kill
```

## docker load
```
docker load
```

## docker login
```
docker login
```

## docker logout
```
docker logout
```

## docker logs
```
docker logs
```

## docker manifest
```
docker manifest
```

## docker network
```
docker network
```

## docker node
```
docker node
```

## docker pause
```
docker pause
```

## docker plugin
```
docker plugin
```

## docker port
```
docker port
```

## docker ps
```
docker ps
```

## docker pull
```
docker pull
```

## docker push
```
docker push
```

## docker rename
```
docker rename
```

## docker restart
```
docker restart
```

## docker rm
```
docker rm
```

## docker rmi
```
docker rmi
```

## docker run
```
docker run
```

## docker save
```
docker save
```

## docker search
```
docker search
```

## docker secret
```
docker secret
```

## docker service
```
docker service
```

## docker stack
```
docker stack
```

## docker start
```
docker start
```

## docker stats
```
docker stats
```

## docker stop
```
docker stop
```

## docker swarm
```
docker swarm
```

## docker system
```
docker system
```

## docker tag
```
docker tag
```

## docker top
```
docker top
```

## docker trust
```
docker trust
```

## docker unpause
```
docker unpause
```

## docker update
```
docker update
```

## docker version
```
docker version
```

## docker volume
```
docker volume
```

## docker wait
```
docker wait
```
非同期通信 Ajax　基礎文法 2

#はじめに
非同期通信を学んでいく上で、用語等を中心に整理していきます。
[非同期通信 １ はこちらをクリック願います。](https://qiita.com/raigakun/items/a5fb7db5c3650e23cf8e)
フレームワークはRailsを前提として進めております。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。

#フォーマットごとに条件分岐できる仕組み (Railsの場合）
###respond_to
リクエストがHTMLのレスポンスを求めているのか、それともJSONのレスポンスを求めているのかを条件分岐してくれる。
  
###$.ajax
jqueryで非同期通信を行うための記述

###doneとfail
ajaxメソッドの後につけることで、非同期通信が成功した際、失敗した際に行う処理を書くことができる。
- 両方ともajaxメソッドとセットとなるメソッド
- doneは通信が成功した時、failは通信が失敗した時に動く。

###FormData
フォームのデータの送信に使用することができる。

###attrメソッド
- 要素が持つ指定属性の値を返す。
- 要素が指定属性を持っていない場合、関数はundefinedを返す。
  
###processDataオプション
- デフォルトではtrueになっている。dataに指定したオブジェクトをクエリ文字列（例: msg.txt?b1=%E3%81%8B&b2=%E3%81%8D）に変換する役割がある。
- クエリ文字列とは、webブラウザなどがwebサーバーに送信するデータをURLの末尾に特定の形式で表記したもの

###contentTypeオプション
- サーバにデータのファイルを伝えるヘッダ
- デフォルトでは、「text/xml」でコンテンツタイプをXMLとして返してくる。

###jbuilder
- rails newコマンドでアプリケーションを作成した際にgemfileにデフォルトで記述されているgem
- 入力データをJSON形式で出力するテンプレートエンジン


#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
Vue.jsのカスタムディレクティブの修飾詞について

##　以下のコードのどれが修飾詞かというと...

ディレクティブの隣のsolidの隣の`round`です！！！！
:がついてるsolidは引数です。


```App.vue
<template>
<!-- :の後に入るのは引数 -->
<!--  引数の後に.(ドット)つけるのが修飾詞-->
<p v-border:solid.round="{width:'5px',color:'red'}">Home</p>
</template>
```

### jsの方では

1. 修飾詞がついてる時とついてない時があるので、if文で分ける
2. roundが、修飾詞として選択されているか見極めたい
3. もしroundが選択されてた場合、trueそうでなければfaulse

```main.js
//{}内に書いたものは、bindとupdatedに適用される
Vue.directive("border",function(el,binding){  
  //上の二つを一気に書くと、
  el.style.borderWidth = binding.value.width;  
  el.style.borderColor = binding.value.color; 
  //arg = argument = 引数
  el.style.borderStyle = binding.arg；
  //修飾詞がついてる時とついてない時があるので、if文で分ける
  //roundが、修飾詞として選択されているか見極めたい
  //もしroundが選択されてた場合、trueそうでなければfaulse
  if(binding.modifires.round){
    el.style.borderRadius = "0.5rem";
	}
  if(binding.modifires.shadow){
    el.style.boxShadow = "0.2px 5px rgba(0,0,0,0.26)";
	}  
});
```
受注詳細のメール通知からメール送信した際に処理を追加する

## 要望
出荷メールを編集して送信したい

## 現状
- 受注詳細から出荷メールを送っても受注一覧でメールのアイコンが出ない。
    - 出荷データに出荷メール送信日が登録されていないため

デフォルトのメール通知はあくまでもお知らせなどを送る用途のため、出荷処理が走らないのは当然ではある。

現状はOrderMailTypeを編集して出してます。

## 実装
コアコードには書かない前提で考えている。
まずはMailControllerを見てみよう。

```MailController.php
$event = new EventArgs(
[
'form' => $form,
'Order' => $Order,
'MailTemplate' => $MailTemplate,
'MailHistory' => $MailHistory,
],$request);
$this->eventDispatcher->dispatch(EccubeEvents::ADMIN_ORDER_MAIL_INDEX_COMPLETE, $event);
```

EccubeEvents::ADMIN_ORDER_MAIL_INDEX_COMPLETEが用意されているためにここに処理を追加すればいいことがわかる。
[eccube4公式](https://doc4.ec-cube.net/customize_symfony)


Customizeディレクトリ配下にEventListenerのファイルを追加。
$eventの変数にはMailControllerで格納されているものがある。（ちょっと自信ない）

ここに自分のしたい処理を記述して、getSubscribedEventsにreturnしてあげればおｋ。

```php
<?php
declare(strict_types=1);
namespace Customize\EventListener\Admin;

use Doctrine\ORM\EntityManagerInterface;
use Eccube\Controller\AbstractController;
use Eccube\Entity\Order;
use Eccube\Entity\Shipping;
use Eccube\Repository\ShippingRepository;
use Eccube\Service\PurchaseFlow\PurchaseContext;
use Eccube\Service\PurchaseFlow\PurchaseFlow;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;

/** 受注詳細のメール送信完了後に処理を追加する
 */
class OrderMailIndexCompleteListener extends AbstractController implements EventSubscriberInterface
{
    /**
     * @var EntityManagerInterface
     */
    protected $entityManager;

    /**
     * OrderEditIndexCompleteListener constructor.
     *
     * @param  EntityManagerInterface  $entityManager
     */

    /**
     * @var PurchaseFlow
     */
    protected $purchaseFlow;

    /**
     * @var ShippingRepository
     */
    protected $shippingRepository;

    public function __construct(
        EntityManagerInterface $entityManager,
        PurchaseFlow $purchaseFlow,
        ShippingRepository $shippingRepository
    ) {
        $this->entityManager      = $entityManager;
        $this->purchaseFlow       = $purchaseFlow;
        $this->shippingRepository = $shippingRepository;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            EccubeEvents::ADMIN_ORDER_MAIL_INDEX_COMPLETE => 'onAdminOrderMailIndexComplete',
        ];
    }


    /**
     * メール通知 受注管理から出荷メールを送った際の処理
     *
     * @param  EventArgs  $event
     *
     * @throws \Exception
     */
    public function onAdminOrderMailIndexComplete(EventArgs $event)
    {
        /** @var Order $Order */
        $Order         = $event->getArgument('Order');
        $orderMailType = $event->getArgument('MailTemplate');

        //出荷メールの場合のみ実行
        if ($orderMailType->getId() === 8) {

            $Shippings = $Order->getShippings();

            foreach ($Shippings as $Shipping) {
                $this->entityManager->persist($Shipping);
                $Shipping->setMailSendDate(new \DateTime());
                $this->shippingRepository->save($Shipping);
            }
            $this->entityManager->flush();

            $this->addInfo('「対応状況のステータスを配送手続き完了にしてください。」', 'admin');
        }

    }

}
```

こんな感じでフックポイントを使うことでコアコードを触らなくても大丈夫。
WordPress REST APIで更新や削除を試す

[アプリケーションパスワードの設定](https://qiita.com/gungungggun/items/70194d588d7393fe423d)をして権限が有る前提です。
これにより、APIで投稿の作成、更新、削除が可能になります。
今回は更新と削除もやってみましょう。

# 更新
## リファレンス
公式を見ると以下のように書かれています。
ほとんど作成と一緒で違うのはエンドポイント。更新したい投稿のidを入れるとこでしょう。

`POST` `/wp/v2/posts/<id>`

|引数|説明|
|:--|:---|
|id|Unique identifier for the object.|
|date|The date the object was published, in the site's timezone.|
|date_gmt|The date the object was published, as GMT.|
|slug|An alphanumeric identifier for the object unique to its type.|
|status|A named status for the object.<br>次のいずれか: publish, future, draft, pending, private|
|password|A password to protect access to the content and excerpt.|
|title|The title for the object.|
|content|The content for the object.|
|author|The ID for the author of the object.|
|excerpt|The excerpt for the object.|
|featured_media|The ID of the featured media for the object.|
|comment_status|Whether or not comments are open on the object.<br>次のいずれか: open, closed|
|ping_status|Whether or not the object can be pinged.<br>次のいずれか: open, closed|
|format|The format for the object.<br>次のいずれか: standard, aside, chat, gallery, link, image, quote, status, video, audio|
|meta|Meta fields.|
|sticky|Whether or not the object should be treated as sticky.|
|template|The theme file to use to display the object.|
|categories|The terms assigned to the object in the category taxonomy.|
|tags|The terms assigned to the object in the post_tag taxonomy.|

## APIを叩く
アプリケーションパスワードで認証をヘッダーに付与することを忘れずに。
エンドポイントは`http://localhost:8000/wp-json/wp/v2/posts/8` （idは適宜変更）
リクエストボディのJSONは

```json:リクエストボディ
{
	"title": "Update Title",
	"status": "publish"
}
```

これで投稿が更新されタイトルが変更され、statusがpublishとなり「下書き」状態が、「公開済み」になります。
ちなみに`POST`メソッドとなっていますが、`PUT`や`PATCH`メソッドでも更新が反映されました。

# 削除
## リファレンス
`DELETE` `/wp/v2/posts/<id>`

|引数|説明|
|:--|:---|
|id|Unique identifier for the object.|
|force|Whether to bypass trash and force deletion.|

## APIを叩く
こちらもアプリケーションパスワードで認証をヘッダーに付与することを忘れずに。
エンドポイントは`http://localhost:8000/wp-json/wp/v2/posts/8` （idは適宜変更）
リクエストボディはなくてもOK。DELETEメソッドなのを忘れずに！
これで`status`が`trash`となりゴミ箱に移動することが確認できます。

もう一度同じAPIを叩くと410のステータスでエラーが返ってきます。

```json:レスポンス
{
    "code": "rest_already_trashed",
    "message": "その投稿はすでに削除されています。",
    "data": {
        "status": 410
    }
}
```

以下をリクエストボディに入れてAPIを叩くとゴミ箱にも残らず完全消去となります。

```json:リクエストボディ
{
	"force": true
}
```

完全消去した後に同じAPIを叩くと404のエラーでレスポンスが返ってきます。
WordPress REST APIはエラー作り込んでますね！好感持てます！

```json:レスポンス
{
    "code": "rest_post_invalid_id",
    "message": "無効な投稿 ID です。",
    "data": {
        "status": 404
    }
}
```

# まとめ
WordPress REST APIで投稿の更新、削除をしてみました。
わりと簡単で、一回やれば覚えられそうですね！
CentOS で SNMP Trap を受信出来るように設定する (snmptrapd)

## 参考

* [CentOS7 で SNMP Trap を受信出来るように設定する - らくがきちょう](http://sig9.hatenablog.com/entry/2017/10/10/000000)

## 設定


```sh:/etc/snmp/snmptrapd.conf
# 受信するコミュニティ名を指定。ここではpublic222とした例
authCommunity   log,execute,net public222
# 受信したらメールで転送
traphandle default /bin/mail -s "snmptrap" to@address 
```

## snmptrapd の起動

```sh:起動
/sbin/service snmptrapd start
```

## ログ出力先の変更

標準だと `/var/log/messages` に出力される。
別の箇所にも出力するには以下。（ /var/log/snmptrapd.log に出力例）

```diff:/etc/sysconfig/snmptrapd.options 
  # snmptrapd command line options
  # OPTIONS="-Lsd -p /var/run/snmptrapd.pid"
+ OPTIONS="-Ls6 -p /var/run/snmptrapd.pid"
```

```diff:/etc/rsyslog.conf
+ local6.*			/var/log/snmptrapd.log
```

```
service rsyslog restart
service snmptrapd restart
```


## 受信したメッセージを元に動作を変える

```sh:/etc/snmp/snmptrapd.conf
# 受信するコミュニティ名を指定。ここではpublic222とした例
authCommunity   log,execute,net public222
# 受信したらメールで転送
# traphandle default /bin/mail -s "snmptrap" to@address 
traphandle default /etc/snmp/trap_handler.sh
```

* /etc/snmp/trap_handler.sh

```bash
#!/bin/bash

msg=$(</dev/stdin)

# メッセージにTESTが含まれていなければメール送信
if [[ "$msg" != *"TEST"* ]]; then
    echo "$msg" | /bin/mail -s "[trap_handler] " to@address
fi
```
論文まとめ：Structured Prediction of 3D Human Pose with Deep Neural Networks

# はじめに 
BMVC 2016 から以下の論文
[1] B. Tekin, et. al."Structured Prediction of 3D Human Pose with Deep Neural Networks", BMVC 2016
のまとめ

arXiv:
https://arxiv.org/abs/1605.05180

コード：
所在は不明

日本語のまとめ記事：
DeNAのざっくりまとめ
https://engineer.dena.jp/#tekin2016

ちなみにBMVC は British Machine Vision Conference の略で、こちらのサイト
http://www.guide2research.com/topconf/
によるとH-indexが46とそこそこのカンファレンス。

# 概要
1. 単眼カメラからの画像から３次元の姿勢を推定するモデル
2. 事前にautoencoderで姿勢の潜在表現を学習する
3. この潜在表現を利用して３次元の姿勢を回帰問題として解く

<img width="942" alt="Auto3Dpose_img00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/d99d62e4-1a83-4154-a1e0-d5b7fa342aea.png">
（[1]Figure3より）
左側の入力画像に対して、その右がground truth、さらに右が本手法で推定した３次元骨格。

# 手法の解説

### 全体像
全体像は以下の図。

<img width="933" alt="Auto3Dpose_img01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/2c74a569-8927-8363-7afd-4afdc1e6f248.png">
（[1]Figure1より）

解説に書いてる通り、以下の３段階で学習を行う。

1. 潜在変数の次元が大きいAuto-encoderで人の姿勢を学習する
2. その潜在変数をtargetとし、画像を入力としたCNNを学習する
3. decoderを付け加えて姿勢を再学習する

# 1. auto-encoderによる姿勢の学習
以下の図のようにauto-encoderで姿勢を学習する。

<img width="438" alt="Auto3Dpose_img02_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/fe3faec0-f70c-9d37-7f7d-28042e16a16a.png">
（[1]Figure2より抜粋）

人の関節のベクトル $y_i$ に等方性のノイズを加えたものを $\tilde{y}\_i$ 、それをパラメータ $\theta_{ae}$ の auto-encoder $f\_{ae}$ により再構築されたものを $\hat{y}$ とすると、

```math
\hat{y} = f_{ae} (y, \theta_{ae})
```

$\theta\_{ae}$ のパラメータのうち、重みに関しては、過適合を防ぐため

```math
W_{dec,j} = W^T_{enc,j}
```

とする。

loss は入力した骨格と再構築した骨格との２乗誤差にencoderのヤコビ行列に対し行列ノルムの２乗を加える。

```math
\newcommand{\argmin}{\mathop{\rm arg~min}\limits}
\theta_{ae}^* = \argmin_{\theta_{ae}} \sum^N_i \|y_i - f(y_i, \theta_{ae} \|^2_2 + \lambda \| J(y_i) \|_F^2
```

このノルムは初めて見たが、ヤコビ行列は $J(y) = \frac{\partial g}{\partial y}(y)$ と、出力を入力で微分してるから重みみたいなものと考えると、そのノルムを取ってるだけなので、重みに対してL2 norm の２乗を取ってるみたいなもん？？

### 2. 潜在空間を回帰で学習する
第２段階として、下図

<img width="534" alt="Auto3Dpose_img02_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/665e8084-dfda-38da-c138-34b201e4ec01.png">
（[1]Figure2より抜粋）
のようにauto-encoder のlatentをtargetとした回帰問題としてCNNを学習する。

このCNNモデルを $f\_{cnn}(x\_i, \theta\_{cnn})$ として loss は

```math
\newcommand{\argmin}{\mathop{\rm arg~min}\limits}
\theta_{cnn}^* = \argmin_{\theta_{cnn}} \sum^N_{i} \| f_{cnn} (x_i, \theta_{cnn}) - h_{L,i} \|^2_2
```

とする。

### 3. decoderを加えて姿勢を再学習する
３段階目として以下の図

<img width="671" alt="Auto3Dpose_img02_3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/713b811f-502f-4f62-8298-f90c88e30268.png">


のように auto-encoder の decoder 部分を付け加えてfine-tuningする。

lossは targetの関節位置と推論の位置とで２乗誤差をとる。

```math
\newcommand{\argmin}{\mathop{\rm arg~min}\limits}
\theta_{ft}^* = \argmin_{\theta_{ft}} \sum^N_i \| f_{ft} (x_i, \theta_{ft} ) - y_i \|^2_2
```

# 実験と結果
### 実験の概要
- dataset・・・Human3.6M
- metrics・・・３次元ユークリッド距離の平均値

### 他モデルとの比較結果

<img width="885" alt="Auto3Dpose_img03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/c87a7371-9df4-b564-9168-406fb644ae77.png">
（[1]Table1より）
2016年当時の他の手法と比較して値がよい。
typescriptでProperty 'includes' does not exist on type 'string[]'.のエラーが出た時の対処法

## 現象
初期設定を簡易的にしたtypescriptのファイルでincludesメソッドを呼び出した時に
`Property 'includes' does not exist on type 'string[]'.`
とエラーが出て怒られてしまった


## 解決策
tsconfig.jsonのlibの箇所に何も書かれていなかったので下記のように追記

```tsconfig.json

"compilerOptions": {
  //中略
  "lib": [
    "es6",
    "dom",
    "es2017"
  ],  
}
```

これでコンパイルもできるようになりました。

includesってes2017からだったんですね。。
Chrome for Macでwindow.open()したのに新規ウィンドウが開かない！ってなった

ブラウザの新規タブや新規ウィンドウを開く際は`window.open()`を使用しますよね。[^1]
新規ウィンドウで開かず苦戦したので~~愚t~~共有します。[^2]


## window.open() おさらい
新規ウィンドウを開くためには以下のように指定します。

```js
window.open('http://example.com/', '_blank', 'width=500, height=500')
```

## 結論
ブラウザの全画面表示時と通常時で**挙動に違い**がある。
びっくりですよね。ずっと全画面でやっていたのでハマりました。
教えてくれた人ありがとう。。。

### 全画面表示時
タブで開かれる。

### 通常時
新規ウィンドウで開かれる。





[^1]: https://developer.mozilla.org/ja/docs/Web/API/Window/open
[^2]: バージョン: 80.0.3987.116（Official Build） （64 ビット）
kibanaについて

いまさら感ありますが、案件で触れる機会があったので軽く知ったことをまとめておく。

# 概要
kibanaはElasticsearch上のデータを様々な形式(グラフ、図)で描画するツール。
したがって、Elasticsearch上に蓄積していないデータは何も閲覧できない。

例えばログ情報をkibanaでわかりやすくみたいのであれば、
生ログをElasticsearch上に投入できるように加工して投入する処理を実装する必要がある。

KibanaはBIツール(ビジネス上の施策を打つために自社内に蓄積されたデータを分析してそのヒントをつかむ)だと思っていたが、
Elasticsearch上に投入できるのであればkibanaの用途は以下様々な模様([kibana公式](https://www.elastic.co/jp/kibana)より)。

- ログ分析
- インフラ監視
- APM
- 運用セキュリティ
- ビジネス分析  
  …のための可視化


# 使い方
案件で見ていたバージョンが2016年のものだったのでちょっと古いですが以下の記事を参考にしていじっていた。

https://qiita.com/windows222/items/098ded70fb6a6b3c49d2

ざっくりいうと、
**Elasticsearchに登録しているインデックスのインデックス名をKibanaに登録してやればあとはすきにグラフとか書ける**

って感じ。
bundle install時に起きたmysql2のgemエラー

## 注意
自分用のメモ書き＆同じ状況のエラーに遭遇した初学者のための投稿になっていますので記事内容が読みづらく雑であったり間違えている箇所があるかと思いますが大目に見てくださると助かります。
間違えている箇所についてはコメント欄にて指摘していただけると助かります。


## 内容
既存のrailsプロジェクトを久しぶりに修正しようとした際にbundle installをしたら下記のエラーが出ました。

```
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds
before bundling.
```
？？？
何もいじっていなかったので戸惑いながらエラー文を読み三行目の`gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'`を実行。
解決できずで何も変わらず、、、

## 解決
まずエラー時は赤くなっている箇所のみではなくとりあえず遡ってちゃんと読むのが大事と改めて学びました。
この時はこんなことが書いてある箇所が少し遡ったところに書いてありました。。。

```
mysql client is missing. You may need to 'brew install mysql' or 'port install mysql', and
try again.
```
MySQLが見当たらない、、これをしてくれと書いてあるではないか！！と思い、`brew install mysql`をまず実行、、、そしたら無事解決しbundle installができました！！
もう一方の`port in stall mysql`はMacPortsという、macOSおよびDarwin OS上のソフトウェアの導入を単純化するパッケージ管理システムのひとつでmysqlを導入できるものらしいです。
11gクライアントから12cへの接続でエラー

11gクライアントから12cサーバーに接続するとエラーが出ます。
ORA-01017: ユーザー名/パスワードが無効です。ログオンは拒否されました。

サーバーは、
WindowsServer2012R2 64bit
Oracle 12.2.0.1.0
クライアントは
Windows10 64bit
Oracle 11.2.0.1.0
※ワケあってOracleは32bitをインストールしています。

ネットで調査したところ、sqlnet.oraを書き換えろと書かれており、以下を試しています。
SEC_CASE_SENSITIVE_LOGON=FALSE
SQLNET.ALLOWED_LOGON_VERSION=8
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
SQLNET.ALLOWED_LOGON_VERSION_SERVER=10
書き換え後にOSを再起動して試したのですが、ログオン拒否の状況に変化ありませんでした。

しつこく検索したのですが、新たな情報にたどり着けません。
何か試すべきことがあればアドバイスいただけますでしょうか？
よろしくお願いします。

補足
エラーはコンフィグレーションアシスタントでセットアップの際にテスト接続したときに出ます。
docker-composeでPHP開発環境

[docker-composeでRails5.2開発環境](https://qiita.com/lumbermill/items/f5d04035753c1ea4c3e1) に続き、PHPの開発環境もdocker-composeで構築してみました。本当はPHP5系の検証環境が欲しかったのですが、5.4のイメージを使うとコンテナ間の通信がどうしてもうまくいかずに断念しました。当初の目的には使えませんでしたが、7系では問題なく動いたので備忘のための投稿しています。

必要なのは以下の２つのファイルです。

```ruby:Dockerfile
FROM php:7.3-apache
RUN docker-php-ext-install pdo_mysql
```

```docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secret
  php:
    build: .
    volumes:
      - ./html:/var/www/html
    ports:
      - 8080:80
    depends_on:
      - db
```

ファイルを設置後、以下のコマンドを実行します。

```bash

docker-compose build
docker-compose up
```

別のターミナルからデータベースの作成コマンドを実行します。

```bash
docker-compose exec db mysql -e "create database mydb default charset utf8" -p
```

今回は、以下のようなプログラムで動作確認しています。htmlフォルダ下に置いてください。

```php:index.php
<p>
<?php echo "Hello PHP on Docker!"; ?>
</p>
<p>
<?php
  // docker-compose exec db mysql -e "create database mydb default charset utf8" -p
  $pdo = new PDO("mysql:host=db;dbname=mydb","root","secret");
  $pdo->exec("create table if not exists t (v varchar(255))");
  $pdo->exec("insert into t values ('Hello MySQL on Docker!')");
  foreach ($pdo->query("select * from t") as $row) {
    echo $row['v'] . "<br/>";
  }
?>
</p>
```

ブラウザで http://localhost:8080 にアクセスすると以下のようなページが表示されます。

![Screen Shot 2020-02-21 at 9.15.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50780/a754f566-9ec2-fea1-7e7a-38238b078928.png)


## ハマりどころ
- phpのイメージで`apt-get`は動作しませんでした、代わりに`docker-php-ext-install`でモジュールを追加します。
- volumesで永続化した領域を意識しましょう。例えば、一度でも起動した後から、MYSQL_ROOT_PASSWORDを変更しても効きません。環境構築中であれば、少しでもおかしくなったなと思ったら躊躇なく削除してやり直すのが早いと思います。
- docker-compose.ymlから何でもやろうとすると、細かいところで詰まります。今回だとデータベースのエンコード設定などです。`docker-compose exec`なんかも組み合わせる必要がどうしてもあるような気がします。
  

## 参考URL
- [php - Docker Hub](https://hub.docker.com/_/mysql)
- [MySQL - Docker Hub](https://hub.docker.com/_/php)
- https://qiita.com/nanakenashi/items/180941699dc7ba9d0922
- https://www.nyamucoro.com/entry/2018/04/17/215150
LAN内で使用されているIPアドレスを調査する（Windows）

# 目的
Windows機からLAN内で使用されているIPアドレスを調査する。

1. 調査したいアドレス範囲に対しpingコマンドを発行.（ARPキャッシュ最新化）
2. arpコマンドにてローカルホスト（コマンドを発行したWindows機）がキャッシュしているARPテーブルを表示.


####1. ping コマンド (繰り返し）

```bash
for /l %i in (0,1,255) do ping -w 1 -n 1 192.168.10.%i && arp -a 192.168.10.%i
```

実行例

```
C:\Users\*****>for /l %i in (0,1,255) do ping -w 1 -n 1 192.168.10.%i && arp -a 192.168.10.%i

C:\Users\*****>ping -w 1 -n 1 192.168.10.0   && arp -a 192.168.10.0

192.168.10.0 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。

192.168.10.0 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、

C:\Users\*****>ping -w 1 -n 1 192.168.10.1   && arp -a 192.168.10.1

192.168.10.1 に ping を送信しています 32 バイトのデータ:
192.168.10.1 からの応答: バイト数 =32 時間 =3ms TTL=64

192.168.10.1 の ping 統計:
    パケット数: 送信 = 1、受信 = 1、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 3ms、最大 = 3ms、平均 = 3ms

インターフェイス: 192.168.200.97 --- 0x1c
  インターネット アドレス 物理アドレス           種類
  192.168.10.1          90-1b-0e-53-48-7e     動的

C:\Users\****>ping -w 1 -n 1 192.168.10.2   && arp -a 192.168.10.2

192.168.10.2 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。

192.168.10.2 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、

C:\Users\*****>ping -w 1 -n 1 192.168.10.3   && arp -a 192.168.10.3

192.168.10.3 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。

192.168.10.3 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、

C:\Users\*****>ping -w 1 -n 1 192.168.10.4   && arp -a 192.168.10.4

192.168.10.4 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。

192.168.10.4 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、

C:\Users\*****>ping -w 1 -n 1 192.168.10.5   && arp -a 192.168.10.5

192.168.10.5 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。

192.168.10.5 の ping 統計:
    パケット数: 送信 = 1、受信 = 0、損失 = 1 (100% の損失)、

（続く）

```

####2. ARP コマンド

```bash
arp -a
```
実行例

```
インターフェイス: 192.168.200.97 --- 0x1c
  インターネット アドレス 物理アドレス           種類
  192.168.0.200         00-a0-de-f3-78-30     動的
  192.168.10.1          90-1b-0e-53-48-0e     動的
  192.168.10.6          9c-5c-8e-90-ef-6f     動的
```
Rails Unicorn起動時のエラー


#本記事投稿のいきさつ
最近Railsの勉強を始めたが、その中でエラー対応に苦戦したためメモ代わりにここに残したいと思います。
また、不慣れのため表現や書き方など、分かりづらい部分があるかと思います。
優しい目で見ていただければ幸いです。

##エラー
Capistranoでデプロイ後にunicornを再起動をしたかったのですが、EC2でunicorn接続をした際上手く接続ができずlessコマンドでエラーログを確認。

```
ArgumentError: Already running on PID:~~
```
との表示がされていました。
##仮説
エラー文から以前のunicorn接続のプロセスが残っていると思い

```
ps aux | grep unicorn
```
入力し確認したところどうやら余分なプロセスは確認できませんでした。
もしプロセスが表示されていれば

```
kill プロセスid
```
で解決できます。しかし他に原因があるようです。
ネットで調べたところ　unicorn.rb に問題がある場合にもこのエラーが発生するとのことでした。

##原因と対策

unicorn.rbを確認したところ

```unicorn.rb
pid "#{app_path}tmp/pids/unicorn.pid"
```
の設定を発見しました。
Capistranoの導入でディレクトリの構造が変わるのですが、それに伴う設定の変更を一箇所出来ていませんでした。
そのため記述を以下に変更

```unicorn.rb
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
```

これで無事動くようになりました。
エラー文だけで判断せず調べることも重要ということを改めて再認識した事象でした。
【ふくだ学習録】アプリ制作part10【37日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )
[Docker入門](https://www.amazon.co.jp/dp/480071091X/ref=cm_sw_r_tw_dp_U_x_xVlmEbN8ZTHZK)


### 今読んでいる本

なし

# アプリ制作

### iframeに対してのスクレイピング
昨日の段階では、欲しい情報がスクレイピングで取得できない理由は、
>動的に生成され、かつクラス名（ID名）も動的に生成される（毎回変わる）要素に関しては取得がうまくいかない。

といった形で、要素が動的に生成されているからだと思っていたが、よくよく調べてみると取得したい情報がiframe内にあるのが原因であると分かった。

iframe内は別ページ（というか別ブラウザって表現のがいいかな？）扱いになるので、iframeのソースページにアクセスしないといけない。iframeのsrcを取得してそこからアクセスしてもいいが、seleniumがそれ用の関数用意してくれていたので、そちらを利用する。

実際に作った関数がこちら。

```python
def into_iframe(query):
    iframe = driver.find_element_by_css_selector(query)  # どのiframeかCSSセレクタベースで指定する
    driver.switch_to_frame(iframe)  # iframeにアクセスする
```

（`switch_to_frame`にiframeの情報渡せば中に入れる。selenium様様やわ。）


[Seleniumでiframe内のDOMを操作する方法](https://qiita.com/polikeiji/items/7822257a0bbc950f2517)

### UAの変更
ブラウザを変更したり、表示画面サイズを変更したりしたかったが、都度別ブラウザを作成したりするのは大変なので、UAを変更することで対応する。
options.add_argumentで指定したいUAを渡せばOK。

```python
options.add_argument('--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3864.0 Safari/537.36')
driver = webdriver.Chrome(options=options)
```

[pythonでUA偽装してseleniumでブラウジング](https://qiita.com/jima262/items/967403e2f65f9acacdb8)


# 今日の一言
実際のアプリ制作になったらアプトプットすることがほぼほぼない笑
うっすい内容のQiita量産しまくっちゃってる。反省なう。
【php】文字列の出現回数を調べる

#substr_count()  
文字列の出現回数を検索する　※大文字小文字を区別する

#文字列の出現数を調べる「substr_count()」
```php
<?php
$text = 'This is a test';
echo substr_count($text, 'is').'<br/>';
// 実行結果　２
?>
```

###4文字目から検索
```php
<?php
$text = 'This is a test';
// 文字列は 's is a test' になっているので, 1 が表示される
echo substr_count($text, 'is', 3).'<br/>';
?>
```
###4文字目から3文字検索
```php
<?php
$text = 'This is a test';
// テキストは 's i' になっているので, 0 が表示される
echo substr_count($text, 'is', 3, 3).'<br/>';
?>
```
###6文字目から10文字検索
```php
<?php
$text = 'This is a test';
// 5+10 > 14 なので、警告が発生する
echo substr_count($text, 'is', 5, 10).'<br/>';
//PHP Warning:  substr_count(): Invalid length value in
?>
```
###重なった場合
```php
<?php
$text2 = 'ABBABBA';
// 重なっている副文字列はカウントされないので、1 が表示される
echo substr_count($text2, 'ABBA').'<br/>';
?>
```
[Android] installreferrer:1.1.1の罠

「INSTALL_REFERRERインテントブロードキャストが廃止される」という公式アナウンスがあった。

https://android-developers.googleblog.com/2019/11/still-using-installbroadcast-switch-to.html

広告系ライブラリを使っているとAndroidManifestに`INSTALL_REFERRER`がだいたい入ってるのため、対応しなきゃならない。

## 対応方法

まずAndroidManifest.xmlから`INSTALL_REFERRER`を消す

```diff
- <receiver>
-     <intent-filter>
-         <action android:name="com.android.vending.INSTALL_REFERRER" />
-     </intent-filter>
- </receiver>
```

次にapp/build.gradleに`com.android.installreferrer:installreferrer`を追加するのだが、、、
ここで自分は最新バージョンの**`1.1.1`**を追加した。

```gradle
implementation 'com.android.installreferrer:installreferrer:1.1.1'
```

このバージョンが失敗だった。

## ここでトラップ発動

Android Studioの **Analyze APK** でAndroidManifestを見てみると、余計なパーミッションが追加されている。

```xml
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission
        android:name="android.permission.READ_PHONE_STATE" />

    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE" />
```

３つも！？

- WRITE_EXTERNAL_STORAGE
- READ_PHONE_STATE
- READ_EXTERNAL_STORAGE

特にREAD_PHONE_STATEが追加されたままリリースすると、ユーザーは驚くこと間違いなし


## 解決方法

`installreferrer:1.0`を使うようにしよう。

```diff
- implementation 'com.android.installreferrer:installreferrer:1.1.1'
+ implementation 'com.android.installreferrer:installreferrer:1.0'
```

これで自動付与されるパーミッションは消えるはずだ

## なぜ起きたのか？

おそらくGoogle側のバグで、過去に意図しないパーミッションが自動付与されることが何回か起きてるらしい。

https://developers.google.com/android/guides/releases

<img width="858" alt="スクリーンショット 2020-02-21 9.03.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52227/02ecc87b-5948-3aa4-9b1c-4df041899942.png">

今後、ライブラリを更新したらパーミッションを確認したほうがいいかも（面倒くさい…）
プログラミング学習の始め方

# 始めに
プログラミングを勉強して２年ぐらいたったので、
プログラミングを学ぶのによかったことを書き留める。

# どこから手を付ければよいか
プログラミングの知識がないと何から学習すればよいかわからないし、
調べたところで単語の意味がピンとこないと思う。
僕がおすすめするのはHTMLとJavaScriptである。（CSSは置いておく）
よく言われがちだが、僕が思う理由はいくつかある。

### 1. 参考書が多い
　始めは独学になると思うので、参考書通りに始めることで環境の設定などが流れで理解できる。
　変に難しい書き方をしておらず、参考書ではコードの書き方の基礎が身につく。
### 2. 更新した内容が目に見えてわかりやすい
　やはり自分で書いたものが目に見えてわかるとテンションが上がる。
　何事も楽しくないと続かない。
### 3. お金になりやすい
　人間なので、お金が絡むと学習するモチベーションが上がる。
　実際にブログやLP作成で稼いでる人がいる。

では、どのように学習するか。

## 学習のポイント

### 大切なのは自分で考えること
なにをするにしても誰かに言われてやることはつまらないし身につかない。
自分からワクワクするように気持ちを持っていこう。

## 少しでも理解できてきたら
想像力を膨らます。
プログラミングを書いていてこんなことができたら楽しいなと思えるような想像をする。
想像したらなにが必要か、どうすればできそうかを考える。

例えば、一覧画面を作っているならば、絞り込みを作るにはどうすればよいか。
1. 絞り込みボタンを作る
　＞HTMLを変更すればいいんだな。
2. ボタンが押されたら一覧に表示知するデータが変わる
　＞ボタンが押されたときにエベントを動かすにはどうすればよいか
3. 一覧にのデータを条件で絞り込む処理はどうするか
　for分とindexOfを組み合わせればできそう

このようにしてプログラミングを楽しむことが大切

## あとはTry＆Errorするのみ
作っているとどうしても今の自分の知識や技術ではどうしようもないものがある。
そうしたときはとにかく調べていろいろ試してみることをおすすめする。
いろいろ試した結果できなかったら一旦諦めることも重要。
そうしていろいろ試しているうちに知識が増えていて、以前できなかったことをもう一度やってみたらできるということがある。

## 結局のところ
大変なのは最初の数か月。
基礎が身につくと意外と難しそうでも調べればできたりする。
できることが増えると楽しい。

# 終わりに
２年前のプログラミングを知らなかったころは業務でわからないことづくしでひーひーいっていたが、
業務外で参考書を読み漁って１年ぐらいたったころにはプログラミングの基礎と調べる力がついていた。
プログラミングを書くことはそんなに難しくないので、興味があったらぜひはじめてみてください！