OmniAICreator/Qiita-1.07M huggingface dataset:
51歳からのプログラミング　備忘　Androidのネットワーク接続の確認

<font color="#f55">NetworkInfoはAPI29から非推奨</font>になりました。
テキストはNetworkInfoを使っているので代替手段を探しました。
めっちゃ時間かかって、もうAndroidとかPHPとかLaravelとか何者なのか忘れてしまいました。

---
さて、リファレンスでは、**ConnectivityManager.NetworkCallback API**をよく読んで、**<font color="#55f">ConnectivityManager#getNetworkCapabilities</font>** とか ConnectivityManager#getLinkProperties　とかを検討してね！ってことらしいので、**<font color="#55f">getNetworkCapabilities</font>** でいいのかな？

#ConnectivityManager.getNetworkCapabilities
```java:
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ネットワークの接続状態を知らせるクラスオブジェクト manager を取得！
        // getActiveNetwork で、現在デフォルトで接続してるネットワークオブジェクトを取得！
        // capabilities 無線接続ポイントや接続に関するキャリアのサービス、通信接続のタイプなど、いろんな接続情を確認できる！
        ConnectivityManager manager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        Network network = manager.getActiveNetwork();
        NetworkCapabilities capabilities = manager.getNetworkCapabilities(network);

        // wifiだったら
        if(capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)){
            Log.d("TRANSPORT","WIFI");
        }
        // 携帯通信だったら
        if(capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)){
            Log.d("TRANSPORT","CELLULAER");
        }
        Log.d("TRANSPORT", String.valueOf(capabilities));
    }
}
```
ネット接続で確認したい状態定数（`NetworkCapabilities.TRANSORT_CELLULAR`とか）は
>https://developer.android.com/reference/android/net/NetworkCapabilities.html#TRANSPORT_WIFI
[Golang]「N<<M」は「N × 2^M」で計算できて、「N>>M」は「N ÷ 2^M」で計算できる件

# 先に結論

表題の通り、
`N << M`は`N × 2^M`と同じで、
`N >> M`は`N ÷ 2^M`と同じです。

#はじめに

今回、Golangのコードを読んでいて、こんなのを目にした。

```golang:気になった、コードの一部分
&fruitsRepository{
	lowerLimit:  -1 << 31,
	higherLimit: 1 << 31 - 1,
}
```

前後のコードは省略するので、これだけではよく意味分からないでしょうが、要は**既に定義済みの`fruitsRepository`というstructを、newしたような形**です。

その部分は今回置いておいて、今回調べたのは値の方。

`-1 << 31`
`1 << 31 - 1`

↑これなんだっけ。

調べてみると、Go言語以外にも、PHPやC言語など、同じ表記方法を使う言語もいくつかあるそうな。
ということで、深ぼってみた。

# シフト演算子が分かりにくい

これは、**シフト演算子**と呼ばれるものだそうです。

[こちらの質問サイト](https://teratail.com/questions/18602)で答えられている通り、**二進数にして左右にズラしている**そうな。

しかし、数学に疎い僕は、どうも腹に落ちません。
というか、**実際はどんな値が入っているのか？**

# シフト演算子の答えをズラッと並べてみた

[こちらの質問サイト](https://stackoverflow.com/questions/5801008/go-and-operators)の回答で、分かりやすいものがありました。

そこから引用したものですが、下のコードは`N << M`を、1から順に続けて10個ずつ出力したものです。

```golang:シフト演算子の答えを書き出すためのコード
package main

import (
    "fmt"
)

func main() {
    var t , i uint
    t , i = 3 , 1

    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d << %d = %d \n", t , i , t<<i)
    }


    fmt.Println()

    t = 512
    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d >> %d = %d \n", t , i , t>>i)
    }

}
```

```text:出力結果
1 << 1 = 2 
1 << 2 = 4 
1 << 3 = 8 
1 << 4 = 16 
1 << 5 = 32 
1 << 6 = 64 
1 << 7 = 128 
1 << 8 = 256 
1 << 9 = 512 

512 >> 1 = 256 
512 >> 2 = 128 
512 >> 3 = 64 
512 >> 4 = 32 
512 >> 5 = 16 
512 >> 6 = 8 
512 >> 7 = 4 
512 >> 8 = 2 
512 >> 9 = 1 
```

この並び、見たことある。
ここでやっと、教養の低い僕でも意味が分かりました。笑

表題の通り、実際の値は以下の方法で計算できます。
`N << M`→`N × 2^M`
`N >> M`→`N ÷ 2^M`

# 10進数でいう、E(指数表記)と同じ感覚かと思われる

学生時代のかすかな記憶で、こういったものを見た覚えがあります。

```
2E12 = 2 × 10^12
     = 2000000000000

2E-9 = 2 × 10^-9
     = 0.000000002
```

これは、`2000000000000`とか`0.000000002`というとても大きな（またはとても小さな）値を表現するときに便利な方法です。(指数表記というそうな…)

**指数表記は10のべき乗で表現しますが、コンピューターは2進数の世界なので2進数で表現されているんでしょうね。**

雰囲気で理解した気になってます。
間違えていたり、詳しい説明ができる方、コメントお待ちしております。

# 今回の実際の値について

これまでのことを踏まえて、今回の値を見直してみました。

## `lowerLimit:  -1 << 31`は`-2147483648`

これは、`N << M`は`N × 2^M`に当てはめて考えると、
`-1 * 2^31`となるので、つまり`-2147483648`のこと。

## `higherLimit:  -1 << 31 -1`は`-2147483649`

`-1 << 31 -1`は上と同じく、`-1 * 2^31`なので`-2147483649`のこと。

## どちらも桁の多い値を示している

この遠り、どちらもとても桁数の多い値を示しています。
なんで、この値なのか…についてはもう少し調査が必要ですが…

# さいごに

ということで今回は、`N<<M`や`N>>M`の実際の計算方法について調べました。
根本的に、どうしてこの値を入れるのかが分かっておらず恐縮ですが、実際の値を確認したい場合に、使っていただけると幸いです。

最後までありがとうございました。
検証用にEC2とSquidを使ってプロキシサーバーを構築＋Macで接続してみた話

## **目的**
問い合わせの検証用にプロキシサーバーを構築する必要があったので
EC2を使って構築してみたときの備忘録です。

## **1.プロキシサーバー用のEC2を作成**
検証用の一時的なプロキシサーバーなのでawsの管理コンソールからぽちぽち作りました。
セキュリティグループで **Squid**に接続するためのポートとして 60088ポートをあらかじめ開けておきます。

<img width="1230" alt="スクリーンショット 2019-09-21 15.12.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/c1f83431-49b5-4eda-1090-28eea8b75500.png">


## **Squidの構築**

**Squidのインストール**
以下のコマンドを入力しながら、Squidをインストールします。

```
$ sudo su - # スーパーユーザに変更
$ yum install squid -y # Squidのインストール
```

**Squidの設定変更**
Mac → EC2(Squid)に接続するためにSquidの設定をおこないます。

SquidのConfを開き

```
$ vi /etc/squid/squid.conf
```

自身のMacからSquidに接続できるように設定を追加します。

```
# And finally deny all other access to this proxy
acl mynetwork src xxx.xxx.xxx.xxx/32
http_access allow mynetwork
http_access deny all
```

また、Squidのデフォルトポートも念のため変更しておきます。

```
# Squid normally listens to port 3128
http_port 60088
```

Squidにアクセスされているかログを表示したければ以下の設定も追加しておきます。

```
access_log /var/log/squid/access.log auto
emulate_httpd_log on
```


最後に、変更したConfのチェックを行い

```
squid -k parse
```

問題なければ、Serviceを再起動します。

```
service squid restart
```

## **2.Macのプロキシ設定**
**Macのプロキシ設定**
`ネットワーク`→`詳細`→`プロキシ`→`Webプロキシ`または`保護されたWebプロキシ（HTTPS)`から
EC2の`IPv4 パブリック IP`とSquidに接続するポート`60088`を入力
`OK`ボタンを押して、`適用`ボタンで適用させます。


<img width="659" alt="スクリーンショット 2019-09-21 15.00.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/f7c80d9e-32c3-4bb6-9eaf-bf59a1c56e01.png">


**動作確認**

あとは、[確認君](https://www.ugtop.com/spill.shtml)などから
「あなたのＩＰアドレス(IPv4)」がプロキシ設定前と変わっていればOKです。

また、接続しているEC2上で以下のコマンドからアクセスされた際のログをリアルタイムで見ることができます。


```
$ tail -f /var/log/squid/access.log
```

<img width="1284" alt="スクリーンショット 2019-09-21 15.16.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54858/cf36b8ef-6ee2-82c4-6b76-8c2594a5a37d.png">


### **参考情報**
Squidって何？
https://qiita.com/zabutonzabuzabu/items/bbe5f540f7536fa95eae
Squid で安全なインターネットアクセス環境を構築する方法 
https://blog.cybozu.io/entry/2017/02/03/080000
Squid経由でAWSマネジメントコンソールにアクセスしてソースIP制限や認証やログ取得 
https://cloudpack.media/359
Squidでホワイトリストプロキシを作成する
https://qiita.com/tosier/items/30297afb6ffbd4567eb5
Squid 10. アクセスコントロール(ACL)
https://www.robata.org/docs/squid/faq_10.html
squidのログを確認するには
https://www.tempest.jp/linux/fedora/documents/text067.html
コマンドで linux サーバー内の溜まったログから必要なデータを一括で抽出

## AWS の EC2 に溜まったログ
現在のサービスでは, アクセスログが logs ディレクトリ以下に `access.log-20190101.gz` といったように日付などで記録されています。
中身は, 以下のような構成になっていました。
gz なので, zcatコマンドで確認できます。
その前に root ユーザーでログインしてからのほうがいいですね

```
sudo -s
```

`zcat access.log-20190101.gz`の結果です。

```access.log-20190101.gz
172.1*.**.* - - [01/Jan/2019:13:29:31 +0000] "GET /index HTTP/1.1" 200 16
172.1*.**.* - - [01/Jan/2019:13:29:31 +0000] "GET /done HTTP/1.1" 200 16
172.2*.**.* - - [01/Jan/2019:13:29:31 +0000] "GET /index HTTP/1.1" 200 16
172.2*.**.* - - [01/Jan/2019:13:29:31 +0000] "GET /menu HTTP/1.1" 200 16
172.2*.**.* - - [01/Jan/2019:13:29:31 +0000] "GET /lp HTTP/1.1" 200 16
```
今回このデータの中から欲しかったログは, doneページまでたどり着いたユーザーの確認がしたいため, プライベートIPアドレスと日付と referer が必要です。

## ログの吐き出し

今回は, 複数のログを確認したいため, ログを一つずつ実行していきます。

```
for log in `find logs/ -name access.log*.gz`;do ........
```

次にアクセスログの中から done ページまでたどり着いた特定の ip を抽出します。awk コマンドでプライベート ip アドレスと referer のセットを作成し, referer から /done にたどり着いたユーザーの ip アドレスを $ip に格納していきます。

```
for ip in `zcat $log | awk '{print $1,$5}' | 'grep /done' | awk print'{$1}'`;do .....
```

上記を用いてそれぞれのログから, それぞれの /done にたどり着いた ip アドレスの行動を収集します。その結果を root ディレクトリ内の result.log に吐き出します。

```
for log in `find logs/ -name access.log*.gz`;do for ip in `zcat $log | awk '{print $1,$5}' | 'grep /done' | awk print'{$1}'`;do zcat $log | awk '{print $4,$1,$5}' | grep $ip;done;done > ~/result.log
```

## サーバーのファイルをローカルに持ってくる
最後にローカル側で scp コマンドを使ってファイルをダウンロードしてきます。詳しい情報はぐぐってみてください。

```
scp インスタンス情報:~/result.log ./
```
お疲れさまでした。一文でできるのは快適ですが, 普通にシェルスクリプト作成してもよかったかもですね〜
Arduino + Grove (2)

[前回記事](https://qiita.com/KNBK/items/60654ec74162dff5c7bc)の最後では
「押している時」「押していない時」をLEDの「点灯」「消灯」と対応付けるコードを書きました
「デジタル入力によって、デジタル出力をコントロール」してみたのですが
今回は、ゼロとイチでは割り切れない別のセンサを使ってみましょう

##ボリュームセンサでLEDの明るさコントロール
A0にボリュームセンサを接続します（D2のボタンは抜く）
![IMG_1783.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499213/9f741e5f-4c88-980c-d1af-707d7efe7ebe.jpeg)


ArduinoIDEで「ファイル」→「新規ファイル」を開き
下記のコードをコピー、ペーストしてSeeduinoに書き込みます

```javascript
const int volumePin = A0; //ボリュームセンサが刺さっているピンを指定
const int ledPin = 3; //LEDが刺さっているピンを指定

void setup() {
  Serial.begin(9600); //コンピュータとのシリアル通信の開始
  pinMode(volumePin, INPUT); //ボリュームセンサが接続されているピンを入力モードに
  pinMode(ledPin, OUTPUT); //LEDが接続されているピンを出力モードに
  
}

void loop() {
  int volumeVal = analogRead(volumePin); //volumeValという変数を指定し、ボリュームセンサの値を読む
  
  Serial.println(volumeVal); //0 - 1023の間でアナログ値を出力（10bit）
  int ledBrightness = map(volumeVal, 0, 1023, 0, 255); //0 - 1023の値を、LEDの明るさ0 - 255に変換する
  analogWrite(ledPin, ledBrightness); //指定された明るさでLEDを点灯

}
```
ボリュームを回転させるとLEDの明るさが変わります

####プログラム解説
プログラム中に`map()`という関数が出てきます。
`analogRead()`関数で取得するボリュームの値は10bit（0-1023）なのに対して、
LEDの明るさを制御している`analogWrirte()`が対応しているのが
8bit（0-255）なのでmap()を使って値を変換しています

###シリアルプロッタで値を見てみる
ArduinoIDEの「ツール」→「シリアルプロッタ」を選択
![スクリーンショット 2019-09-21 12.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499213/2dbe14b7-db33-ea2a-7c6b-41d1581f0022.png)

ボリュームを回転させると値に応じてグラフが変化します！
※シリアルプロッタが動作しない方は画面下部のボーレート（seeeduinoとPCが通信する速度の取り決め）を「9600bps」に設定してみてください！
![Graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499213/c56cfb4d-c0b6-ad88-2e31-f3a3844efcdc.png)

### PWM出力について

LEDの明るさを段階的にコントロールできるのは、Arduinoが持つ**PWM**という出力方式のおかげです
PWMは（Pulse Width Modulation）の頭文字をとった略語で、単位時間あたりで電流を流す（ピンをHIGHにする）時間を変えているのです
実際にはピンのON/OFFが高速に切り替わっており、LEDは高速で明滅しているのですが、人間の目には「明るさが変わっているようにみえる」のです

![スクリーンショット 2019-09-21 14.29.43](https://tva1.sinaimg.cn/large/006y8mN6gy1g772rztq3ej30ga0ee0te.jpg)

[図の引用元](https://www.electronicshub.org/arduino-pwm/)

### 様々なセンサ・アクチュエータ

入力装置としての役割を持つ**センサ**（ボリューセンサ、ボタン）
出力装置としての役割を持つ**アクチュエータ**（LED、傾きスイッチなど）には沢山の種類があります
上のプログラムに対応したセンサは下記になります。A0に接続して試してみましょう
その際、ArduinoIDEのシリアルプロッタを表示しておいて、どのような振る舞いによって値が変化するのかを確認してみましょう

1. スライドセンサー![Sliding1](https://tva1.sinaimg.cn/large/006y8mN6gy1g773di96h5j30jg0eljs2.jpg)
2. CDS（明るさをセンシング）![img](https://tva1.sinaimg.cn/large/006y8mN6gy1g773el0ms2j30jg0elaad.jpg)
3. FSR（圧力をセンシング）

![main](https://tva1.sinaimg.cn/large/006y8mN6gy1g773fu3o2xj30sg0lc0vl.jpg)





また、上のプログラムは「振動モータ」にも対応していますので、D3に接続してセンサでコントロールしてみましょう

![Grove - Vibration Motor](https://tva1.sinaimg.cn/large/006y8mN6gy1g773jsd47yj30jg0elmxk.jpg)
今日から始めるvelodyne生活[接続方法]

最近velodyne(LiDAR)をよく触っているのですが，触り始めたころは接続方法にすら詰まってしまう状態だったので備忘録も兼ねてvelodyneの接続方法を書いていこうかと思います．

ちなみにこの記事で話す内容は基本的に以下のサイトを見れば十分かと思います．
http://wiki.ros.org/velodyne/Tutorials/Getting%20Started%20with%20the%20Velodyne%20VLP16

ただ自分が触りたてのころはこの記事だけではわかりにくい部分もあったのでそこらへんも踏まえて解説していこうと思います．
※今回説明するのは上記ページの1.1の方法のみです．

環境としてはubuntu16.04，ROS kineticです．

#velodyne接続方法

まずvelodyneをPCと接続してNetwork Connectionsを起動します．Network ConnectionsにてEthernet接続の部分を見てください．この時，以下の選択肢があるかと思います．

- 接続先が自動で増えている場合
- 接続先が増えない場合

接続先が増えている場合は以下で説明する方法を途中から実践すればいいので以下では接続先が増えていない場合のみ解説します．

まず接続先が増えていない場合Network Connectionsが以下のような画面となっているはずです．

![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255562/579ed52f-cdf0-4df1-46d1-333908565cbc.png)

上記のような画面の場合(connection 1は自分のルーターとの接続)にはAddから接続を追加します．connection typeはEthernetを選択してください．

DeviceはvelodyneのconnectionのDevice IDを選択してください．このDevice IDはターミナルでifconfig等を用いて特定するのが楽かもしてないです．(一度velodyneの接続を抜いて挿し直した時に増えたDevice IDがvelodyneのやつです．)
以下の場合はenx~がDevice IDとなっています．

![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255562/fa0db699-6af8-db3d-9f68-7b059a078840.png)

これからはaの場合も当てはまります．接続先が増えていた場合は接続を編集したら上の画像からスタートしているはずです．

そして次にIPv4 Settingsを以下のように変更して保存してください．

- Address:192.168.1.100(デフォルト)
- Netmask:255.255.255.0 
- Gateway:0.0.0.0


これで準備はOKです．次にvelodyneのIP(デフォルトは192.168.1.201)をブラウザに入力するとvelodyneの設定ページにアクセス可能です．
あとは理想のvelodyneライフを楽しんでください．


# velodyneをDHCP接続ONにした場合，IPを忘れた場合にどうするか
※みなさんがこれを読む必要がないことを祈ります

これは基本的にみなさん読む必要がないかと思いたいですが私がマジでvelodyne使えなくしちゃったと焦って泣きながら調べたので備忘録として書いていきます！

まずしのごの言わずにWireSharkをインストールします．
詳しくは
https://qiita.com/smatsuo/items/9cf8098605d0de7342dc
を参照すればいいかと思います．

```
sudo apt-get install wireshark
```

そしてWireSharkを起動するんですが権限の追加等うまく行かない場合は`sudo wireshark`で起動すれば接続されてるインターフェースが以下のように表示されます．

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255562/4f3cd87f-7803-5e9f-a52b-01005ce86b65.png)

この画像の場合はDHCP OFFなので設定したIPアドレスが表示されています．IPを忘れた場合はここのIPを入力すれば接続可能です．

DHCPをONにしてしまった場合，WiresharkのSourceの部分が169.254.xxx.yyyみたいになってるはずです．
つまりこれがvelodyneのIPになってしまっているのでNeteork ConnectionsでのIPv4 Settingsの部分で169.254.xxx.zzz(最後の３桁はSourceのアドレスと被らないように)，NetmaskとGatewayそのままとするとたぶん接続できるはずです．
自分がやった時はNetmaskは255.255.255.255でやったけど接続できました．

# 参考文献
velodyne接続関連
http://wiki.ros.org/velodyne/Tutorials/Getting%20Started%20with%20the%20Velodyne%20VLP16

wireshark
https://qiita.com/smatsuo/items/9cf8098605d0de7342dc

DHCP関連
https://www.manualslib.com/manual/1407706/Velodyne-Vlp-16.html?page=88
https://www.manualslib.com/manual/1407706/Velodyne-Vlp-16.html?page=89
Vueでmoment.jsの使い方

#はじめに
この記事はVue触りたての筆者のメモのようなものです。

#やりたいこと
データベースからとってきたデータを表示するときにtimestampを```"YYYY/MM/DD HH:ｍｍ"```のフォーマットに直したい

#Vueでmomentの使い方

以下のタグをHTMLに追加します。

```index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js" type="text/javascript"></script>
```

あとは行いたい処理をかけばok!
筆者は日付の変換が行いたかったため以下のような処理を書きました。

```index.html
<div class="ui segments" v-if="posts.length > 0">
      <div class="ui segment" v-for="post in posts">
      <h2>
      <div class="header">{{ post.userId }}</div>
      </h2>
      <!--index.jsで定義した日付の変換をする関数の呼び出し-->
　　　<!--{{ 関数に渡したい値 | 関数 }} とすることで関数に引数を渡すことができる-->
      {{ post.timestamp | moment  }}
      <div class="ui sub header">{{ post.text }}</div>
      <div class="ui grey label">{{ post.category }} 
    </div>
  </div>
</div>
```

```index.js
var vm = new Vue({
    el: "#app", // Vue.jsを使うタグのIDを指定
    //日付を変換するフィルターの定義
    filters: {
        moment: function (date) {
            return moment(date).format('YYYY/MM/DD HH:mm');// eslint-disable-line
        }
    },
    //いろんな処理…
})
```
##落とし穴
スクリプトタグを書く位置に注意！
※必ず```moment()```を使いたいJSファイルを読み込むscriptタグより前に書かないとエラーを吐かれる

うまくいく例

```index.html
<body>
    <!--momentの読み込みは必ず先に！-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js" type="text/javascript"></script>

    <!--momentを使いたいjsの読み込み-->
    <script src="./js/index.js" charset="utf-8"></script>
</body>
```

失敗する例

```index.html
<body>
　　<!--momentを使いたいjsの読み込み-->
    <script src="./js/index.js" charset="utf-8"></script>

    <!--momentの読み込み-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js" type="text/javascript"></script>
</body>
```

#終わりに
今回の内容は恐らく超基本的なモノだと思います。
筆者はスクリプト言語を触るのがほぼ初めてだったためコードの上から順に読み込まれるということをすっかり忘れてて1日中ハマり続けました笑
CentOS7.6にNode.js11をインストールする手順

### 経緯：
 - 必要なライブラリがNodeだったので

### 環境：
 - CentOS7.6

### 手順：
```console:rootで以下実行
# yum install https://rpm.nodesource.com/pub_11.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
```

```console:rootで以下実行
# yum install nodejs
```

```console:nodejsのバージョン確認
# node -v
v11.15.0
```

```console:npm(パッケージマネージャ)のバージョン確認
# npm -v
6.7.0
```
複数のリポジトリを一つの大きなリポジトリにまとめる方法

#はじめに

この記事は、Dockerでコンテナごとにリポジトリ分けたいと思ったときに見つけた方法を備忘録として残したものです!
今回大きなリポジトリにまとめる方法として[このサイト](https://git-scm.com/)を参考にして、`git submodule`を使うことにしました!

### git submodule とは

あるリポジトリ1を別のリポジトリ2の一部として使いたい。だけど、リポジトリ1は個別で管理したいという問題を解決できるGitの機能です!

具体的には
> 外部の git リポジトリを、自分の git リポジトリのサブディレクトリとして登録し、特定の commit を参照する仕組み

です。


# 使ってみる

### 準備

1. 大元となる`git_submodule_practice`リポジトリとサブリポジトリである`sub_repository`をGitHub上で作成。

2. `git_submodule_practice`をローカルにcloneして、`git_submodule_practice`内に`sub_repository`をcloneする。

3. 各ディレクトリ配下にREADME.mdを作成し、そのディレクトリにcommitしておく


今のディレクトリ構造です。

``` :git_submodule_practice
.
├── README.md
├── .git
└── sub_repository
    ├── .git
    └── README.md
```

この状態で`git_submodule_practice`ディレクトリで`git status`をしてみます。

```
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        
    sub_repository/

nothing added to commit but untracked files present (use "git add" to track)
```

`sub_repository`配下がgitにtrackされています。この状態だと`sub_repository`内の差分も`git_submodule_practice`で管理されてしまいます。


### submodule化する

submodule化するのはこのコマンド!`git_submodule_practice`直下で実行してください。後ろのurlはcloneするときのurlです。sshでも問題ないです。

```
$ git submodule add https://github.com/{GitHubアカウント 名}/sub_repository.git
Adding existing repo at 'sub_repository' to the index
```

結果として、以下の文字
> 'sub_repository' does not have a commit checked out 

が出てきたら`sub_repository`内でREADME.mdをcommitしましょう。submoduleはcommitを参照しているため、一つもcommitがないとsubmodule化ができません。

今のディレクトリ構造です。

``` :git_submodule_practice
.
├── README.md
├── .git
├── .gitmodules
└── sub_repository
    ├── .git
    └── README.md
```

.gitmodulesというファイルができましたね？そのファイルをのぞいてみると以下のようになります。ここにsubmoduleを追跡しないようにigunoreを記載しましょう!


```:.gitmodules
[submodule "sub_repository"]
        path = sub_repository
        url = https://github.com/{GitHubアカウント 名}/sub_repository.git
        ignore = all    //追記
```



これで、`sub_repository`はsubmodule化され、変更は大元となる`git_submodule_practice`に反映されなくなりました！！

 

# 追記

大元の`git_submodule_practice`のディレクトリにcloneする前であれば、`git submodule add https://github.com/{GitHubアカウント 名}/sub_repository.git`で`git clone` + submoduleへの追加をしてくれます。



# 参考
- [git-scm](https://git-scm.com/)
- [Git submoduleの押さえておきたい理解ポイントのまとめ](https://qiita.com/kinpira/items/3309eb2e5a9a422199e9)

- [Git submodule の基礎](https://qiita.com/sotarok/items/0d525e568a6088f6f6bb)
Ubuntu 18.04でPoetryを動かしてみる。

# この記事は何か?

* pythonのパッケージ&仮想環境管理ツール `Poetry` をインストールして動かしてみた記録。
* 基本的に公式マニュアルに書いてあることをやっているだけ。

# 環境

* Ubuntu 18.04
* Python 3.6.8

# インストール

* 参考: https://cocoatomo.github.io/poetry-ja/

ほぼ書いてある通りに実行。
ただし、`| python` は `| python3`に変えた。

```bash
$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python3
```

このように言われるので、`source $HOME/.poetry/env`を実行した。

```bash
To configure your current shell run `source $HOME/.poetry/env`
```

`python` が無いと言われる。

```bash
$ poetry --version
/usr/bin/env: ‘python’: No such file or directory
```

`python3`を見に行ってほしい。
こんなやり方で良いのか分からないがシンボリックリンクを作ってしまう。

```bash
$ cd /usr/bin/
$ ln -s /usr/bin/python3 ./python
```

とりあえず動いた。

```bash
$ poetry --version
Poetry 0.12.17
```

# Usage

## 環境を作ってみる

以下のコマンドでcurrent directory以下にpoetry-demoというフォルダができる。

```bash
$poetry new poetry-demo
```

```bash
poetry-demo
├── pyproject.toml
├── README.rst
├── poetry_demo
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_poetry_demo.py
```

## 依存パッケージを追加してみる

```bash
$ poetry add numpy
$ poetry install
```

`pip`が無いと言われる。

```
$ poetry add numpy
Using version ^1.17 for numpy

Updating dependencies
Resolving dependencies... (0.1s)


Package operations: 9 installs, 1 update, 0 removals

  - Installing more-itertools (7.2.0)
                                                                                                                                      
[EnvCommandError]                                                                                                      
Command ['/home/r7/.cache/pypoetry/virtualenvs/poetry-demo-py3.6/bin/python', '-m', 'pip', 'install', '--no-deps', 'more-itertools==7.2.  
0'] errored with the following return code 1, and output:                                                                           
/home/r7/.cache/pypoetry/virtualenvs/poetry-demo-py3.6/bin/python: No module named pip                                              
                                                                                                                                      
add [-D|--dev] [--git GIT] [--path PATH] [-E|--extras EXTRAS] [--optional] [--python PYTHON] [--platform PLATFORM] [--allow-prereleases] [--dry-run] [--] <name> (<name>)...
```

よく分からないがとりあえず入れる。

```
$ wget https://bootstrap.pypa.io/get-pip.py
$ /home/r7/.cache/pypoetry/virtualenvs/poetry-demo-py3.6/bin/python get-pip.py 
```

入れたら通った。
## Poetryが作った仮想環境に入ってみる

```bash
$ poetry shell
Spawning shell within /home/r7/.cache/pypoetry/virtualenvs/poetry-demo-py3.6
```
```
$ python -c "import numpy; print(numpy.__version__)"
1.17.2
```

できた。
Mysql2のエラー

###エラー１
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
→mysqlの再起動

###エラー２
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
→mysql.sockファイルがない
→sudo touch /tmp/mysql.sockで作る

###エラー３
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (13)
→権限がない
→chmod 777 /tmp/mysql.sock


####そのほかでやったこと
・bootstrapとmaterializeを消した。
DockerとNginxでVue.jsサービス構築

#はじめに
DockerでNginxを作成する際にproxy_passは効かないで502 Bad GateWayエラーになる場合があります。
502エラーのときは、proxy_passのIPが正しくない可能性が高いです。

#DockerFile
Vue.jsのソースをビルドして、nginxの/var/www/htmlディレクトリにコピーします。

```dockerfile
# ビルド環境
FROM node:lts-alpine as build-stage

WORKDIR /app

# package.json, package-lock.jsonをコピー
COPY package*.json ./

# モジュールのインストール
RUN npm install

COPY . .

# ビルド
RUN npm run build

# 本番環境
FROM nginx:stable-alpine as production-stage

COPY --from=build-stage /app/dist /var/www/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
```
#vue.js向けのnginxのconf概要
```conf
    root /var/www/html;
    index index.html;
    charset utf-8;

    ## ヘッダーの項目の名前には「_」が使えるように設定
    underscores_in_headers on;
    
    # /apiのURLだったら、3001のポートに転送
    location /api {
      # Dockerの場合、nginxコンテナ外のサービスをproxyしたい場合、localhostはNGです。
      # proxy_pass http://localhost:3001/api;

      # hostサーバのIPを指定
      proxy_pass http://HostIP:3001/api;

      # カスタムヘッダー項目を設定
      proxy_set_header X-my_custom_header_field $http_x_my_custom_header_field;
    }

    # vue.jsのURL
    location / {
      # 404エラーの回避策
      try_files $uri $uri/ /index.html;

      # CSS,JSファイルはtext/htmlに誤認識されないように設定
      include /etc/nginx/mime.types;
    }
```

nginx: http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers
vue.js docker化： https://jp.vuejs.org/v2/cookbook/dockerize-vuejs-app.html

以上
ElasticsearchのsnapshotをAmazon S3に保存しようとしたら、しばらくすると保存できなくなって困った件

## ElasticsearchはスナップショットをAmazon S3に保存できる
検索エンジンであるElasticsearchにはインデックスのスナップショットを取って保存する機能があります。要はある時点でのバックアップを取れます。

https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-snapshots.html

説明を読んだ感じ、全マスターノードとデータノードで共有しているストレージに保存するのがデフォルトっぽいですが、**共有ストレージに障害があると即ES自体の障害になるらしい**とかで、Amazon S3に保存するようにしました。

## 直後はいいが、数日経つとスナップショットを保存できなくなる

設定自体は特に問題なく入れた後の動作確認もできたため、実際に定期的に保存をしていたのですが、どういうわけか**しばらくするとスナップショットをS3に保存できなくなってしまっていました**。ノードを再起動すると再び保存できるようになるのですが、やはりしばらくするとダメ。保存できなくなるまでの期間も特に周期があるというわけでもなく、数日から数週間程度だったでしょうか。
ESのノードの再起動は結構な苦行ですので（自動化はできますが）、定期再起動をかけるという原始的な解決策は取りづらいですし、何よりダサすぎます。

## 原因と対策
普通にインターネットを通してS3に保存しているわけではなかったので、経路を疑ったりもしたのですが、どうも分からず。
困っていたところ、何かの拍子で以下のページにたどり着きました。

https://docs.aws.amazon.com/ja_jp/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html

> Java 仮想マシン (JVM) は DNS 名参照をキャッシュします。JVM がホスト名を IP アドレスに変換するとき、time-to-live (TTL) と呼ばれる指定期間 IP アドレスをキャッシュします。
> 
> AWS リソースは、ときどき変更される DNS 名を使用するため、60 秒を超えない TTL 値で JVM を設定することをお勧めします。（略）
> 
> 一部の Java 設定では JVM のデフォルトの TTL が設定されるため、JVM が再起動されるまで、DNS エントリが更新されることはありません。

**JVMが揮発しないDNSエントリーのキャッシュを持っていた**とは…。ElasticsearchはJavaのアプリケーションですので、この指摘に当てはまります。というわけでそのページに書いてある通り、 **`networkaddress.cache.ttl` の設定を行うことで無事S3に保存し続けることができる**ようになりました。

分かっていれば簡単なんですけどね。ElasticsearchとS3に保存する手順を検索しても特に注意事項として書いてなくハマりましたので、同じような目にあった人のためにメモを残しておきます。
文系エンジニアにも分かる機械学習～機械学習とはナニモノ～

#目次
１．Introduction
　１－１）目的
　１－２）対象

２．機械学習とは
　２－１）特徴量
　２－２）ベクトル
　２－３）回帰
　２－４）最適化

３．参考文献

#１．Introduction
##１－１）目的
本などでインプットした知識をアウトプットして脳内整理する目的で
Qiita投稿を始めました。
そのため、粒度が荒かったり誤った情報がある可能性がありますので
その際はご指摘頂ければ嬉しいです。

##１－２）対象
この記事の対象としては、
ITの世界に入って間もない方や、ITとは無関係のお仕事や勉強をされている方です。
難しい内容でもかみ砕いて誰にでも分かりすい記事となるようにしていきます。
自分自身の理解も深めたいため、かなり初歩的なところから記載していきます。
それでは本題に入ります。


#２．機械学習とは
文字通り、機械（コンピュータ）が学ぶということ。
人間が四則演算のやり方を先生や親に教えてもらって学習するのと同じように、
人間がコンピュータに勉強させるイメージ。

さらに、コンピュータが学び取ったことを活用して、
世の中の様々な出来事を予測します。

**例）**天気の予測 / 地震予測 / 病気の診断 / 犯罪者の罪の重さ判断

もちろん、コンピュータが天気の意味や病気の症例の意味そのものを理解しているのではありません。

人間がコンピュータに対して、問題と解答のパターン（データ）を大量に入力し、
その大量データに基づいて
「こういう時はこうなる」「こういうケースではこうやって計算する」というように
コンピュータが解法パターンを見出すことにより、解答にたどりつけるようになります。

##２－１）特徴量
▶どんなところに注目したらよいか

**例）**かっこいいランナーとかっこよくないランナーの判断基準
![ランナー茶道](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498362/2fd60b23-afc8-3b68-750c-267d7af06b25.png)
[（画像引用元）](http://pictogram2.com/?p=1553)

- 背筋のまっすぐさ
- 足の上がり具合
- 目線の高さ
- 腕の振り具合
- ピッチ
- ストライド
- 速さ（タイム）

このような判断基準の一つひとつを特徴量と言います。

##２－２）ベクトル
▶特徴量ごとの数字をまとめたもの

例）チョメチョメさんのベクトル
![ベクトル.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498362/2dd10f2c-9f2f-22fb-afea-807eb9deafc1.png)



##２－３）回帰
▶コンピュータが大量のデータを学習して、学習したデータ・数値から知らない数値を予測すること
#####予測する仕組み
ベクトルの数値を入力すると出力が返ってくる関数を作ります。

**イメージ**
![関数.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498362/5cc3730e-0447-c5f0-97b1-c2d0e1ace11e.png)
中学校・高校で習う数学の問題ではXとYの値が与えられていて、
それらを関数にあてはめて答えを求める問題が多いかと思います。

機械学習では、入力と出力の値（ベクトル）をコンピュータに大量に学習させ、
コンピュータが入力と出力との間の法則性を見出します。
そうして入力から出力を求められるような関数を作ることにより、
未知の値を予測することができるようになります。

関数はシンプルな直線の一次関数かもしれないし、
得体の知れないウネウネしたグラフの関数かもしれません。

##２－４）最適化
▶正しい出力を求められるように、関数を少しずつ調整していくこと

**イメージ**
学習データのうち、入力をxとし、出力をYとします。
最適化前はプロットされた点とグラフ（関数）が交わっている箇所が1つしかない状態です。
しかし、最適化をすると学習データの全てがグラフと交わります。
このようにして、グラフの傾きを変えたり、高さを変えたりして調整することを**最適化**と言います。

![最適化.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498362/5200d742-5bae-98d9-6337-7235950f3752.png)

#３．参考文献
多くの情報を以下の本から得ています。
機械学習についてストーリー仕立てで分かりやすく書かれています。
amazonのページは[こちら](https://www.amazon.co.jp/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E5%85%A5%E9%96%80-%E3%83%9C%E3%83%AB%E3%83%84%E3%83%9E%E3%83%B3%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%8B%E3%82%89%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92%E3%81%BE%E3%81%A7-%E5%A4%A7%E9%96%A2%E7%9C%9F%E4%B9%8B/dp/4274219984/ref=asc_df_4274219984/?tag=jpgo-22&linkCode=df0&hvadid=295704876452&hvpos=1o4&hvnetw=g&hvrand=1137465141939269708&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009461&hvtargid=pla-524029648259&psc=1&th=1&psc=1)
VoIP Push (PushKit) は着信通知専用になりました・・・

*注意：この記事はAppleのドキュメントを参照して書きました。実際に実装していないので間違いがあるかもしれません。*

## VoIP Push は CallKit とともに！（iOS13)
iOS 13 SDK でビルドしたアプリを iOS 13 上で動かした際、[VoIP Push を受けたとき](https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/2875784-pushregistry)に CallKit の [reportNewIncomingCall](https://developer.apple.com/documentation/callkit/cxprovider/1930694-reportnewincomingcall) を呼び出さなければならないことになりました。
　
[reportNewIncomingCall](https://developer.apple.com/documentation/callkit/cxprovider/1930694-reportnewincomingcall) を呼び出すと、電話の着信画面が表示されます。
つまり、VoIP Push は着信通知にしか使えないということになります！
　
チャットなどをサポートしている VoIP アプリは、VoIP Push を着信通知以外に利用していることもあると思いますが（~~え、そんなことしてない？？~~）、今後は通常のPushを使う必要があります。
　
また、VoIP Push を使っているが CallKit には未対応という VoIP アプリもあるかと思いますが、今後はＮＧとなります。
CallKit に対応するか、通常のPush を使うか、対策が必要です。
（中国では CallKit 対応アプリをストアに提出できないと聞いてますがどうするのでしょうね・・・）
　
**2020年4月以降に提出するアプリは iOS 13 SDK 対応必須ですので、それまでに対応必須です！**

## iOS 13 SDK の変化点
詳細は以下を参照ください。
> [Responding to VoIP Notifications from PushKit](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit)

[pushRegistry(_:didReceiveIncomingPushWith:for:completion:)](https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/2875784-pushregistry) で VoIP Push を受信した際、この関数内で [reportNewIncomingCall](https://developer.apple.com/documentation/callkit/cxprovider/1930694-reportnewincomingcall) を呼び出さないとアプリの起動が停止されるそうです。

[WWDC2019 の資料](file:///C:/Users/yasua/Downloads/707_advances_in_app_background_execution.pdf)に以下のようにかかれています。
>Must report incoming call with CallKit in didReceiveIncomingPush callback
>If not, system may stop launching your app for VoIP pushes
VisualStudioCodeで競技プログラミングの環境を作る(MacとC++)

**この手順は当時の環境構築時のものです。2023年2月現在はこの手順で構築できないようなので後日更新いたします。**

PCを交換したので環境を構築します。
以下の記事を参考にさせていただきました。

**Visual studio codeで競プロ環境構築[mac OS]**
https://qiita.com/fuji_20/items/ffa2a7b4d264e7a052c6

**CodeRunnerの出力をターミナルに出す方法[VSCode]**
https://murabitoleg.com/vscode-runner/

##やること
homebrewのインストール
gccのインストール
VisualStudioCodeのインストール
環境整備

### homebrewのインストール

```bash:ターミナルで実行
$ xcode-select --install
```

[brewの公式ページ](https://brew.sh/index_ja.html)からコマンドをコピペ

```bash:ターミナルで実行
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$brew --version
Homebrew 2.1.11
Homebrew/homebrew-core (git revision 0aa56; last commit 2019-09-21)
```
### gccのインストール
```bash:ターミナルで実行
$ brew install gcc
$ ls -l /usr/local/bin/g++-9 
lrwxr-xr-x  1 kusakai  admin  29  9 21 12:33 /usr/local/bin/g++-9 -> ../Cellar/gcc/9.2.0/bin/g++-9
$ ln -s /usr/local/bin/g++-9 /usr/local/bin/g++
$ which g++
/usr/local/bin/g++
$ ls -l /usr/local/bin/g++
lrwxr-xr-x  1 kusakai  admin  20  9 21 12:24 /usr/local/bin/g++ -> /usr/local/bin/g++-9
```

### VisualStudioCodeのインストール
[Mac版をDLしてインストールする](https://code.visualstudio.com/Download)

### 環境整備
VisualStudioCodeを起動して、CodeRunnerとC/C++のプラグインをインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/98b16d3b-c675-cba3-0575-2c6b029317b5.png)

CodeRunnerから実行した場合、標準入力を操作不可のため一部の設定を変更する。
「command ,」でSettingsを開き、「settings.json」を入力して「Edit in settings.json」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/73dfade9-9105-ed0b-393d-8c0cb1ba13ae.png)

以下２行を追加する

```diff:settings.json
    "window.zoomLevel": -1,
+    "code-runner.clearPreviousOutput": true,
+    "code-runner.runInTerminal": true,
```

stdc++.hの場所移動

```sh:ターミナルで実行
$ ls -l /usr/local/Cellar/gcc/9.2.0/include/c++/9.2.0/x86_64-apple-darwin18/bits/stdc++.h 
-rw-r--r--  1 kusakai  staff  3213  8 12 16:58 $ /usr/local/Cellar/gcc/9.2.0/include/c++/9.2.0/x86_64-apple-darwin18/bits/stdc++.h
$ cd /usr/local/include/
$ cp /usr/local/Cellar/gcc/9.2.0/include/c++/9.2.0/x86_64-apple-darwin18/bits/stdc++.h .
```

これで準備できたので、動作確認として以下を動かします。

```c++:main.cpp
#include <bits/stdc++.h>
using namespace std;
int main(){
    int a, b;
    cin >> a;
    cin >> b;
    cout << a + b << endl;
}
```

VisualStudioCode右上の再生ボタン（？）を押下（または右クリック→「Run Code」など）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/5edcd78a-4412-43b4-1b7d-518a5f858bc1.png)

想定通り動作してます。
ヤフオク等のECサイトからスクレイピング (ruby + Nokogiri)

※2019年9月時点のxpathなのでヤフオク側の変更のより取得できなくなるかもしれません。

ランサーズなどよく見るでヤフオク、amazon等のECサイトからの単純なデータ収集のお仕事。
プログラミングを使えば結構簡単にできちゃいます。
いわゆるスクレイピングっていう技術ですね。

今回は言語はruby、スクレイピングライブラリとしてNokogiriを使い、
ヤフオクの商品ページのタイトル、画像URL、価格などのデータを取得しcsvで出力します。

前提条件
--
rubyはインストール済み。


準備
-----
まずNokogiri gemをインストール。

```
$ gem install nokogiri
Building native extensions. This could take a while...
Successfully installed nokogiri-1.10.4
Parsing documentation for nokogiri-1.10.4
Done installing documentation for nokogiri after 1 seconds
1 gem installed
```

続いてcsv gemをインストール

```
$ gem install csv
Successfully installed csv-3.1.1
Parsing documentation for csv-3.1.1
Done installing documentation for csv after 0 seconds
1 gem installed

```
準備完了！

rubyスクリプトを作成
---

```rb
require 'nokogiri'
require 'open-uri'
require 'csv'

 #取得したいURLを配列に格納する
urls = %w(
  https://page.auctions.yahoo.co.jp/jp/auction/r349735904
  https://page.auctions.yahoo.co.jp/jp/auction/v661258739
  https://page.auctions.yahoo.co.jp/jp/auction/s688301927
  https://page.auctions.yahoo.co.jp/jp/auction/j555196435
  https://page.auctions.yahoo.co.jp/jp/auction/v643884399
)

#取得したい値のxpathを格納する
xpaths = [
 '//h1[@class="ProductTitle__text"]',                      #商品名
 '//dd[@class="Price__value"]/text()',                     #現在価格
 '//dt[contains(text(),"入札件数")]/following-sibling::dd[1]/text()', #入札件数
 '//dt[contains(text(),"残り時間") and @class="Count__title"]/following-sibling::dd[1]/text()', #残り日数
 '//ul[@class="ProductImage__images"]/li[1]/div/img/@src', #画像1枚目
 '//ul[@class="ProductImage__images"]/li[2]/div/img/@src', #画像2枚目
 '//ul[@class="ProductImage__images"]/li[3]/div/img/@src', #画像3枚目
 '//ul[@class="ProductImage__images"]/li[4]/div/img/@src', #画像4枚目
 '//ul[@class="ProductImage__images"]/li[5]/div/img/@src', #画像5枚目
]

values = []
hash = {}
#csvで出力する際のヘッダーを格納
hash[0] = %w(商品名 現在価格 入札件数 残り日数 画像1 画像2 画像3 画像4 画像5)

i = 1
charset = nil
urls.each do |url|
  html = open(url) do |f|
    charset = f.charset
    f.read
  end

  doc = Nokogiri::HTML.parse(html, nil, charset)
  xpaths.each do |xp|
    node = doc.xpath(xp)
    value = node.inner_text.delete("\n").delete("円")
    values.push(value)
  end
  hash[i] = values
  i += 1
  values = []
end

 CSV.open("yahuoku.csv", "w") do |csv|
   hash.count.times do |i|
   csv.add_row(hash[i])
  end
 end
```

出力結果
--
![スクリーンショット 2019-09-27 13.34.21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425910/631138ab-ae89-c27e-9a9b-b852a6759ca1.jpeg)
※出力されたcsvファイルをグーグルスプレッドシートで開いています。


反省
--

機能はしますが、計算速度や読みやすさという点では改良の余地がかなりありますのでご了承ください。
改善点等ご指摘いただけたら大変助かります。

参考ページ
--
[クローラ作成に必須！XPATHの記法まとめ - Qiita](https://qiita.com/rllllho/items/cb1187cec0fb17fc650a)
[Ruby + Nokogiriでスクレイピング - Qiita](https://qiita.com/kumamonmaster/items/9bb2aadde56c956fdc9f)

補足
--
最近(2020/6月)このコードを実行してみたら、現在価格の取得がおかしくなってました。
おそらくヤフオク側の仕様変更だと思われます。
そのうち修正します。
MongoDB基礎：DB接続の書き方

#はじめに
MongoDBのDBへの接続する書き方はマニュアルにありますけど、たまに注意しないでエラーになる場合があります。

#エラー例
## 1. サービス起動していない　OR　起動したMongoDBのIPがlocalhostではなく別サーバ
```text
Error when connecting to the databaseMongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
```

## 2. database名の後ろに余分な「/」が付けている
```text
Error when connecting to the databaseMongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoError: Invalid database name: 'mydb/']
```

## 3. 認証がある場合、認証DBを指定していない
```text
Error when connecting to the databaseMongoNetworkError: failed to connect to server [10.0.87.26:27017] on first connect [MongoError: Authentication failed.]
```

## 4. クラスターの場合、replicaset名不正か、そもそもクラスターが異常がある
```text
Error when connecting to the databaseMongoError: no primary found in replicaset or invalid replica set name
```

#書き方
`mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[database][?options]]`

#サンプル
## localhost
`mongodb://localhost:27017`

## DB指定
`mongodb://localhost:27017/mydb`

## 認証あり(adminデータベースで認証)
`mongodb://user:password@localhost:27017/?authSource=admin`

## replicaSetあり（set名：dbs）
`mongodb://IP1:27017,IP2:27017,IP3:27017/?replicaSet=dbs`

## 認証　＋　replicaSet
`mongodb://user:password@IP1:27017,IP2:27017,IP3:27017/?replicaSet=dbs&authSource=admin`

など
ほかのパラメータもいろいろ制御できます。


マニュアルURL: https://docs.mongodb.com/manual/reference/connection-string/

以上
Rails + Grapeを使ってWebAPIを作成する。(②Grape_swaggerを使って結果を出力できるようにする。)

#はじめに
7月よりwebエンジニアとなり、研修の一環として社内Qiitaの作成を行いました。
自社にて開発しているシステムでもWebAPIを使用するので、予行演習としてこの社内QiitaでもWebAPIを作成したので作成の流れを3分割して説明したいと思います。

- ①[User.allを返す。(前回)](https://qiita.com/shicchi7913/items/cf2ff74e084263c8ce20)
- ②Grape swaggerを使ってAPIの結果を表示する。(今回)
- [③ログイン・ログアウトできるようにする。](https://qiita.com/shicchi7913/items/0e998e75e080ba70729f)

前回の投稿では、``` User.all ```を返すWebAPIについてまとめました。
ここでRailsでWebAPIを作成するにあたってJSON形式で送られてくる結果をどうやって確認するのかというと

- grape_swagger(gem)
- Postman

この2つのどちらかが多いと思います。
今回はGrape_swaggerを使用して送られてくるJSON形式のデータを出力させるまでをまとめたいと思います。

#Gemfile

まずはgemをインストール。

```
gem 'grape-swagger', group: :development
gem 'grape-swagger-rails', group: :development
```
#root.rb

インストール後、rootノード(一番上の階層にあるWebAPIの全般的な設定を行うファイルと言ったらいいかな？)に``` grape-swagger ```を読み込むよう諸設定を行います。
``` add_swagger_documentation ```ではAPIの名称や説明文をswaggerに記載できます。他にもオプションがあるので気になる方は[こちら(参考)](https://github.com/ruby-grape/grape-swagger#configure-)を参照してください。

```api/root.rb
#gem grape-swaggerの読み込み(本番環境以外)
require 'grape-swagger' unless Rails.env.production?

class Root < Grape::API
  prefix 'api'
  format :json

  mount V1::Root
　#本番環境以外では以下記述を反映させる。
  if defined? GrapeSwaggerRails 
    add_swagger_documentation(
      info: {
        title: 'SAMPLE_API',  #このAPIの名称
        description: 'API'        #説明文
      }
    )
  end
end

```

#routes.rb
swaggerにアクセスする際のURLを設定します。
この時のURLは私は'docs'と記載しましたが、お好みのURLを設定してください。

```routes.rb
Rails.application.routes.draw do
  mount Root => '/'
  mount GrapeSwaggerRails::Engine => '/docs'
end

```

#swagger.rb

次にswagger自体の諸設定です。
``` config/initializers/ ```に以下の ``` swagger.rb ```を置いてください。

```swagger.rb
unless Rails.env.production?
  # 完成形のヘッダにあるタイトルを示します。
  GrapeSwaggerRails.options.app_name = 'API_TUTORIAL_APP' 
  # このURLは固定です。
  GrapeSwaggerRails.options.url = '/api/swagger_doc.json'

  GrapeSwaggerRails.options.before_action do
    # 完成形のヘッダにあるタイトルをクリックすることによって開発中のWebアプリに遷移してくれます。
    # localhost:3000/docs (クリックすると)=> localhost:3000 に遷移。
    GrapeSwaggerRails.options.app_url = request.protocol + request.host_with_port
  end
end
```

#完成形
あとはlocalhost:xxxx/docsにアクセスすれば完了です。

<img width="1213" alt="スクリーンショット 2019-09-21 12.44.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280603/9422db04-1aca-d0a0-59e3-384753968a98.png">

次は[WebAPIでログイン・ログアウトできる](https://qiita.com/shicchi7913/items/0e998e75e080ba70729f)ようにしていきたいと思います！


#参考
[gem ruby-grape/grape-swagger](https://github.com/ruby-grape/grape-swagger)
[gem ruby-grape/grape-swagger-rails](https://github.com/ruby-grape/grape-swagger-rails)
laravel-mix-polyfill　でcore-js.....エラーが出たときの対処法

##laravel-mix-polyfillをインストール
laravel-mixでIE11に対応させたいと思いまして、
extensionにlaravel-mix-polyfilltというものがあり、これを追加するだけで使えるということで
早速追加しました。

```
npm install laravel-mix-polyfill --save-dev
```

https://laravel-mix.com/extensions/polyfill

##しかし、使えんぞ・・・・・・・
インストールが終わって、早速、**npm run watch**しました。

しかし・・・・・・

```
ERROR in ./resources/js/components/test.vue?vue&type=script&lang=js&    
 (./node_modules/babel-loader/lib??
ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/test.vue?vue&type=
script&lang=js&)   
Module not found: Error: Can't resolve 'core-js/modules/web.dom.iterable' in '/Users/.....'
```

エラー発生！

##とりあえず、エラーを読もう
エラーを読む限り、core-jsがないらしい。
そんなはずは、ないが、そういっているのでcore-jsを入れます。

```
yarn add core-js
```
最新は、**3.2.1**なので3.2.1を入れてました。(yarn 使ってますが、npmでも一緒です。）

しかし...

エラーは、変わらず・・・・

![tumblr_o42b19PCrd1ukxrvfo1_500.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322732/afb9154f-c4ae-93d0-391e-e84c8c66f8f2.gif)


##ネットサーフィンの結果
海外のサイトで
>I returned core-js to the @2.6.5 version without misreporting.

ということだそうです。つまり、**2.6.5**にしたら、使えると・・・・

```
yarn add core-js@2.6.5
```

上記で使えるようになりました。
###Compiled successfully in 7329ms   

めでたし、めでたし。
BEMについて[備忘録]

#BEM

BEMではページを構成する要素を
・Block
・Element
・Modifer
の3つに分類し、組み合わせることでクラスを命名します。Block、Element、Modiferの3つを使用して命名することで、クラス名だけでHTML要素の意味を伝えられます。

 ・Block
Blockとは、ある要素の大元となるブロック要素です。Blockの命名には名詞を使用します。以下で説明するElementやModifierは、このBlockを起点に命名されます。

 ・Element
Elementとは、Blockに属する子要素です。1つ以上のElementによって、Blockは構成されています。Elementの命名には名詞を使用する。

 ・Modifier
Modifierとは、Blockまたは、Elementに特別な修飾をする要素です。Modifierの命名には形容詞を使用する。

昨日はエラーにぶち当たってしまいそれと格闘していたら気づいたら寝落ちしてて更新を忘れてしまいました。反省。
備忘録

#proxomitron


####スクリプトを読み込まない（簡易版）
```:default.cfg
(1)
Match = "<script src="http://xxx.*"></script>"
(2)
Match = "https://www.xxx.com/xxx.js"
```


####スタイルシートを読み込まない（簡易版）
```:default.cfg
Match = "rel="stylesheet""
Replace = "></link>"
```


使用前

```html:test.html
<link rel="stylesheet" type="text/css" href="xxx.css">
```

使用後

```html:test.html
<link ></link> type="text/css" href="xxx.css">
```

####コードを追加する
```:default.cfg
Match = "<ul class="xxx">"
Replace = "<ul class="xxx"><a href="#contents">GO TO NEXT</a>"
```

####書き換え
```:default.cfg
(1) 値の書き換え
Match = "<input type="hidden" name="xxx" value="0">"
Replace = "<input type="hidden" name="xxx" value="15">"
(2) 非表示化
Match = "<ul class="xxx">"
Replace = "<ul class="xxx" style="display:none">"
(3) 同じタブで開かせる
Match = "<form action="xxx" method="get"  target="_blank">"
Replace = "<form action="xxx" method="get" target="_self">"
```


#GreaseMonkey

```javascript:test.js
Ar_input = document.getElementsByTagName('input');

for (let i=0;i<Ar_input.length;i++){
	if (Ar_input[i].type == "radio" || Ar_input[i].type == "checkbox"){
		Ar_input[0].checked = true;
		clickSubmit();
		break;
	}
}

function clickSubmit(){

	for (let j=0;j<Ar_input.length;j++){
		if (Ar_input[j].type == "submit"){
			Ar_input[j].click();
			break;
		}
	}

}
```

Ar_input[0]は、間違いではなく、敢えてそうしたはず。
【paiza】swift スキルチェック用コマンド(自分用メモ)

# セパレート -> Int型配列にする
```separete.swift
// readLine()! はpaizaから与えられる標準入力
var arrayInt = readLine()!.split(separator: " ").map { Int($0)! }
```
# 連続文字をセパレート（分割）する
```separate.swift
let num: String = "111010"
let array = num.map { string($0) }

print(array) // 結果 -> ["1", "1", "1", "0", "1", "0"]
```
# 10進数 -> 2進数、8進数、16進数
```radix.swift
let num = 11
let str2  = String(num, radix: 2)  // -> 1011
let str8  = String(num, radix: 8)  // -> 13
let str16 = String(num, radix: 16) // -> b
```
【OCI】oracle cloud -コンパートメント作成編-【初心者向け】

# コンパートメント
コンパートメントは、テナントの内部を論理的に分割できます。
コンパートメントの中にリソースを配置したり、
ポリシーを割り当てることで権限を設定することができ、
コンパートメント毎に支払い額を確認することができるので、
他クラウドの様にサービス毎にアカウントを作成する必要もなくなります。
コンパートメントは階層化することもできます。

## コンパートメントの作成
左側のメニューからアイデンティティ→コンパートメントをクリック
![instance_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/2a6286eb-7563-10b0-4037-13dde7d4ad74.png)

コンパートメントの作成をクリック
![instance_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/f36c7b33-8c8d-1442-a69c-9da1e742f4eb.png)

| 項目       |       概要 |
|:-----------------|:------------------|
| 名前              | 任意のコンパートメント名を入力します。 |
| 説明              | コンパートメントの説明を入力します。 |
| 親コンパートメント | 親となるコンパートメントを選択します。 |
今回はルートコンパートメントに作成しています。

入力が終えたらコンパートメントの作成をクリック
![instance_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/a0fc4f38-6d48-2d3f-2252-1633294770f4.png)
これで作成完了
![compa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/9b4984e3-1494-4a9b-fd27-c1a0dbf02ef9.png)


## 次回
作成したコンパートメントに仮想クラウド・ネットワークを構築していきます。

[仮想クラウドネットワーク編はこちら](https://qiita.com/manaki079/items/1283bfe3f6e7667bfb43)
Capybara利用時に発生した「sending SIGTERM to all processes」

# 現象
Capybaraを利用するジョブを作成し、画面でボタン押下時にそのジョブを呼び出そうとしていた。
railsコンソールからジョブを呼び出した時は正常に処理が終了するが、画面からボタン押下してジョブを呼び出した場合には、webページアクセス(Capybara::Session#visit)のタイミングで以下のようなエラーが発生し、処理が中断してしまう。

```
08:20:32             | exited with code 0
08:20:32 system      | sending SIGTERM to all processes
08:20:32 web.1       | terminated by SIGTERM
08:20:32 web.1       | terminated by SIGTERM
08:20:32 web.1       | terminated by SIGTERM
08:20:32 webpacker.1 | terminated by SIGTERM
```

ログがこれだけ。

# 環境
- ruby 2.5.3
- rails 5.2.3
- Capybara 3.29.0

※ foremanを利用して、railsとwebpackerをdockerコンテナ上で起動している。

# 原因
foremanが、Capybara::Session#visitのタイミングで、同時起動するプロセスを全てkillしていた。

# 対応
foremanを利用する開発環境だけの事象ということがわかったため、Dockerfile上でforemanを利用しないように修正することで対応。

```
CMD ["bundle", "exec", "foreman", "start", "-f", "Procfile.dev"]
```
↓

```
CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
```
ShellScript 変数 に \ を格納する

# 目的

- Linuxで変数に`\`(バックスラッシュ)を格納する方法を知る。

# "\"(円マーク バックスラッシュ)は特殊文字

- `\`は特殊な意味を持った文字として扱われるらしい。
- `\`はエスケープ文字として扱われている。
- エスケープ文字とは\を含む特殊文字を通常の文字として扱うことができるようにするためのもの
- 特殊文字を普通のもじとして使用したいときにエスケープ文字を置き、そのあとに特殊文字を置く
- エスケープ文字について下記で説明する。(>はターミナルの出力)

``` shell
# 下記のコマンドは一つ前のコマンドの戻り値を出力するコマンド(正常に実行されると0を出力する)
$ echo $?
>0

# ターミナルに[$?]という文字を出力させたいときにエスケープ文字を使用する
$ echo \$?
>$?
```

# "\"(円マーク バックスラッシュ)を表示するには

- 前の`\`が後ろの`\`をエスケープしている。
- `\`一つでエスケープできる文字は一つである。
- 前述の内容を加味すると`\`を2個連続で出力したいときは`echo \\\\`となる。
- 下記に`\`をターミナル上に出力する方法を記載する。

``` shell
$ echo \\
>\
```

# "\"(円マーク バックスラッシュ)を変数に格納するには

- 下記に変数stringに\を格納する方法を記載する。

``` shell
#\を一つ格納する
$ string=\\
$ echo ${string}
> \

#\を二つ格納する
$ string=\\\\
$ echo ${string}
> \\

#\を三つ格納する
$ string=\\\\\\
$ echo ${string}
> \\\
```
#AWS のサーバーサイド暗号化とはなんなのか？ 分からないままに。

この説明がわかりやすい気がした。

>サーバーサイド暗号化は、ファイルを配置する際にS3が自動的に暗号化してAWSのデータセンター内のディスクに書き込んでくれ、ファイルを取り出すときに複合してくれます。
>クライアント暗号化は暗号化、複合化を自分で行う必要があるため、そちらの方が大変です。

https://public-cloud-pci-dss.jp/aws/75/

ディスクに書き込む時の暗号化・複合方式であって、暗号化しつつ、他はユーザーが意識せずにサービスを使えるというイメージだろうか。

それならデフォルトでそうしてくれれば良いのでは？と思うが、なぜオプショナルなのかが分かっていない。どんな不都合があるのだろう。

氷結STRONG ピーチ＆マンゴーを飲みながら考えようか。土曜日だし。

![image](https://user-images.githubusercontent.com/13635059/65365895-9239b900-dc58-11e9-9e16-5f776a7b7cc4.png)



# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
VSCodeの TypeScriptで、「Cannot redeclare block-scoped variable」が表示される

VisualStudio Codeで TypeScriptを作った後、以下のコマンドなどでコンパイルをします。

```sh
tsc test.ts
```

すると、同じディレクトリーに .jsファイルができあがりますが、この時 VisualStudio Code上に図のようなエラーが表示されるようになります。

<img width="513" alt="2019-09-21_11-54-30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977/503c9576-89c3-1b77-3056-f93c0d4cbb91.png">

> Cannot redeclare block-scoped variable '...'

これは、コンパイル時の ECMAScriptのバージョンによるもののようで、「tsconfig.json」ファイルがあれば防ぐことができます。

tsconfig.json

```js:tsconfig.json
{
  "compilerOptions": {
    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
  }
}
```

先に、次のように初期化をしてから始めるとよさそうです。

```sh
tsc --init
```
【初心者向け】変数を会社のルールに例えて説明してみた。


# はじめに

プログラミングの学習をしていて、**イメージが付かず、理解出来ないもの**が多かったので、
今回は、変数や定数を初心者でもわかるように、会社のルールにたとえて、
わかりやすく説明してみました。

イメージも画像として入れているので、楽しみながら学んでいただけると嬉しいです！
間違っている点などあれば、コメント等いただければと思います。


# 変数


簡単に言うと、**値を入れておく型**、だとよく言われます。
※私は、型ってなんだよ！ってなりました。笑

では、プログラミング用語を元に、型とはなんなのか、どうやって使っていくのか、
説明していきます！

## 変数 = 型

<img width="731" alt="スクリーンショット 2019-09-20 12.18.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465338/20ce23e7-fbb1-1f4c-2963-7db50221aef8.png">

変数とは、会社内で例える、書類のようなものです。
残しておきたいものや値などを、入れていきます。
そして、入れ方や記入方法が書類に応じてあるように、変数にも存在します。

### 変数名のルール

<img width="779" alt="スクリーンショット 2019-09-20 12.51.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465338/c43260ae-a84f-3d5a-79d9-d9d838979763.png">

会社によって書類の名前の付け方にルールがありますよね。
 > 2019XXYY.text　のように日付を記入しなさい！
 > 営業資料_〇〇会社.pxp のように営業資料には社名も入れろ！！　などなど

これと同様に変数にも、ルールがあります。
例えば、
> 数字で始まるのはダメ！　（123hensuu 55gogo など）
> 大文字は使ってもいいよ！ or 大文字使えません！　などなど

自分が使いたい言語のものも調べてみましょう！
※変数を使う記号等にルールはあれど、設定方法はかなり緩いので、管理が大変なので、
　プロジェクトなどによって、変数の定義方法が決められていることも多いです。




### 型

<img width="806" alt="スクリーンショット 2019-09-21 11.54.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465338/326e6f4b-6958-01b1-7c2f-32bd3ed543ad.png">


会社によって、資料の書類の種類がいくつかあり、それぞれに大まかな記入方法があるように、
変数にも、量は違えど、種類や記入方法が存在します。

たとえば、
>整数だけが入るもの（整数型）
>文字列だけが入るもの（文字列型）　などなど

そして、プログラミング言語ごとに、それぞれに記入方法や定義、設定方法が異なっていたりします。
※プログラミングで変数を設定する際は気をつけましょう。！



### 書き換え可能

<img width="801" alt="スクリーンショット 2019-09-21 12.00.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465338/01688bbe-e48f-f9c4-3a0f-7c8a5b363c63.png">

会社でも書類等の書き直しの際にルールが存在するように、
>プログラミングの変数でも変数の書き直し方やルールが存在します。

例えば、一度変数を定義してしまうと、その型を変えてはいけない。など。
再定義の方法もプログラミング言語によって異なったりもします。
※プログラミングで変数を再設定する際は気をつけましょう。！




#まとめ

変数とは、**値を入れておく型**

<img width="1015" alt="スクリーンショット 2019-09-21 12.07.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465338/d4edf08b-27c4-5bdc-a52b-3a4bd3b4bd5d.png">

プログラミングを行なっていると、様々な場面で繰り返し使いたい要素が現れます。
それらを社内で記入を行う書類のように、
プログラミングの中で忘れない、または使えるようにしておくだけなんだなあと、
難しく考えすぎずに、変数を使いまくりましょう！！！


# さいごに

会社にたとえて記入しましたが、解釈や理解の仕方は人それぞれなのかなと思っています。
私は、型や変数などをきちんと理解するのに時間がかかったので、、、
理解を行う際に、そんなことか、難しくないじゃん！って思ってもらえたら嬉しいです！