OmniAICreator/Qiita-1.07M huggingface dataset:
Auroraのカスタムエンドポイントを確認してみた

Auroraにカスタムエンドポイントが…！
バックグラウンドジョブや解析用とwebを振り分けるのが簡単になりそうなので確認してみました。

# TL;DR>Auroraのカスタムエンドポイントを使うと…
- 特定のインスタンスをまとめたエンドポイントを作成できる！
- 特定のインスタンスを除外した読み込みエンドポイントを作成出来る！
    - フェイルオーバーでのマスタースレーブ入れ替わりにも対応している！

# 実行イメージ
こんな構成が
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/68048/9abf7961-e63d-67a0-6a71-3bba72c76bda.png)
こうなりました
![図2.png](https://qiita-image-store.s3.amazonaws.com/0/68048/5c4d7464-f0da-cb9c-041c-c1f017a714a9.png)


# コマンド例

カスタムエンドポイントA

```bash
$ aws rds create-db-cluster-endpoint --db-cluster-endpoint-identifier custom-endpoint-doc-sample \
  --endpoint-type reader \
  --db-cluster-identifier cluster_id \
  --excluded-members custom-endpoint-demo-09 custom-endpoint-demo-10 \
  --region $REGION
```

カスタムエンドポイントB

```bash
$ aws rds create-db-cluster-endpoint --db-cluster-endpoint-identifier custom-endpoint-doc-sample \
  --endpoint-type reader \
  --db-cluster-identifier cluster_id \
  --static-members custom-endpoint-demo-09 \
  --region $REGION
```

カスタムエンドポイントC

```bash
$ aws rds create-db-cluster-endpoint --db-cluster-endpoint-identifier custom-endpoint-doc-sample \
  --endpoint-type reader \
  --db-cluster-identifier cluster_id \
  --static-members custom-endpoint-demo-10 \
  --region $REGION
```


# 軽く解説
公式の通り実行するだけなのですが、現在（2018/11/13）はマネジメントコンソールからは制限があるので、CLIで実行するといろいろ出来ます
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.Endpoints.html

## 重要パラメータ
- endpoint_type
    - anyかreaderを選びます。anyにすると全インスタンスが対象、readerにすると読み込みインスタンスのみが対象になります。anyの場合だと、読み込みエンドポイントにしたつもりがフェイルオーバーでwriterが紛れ込んでくるので注意が必要です。
    - マネジメントコンソールからは現状anyのみの模様（やり方知ってたら教えてください）
- excluded-members
    - 除外するインスタンスを指定します。この指定の場合はオートスケーリングで増加した場合もこのエンドポイントに追加されます
- static-members
    - インスタンスを直接指定します
    - excluded-membersと共存は出来ません

## マネジメントコンソールでの操作
パターン1: `--static-members test-2 test-sidekiq --endpoint_type any`
![スクリーンショット 2018-11-13 17.42.33.png](https://qiita-image-store.s3.amazonaws.com/0/68048/2ac2cf16-8fc4-e488-385e-98f8ba4ab081.png)

パターン2: `--excluded-members test-sidekiq --endpoint_type any`
![スクリーンショット 2018-11-13 17.49.37.png](https://qiita-image-store.s3.amazonaws.com/0/68048/45e6bee7-95e9-b8c5-c5ae-d21ba4d77c29.png)


# Fin
~~※動作を確認したのみでまだ本番には投入しておりません！~~
本番導入から1週間経過し、全く問題なく快適に使えております！！
VSCode が正規表現の後方参照 / 先読みに対応した

# アップデート内容

## リリースノート

[Visual Studio Code October 2018](https://code.visualstudio.com/updates/v1_29)

## 主なアップデート内容

- 複数行での検索
- 正規表現の後方参照 / 先読み対応 ← **本記事で扱う内容**
- macOS Mojave のダークモード対応
- 修正したタブのハイライト表示

# 正規表現での検索がより便利に

## 後方参照って？

一致したパターンをキャプチャし、後で再び使用できるようにする機能。

詳しい解説 → [後方参照](https://msdn.microsoft.com/ja-jp/library/cc427982.aspx)

## 先読みって？

素晴らしい解説 → [正規表現の先読み・後読み](http://chibinowa.net/note/web/regex-looks.html)

### 肯定的先読み

```
look(?=ahead)
```

`ahead` 部分の正規表現に合致する `look` 部分にマッチする。

### 否定的先読み

```
look(?!ahead)
```

`ahead` 部分の正規表現に合致しない `look` 部分にマッチする。

# 実際に使ってみる

## 使用するには

以下の設定は必要。

```json
{
  "search.usePCRE2": true,
}
```

## 後方参照を使ってみる

前方で `<h1>` 及び `<h2>` をキャプチャし、後方で `\1` を使って参照する。
![スクリーンショット 2018-11-13 17.21.38.png](https://qiita-image-store.s3.amazonaws.com/0/241738/017bc0bc-0ea3-1b96-6c1c-ff6710775815.png)

## 先読みを使ってみる

### 肯定的先読み

バージョンが数字の `Windows` にのみマッチする。
![スクリーンショット 2018-11-13 17.41.18.png](https://qiita-image-store.s3.amazonaws.com/0/241738/23b8661e-056f-eac1-02a9-bdee50481ed7.png)

### 否定的先読み

バージョンが数字以外の `Windows` にのみマッチする。

![スクリーンショット 2018-11-13 17.42.37.png](https://qiita-image-store.s3.amazonaws.com/0/241738/f58a9f74-6d93-feb1-9466-3da6e96b7b4a.png)

## 後読みは？

後読みには未対応。
![スクリーンショット 2018-11-13 17.45.02.png](https://qiita-image-store.s3.amazonaws.com/0/241738/d489a199-a18d-bd33-282b-fd360f4b886b.png)

# まとめ

- 後方参照 / 先読みを使って検索ができる。
- 普段正規表現で検索する人には朗報。
- より詳細な仕様は、使用されている [PCRE2](https://pcre.org/) エンジンのページが詳しい。
- もっといい例があると思うので、コメントお待ちしています🙇
TransitionManager + BindingAdapterで簡単Fade Visibility Animation

個人用メモみたいなものです

```kotlin
@BindingAdapter("bind:fadeVisibility")
fun View.fadeVisibility(visibility: Int) {
    val viewParent = this.parent
    if (viewParent is ConstraintLayout) {
        TransitionManager.beginDelayedTransition(viewParent)
    }
    this.visibility = visibility
}
```

```xml
<View
  android:id="@+id/divider_below_wallet_setting"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  bind:fadeVisibility="@{viewModel.isShow ? View.VISIBLE : View.GONE}"/>
```

-------------

これでfadeがかかりながら出たり消えたりしてくれます
[GAS]営業日判断スクリプト

###はじめに
営業日のみ日報を送りたかったので作成しました。

上から土日判別、祝日判別を組んでいます。
条件に合致したら、returnで終了してます。
祝日はGoogle Calendarから持ってきています。

```js

//営業日を判別するスクリプト
//土日祝日は”false”,平日は”true”を返す
//祝日はGoogleカレンダーから取得
//目的：土日祝日動いていないアカウントにはメールを送らない

function checkHoliday() {
  
  var moment = Moment.moment();
  var today = moment.format("YYYY/MM/DD");
  var Weekday = moment.format("dddd");
  
  //HACK:elseifのほうが自然?
  if(Weekday == "Sunday" || Weekday == "Saturday"){
    return false;
  }
  
  var holiday = CalendarApp.getCalendarById("ja.japanese#holiday@group.v.calendar.google.com");//祝日カレンダー
  var date = moment.toDate();//getEventsForDayでDATE形式が必要なため
  var holidayEvent = holiday.getEventsForDay(date);
  
  if(holidayEvent.length > 0){//Googleカレンダーから祝日の有無を確認
    return false;
  }
  return true; 
}

Logger.log(checkHoliday());
```
InfluxDB v1.8: python で接続

こちらで作成したデータベースに python で接続します。
[InfluxDB の cli の使い方](https://qiita.com/ekzemplaro/items/5d77636c07c36d14569f)

```py:influxdb_query.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	influxdb_query.py
#
#						Nov/13/2018
# ------------------------------------------------------------------
import sys
import requests
import json

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
args = {
	"q": 'SELECT * FROM "tochigi"'
	}
url = "http://localhost:8086/query?db=city"
#
rr=requests.get(url,args)
# print(rr.text)
dict_aa = json.loads(rr.text)
# print(dict_aa.keys())
llx = len(dict_aa['results'])
sys.stderr.write("len(dict_aa['results']) = %d\n" % llx)
# print(dict_aa['results'][0])
# print()
# print(dict_aa['results'][0]['series'])
lly = len(dict_aa['results'][0]['series'])
sys.stderr.write("lly = %d\n" % lly)
# print(dict_aa['results'][0]['series'][0])
# print()
array_values = dict_aa['results'][0]['series'][0]['values']
llz = len(array_values)
sys.stderr.write("llz = %d\n" % llz)
print(array_values)
print()
#
for unit in array_values:
	print(unit[0],unit[1],unit[2],unit[3],unit[4])
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./influxdb_query.py 
*** 開始 ***
len(dict_aa['results']) = 1
lly = 1
llz = 3
[['2018-11-13T08:14:33.488107961Z', '2003-8-12', 't0921', '宇都宮', 34981], ['2018-11-13T08:14:39.379152598Z', '2003-7-20', 't0922', '小山', 51982], ['2018-11-13T08:14:44.529336419Z', '2003-9-8', 't0923', '佐野', 75984]]

2018-11-13T08:14:33.488107961Z 2003-8-12 t0921 宇都宮 34981
2018-11-13T08:14:39.379152598Z 2003-7-20 t0922 小山 51982
2018-11-13T08:14:44.529336419Z 2003-9-8 t0923 佐野 75984
*** 終了 ***
```

次のバージョンで確認しました。

```text
$ influx -version
InfluxDB shell version: 1.8.10

$ python --version
Python 3.10.7
```
DataCore セカンダリーIPでiSCSIの性能アップ

OS上でセカンダリーIPを設定することでターゲットポートが追加でき、より多くのポーラー(I/O処理）プロセスを割り当てることができるようになります。その結果、1つの物理パスでより多くのI/Oが処理できるようになるようなのでさっそくやってみましょう。

##前提
**1. 10Gb物理ポートで最大4IPを目処に設定して下さい。**
**2. もし使い切るつもりなら1論理ポート2CPUを基準に割り当てて下さい。**
**3. 1IPあたりの性能上限はCPUクロック次第です。**
例: 56Gb NICなら20IP、40コアを割り振ることで使い切れるらしいです（途方もない数字なので未検証）


##設定
OS上でIPアドレスを追加します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/c1da727b-6eb0-e274-0c23-4581a63dfcf3.png)

Rescan Portsをするとポートが増えました。 （Server iSCSI Port7と8）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/dcd7a743-12a1-cc53-3bf1-92e0be2865db.png)

名前をつけて、FE（フロントエンド＝ターゲット）の役割を割り振りましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/8158e618-8c41-ded7-ee7a-fbf6dd754554.png)

手入力は大変なのでPowerCLIで設定します。
今回は2台x2ポートなので計4ポート分を全ESXiに追加してリスキャンします。

```
Get-vmhost | get-vmhosthba -type iscsi | New-IScsiHbaTarget -Address "10.10.0.13"
Get-vmhost | get-vmhosthba -type iscsi | New-IScsiHbaTarget -Address "10.10.2.13"
Get-vmhost | get-vmhosthba -type iscsi | New-IScsiHbaTarget -Address "10.10.0.14"
Get-vmhost | get-vmhosthba -type iscsi | New-IScsiHbaTarget -Address "10.10.2.14"
Get-VMHost | Get-VMHostStorage -RescanAllHBA
```

GUIで確認してもちゃんと裏で実行されていますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/4c9589fe-23c5-ae93-008b-a9b323a23679.png)

今回は試しに既にあるデータストアにパスを足してみました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/ad9d1cbd-6ff2-7b3f-0bb1-64c72c5e4e29.png)

もう1回リスキャンしておきましょう。

```
Get-VMHost | Get-VMHostStorage -RescanAllHBA
```

パスが4から8に増えました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115778/22f30a32-1d64-5ea9-1cc3-174c43734df8.png)

**実際にはデータストアを8パスにしても意味がないです！IP数に応じてデータストア（vDisk）数を増やしましょう。**
各データコアサーバーがFEを4パス持っているなら、データストアは4個以上を目安にしましょう。

次回は性能検証をしてみます。
Ubuntu で boot 領域が一杯になって autoremove もできなくなったとき

## はじめに
サーバを複数台管理していて，タイトルのような現象がよく起こる．

## 準備
カーネルのバージョンを確認する．

```bash
$ uname -r
4.4.0-119-generic
```

## 実行
上記以外のバージョンについて，ヘッダやイメージ等を削除する．
ここでは `4.4.0-101` の場合を例に示す．

```bash
$ sudo dpkg -r linux-headers-4.4.0-101-generic
$ sudo dpkg -r linux-image-extra-4.4.0-101-generic
$ sudo dpkg -r linux-image-4.4.0-101-generic
```

こんな感じのスクリプトを書くと便利かも…？

```bash:remove.sh
#!/bin/bash

if [ $# -ne 1 ]; then
  echo 'Usage: remove.sh <version>'
  exit 1
fi

dpkg -r linux-headers-$1-generic
dpkg -r linux-image-extra-$1-generic
dpkg -r linux-image-$1-generic
```

## 確認
`autoremove` ができるようになれば OK

```bash
$ sudo apt autoremove
```

## まとめ
こまめに `apt autoremove` しよう！

※上記方法でどうしてもうまくいかない場合， `/boot` の不要なバージョンを手動削除するとなんとかなります．ただし自己責任でお願いします．
rpmをダウンロードだけしたい

# やりたいこと
rpmをダウンロードだけしたい。

# 手順
yumdownloaderをインストール

```
$ sudo yum install yum-utils
```

ダウンロードする。(例としてsubversion)

```
$ yumdownloader subversion
$ ls -1 subversion*
subversion-1.7.14-14.el7.i686.rpm
subversion-1.7.14-14.el7.x86_64.rpm
```

以上。

※取得したrpmの中身を取り出したい場合は以下

```
rpm2cpio ./subversion-1.7.14-14.el7.x86_64.rpm | cpio -id  
```

※取得したrpmをインストールしたい場合は以下。

```
$ sudo yum localinstall ./subversion-1.7.14-14.el7.x86_64.rpm
```
InfluxDB v1.8: cli の使い方

InfluxDB v1.8 の cli の使い方です。

## サーバーのインストール方法


Ubuntu 22.10

```bash
wget https://dl.influxdata.com/influxdb/releases/influxdb_1.8.10_amd64.deb
sudo dpkg -i influxdb_1.8.10_amd64.deb
```

バージョンの確認

```text
$ influx -version
InfluxDB shell version: 1.8.10
```

サーバーの起動

```bash
sudo systemctl start influxdb
```

## cli の　サンプル

```text
$ influx
Connected to http://localhost:8086 version 1.8.10
InfluxDB shell version: 1.8.10
Enter an InfluxQL query
> create database city
> use city
Using database city
> insert tochigi,key=t0921 name="宇都宮",population=34981,date_mod="2003-8-12"
> insert tochigi,key=t0922 name="小山",population=51982,date_mod="2003-7-20"
> insert tochigi,key=t0923 name="佐野",population=75984,date_mod="2003-9-8"
> select * from tochigi
name: tochigi
time                date_mod  key   name population
----                --------  ---   ---- ----------
1542096873488107961 2003-8-12 t0921 宇都宮  34981
1542096879379152598 2003-7-20 t0922 小山   51982
1542096884529336419 2003-9-8  t0923 佐野   75984
> quit
```

time の表示を見やすくするには、
ただし、時刻は UTF です。

```text
$ influx -precision rfc3339
Connected to http://localhost:8086 version 1.8.10
InfluxDB shell version: 1.8.10
> use city
Using database city
> select * from tochigi
name: tochigi
time                           date_mod  key   name population
----                           --------  ---   ---- ----------
2022-12-05T08:12:58.718002103Z 2003-7-20 t0922 小山   51982
2022-12-05T08:13:08.290512976Z 2003-8-12 t0921 宇都宮  34981
2022-12-05T08:13:26.921954067Z 2003-9-8  t0923 佐野   75984
> 
```

よく使うコマンド

```text
show databases
use city
show measurements
```

## API を使ってデータの確認

GET でアクセス

```bash
curl -G 'http://localhost:8086/query?db=city' --data-urlencode 'q=SELECT * FROM "tochigi"' | jq . | less
```

```bash
http 'http://localhost:8086/query?db=city&q=SELECT * FROM "tochigi"'
```


POST でアクセス

```bash
curl -XPOST 'http://localhost:8086/query?db=city' --data-urlencode 'q=SELECT * FROM "tochigi"'  | jq . | less
```

```bash
http --form POST http://localhost:8086/query db=city q='SELECT * FROM "tochigi"'
```

## 参考ページ
[Influx Query Language (InfluxQL) reference](https://docs.influxdata.com/influxdb/v1.8/query_language/spec/)
Pycharmの使用方法(参考にしたページストック)



#Pycharmの使用方法で参考にしたページ

###Jupyter Notebookとの連携やAnaconda仮想環境への対応など
>https://qiita.com/pashango2/items/de342abc10722ed7a569

###Pycharmでの価格やDjangoとの連携など
>https://qiita.com/yamionp/items/f88d50da8d6b548fc44c
uuidによるデバイスのマウント

※ はてなブログから技術ネタを移動しました
※ [初稿](http://qpshinqp.hateblo.jp/entry/20110214/1297698515)：2011-02-14

試行錯誤の後、目標が達成された技術項目についてはTipsというカテゴリーで日記を書くことにする。

id:qpSHiNqp:20110214:1297651801 の最後の方にちょっと書いたが、UUIDを用いてデバイスをマウントする設定法をメモしておく。


UUIDを用いてfstabを記述することで、デバイスの接続順に関わらず(≒/dev/sd*の*の部分に関わらず)、任意のデバイスを任意のマウントポイントにマウントすることができる。

たとえば、USBメモリその1とUSBメモリその2があるとする。/dev/sda, /dev/sdbといったデバイス・ファイル名はUSBメモリの接続順に影響を受けるが、UUIDを使うと接続順に関係なくUSBメモリその1を/mnt/usb1, USBメモリその2を/mnt/usb2にひと通りにマウントするということができるということ。

これはUUIDの特性によるものだ。

>自分の機器を管理・識別するために使える−−。そんな不思議なIDが「UUID」（universally unique identifier）です。日本語では「汎用一意識別子」などと訳しますが，実際にこちらを使うことはまずありません。
http://itpro.nikkeibp.co.jp/article/Keyword/20090206/324330/

つまり、特定のデバイスをUUIDで指定して、それをどのマウントポイントにマウントするかという指定をfstabに書くことができるのだ。

UUIDを使ったfstabの書式は以下である

```
#                
UUID=7AAE-3D22	/mnt/usb	vfat	defaults	0	0
UUID=a6855e1f-dde5-4322-b671-84d46ab24ce6	/mnt/backup2T	ext4	defaults	0	0
```
普段の/dev/sdaとかの部分がUUID=hogehogeに置き換わっただけである。


デバイスのUUIDの調べ方は、

>先駆者様を探したら、blkidを使った事がある人いた。真似して、恐る恐る

>```shell-session
sudo blkid /dev/sda1 
```
と打ったら、

>```shell-session
/dev/sda1: UUID="0xxxxxxxxxxxxx" LABEL="Local" TYPE="ntfs" 
```
>とでた。(ノ´▽｀)ノオオオオッ♪
http://ankyo.blog.so-net.ne.jp/2010-01-26

ということらしいです。

```shell-session
# sudo vim /etc/fstab [Enter] 
```
として上記のfstabの書式に従い追記し、

```shell-session
# sudo mount -a　
```
とすると、ちゃんとマウントされます。

UUIDの調べ方については、

>最初調べたときにvol_idというコマンドでUUIDがわかるって書いてあったのにDebianにもUbuntuにもそんなコマンドなくて驚愕したけど

>```shell-session
ls -l /dev/disk/by-uuid/ | grep sda1 
```
とか

>```shell-session
sudo tune2fs -l /dev/sda1 | grep UUID 
```
とか

>```shell-session
sudo blkid /dev/sda1 
```
とか、あらゆる方法でUUIDを調べることができるのであった。
http://d.hatena.ne.jp/kamipo/20101107/1289137788

こんなのもあるようで。
centOS7x64にvim8.1+lua+pythonプラグイン環境を構築するぞ

# 2019/6/14 追記
> [Vim or NeoVimを使っている人は、すぐにアップデートしましょう CVE-2019-12735](https://qiita.com/syui/items/da358d56cb2faf6560c9)

`vim --version`の結果、適用済みパッチが`1-1365`以下の場合、vimリモート機能を悪用した脆弱性があるようです。記事を書いているときのバージョンは`1-1525`でした。ちゃちゃっとアップデートしておきましょう。

# 標準vimはあかんねん

標準で入っている`vim`はバージョンが`7.4`と古く`lua`や`python`とも連携していないため、`vim`の便利なpluginが使えません。
今回はタイトル通り、*centOS7*環境に**vim8.1+lua+python3.6**環境を作っていきたいと思います。[^1]
[^1]: とりあえず過去のコマンドを見ながら思い出しつつ書いているので、間違っていたらどんどん教えてください。

## やること

1. 後の作業に必要なパッケージ群やリポジトリのインストール
1. 標準vimの削除
1. python3.6のインストール


# 前提パッケージ、リポジトリ準備

```bash
sudo yum install https://centos7.iuscommunity.org/ius-release.rpm
sudo yum install openssl-devel readline-devel zlib-devel 
```

# perlのインストール

vimのコンパイル時にこれが無いとエラります

```bash
sudo yum install perl-ExtUtils-Embed
```

# luaのインストール

```bash
sudo yum install lua-devel ncurses-devel
```

# rubyのインストール

もとから入っているやつは化石みたいなバージョンなので、最新版を入れましょう

```bash
cd /tmp
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
rbenv -v
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
sudo ~/.rbenv/plugins/ruby-build/install.sh
rbenv install -l
rbenv install 2.5.3
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
rbenv global 2.5.3
ruby -v
```

# python3.6のインストール

```bash
sudo yum install python-devel python36u python36u-libs python36u-devel python36u-pip
```
# vim-enhancedの削除

vim-commonとか入っているかもしれないけど、`vim-enhanced`だけ削除すればよろしい

```bash
sudo yum list installed | grep vim
sudo yum remove vim-enhanced
```

# vim8.1のインストール

###### make installする前に、lua, python, rubyが'+'になっているかを確認すること!!

![vim.jpg](https://qiita-image-store.s3.amazonaws.com/0/246065/06fd5735-d5f3-1318-cb62-1abc3519f54a.jpeg)

```bash
cd /tmp
git clone https://github.com/vim/vim
cd vim

sudo ./configure \
    --enable-fail-if-missing \
    --with-features=huge \
    --disable-selinux \
    --enable-luainterp \
    --enable-perlinterp \
    --enable-pythoninterp=dynamic \
    --with-python-config-dir=/usr/lib64/python2.7/config \
    --enable-python3interp=dynamic \
    --with-python3-config-dir=/usr/lib64/python3.6/config-3.6m-x86_64-linux-gnu \
    --enable-rubyinterp=dynamic \
    --with-ruby-command=/home/'あなたのユーザ名'/.rbenv/shims/ruby \
    --enable-cscope \
    --enable-fontset \
    --enable-multibyte \
    vi_cv_path_python3=/usr/bin/python3.6

sudo make 

# ↓↓↓make installする前に、lua, python, rubyが'+'になっているかを確認すること↓↓↓
./src/vim --version
# ↑↑↑make installする前に、lua, python, rubyが'+'になっているかを確認すること↑↑↑

sudo make install
```

つつがなく終わったら、`vim --version`で確認。画像の通りになっていますか？`- lua`にとかになっていたら失敗しているので、もう一度やりましょう...

# 終わりに

ビルドに失敗したら、以下のコマンドで全てをなかったことにしましょう

```bash
sudo rm -rf /usr/bin/vim
sudo rm -rf /usr/local/share/vim
cd /tmp/vim/src
sudo make distclean
```
新人がProgateでプログラミングを勉強してみました

###この記事を書いている人について
IT未経験で入社した１年目の新人です。
学生時代はゴリゴリの文系で、プログラミングに触れる機会はほとんどありませんでした。
入社後2ヶ月間の研修を受けて、その中ではJavaとSQLがおもしろかったなーと思っていたら
ラッキーなことにJavaメインのチームに配属されました。ヤッター
でも最近はSQLとにらめっこしてることが多いです。

###Progateを使ってみた
社内の新人向け勉強会でProgateを使ったので、今日はその感想をまとめます。
あくまで個人的な感想なので、同じサービスを使ってもまったく違う感想になる方も
いらっしゃるかと思いますがあしからず。

![Main_RGB.png](https://qiita-image-store.s3.amazonaws.com/0/315237/09dd5462-37d6-1f65-af85-483c029b3950.png)
https://prog-8.com/
>Progateはオンラインプログラミング学習サービスです。「初心者から、創れる人を生み出す」ことが、私たちの理念です。プログラミング初心者のハードルを出来る限り取り払うこと、そして本当に創れるようになるレベルの高い学習を提供することを目指しています。(公式HPの説明より引用)

無料会員と有料会員があり、有料会員は全レッスンが受講可能です。
(無料だと初級レッスンのみの制限アリ)
この記事は有料会員としてProgateを使った感想になります。

現在のコース消化率は
HTML&CSS 61%
Java 100%
Command 100%
Git 100%
SQL 100%
といった具合です。
上記にないコースには手を付けていません。

学習に使ったのはPC版がメインで、アプリ版はどういうものか少し触ってみた程度です。
(アプリ版のほうがより初心者向けとのことです)
以下の感想はPC版に基づくものです。

![Progate_image.png](https://qiita-image-store.s3.amazonaws.com/0/315237/d9573e6f-b350-f84c-3d0b-6c7004410684.png)


##Javaコース
#####良かった点
Javaコースに限ったことではないんですが、スライドが簡潔＋図解が多いのでわかりやすかったです。
どのコースも
-スライドを読む
-演習
の流れなので、覚えたこと・理解したことをすぐに演習で使って確かめられました。

また、通常のレッスンの合間に「道場」という、それまでのレッスンの総まとめ演習がありました。
Javaの道場の演習内容は通常レッスンで行った演習とほとんど同じなので
通常レッスンから一気に進めずに少し日をおいてからやった方が知識の定着の確認になるのかなと思います。

#####微妙だった点
演習はコードについての指示が細かく「何を作ればいいのか」が分かりやすい反面
「どうやったら思い通りに動くのか？」を考える練習にはあまりならないように感じます。
結構はしょられている説明も多いので(例外とかについては触れられません)、
これひとつでJavaがある程度できるようになるというよりは、プログラミング未経験者の
「Javaってよくわからん…………」という苦手意識をなくす効果のほうが大きいかも？

学習の入口としてはとても良かったなあと思います。
もっと勉強してみようって気持ちになりました。

##SQLコース
#####良かった点
もともとSQLに興味があったのもありますが、単純に面白かったです。

説明や演習の場面設定が想像しやすかったので
「何を目的に、どんな場面でこの関数を使うのか」ということの理解の助けになりました。
場面設定というのは、たとえば売上記録のテーブルと顧客情報のテーブルがあって
女性に人気の商品を調べたい、だとかそういった感じでした。

#####微妙だった点
特に思いつかないです。
強いて言えば道場が少し難しかったかも？
こちらの道場はJavaと比べて「自分で考える」ことにウエイトを置いている印象です。
正解のSQLについて解説があればなお良かったなあと思います。
(合ってるか自信がないけどとりあえず試してみたら正解だった、なんてことがあったので…………)

##HTML&CSSコース
#####良かった点
(最後まで受講していないのに感想書くのも気がひけるんですが…………)
お手本のWebページがかわいくてやる気になりました！笑
こういうの作れるようになりたいな、と思いながら勉強すると心なしか色々と覚えやすいように感じます。
説明も過不足無くてちょうどいい感じでした。

#####微妙だった点
Javaと被るんですが指示が細かすぎる点がやっぱり微妙でした。
たとえばCSSで文字サイズを指定したいときに「font-sizeを10pxにしてください」と指示があると
「文字サイズを変えるには何を指定すればいいんだっけ」みたいなことを考える機会を逃しているような？気がします。
まあそれは後々自分で勉強するときにやればいいとも思うので不満ってほどではないです。

###まとめ
総合すると満足度90％という感じでしょうか。
「もっと〇〇だったらいいのになあ」がないわけでありませんが、全体的に説明がわかりやすく
基礎的な部分をさらうにはぴったりでした。
自分で書けるようになるにはまだまだ勉強していかないといけないけれど
その勉強に取り掛かるハードルを下げてくれたように感じます。
自分のような未経験でIT系に入った人にはおすすめです。
今年中にHTML&CSSコースを完走できたらいいな…………。
@IBDesignableでstoryboardが壊れる

メモ。

## こうなる......
@IBDesignableでAttributeインスペクターから
textFieldのボーダー指定などの編集項目を追加してた。
そしたらいつの間にか__お亡くなり__になった。
![スクリーンショット 2018-11-13 16.13.45.png](https://qiita-image-store.s3.amazonaws.com/0/233386/835d7eb1-020b-3b30-3a0f-212d8aef60f7.png)

## 原因探し
クラッシュしたわけではないけどログを確認。。とりあえずログを確認。
/Users/ユーザー名/library/Logs/DiagnosticReports/
IBDesignablesAgent-iOS_2018-11-12-173509_mopiemon.crash

```
error: Use of unimplemented initializer 'init(frame:)' for class 'プロジェクト.MaterialTextField' 
```
とのこと。

## 解決策

@IBDesignableのクラスに

```swift
    override init(frame: CGRect) {
        super.init(frame: frame)
        awakeFromNib()
    }
```
これ追加で復活。
requireとかなかったけどinit(frame: CGRect)が必要なことはどこで確認すればいいんだ。




慣れてないのでツッコミくださると嬉しいです😇
日付、日時の正規表現についてまとめ(基礎知識・正規表現例)

# まえがき
* PHP、JavaScriptで判定  
( 正規表現チェッカーを使用  
 http://okumocchi.jp/php/re.php)
* 正規表現について、どうしても苦手意識があり、  
  調べて出てくる多数の正規表現サンプルを見ても、  
やはり書くのに時間がかかってしまう...理解ができない...  
といったことがあったので、今後忘れないようにメモとして書かせて頂きます。
* **「正しい形式しか許容しない」**というのが前提になっております。

## 例(単体使用)
* 「Y/m/d」ex).2018/01/01
* `^`→開始
* `$`→終了
* `[0-9]`→0~9の数字
* 「`/`」の前にバックスラッシュが必要
*  { }の中に、数字の桁数を指定  
* 年は西暦のため、4文字→`{4}`  
時間、分は2文字→`{2}`  
(`+`(1回以上)だと2018/01/111111も許容してしまう  
先頭の0を表示しない場合は、1文字以上2文字以下となるため`{1,2}`)

```
/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/
```

* 「h:i」 ex).02:11

```
/^[0-9]{2}:[0-9]{2}$/
```

* 「Y/m/d - Y/m/d」（範囲指定）ex).2018/01/01 - 2018/01/02
* `\s`→空白文字

```
/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}\s-\s[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/
```

##例(組み合わせ)
* 「Y/m/d - Y/m/d」、「Y/m/d h:i」、「Y/m/d」を許容する
* 「- Y/m/d」と「h:i」を`()?`でくくる
* `?`→0回か1回
* `「|」`→OR表現(「Y/m/d - Y/m/d h:i」を許容しないため)

```
/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}(\s-\s[0-9]{4}\/[0-9]{2}\/[0-9]{2}|\s[0-9]{2}:[0-9]{2})?$/
```
---

どうしても正規表現ってごちゃごちゃ文字が並んでいるイメージを抱いてしまい、 
見た瞬間に思考が停止してしまいがちです。
ですが、簡単な表現を最初に書いて、([0-9]など、ぱっと見で意味が理解できる箇所)
正規表現チェッカーでその都度、動作確認をしていきながら書いていくのが
一番効率的だと漸く気がつけました。

参考リンク
https://javascript.programmer-reference.com/js-regexp-sample/
https://www.megasoft.co.jp/mifes/seiki/meta.html
https://www.sejuku.net/blog/22396
wordpress・SES経由でメールを送信できるようにする


# WP Mail SMTPというWordPressプラグインを使う



- プラグイン ＞ 新規追加から検索し、インストール→有効化まで。


# Amazon SESのSMTPサーバーを使う

SESで送信アドレスの認証
SES（Simple Email Service）
リージョンは、

- 米国東部
- 米国西部
- EU（アイルランド）

まず、SES経由で送信したいメールの、
「送信元アドレス」をSESに登録して認証する必要があります。
サイドバーのEmail Addressesから「Verify a New Email Address」ボタンをクリック。

![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092558673_Screenshot-2017-10-09-16.41.45.jpg)


ここで、「送信元アドレス」として使いたいメールアドレスを入力します。



![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092598340_Screenshot-2017-10-09-16.43.28-768x331.jpg)



入力して「Verify This Email Address」をクリックすると、
認証メールが飛んできます。
メール本文内のリンクをクリックして認証完了しましょう。

![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092626301_Screenshot-2017-10-09-16.44.43.jpg)



こんな感じでverifiedになってたらOKです。

次に、また左のサイドバーからSMTP Settingsをクリックし、
Create My SMTP Credentialのボタンを押します。


![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092729425_Screenshot-2017-10-08-20.17.26.jpg)


次に、IAM作成画面へ移行します。
そのまま右下の「作成」をクリック。

![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092765874_Screenshot-2017-10-08-20.17.38-768x340.jpg)


するとIAMユーザが作成されました。
CSVが出力されるので、

- SMTPユーザー名
- SMTPパスワード

をメモっときましょう。

IAM User : xxxxxx
Smtp User : xxxxxxxxxxx
Smtp Password : xxxxxxxxxxxxxxxxxxx


これでAWS側の設定は完了です。



# WP Mail SMTPの設定

次に、WordPressにインストールしたWP Mail SMTPの設定を行います。

SESのSMTP Settingに

- Server Name
- Port

を設定します。


![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542093440348_.001.jpeg)






# WordPress WP-SMTP
![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542095397726_.001.jpeg)



# テストメール送信


![](https://d2mxuefqeaa7sj.cloudfront.net/s_601916EF644F8A72033EA6E0C7D63E373B011C16A066E35519D0A5009AB60E62_1542092964452_Screenshot-2017-10-09-16.50.44-768x205.jpg)


受信できたら成功です。
CircleCI 2.0 導入覚え書き

# はじめに
CircleCIとdockerを使用して環境構築をしようと思ったものの
どこから手をつけていいのかわからなかったのでメモしながら進めます。

# そもそもCIとは？
CIとは Continuous Integration ＝ 継続的インテグレーションの略で、プログラムの品質を常に高く保つための**習慣**のこと。
以下Wikipediaからの引用です。

>**継続的インテグレーション、CI**（英: continuous integration）とは、主にプログラマーのアプリケーション作成時の品質改善や納期の短縮のための習慣のことである。エクストリーム・プログラミング (XP) のプラクティスの一つで、狭義にはビルドやテスト、インスペクションなどを継続的に実行していくことを意味する[1]。
>引用元：[Wikipedia](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

つまるところ、テストを自動化してチーム間で共有できるようにして、バグを早期に発見できるようにしておこう、ということ。

これを簡単にするためのものが **CIサービス** と呼ばれるサービス群であり、CircleCIはそのひとつ。

# CircleCIの導入

ここからは[公式のdocs](https://circleci.com/docs/2.0/getting-started/#section=getting-started)に沿ってやっていきます。

## 前準備

- Githubアカウントの準備
- CircleCIアカウントの取得（Githubを連携させるだけで済むので割愛） 

## 流れ

1. 新規リポジトリの作成
2. configファイル(config.yml)の作成
3. CircleCI上でプロジェクト（＝githubリポジトリ）をビルド

### 新規リポジトリの作成

公式docsにならいcircleci-101という名前で作成します。
101というのは入門科目という意味です。ワンちゃんじゃないです。

### configファイルの作成

プロジェクトディレクトリに
.circleci/config.yml というファイルを作成。

``` .circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.4.1
    steps:
      - checkout
      - run: echo "A first hello"
```

最初なので非常にシンプルな内容です。
dockerのイメージを使用しているのがわかります（後述）。

### ビルド

CircleCIのappページ（コンパネ）に行き、左側のタブからADD PROJECTSを選択します。
https://circleci.com/add-projects/gh/username

すると連携させたGitHubのリポジトリが一覧で表示されますので、さきほどのcircleci-101リポジトリを見つけて右側にある"Set Up Project"ボタンを選択。

![screenshot01](https://qiita-image-store.s3.amazonaws.com/0/300822/a8fb6899-1549-ac8f-eb76-0a66cbb40093.png)

選択された状態が上です。

次の画面で詳細を設定します。

![screenshot02](https://qiita-image-store.s3.amazonaws.com/0/300822/65930e12-a698-bc14-62a2-85aaf239636b.png)

言語選択がありますが、config.ymlの内容を案内してくれるだけですので、書けていればそのままで問題ないです。

下までスクロールして start building のボタンを押します。

左のタブでJobsを選択すると、タスク一覧が出てきます。
左側が緑色のsuccessになっていれば成功です。
（エラーが出る場合は、config.ymlに書き間違えが無いか確認しましょう）

これでCircleCIでのビルドができました。
あとはこのリポジトリにコミットするだけで自動的に再ビルドしてくれます。

## 余談）docker imageの使用について

使用するdocker imageですが、公式のimageにCirecleCI向け機能を追加したものなので、できるだけここからビルドするのが望ましいそうです。
https://circleci.com/docs/2.0/circleci-images/

このへんは調べつつ後で追記します。

## メモ
YAML - [Learn X in Y minutes](https://learnxinyminutes.com/docs/yaml/)
docker-composeの使用 [Installing and Using docker-compose](https://circleci.com/docs/2.0/docker-compose/#section=configuration)　※pre-build imagesなら既に含まれている
embulk-output-bigquery プラグインがBroken Pipe時にリトライされなかったのでアドホック対応してしまった。

## Embulkとは

embulkはバッチ処理でデータのインプットから加工、出力を行うツール。
プラグインが多数作られており様々な入力、様々な加工、様々な出力を行うことができる。
たとえば入出力はDBだったりファイルだったりS3等のストレージや外部DBサービスも利用できる。

`embulk-output-bibquery`は出力を担当するプラグインで、名前の通りbigqueryへの一貫した出力を行うことができる。
bigqueryへの出力時はデータを一度Google Cloud Storageに配置してからbigqueryへのロードが行われているが、詳細はソースを読むべきです( https://github.com/embulk/embulk-output-bigquery )。

## リトライされない問題
ソースコードを読むと、Broken pipeによるネットワーク切断はリトライ対象となっており設定に指定した回数までは異常終了されずにリトライするはずであったが、現システムにおいて何故かリトライされずに異常終了となってしまっていた。週2,3のペースで。
(そもそもほぼ毎晩処理中にBroken pipeが発生する環境もよくないのだが)


Broken pipeはファイアーウォールによる切断でリトライすれば成功する可能性の高いものなので通常はリトライされるべきです。ということでちょっと詳細に調査していきました。

## 問題点
### ソースコード
https://github.com/embulk/embulk-output-bigquery/blob/master/lib/embulk/output/bigquery/google_client.rb#L84

```ruby
if ['Broken pipe', 'Connection reset', 'Connection timed out'].include?(e.message)
```

上記にマッチした場合にリトライされるようになっている。

### システム状況

```
e.message -> 'Broken pipe (Write failed)'
```

要するにエラーメッセージで判断しようとしているけど、Broken pipeなのに予期していないメッセージなので文字列マッチでリトライ対象に判断されなくなっている。

### ちなみに

ruby久々過ぎてちゃんと調べたことを書いておく。

```ruby
if ['Broken pipe', 'Connection reset', 'Connection timed out'].include?(e.message)
```
これは配列に対する include? メソッドになっていて、 「配列の要素に引数が含まれているか」を判断しているため、文字列は完全一致で判断される。
文字列に対する include? メソッドは「文字列に引数の文字列が含まれているか」なので部分一致。

## 修正内容

```ruby
if ['broken pipe', 'connection reset', 'connection timed out'].any? {|item| e.message.downcase.include?(item)}
```
あくまでリトライの判断でクリティカルな処理ではないので、広めに判断できるようにしてみた。
any? は配列の要素それぞれに続く `{}` ブロックの処理を行い、いずれかが `true` なら `true` を返す。
大文字小文字もゆるく判断してくれる方が都合がいいので小文字にととのえてe.messageにもdowncase。

この対応でちゃんと `Broken pipe (Write failed)` エラーに対してリトライされるようになりました。

### ただし

こういった外部ライブラリの修正は `embulk gem install` したモジュールに手を加えているので本来ならバッドパターンです。
なぜプルリク送らなかったの？と言われれば、環境依存ぽく、Java側まで見に行く余裕がなかったので・・・・
oracledb(npm package)でエラー

## NJS-054が発生してyarn add出来ない
### 前提
windows7 + nodist + oracledb

### 結果
- node-oracledbはNodeのバージョンに依存したバイナリを生成する
- nodistでバージョン変更すると動かなくなる
- yarn add oracledb を __管理者権限のPowerShellで__ 実行することでバイナリが再生成される

ずっとコマンドプロンプトで試していて、嵌ったのでメモ
ここ最近便利だと思ったもの（2012-05-29版）

※ はてなブログから技術ネタを移動しました
※ [初稿](http://qpshinqp.hateblo.jp/entry/20120529/1338297310)：2012-05-29

### Visitors

まぁ、Google Analyticsとかでもアクセス解析はできるんですけど、ローカルでちょちょっと解析したい時に。

Ubuntuなら

```shell-session
sudo aptitude install visitors
```
でインストールできて、

```shell-session
visitors -A -m 30 access.log -o html > report.html
```
で生成したファイルをブラウザに放り込むだけ。1時間あたりのアクセスとかがさくっと出せていいです。

ここに書いてありました。

- [Apacheのアクセスログを解析するフリーソフト4種 - ぼくんちのTV 別館](http://freesoft.tvbok.com/freesoft/web/apachelogviewer.html)
- [Visitors - fast web log analyzer](http://www.hping.org/visitors/index_jp.php)

### iPhoneのホームボタンが効かなくなったときに...

1. 電源ボタンを長押しして、電源を切るスライドを表示させる
2. ホームボタンを「いつもの強さで」長押しし続ける
3. スライドが消えたら、完了
恐らく、この2の操作でホームボタン押下の強度キャリブレーションを行っているようです。

ここに書いてありました

- [iPhoneのホームボタンの効きが悪くなったら - Qiita](http://qiita.com/items/50206cd856225d46952d)

### openx - 広告配信システム

これをサーバーにインストールすると、広告配信ができます。なんかちょっと複雑なので説明するのはめんどくさい。

ここに書いてありました

- [OpenX （Openads） 広告配信までの流れ ～ 【広告主】 と 【キャンペーン】](http://safe-linux.homeip.net/web/OpenX/openx-05.html)

他にもいろいろ便利だと思ったものはありますが、またの機会に。
WIP: プログラマだから分かった気になれる総和(Σ)

```math
\sum
```

「総和」というと高校の数学で教わったなぁ程度の記憶しかなく、Σ(sigma)記号は印象的だったけれど、当時はまったく理解できませんでした。

総和って一体何者だったんでしょうか？プログラマ視点で学び直してみたいと思います。

理解不足もあるため数学に詳しい人が見たら、「分かってねーな」「全然ちげーよ」「JSかよ！」などとブコメを頂きそうですが、ご指導いただける場合はコメントいただけると嬉しいです。

## 総和とは

まず、総和ってなんでしょうか？

Wikipedia日本語版によれば、

> 数学において、総和（そうわ、summation）とは与えられた数を総じて加えることである。

とのことです。

「与えられた数を総じて加える」
「与えられた数を総じて加える」
「与えられた数を総じて加える」

お分りいただけだただろうか？

・・・

うーん、50％くらい・・・。

プログラマの僕としては、英語版Wikipediaの方がわかりやすかったです。

> In mathematics, summation (symbol: ∑) is the addition of a sequence of numbers; the result is their sum or total.

「sequence of numbers」と書いてあるので、数字の配列か、ふむふむ。計算結果はその「sum」になるそうなので、数字配列の合計値のことを総和というのね、とスッと入ってきました。

## Σという記号

日本で生まれ育って、普段の生活でひらがな・カタカナ・漢字・ローマ字・算用数字くらいしか馴染みのない僕にとって、いきなりシグマと言われても、Σ(･口･)!?っとなります。なぜ、総和はΣという記号を使うのでしょうか？

総和は英語でsummationです。Σはギリシャ文字。ローマ字ではSに対応しています[^翻字について]。「Σは`summation`の頭文字か、なるほど」と思うと覚えやすいです。

そもそも、なぜ数学はギリシャ文字なんか使うんでしょうね。文字のバリエーションを考えても表現力としてはローマ字とあまり変わらない気がしますが・・・。

> **ギリシャ文字をなぜ使うのか**
> ギリシャ文字を使うメリットです。
> ・数式を見ただけで何を表しているか分かりやすい
> ・ギリシャ文字を使わないと記号が足りない
> \- [数学と物理におけるギリシャ文字の使い方一覧 | 高校数学の美しい物語](http://mathtrain.jp/greek)

数学がギリシャ文字を使う理由は、ヨーロッパで数学が育ってきた背景があって、ヨーロッパの人々は古典としてギリシャ語に親しんでいて、ローマ字だけでは文字数が足りないので、ギリシャ文字も使ったという経緯があるのかもしれませんね。

昨今のプログラミング言語なら、変数名や関数名のシンボルは単語が使えますし、エディタの補完機能もあるので書くのも苦労しないので、ローマ字だけで式を書けますが、数学が発展してきた当時は手書きですし、文字数を増やす代わりに記号の種類を増やすというのは合理的だと思います。

もしヨーロッパの人々が、ギリシャ語ではなく中国語古典の方に親しみを持っていたら、総和はこうなっていたかもしれませんねw


```math
\underset{i=m}{\overset{n}{\huge 和}}
```


## 総和のHello World

```math
\sum_{i=1}^{5} i= 1 + 2 + 3 + 4 + 5 = 15
```

多分これが一番具体的な式だと思います。シグマの上に5があり、下には`i=1`があります。これだけでもなんとなくわかると思いますが、これと同じ計算結果になるコードをプログラムで書いてみると、シグマの上下の式がなんなのかもっとはっきりします。

```php:PHP
$i = 1;
array_sum(range($i, 5)); // 15
```

```scala:Scala
val i = 1
(i to 5).sum // 15
(i to 5).reduce { (sum, n) => sum + n } // 15
```

```js:JavaScript(ES6)
function range(from, to) {
  let nums = [];
  for (let i = from; i <= to; i++) {
    nums.push(i);
  }
  return nums;
}

Array.prototype.sum = function () {
  return this.reduce((a, b) => a + b);
};

const i = 1;
range(i, 10).sum(); // 15
```

このコードを見ると、シグマの上は配列の個数で、下は配列の最小値であるように思えます。

もう少し違った総和の式も見てみます。

```math
\sum_{i=3}^{6} i^2= 3^2 + 4^2 + 5^2 + 6^2 = 86
```

```php:PHP
array_sum(array_map(function($a) {
  return pow($a, 2);
}, range(3, 6))); // 86
```

```scala:Scala
(3 to 6).map(a => Math.pow(a, 2)).sum // 86
```

```js:JavaScript(ES6)
range(3, 6).map(a => a ** 2).sum(); // 86
```

・・・

もう少し複雑な数式も説明したかったが、時間がなくなったので続きはまたいつか。つづく…？


[^翻字について]: ギリシャ文字からローマ字への翻字については『[Romanization of Greek - Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Romanization_of_Greek#Modern_Greek)』参照
rubyでzipファイルを展開する方法

```ruby:filename.rb
require 'zip'
require 'fileutils'
require 'byebug'

dest = 'out/'

Zip::File.open('sample.zip') do |zip|#zipファイル開く
  zip.each do |entry|#その中身をentryにひとつずつ渡してゆく
      byebug
    p entry.name#zipファイルの中に入っているファイルの名前（フォルダ名/ファイル名の形式）
        dir = File.join(dest, File.dirname(entry.name))#File.dirname(entry.name)でディレクトリの名前を取得。destと結合
        FileUtils.mkpath(dir)#dir=out/sampleというフォルダを作成
    zip.extract(entry, dest + entry.name) { true }#entryをdest + entry.nameに格納する
  end
end

```


ポイントは

```ruby:qiita.rb

dir = File.join(dest, File.dirname(entry.name))#File.dirname(entry.name)でディレクトリの名前を取得。destと結合
FileUtils.mkpath(dir)#dir=out/sampleというフォルダを作成
```
ここで、先にフォルダを作成してしまうこと。
これがないと、「そのようなディレクトリは見つかりません」エラーがでてしまうことがある
IBM CloudのNode-REDで追加ノードの導入手順

# はじめに
IBM Cloud上のNode-REDで、追加ノードの導入がいつの間にかUIでできるようになっていたので、その手順をメモしておきます。

# 前提
IBM Cloud上でNode-REDが動くようになっていること。
手順については [IBM LiteアカウントでNode-REDインスタンスを作成する](https://qiita.com/makaishi2/items/ed9d4412331d7d65fde5) 等を参考にして下さい。

# 手順
* Node-REDの編集画面で右上のメニューをクリック
* ドロップダウンで「Manage Pallete」を選択

![スクリーンショット 2018-11-13 15.51.11.png](https://qiita-image-store.s3.amazonaws.com/0/206130/e75cb140-3d68-9fc7-5b55-37f3d045daf0.png)


* 下の画面が表示されたら、「Install」タブを選択
* 検索画面で導入したいノード名を入力
* 導入したいノードを選択後「Install」ボタンをクリック

![スクリーンショット 2018-11-13 15.52.16.png](https://qiita-image-store.s3.amazonaws.com/0/206130/d5568018-285b-1a85-afb3-a25b739ad9e6.png)

* 下の画面が表示されたら、一番右の「Install」ボタンをクリック

![スクリーンショット 2018-11-13 15.52.30.png](https://qiita-image-store.s3.amazonaws.com/0/206130/bfdacc2f-38de-0089-7577-a40eece874ea.png)

あとは導入完了を待つだけです。新しいノードはリブートなしにすぐに使えるようになっています。

![スクリーンショット 2018-11-13 16.22.21.png](https://qiita-image-store.s3.amazonaws.com/0/206130/f3d8acf3-1aec-82a3-8b2b-741413b2bf80.png)
イベントソーシングでイベントを変更/削除する必要がある場合の対処

本稿ではイベントストアを改変せずに、イベントストアに蓄積したデータを削除するひとつの実験的なアイディアを紹介する。

イベントソーシングは原則、イベントを変更・削除してはならない。Aggregateを削除するようなコマンドも、イベントストア上では「削除しましたイベント」が追加される。要するに論理削除のような状態になる。

## どうしても削除が必要なケース

しかし、ある状況下ではこの原則を破らないといけないことがある。ユーザからの個人情報削除要請があった場合だ。日本の個人情報保護法では、正しく個人情報を扱っている事業者には、個人情報削除の義務は課せられていないものの[^1]、何らかの業務上の理由で削除しなければならないことがあるかもしれない。

このようなケースでは、イベントストアに「個人情報を削除した」イベントを追加するだけでは、イベントストア上に依然として情報が残っており問題となりうる。

## イベントストアから情報を削除する方法

### 物理削除


イベントをストアから削除してしまう。なかったことにする。


### ダミーへの置き換え

イベントを書き換えて、内容を無害なものにする。たとえば、クレジットカード番号なら「0000-0000-0000-0000」といった無意味なものにするとか。

これらどちらもイベントストア自体を改変することになる。

## イベントストア自体を改変せずに削除する方法

イベントストア自体を改変せずに削除する方法のひとつのアイディアとして、暗号消去(Cryptographic Erase;CE)は検討に値する。暗号消去とは、暗号化されたデータを直接削除する代わりに、データを複合するための暗号鍵を削除することで、データを消去したとみなす方法。NISTが定めたデータの消去方法のガイドライン[Guidelines for Media Sanitization](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-88r1.pdf)にも取り上げらてている。

イベントストアでCEを実施する前提として下記に注意する。

* 暗号鍵が適切に管理されていること。破棄した鍵が、他のデバイスやストレージに鍵が残っていたらダメ。
* 十分な暗号化アルゴリズムが用いられていること。
* イベントストアのデータが既に暗号化済みであること。

したがって、消去が必要なイベントが既に平文で蓄積された状態では手遅れであり、予めCEを導入しておく必要がある。

## イベントストアでCEするメリット

* 後でイベントを改ざんしなくて済む
* 鍵さえ消去すればいいので、イベントの特定の手間が無く、特定漏れによる消去未実施のリスクが少ない

## イベントストアでCEするデメリット

* 鍵の管理を徹底しないとならない

## イベントストアでのCEの対応方法

データの消去の単位を決める必要がある。ユーザごとなのか、Streamごとなのか、フィールドごとなのか。これによって発行する鍵の数が変わってくる。

データ消去単位を決めたら、その単位ごとに鍵を発行する。例えば、個人情報は最小の単位としてユーザごとに消去要請がありえる。この場合、ユーザアカウントごとに1つずつ固有の鍵を作ることになる。

次に、イベントの中身に着目する。イベントの属性の中で、消去要請後も保持していい属性とそうでない属性を決める。消去が必須の属性は、暗号化してイベントに持たせるようにする。イベントまるごと暗号化してしまうと、鍵消去後にそのイベント自体を再生できなくなってしまうので、属性ごとの暗号化が望ましい。また、鍵が特定できるよう、フィールドやイベントのメタデータ等に鍵名を入れておくようにする。

```js
// 平文イベント
{"user_id": 123, "name": "田中 太郎"}

// 暗号イベント(鍵名 $ 暗号化データ という書式にする)
{"user_id": 123, "name": "user0001.key$U2FsdGVkX19KkrXKIx2TQ61W0ZVkLT3uzxYYPFLLQOI="}
```

イベントをストアから取り出す際は、鍵を使い各暗号化属性を復号するようにする。鍵は消去済みかもしれないので、復号出来ない場合はダミーのデータに置き換える処理は必要になる。ダミーのデータは、ドメインモデルやQuery Modelに影響しないような無害で無意味なものを採用する。

## CEの実施

いざ、CEを実施するとなったら、まずは鍵を完全に破棄する。もし、Query Model等の写像データに削除したいデータが残っている場合は、イベントストアに削除イベントを追加した上で、Query Modelにそれを処理させるか、Query Modelを消去して、イベントを再生する必要もある。

## 雑感

* それでもイベントストアは改変しないほうがいいと思う。してはならないとも言える。
* どうしても改変が必要な場合は、CEを検討できるかもしれない。
* CEにすると、イベントストア単体ではQuery Model等を作れなくなるデメリットはある。
* CEは鍵の管理が大変そう。

[^1]: [個人情報を削除してもらう方法はありますか - 弁護士ドットコム](https://www.bengo4.com/internet/1069/1182/b_187372/)
[^2]: [マイナンバーガイドライン入門](https://www.keidanren.or.jp/policy/2014/105_shiryo2.pdf)
Google ToDoとリマインダーについて調べた

2018年11月9日現在。Inboxが2019年3月に終了するにあたり、リマインダー及びTodoについて調べた。

# Googleのタスク・リマインダー的なサービスは２種類ある

Googleのタスクサービス関係はとても複雑になっていて、下記の２種類がある。

## Google ToDo

* **機能**
    * いわゆるtodo管理ツールとしてのタスク。タスクをまとめるリスト、タスクの中のサブタスクが作れる
    * webで他Googleサービスから使うためのwebアドオンがある。
    * **期限**は日付のみ、時刻・繰り返し設定不可
    * **専用サービス**はiOS/Androidアプリ、webサイトも[一応ある](https://mail.google.com/tasks/canvas)、、、 
* **統合**
    * **Gmail**ではwebアドオンとして右パネルで設定操作可能
    * **Calendar**は深く統合されてて予定追加時の"タスク"を選んで追加できる。表示カレンダは`ToDoリスト`。またはGmail同様webアドオンでも操作可能。
        * Android版Calendarからは操作表示不能。専用アプリを使う
* **開発**
    * APIあり https://developers.google.com/tasks/

## リマインダー

* **機能**
    * 通知を主目的にしたタスク。リストやサブタスク的な機能はない。
    * webで他Googleサービスから使うためのwebアドオンはない。
    * **期限**は日時設定可能、繰り返しも可能
    * **専用サービス**はない。アプリもwebサイトもない。
* **統合**
    * **Inbox**は深く統合されていて受信メールと同等のリスト表示管理が出来る
    * **Calendar**はToDoと同様の統合がされていて作成、管理が可能。（だがwebアドオンはない） 
        * Android版Calendarから操作**可能**。
    * **Assistant**は音声や対話型インターフェイスで登録、Androidではアプリ開いて、その他＞リマインダーから表示操作可能（おまけ的扱いぽい）
    * **Google Keep**にもリマインダーが深く統合されているが、何故かInbox,Calendar,Assistantで作成したリマインダーは未連携で表示すらされない。逆にKeepから作成したリマインダーは各サービスで表示操作出来る。
* **開発**
    * APIなし


という状況。ToDoは2018年6月にG Suiteの中核サービスになり専用アプリもあるが、リマインダーの立ち位置はよくわからない。

個人的にはアシスタントでの音声登録と、Inboxでのメールとリマインダの統合リストがとても便利だったので、Gmailでそれが出来なくなるのがつらい。APIもない（Calendar APIでも操作不能）のでサードパーティで開発することも出来ない。
OpenBlocks AX3にVyatta 6.4をインストールする

※ はてなブログから技術ネタを移動しました
※ [初稿](http://qpshinqp.hateblo.jp/entry/20130711/1373527508)：2013-07-11

OpenBlocksはARMプロセッサを使っており, 一般的なi386, x86_64アーキテクチャ用のビルドだとそのまま使うことはできません. そこでarmelアーキテクチャ用に自分でビルドし直す必要性があります.

そこで, [OBDNマガジン: OpenBlocks AX3でVyattaを動かす(ビルド編)](http://obdnmagazine.blogspot.jp/2012/10/openblocks-ax3vyatta.html)を見ながらvyatta入りkernelをビルドしようとしたのですが, kernelに当てるunionfs.diffがリンク切れになってたりと、結局ビルドできませんでした。
よーく探すと [Vyatta CORE for OpenBlocks AX3](http://vyatta.yellowback.net/) にビルド済みのisoが置いてあったので結局これを使うことに. [OBDNマガジン: OpenBlocks AX3でVyattaを動かす(起動編)](http://obdnmagazine.blogspot.jp/2012/10/openblocks-ax3vyatta_16.html) を参考にしながらこのisoを使ってOpenBlocksにVyattaを導入することに成功しました.
具体的には, ODBNマガジンの起動編「 ◆OpenBlocks AX3でVyattaをlive起動」以降の手順を踏めば良いはずです.
gitで確認

FreeBSD 12.0のリリースが近づいているので、いろいろ確認してみています。FreeBSDのメインのソース管理はSVNですがgithubにもコピーがあるので私はgitで操作しています。

プランチの流れはこのようになっていたようです。

![12-CURRENT.png](https://qiita-image-store.s3.amazonaws.com/0/104066/00971d72-81cf-fe05-acd7-73ac6c37a636.png)


FreeBSDでは修正はheadに入れてそれをMarge From Current(MFC)してそれぞれのブランチに反映します。

12-CURRENTの頃にレビューしてhead(master)に入れてもらった物はstable/12ブランチそのままでいけますが、まだ[レビュー中](https://qiita.com/yamori813/items/009a7c1dac6fe35c84eb)の物やレビューに出してない独自のソースも含めてビルドしたい場合以下のようにします。

レビュー中の物を反映

```
% arc export --revision D13583 --git | patch　-V none
```

他のブランチから反映

```
% git checkout zrouter -- sys/geom/geom_flashmap.c
```

上の操作で以下のような状態になります。

```
% git status
On branch stable/12
Your branch is up to date with 'upstream/stable/12'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sys/geom/geom_flashmap.c

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   sys/conf/options
        modified:   sys/fs/tmpfs/tmpfs.h
        modified:   sys/fs/tmpfs/tmpfs_vfsops.c

```

このツリーをビルドすると、起動時にdirtyと表示されます。

```
FreeBSD 12.0-BETA4 #0 e78279655eb(stable/12)-dirty
```

元に戻す方法は以下になります。checkout .だと他のブランチから持って来た物が戻らないようです。

```
% git reset --hard HEAD
```

上の二つのパッチは[リモートアップデート](https://qiita.com/yamori813/items/437dee80478fccac34ee)をおこなうための物です。一つはtmpfsのサイズのチェックのworkaroundでもう一つはdtsのパーティションマップのfirmwareからrootfsを探し出すパッチです。これらで問題なくリモートアップデートが出来るので、確認が簡単にできます。
IntelliJ - Docker Toolbox on Macの環境設定

## tl;dr
Docker Toolbox on macOSを使っていますが、IntelliJのTerminalからDockerの操作をしようとするとエラーになったので、調べた内容をメモしておく。

## IntelliJのターミナル起動
下のバーにある「Terminal」から起動する。
![intellij.png](https://qiita-image-store.s3.amazonaws.com/0/142279/6d5ba63a-ed3f-35cf-2a91-ca23eef661f5.png)

## エラー内容
下記のようなエラーが発生しました。

```bash:ターミナル
$ docker-compose ps
ERROR: Couldn't connect to Docker daemon - you might need to run `docker-machine start default`.
```
エラーにしたがってdocker-machineのdefaultを起動してみる。

```bash:ターミナル
$ docker-machine start default
Starting "default"...
Machine "default" is already running.
```

既に起動済み・・・
docker-machineの一覧を確認してみる。

```bash:ターミナル
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v18.06.1-ce
```

docker-machineにdefaultは存在するようです。
次に環境変数を確認してみる。

```bash:ターミナル
$ env | grep DOCKER
```

何も表示されない。
どうやらこれが原因のようです。

## 解決方法
下記コマンドにて、docker-machineの環境変数を設定する。

```bash:ターミナル
$ eval "$(docker-machine env default)"
```

設定状況を確認してみる。

```bash:ターミナル
$ env | grep DOCKER
DOCKER_HOST=tcp://192.168.99.100:2376
DOCKER_MACHINE_NAME=default
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/Users/hoge/.docker/machine/machines/default
```

再度、docker-composeコマンドを試してみる。

```bash:ターミナル
$ docker-compose ps
Name           Command          State          Ports        
------------------------------------------------------------
rails   /usr/local/bin/run.sh   Up      0.0.0.0:80->3000/tcp
```

無事にDockerが操作できるようになりました。

## まとめ
Intellij起動時に毎回実行するのもちょっと面倒な感じがします。
初期値の設定みないな機能が何かいいのですが・・・

以上

## 参考サイト
- [Can't connect to docker from docker-compose](https://stackoverflow.com/questions/29101043/cant-connect-to-docker-from-docker-compose)
親Window画面から子Window画面にcallback関数を定義する方法

```子画面.js
var RunCallbackFunction = function() { }; //reference holder only
```

```親画面.js
var myPopup = window.open(...);

setMyFunction = function() { myPopup.RunCallbackFunction = myFunc; };

//IE使わないならコレ
myPopup.addEventListener('load', setMyFunction, false);
//IE使うならコレ
myPopup[myPopup.addEventListener ? 'addEventListener' : 'attachEvent'](
  (myPopup.attachEvent ? 'on' : '') + 'load', setMyFunction, false
);
```

JavaScriptで親画面に値を渡す小窓を作る方法
https://qiita.com/shibafu/items/c71a5e93f7c3b6cebe42

ググると親画面に値を渡す方法として`window.opener`を使う方法がたくさんヒットするが、呼び出し元でcallback関数を渡したいのに固定の関数とか。。。。


これに関する情報が日本語で全くなかったので転載。
https://stackoverflow.com/questions/3030859/detecting-the-onload-event-of-a-window-opened-with-window-open/3030893#3030893
https://stackoverflow.com/questions/2797560/set-a-callback-function-to-a-new-window-in-javascript#comment2834701_2797574
JSは盛んだけど、子Windowを立ち上げるシチュエーション自体、SIでも一部しか使わないから情報ないのかな・・・
LINQつかいはじめました

いまさらですが　LINQつかいはじめました
LINQ式は前々から覚えようと思いつつ、分量も少ないので 必要になるまで遅延評価していましたが
そろそろ必要になったので 勉強しました
トータルでも1日かからず　完全に理解しました

![rikai.jpg](https://qiita-image-store.s3.amazonaws.com/0/13916/8e45ba85-b5ab-224d-7763-64161d0ca8dc.jpeg)


#お題
2次元配列からなる整数の配列が与えられる
{ 1,2,3 },{ 1,4,5 },{ 1,2,6 };
この中から 3より大きい要素のみ取得する
ただし 配列の形状は崩さず 空集合もみとめない
つまり　下記の結果が得られる
{4, 5},{6}


#勉強＆回答

##クエリ形式の練習
SQLっぽい構文がある。
なぜクエリ構文だと 最後にSelectかGroupByがないとNGかは　よくわからない

```cs
int[] a_ = { 2, 7, 5, 8, 1, 6 };

// 本当は var o1 = ... と書くが 勉強のため型を書く
IEnumerable<int> o1 =
    from a in a_
    where a > 5
    orderby a descending
    select a;                       // クエリ形式だと select句必要


// 結果
{8,7,6}
```

##メソッドチェーン
一般的にはこちらの形式が好まれるのでこちらに統一する
SelectなくてもOK

```cs
IEnumerable<int> o2 =
    a_                              // from a in a_
    .Where(x => x > 5)              // where a > 5
    .OrderByDescending(x => x)      //orderby a descending
    ;                               //select a;


// 結果
{8,7,6}
```

##ForEach
ForEachを使えば 全ての要素に対して処理を行える
（LINQ式ではないが　メソッドチェーンなので LINQ以外も繋げられる）

```cs
a_
    .Where(x => x > 5)
    .OrderByDescending(x => x)
    .ToList()
    .ForEach(x => Console.Write(x));


// 結果
876
```

##Selectは誤り
上記をLINQのSelect()を使えば出来そうだが　何も出力されない
Selectの戻りを何か工夫すればいけるんだろうか？
ここはよく理解できてない
(多分Selectの戻りが IEnumerableだからだとおもうが深く追わない)


```cs
a_
.Where(x => x > 5)
    .OrderByDescending(x => x)
    .Select(x => { Console.Write(x); return 1; });
```

##Selectで射影し要素の値を2倍値にする

```cs
a_
.Where(x => x > 5)
    .OrderByDescending(x => x)
    .Select(x => x * 2)
    .ToList()
    .ForEach(x => Console.Write("{0}, ", x));

//結果
{16, 14, 12}
```

##Anyをつかい 配列に2が含まれるかどうか

```cs
a_.Any(x => x == 2);


//結果
True
```

##Anyを使い 2を含む配列のみ取得

```cs
int[][] a2_;
a2_ = new int[3][];
a2_[0] = new int[]{ 1,2,3 };
a2_[1] = new int[]{ 1,4,5 };
a2_[2] = new int[]{ 1,2,6 };

a2_
.Where(x => 
    x.Any(y => y == 2)  
)


//結果
{1, 2, 3}
{1, 2, 6}
```

## y>3を含む配列取得

```cs
IEnumerable<int[]> o3 = 
a2_
.Where(x =>
    x.Any(y => y > 3)
);


//結果
{1, 4, 5}
{1, 2, 6}
```

##SelectManyは多次元配列を1次元に投影する

```cs
IEnumerable<int> o4 =
    a2_
        .SelectMany(x => x
            .Where(y => y > 3
    ));


//結果
{4, 5, 6}
```

##Selectは配列構造維持したまま射影できる

```cs
IEnumerable<int[]> o5 =
a2_
    .Select(x => x
        .Where(y => y > 3)
        .ToArray()
    )
;


//結果
{}
{4, 5}
{6}
```

まだ空集合が入ってる


##空集合を除去

```cs
IEnumerable<int[]> o6 =
a2_
    .Select(x => x
        .Where(y => y > 3)
        .ToArray()
    )
    .Where(x => x.Count() > 0)
;


//結果
{4, 5}
{6}
```

望み通りのデータが出来た！！


##パフォーマンスのためAnyを使う＆int[][]に

```cs
IEnumerable<int[]> o6 =
a2_
    .Select(x => x
        .Where(y => y > 3)
        .ToArray()
    )
    .Where(x => x.Any())
    .ToArray()
;


//結果
{4, 5}
{6}
```

#総括
ToArrayが入ってしまうので速度的に気になるのだけど
foreachで書くことを考えると
とてもシンプルに出来たと思う

LINQは正義！
Git のタグやコミットを (PGP ではなく) S/MIME で署名する

Git 2.19 からタグやコミットの署名・検証に S/MIME がサポートされ、GitHub でも S/MIME 署名が検証されるようになった。

[S/MIME Signature Verification | The GitHub Blog](https://blog.github.com/changelog/2018-09-10-smime-signature-verification/)

[ca-certificates](https://packages.debian.org/hu/jessie/ca-certificates) に含まれている CA に辿れる S/MIME 証明書を使えば、PGP のように GitHub に公開鍵をアップロードしなくても GitHub 上で署名が検証される。

S/MIME で署名してそれを確認するまでの手順を記録しておく。

# 準備
## Git のバージョンが 2.19 以降であることを確認

```sh
$ git --version
git version 2.19.0
```

Git が 2.19 より古い場合は、2.19 以上にアップグレードする。

## smimesign をインストール
```sh
$ brew install smimesign

# 代わりにソースからビルドすることもできる
$ go get github.com/github/smimesign
```

## Git の user.email 設定を確認
証明書のメールアドレスと一致している必要があると思われる。
現時点では、メールアドレスが一致していないタグを GitHub に push すると、タグの詳細画面で 500 エラーが発生した。

```sh
$ git config --get user.email
hoge@example.com
```

Git 側の設定は下記のようなコマンドで変更できる。

```sh
$ git config --global user.email "hoge@example.com"
```

## 有効な証明書があること
個人使用の場合は [COMODO](https://www.comodo.com/home/email-security/free-email-certificate.php) から無料で S/MIME 証明書を入手できる。

発行した証明書は OS の証明書ストアに取り込んでおく必要があった (macOS では「キーチェーンアクセス」アプリ)。

```sh
$ smimesign --list-keys
```
`Emails` の行に自分のメールアドレスが出てくればよい。


## 署名に S/MIME を使うように設定
個別のリポジトリだけに適用する (`--local`) か、全体に適用する (`--global`) かが選べる。

既に GPG の設定があるとうまくいかなかった。`~/.gitconfig` や `.git/config` でコメントアウトして対応した。

### 個別のリポジトリに設定する場合
```sh
# リポジトリ内から実行
$ git config --local gpg.x509.program smimesign
$ git config --local gpg.format x509
```

### グローバルに設定する場合
```sh
$ git config --global gpg.x509.program smimesign
$ git config --global gpg.format x509
```

## 署名鍵を指定
署名に使用する鍵を指定することができる。
指定しなくても動いたが、鍵が複数ある場合は指定しておくとよさそう。
`smimesign --list-keys` の出力から、`ID` の値を指定する。

```sh
$ git config --global user.signingkey "(鍵の ID)"
```

# タグを署名する
```sh
$ git tag -s
```

GitHub 上では下記のように表示された。

<img width="438" alt="スクリーンショット 2018-11-13 14.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/487/f3754090-8df7-67d6-4585-fd6ae95e5211.png">


# コミットを署名する
```sh
$ git commit -S
```

署名されたコミットができる。

GitHub では下記のように表示された。

<img width="334" alt="スクリーンショット 2018-11-13 11.59.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/487/d520bd24-b4f6-04d2-b283-e161c4fadb60.png">

# ローカルで署名を検証する
```sh
$ git show --show-signature
```

現時点では、署名の検証に失敗した場合にのみメッセージが表示され、成功した場合は特にメッセージが出ない様子。

## `smimesign` を入れていない環境で `git log --show-signature` が止まった場合
S/MIME の設定をしていない環境で `git log --show-signature` すると、S/MIME で署名したコミットのところで出力が止まってしまった。
`smimesign` をインストールして、検証に `smimesign` を使う設定をすると見ることができるようになった。

```sh
$ brew install smimesign
$ git config --global gpg.x509.program smimesign
```

# See also
GitHub による解説
https://help.github.com/articles/about-commit-signature-verification/#smime-commit-signature-verification

`smimesign` (github/smimesign)
https://github.com/github/smimesign