OmniAICreator/Qiita-1.07M huggingface dataset:
【javascriptでカウントダウンタイマーを作る】part.3 忘備録

# 完成形のイメージ
日本人の平均男性が80歳ぐらいまで生きると想定し、
自分の年齢を入力して余生を日数ではなく時間単位でカウントダウン表示する

# 実装したい機能を言語化しよう
**"１日の睡眠時間と選択した年齢から余生を〜時間で出力する"**

# 今日の課題は「年齢を入力したら80歳まで生きるとして乗り時間を表示させる」
**「人生の残り時間」 = "１日の起きている時間 × 1年間" × "80 - 自分の年齢"**



```javascript:life_timer.js
//年齢を選択する時に発火する関数
    setAgeNumber();

    function setAgeNumber(){
        for(var i = 10; i <= 80; i ++){
            var option = document.createElement("option");
            option.value = i;
            option.innerText = i;
            Age.appendChild(option);
        }
    }

    //年齢を選択するプルダウンメニューを変更したら発火
    Age.addEventListener('change',function(){
        var ageValue = document.getElementById("age").value;

        //余生の時間を計算
        leftLifeTime += (hoursLeft - ageValue); 
        alert(leftLifeTime);
    });


    //睡眠時間を選択する際に発火する関数
    setSleepNumber();

    function setSleepNumber(){
        for(var i = 1; i <= 24; i++){
            var option = document.createElement("option");
            option.value = i;
            option.innerText = i;
            Sleep.appendChild(option);
        }
    }

    //睡眠時間を選択するプルダウンメニューを変更したら発火
    Sleep.addEventListener('change',function(){
        var sleepValue = document.getElementById("sleep").value;

        //残り時間を計算 
        awakeTime = (dayHours - sleepValue) * 365 * leftLifeTime;
        alert(awakeTime);
    });
```
# 課題
取得できた残り時間の値をカウント時間として表示させる
digdagでエラーを無視して後続タスクを進める

## 概要

digdagでワークフローを作成する場合に、
親ワークフローから子ワークフローを呼び出すようなケースはよくあると思います。

普通に実装すると、以下のようにcallオペレータを使うと思います。

```parent.dig
+task1:
  call>: child1

+task2:
  call>: child2

+task3:
  call>: child3
```

ただ、この場合途中でエラーが起こった場合に最後まで実行されないことになる。
task間の依存関係が無い場合にどこかで失敗した場合も最後まで実行したい、
そんなケースの場合はrequireオペレータを使うと良い。

## requireオペレータを使う

requireオペレータだとignore_failureというオプションがあり、
呼び出したワークフローが失敗しても親ワークフロー内ではエラーにならない。

```parent.dig
+task1:
  require>: child1
  ignore_failure: true

+task2:
  require>: child2
  ignore_failure: true

+task3:
  require>: child3
  ignore_failure: true
```

上記のようにしておくと例えばtask2で呼び出すchild2が失敗した場合もtask3まで実行され、
親ワークフローとしては全タスクがSuccessのステータスで完了します。

エラー検知したい場合は子タスクの中で_errorとかで検知する必要があるので注意が必要ですが、
リカバリは子タスクのみ再実行すればよいので保守性が高まる気がします。
可視化(2D) > 垂直分布 > 三面(分布)図 | Zonal XXXとMeridional XXX

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

### 希望

- とある数値の垂直分布を見たい

### 三面（分布）図

検索して見つけたのは「三面（分布）図」

- [FVmapによる三面分布図の作成](http://forests.world.coocan.jp/fvdb/fvmap-page.html)

製図の正面図、上面図、側面図のような感じ。

### Zonal and Meridional

思い出したのはClimateなどの表現で使われるもの。

- [Temperature and Zonal Wind Climatology](https://www.sparc-climate.org/data-centre/data-access/reference-climatology/randals-climatologies/temperature-wind-climatology/)

https://en.wikipedia.org/wiki/Zonal_and_meridional
> Zonal means "along a latitudinal circle" or "in the west–east direction."
しばらく書かないと忘れそうなGoのインターフェースについて、未来の自分へのメモ

Go始めた時に「ん？」って思ったインターフェースについての私的です。
未来の僕が困らないためにここに記しておきます。


## golangのインターフェース

馴染みのあるインターフェース

```go
type Unk interface{
    out()
    call()
}

type MyUnk struct {
    name string
}

func (u *MyUnk) out() {
    fmt.Println(name + "ちゃん出た")
}

func (u *MyUnk) call() {
    fmt.Println("虫を呼ぶよ")
}

//　A Tour of Go： https://go-tour-jp.appspot.com/methods/9
//　interface(インタフェース)型は、メソッドのシグニチャの集まりで定義します。
//　そのメソッドの集まりを実装した値を、interface型の変数へ持たせることができます。

```

個人的に「ん？」となったインターフェース型

```go
var i interface{}
i = 20             // reflect.TypeOf(i) String
i = "unk"         // reflect.TypeOf(i) int
i = []byte("unk") // reflect.TypeOf(i) []uint8
i = map[string]interface{}{
	"Type":  "unk",
	"State": "oops",
}                  // reflect.TypeOf(i) map[string]interface {}

//　A Tour of Go： https://go-tour-jp.appspot.com/methods/14
// 空のインターフェースは、任意の型の値を保持できます。 (全ての型は、少なくともゼロ個のメソッドを実装しています。)
```

interface型はなんでもおkらしい
全ての型は、0個のメソッドを持っているので、との事。

```go
type Empty interface{
}
```


試しに

```go

func main() {
	var i interface{}
	i = 20
	Otamesi(i) // int
}

func Otamesi(v interface{}) {
	fmt.Println(v)
	fmt.Println(reflect.TypeOf(v))
}
// なんでもおk！
```

## 型アサーションで良い感じに出来る

vendor以下に潜っていて構造体でinterfaceの値を持っているものなど、必要な値を抽出したい時によくお世話になりました。

```go
// assertion
str, ok := interface.(string)
int, ok := interface.(int)
map, ok := interface.(map[string]interface{})
```

## interfaceはキャスト出来ない。

```
// cast
str := string(int)       // ok
str := string(interface) // panic
```

## 型判定

多言語でのswitch文とちょっと違う。

```
switch v := i.(type) {
	case int:
		fmt.Printf("Twice %v is %v\n", v, v*2)
	case string:
		fmt.Printf("%q is %v bytes long\n", v, len(v))
	default:
		fmt.Printf("I don't know about type %T!\n",
}

// A Tour of Go: https://go-tour-jp.appspot.com/methods/16
```

Goのswitchは条件にヒットした場合、そのスコープ内の処理を終えた後、自動でbreakします。

## 記事中に何度も出てきてるけどよくお世話になった連想配列シリーズ

```go
unk := map[string]interface{}{
    "name": "smith",
}
```


## jsonの取り扱い

toJson

```go
unk := &Unk{
	Type:  "secret",
	State: "new",
}
unkBlob, _ := json.Marshal(unk)
fmt.Println(unkBlob)
fmt.Println(string(unkBlob))
// {
//     "Type": "secret",
//     "State": "new"
// }
//
```

toStructType

```go
blob := []byte(`{"Type": "secret", "State": "new"}`)
var unk Unk
err := json.Unmarshal(blob, &unk)
if err != nil {
	fmt.Println(err)
}
fmt.Println(&unk)
//
// &{secret new}
//
```

toInterface

```go

blob := []byte(`{"Type": "secret", "State": "new"}`)
var unk interface{}
err := json.Unmarshal(blob, &unk)
if err != nil {
	fmt.Println(err)
}
fmt.Printf("%#v\n", &unk)
// (*interface {})(0xc42000e220)

fmt.Printf("%#v\n", unk)
// map[string]interface {}{"Type":"secret", "State":"new"}

fmt.Println(unk["Type"]) // panic

// ここでアサーション
fmt.Println(unk.(map[string]interface{})["Type"])
// "secret"
```


## 参考
[A Tour of Go](https://go-tour-jp.appspot.com/welcome/1)
[golang.jp](http://golang.jp/go_tutorial)
Windowsのgvimでクリップボードにコピー＆ペースト

# Windowsのgvimでクリップボードにコピー＆ペースト

## 1.Vim風ショートカットキー入力によるクリップボードの操作
### ・ショートカットキー

| 機能 | キー | 説明 | 
|:-:|:-:|:-:| 
| コピー  | Ctrl-Insert  |  ビジュアルモードで選択したテキストをクリップボードにコピー。 | 
| カット  | Ctrl-Delete <br> または <br> Shift-Delete  |  ビジュアルモードで選択したテキストをカットし、クリップボードにコピー。 | 
| ペースト | Shift-Insert  |  クリップボードのテキストをペースト。 | 
※ VIMのデフォルトの設定を利用して、Windows-VIM間のコピペが可能
※ VIMのコピーコマンド(yy)やペースト(p)などでは、Windows-VIM間のコピペ不可

## 2.ウィンドウズ風ショートカットキー入力によるクリップボードの操作
「_vimrc」ファイルに下記記述を追加することで、Windowsのショートカットキー入力による
コピー＆ペーストが利用可能になります。

### ・追加内容
source $VIMRUNTIME/mswin.vim

### ・ショートカットキー

| 機能 | キー | 説明 |
|:-:|:-:|:-:|
| コピー  | Ctrl-c  |  ビジュアルモードで選択したテキストをクリップボードにコピー。 |
| カット  | Ctrl-x |  ビジュアルモードで選択したテキストをカットし、クリップボードにコピー。 |
| ペースト  |  Ctrl-v | クリップボードのテキストをペースト。  |
※ 短形で選択 (ctrl+v)や直前の処理の取消を取消(ctrl+r)などのctrlを利用するVIMコマンドが利用不可

## 3.ヤンク,カット操作によるクリップボードの操作
「_vimrc」ファイルに下記記述を追加することで、VIMのヤンク＆ペーストコマンドが
クリップボードを利用するようになるため、別アプリケーションと連携可能になります。

### ・追加内容
set clipboard=unnamed,autoselect

### ・ショートカットキー

| 機能 | キー | 説明 |
|:-:|:-:|:-:|
| コピー  | yy |  カーソルのある行をクリップボードにコピー。 |
| カット  | dd |  カーソルのある行をカットし、クリップボードにコピー。 |
| ペースト  |  p | クリップボードのテキストをペースト。  |
CordovaでAndroidをビルドするときにはまったこと

以下の環境でCordova Androidアプリを

- Cordova: 8.0.0

- Android: Studio 3.1.3

- Java: Java(TM) SE Runtime Environment (build 1.8.0_171-b11)

```
cordova build android
```
でビルドすると…
以下のようなエラーが出る

```
Minimum supported Gradle version is 4.4. Current version is 4.1. If using the gradle wrapper
```

こちらの投稿によるとGradleのバージョンが違うということなので、
https://qiita.com/mana-bin/items/eaa0c2c2335140e3f707

[PROJECT_ROOT]/platforms/android/cordova/lib/builders/GradleBuilder.js
のL240辺りを以下のように改訂すると解消できた。

```
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.4-all.zip';
```

まだ、以下のエラーが残っていたので、

```
A problem occurred evaluating project ':CordovaLib'.
> Plugin with id 'com.github.dcendents.android-maven' not found.
```

以下の二つのファイルを

- [PROJECT_ROOT]\platforms\android\CordovaLib\build.gradle

- [PROJECT_ROOT]\node_modules\cordova-android\framework\build.gradle

以下のように変更すると解消できた。

``` :修正前
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
    }
```

``` :修正後
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
    }
```

デフォルト値が間違っているのは分かりにくい。。
seabornでintroductionを見ながら最短でグラフを出力するところまで

# 導入

業務で使うレベルではないですが、データから的確な戦略に落として経営の戦略を策定していく、データサイエンティストというキーワードに憧れて、seabornの勉強を始めました。
最短でグラフを出力するところまでやってみました。


# code


```introduction.py
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
tips = sns.load_dataset("tips")
sns.relplot(x="total_bill", y="tip", col="time",
            hue="smoker", style="smoker", size="size",
            data=tips);
plt.show()
```

## 出力されるグラフ

<img width="1094" alt="Screen Shot 2018-07-30 at 18.00.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/30490/65f72589-fccd-47a2-b17e-655e7088b7a6.png">

## データの中身

| total_bill | tip | sex | smoker | day | time | size |
|---|---|---|---|---|---|---|
| 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
| 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
| 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
| 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
| 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
| 25.29 | 4.71 | Male | No | Sun | Dinner | 4 |

```
tips = sns.load_dataset("tips")
```
で定義されるテストデータがなんのデータを表しているのか？
たくさん調べましたが、たどり着くことができませんでした。
予測ですが、レストランの来客情報で、かつ、tipがあるので、英語圏のデータだと予測しています。
LunchとDinnerにおける、total_billとtipの相関をrelplotで確認することができました。


# 参考
[introduction to seaborn]("https://seaborn.pydata.org/introduction.html")
virtualenvをgitで管理すると便利

# 概要
pythonのvirtualenvを使うと，独立した環境でpythonの環境を構築できる．
これらをgitを通してOS間，PC間で共有したい．
多分イカしたgitignoreやディレクトリ間の設定があるだろう，ということで調べた．

# なにがうれしい？
* virtualenvを使うと簡単にpython環境が構築できる
* virtualenvなのでローカルの設定を汚さない
* gitを使って構築したpython環境を簡単に共有

# 元リポジトリでやること
1. git環境構築
2. virtualenv用のgitignoreを設定
3. virtualenv構築
4. pipでパッケージを入れる
5. requirement.txtを出力
6. リモートリポジトリに反映

具体的な手順

```
#1. git環境構築
#作業用リポジトリ作成
$ mkdir repo
$ cd repo

#git環境構築
$ git init .

#2. virtualenv用のgitignoreを設定
#以下のgitignoreを追加する
$ touch .gitignore
$ git add .gitignore
$ git commit -m "add .gitignore"
```

```text:.gitignore
# Created by https://www.gitignore.io/api/virtualenv

### VirtualEnv ###
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json


# End of https://www.gitignore.io/api/virtualenv
```

```
#3. virtualenv構築
$ virtualenv .

#4. pipでパッケージを入れる
$ pip install hoge

#5. requirement.txtを出力
$ pip list
$ pip freeze > requirements.txt

#6. リモートリポジトリに反映
$ git add .
$ git commit -m "set python env"
$ git push -u origin
```



# クローン先のリポジトリのやること
1. git clone
3. virtualenv構築
4. requirement.txtからpipでパッケージを入れる
6. 同期完了

```
#1. git clone
$ git clone fuga

#2. virtualenv構築
$ virtualenv .

#3. requirement.txtからpipでパッケージを入れる
$ pip install -r requirements.txt

#4. 同期完了
$ pip list
```
# 補足
virtualenvすると以下のようなファイルが出てくる.
なのでprojectファイルなどを作成して，そこにソースコードを記述していくと簡潔で分かり良い

```
# virtualenv した直後のファイル構成
bin/
include/
lib/
local/
share/
pip-selfcheck.json

# 追加したprojectファイル以下にソースコードを入れていくとさらにわかりやすい
project/ 
```

## 自分でやってみたリポジトリ
[https://github.com/m-masaki72/virtualenv_git_test](https://github.com/m-masaki72/virtualenv_git_test)


# 参考文献
[Best Practice for virtualenv and git repo
](http://libzx.so/main/learning/2016/03/13/best-practice-for-virtualenv-and-git-repos.html)
[virtualenv (Python仮想環境)の使い方](https://sgry.jp/blog/2014/11/15/2015/comment-page-1/)
[Python Tips：ライブラリをまとめてインストールしたい](https://www.lifewithpython.com/2014/03/python-install-multiple-modules-.html)
恒等モナドで分かる、モナドの使い方入門

#前置き
記事の修正点は、真摯に対応いたします。
よろしくお願いします。
#モナドとは
関数型プログラミング上では、「クライスリ圏」における３則を満たすもののこと…
##ってもっと簡単に（笑）
_プログラミングが分かる人向けの説明にすると…_

ある__値__を__状態__として__保持__しておくことの出来る__計算機構__を、
その言語や環境内部に実装したもの…

と言い換えると、あれってなる人はお察しの通り、
__チューリング完全__
ってやつです。

#モナドの使い方
ある計算機構がモナドである場合、以下の関数を内部に保持しています。

* of
* bind
* join

##of
計算機構に対して値を代入します。
言語によっては構造体やオブジェクト、関数なども代入できます。

```javascript
Monad.of({a: 1})
```
又は単なる関数実行の場合もあります。
_（本記事では、以後こちらを使います。）_

```javascript
Monad({a: 1})
```
##join
計算機構から値を取り出します。

```javascript
Monad({a: 1}).join() //{a: 1}が返る
```
実装によっては、単なる _get_ の場合もあります。
_（本記事では、以後こちらを使います。）_


```javascript
Monad({a: 1}).join //{a: 1}が返る
```
##bind
モナドを返す関数 _f_ を引数に取って、_f(x)_ の冒頭の引数に保持している値を
代入します。
関数の返値をモナドの中に再代入しますが、この時そのまま代入すると…

```javascript
Monad(Monad(...)).join.join
```
になってしまうので、内部で値を１段階裸にします。

これにより、副作用を隠蔽しているわけです。
しかも、モナドが返っているので連続的に記述できます。

```javascript
Monad({a: 1})
.bind(o => Monad({a: o.a + 5}))
.bind(o => Monad({a: o.a * 5}))
.join
//{a: 30}になってる！！！
```

#何が凄いのか？
最大のメリットは、抽象化された無名関数を代入するので、命名に悩まされないと言えるでしょう。
以下に、メリットをまとめます。

* __命名なし__に処理をまとめて記述出来る。
* オブジェクトのメソッドに__返り値がない場合__でも、__連続的__に書ける。
* 処理を__まとまり毎__に記述できる。

#おまけ
モナドはfunctor（関手）の機能を内在していることがほとんどです。
引数にとった関数の冒頭の引数に保持している値を代入するのはbindと同じです。

```javascript
Functor({a: 1}).map(o => o.a === 1).value // true
Monad({a: 1}).map(o => o.a === 1).join // true
```
#モナドの作り方について
モナドを作る際の事については、以下にまとめます。
[恒等モナドで分かる、モナドの作り方入門](https://qiita.com/johnny-shaman/items/743efa743dfae7adb5ba)

最後までお読みいただき、ありがとうございました。
ruby + cairo + ffmpeg で砂嵐動画を作成する

適当なダミー動画が欲しい時にこれでサクッと作成できます。

![out.gif](https://qiita-image-store.s3.amazonaws.com/0/19869/1312074f-9cfd-046a-ca63-0ed3019022f7.gif)

#### cairo のインストール

```sh
$ gem install cairo
```

#### Rubyコード

```ruby:suna.rb
require "cairo"

format = Cairo::FORMAT_ARGB32
# キャンバスの大きさ
width = 400
height = 300

surface = Cairo::ImageSurface.new format, width, height
context = Cairo::Context.new surface

# 1ピクセルの大きさ
cell_height = 2
cell_width = 2

# 解像度
num_cols = width / cell_width
num_rows = height / cell_height

66.times do |n|
  current_col = 0
  current_row = 0

  num_rows.times do |i|
    num_cols.times do |j|
      # ピクセルの座標
      y = i * cell_height
      x = j * cell_width
      # ランダムな色
      r = rand(100) / 100.0
      g = rand(100) / 100.0
      b = rand(100) / 100.0
      context.set_source_rgb r, g, b
      # ピクセルを描画
      context.rectangle x, y, cell_width, cell_height
      context.fill
    end
  end
  # ファイルに書き込み
  surface.write_to_png "out/suna#{format "%03d", n}.png"
end
```

#### 連番画像を生成

```sh
$ ruby suna.rb
```

#### ffmpeg のインストール （Homebrew の場合）

```sh
$ brew install ffmpeg
```

#### ffmpeg で連番画像から動画を作成
```sh
$ ffmpeg -r 15 -i ./out/suna%03d.png -r 15 -an -vcodec libx264 -pix_fmt yuv420p out.mp4 
```
iTerm2 — Control+d でセッションを閉じるショートカットを無効化する

**追記: vimを操作しているときなどの control+d も無視されてしまうことが判明。現在解決中。**

vimをよく使うようになってから、とにかく誤操作が多い。

## 手順

**iTerm2 > Preferences > Keys > +**

- Keyboad shorcut: Control + D
- Action: ignore

![image](https://user-images.githubusercontent.com/13635059/43388237-94049dfa-9423-11e8-938c-41fab892ece0.png)

![image](https://user-images.githubusercontent.com/13635059/43427971-e32c742a-9496-11e8-83e1-854a304dfe94.png)



## cf.

- [macos - Iterm2 disable Command shortcuts - Ask Different](https://apple.stackexchange.com/questions/85489/iterm2-disable-command-shortcuts)

## Gist

- [iTerm2—How to disable close session shortcut command + d](https://gist.github.com/YumaInaura/8efcbd4bc80311c719d4b7d8a646cd31#file-readme-md)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
JavaおじさんがPythonを使えるようになるまでの全記録（その7）

#環境構築あれこれ
こんにちは、Javaおじさんです。

何となく文法もわかってきつつあるので、そろそろDjangoの開発環境もそろえねば、と思っていろいろ情報をあさっているのだけれど、とあるページでこんなことを読んで「マジ？」ってなった。

> Pythonエンジニアは、ほぼこれ(PyCharm)を使っていると言っても過言ではありません。

![本当に？.jpg](https://qiita-image-store.s3.amazonaws.com/0/275064/63f26e40-7b5b-e6fb-12b1-c13c412f4429.jpeg)

どっかにPythonの開発環境に関する比較記事載ってないかな(他力本願)
と思って検索したら結構な率でPyCharm推しだった。
んーでも有償版と無償版で機能制限付いてるみたいだし、とりあえず今のところVisual Studio Codeで不便感じてないからいっかな。

ま、それはともかく。
一応[この辺](https://qiita.com/taijijiji/items/8da746e150d1e0947107)を見つつセットアップをしているのだけど、Vagrant使う必要あるのかなあという気がしてきている。
いやまあ諸々の関係上使った方がたぶんいいんだと思うんだけど、開発環境としてWindowsのAnacondaでコード書いて実行環境としてVagrant環境にアップロードするとか考えるとちょっと手間じゃないかなという気もしていて。特にDBからむテストコードを書く場合にいちいちアップロードしてテストしてとかやってるとコスト高い気がするのよね。
CI環境作らんとだめかしらね。でもそれはそれでむしろ逆に重くないか？
とか考えつつ昨日から試行錯誤している。

#リストと可変性
とはいってもマルチタスクができるほど器用ではないので[テキスト](https://www.amazon.co.jp/gp/product/4764905183/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1)の読み進めの方をメインに進めてはいる。

今日は「5-2 リストと可変性」を読んでいる。
リストとタプルの違いとしては以下。

- タプルの初期化には()を使うのに対してリストは[]を使用する。[1,2,3,4][1:3][1]とかいう表現もできる。
- リストの場合は要素が1つでもタプルと違って,は不要。まあこれは冷静な話をすると構文解析の問題なので是非もないね。
- タプルは不変、リストは可変

最後のポイントは以前コメントでも指摘してもらってた「メソッドは副作用を伴う」という話にもリンクしている。
つまるところリストは可変なので、副作用を伴う（＝内部状態を変化させる）メソッドを使ってリストそのものを書き換えることが可能になる。＋や*といった演算子は副作用を伴わない（＝内部状態を変化させない）ため、リストに対してこれらの演算子を使用すると新しいリストを作り出して返してくる。
タプルの場合不変なので、そもそも内部状態を変更するためのメソッドそのものを持たない、ということになる、のかな？その辺の言及がこのテキスト明確でないからいまいち断言しづらいんだけど。

たぶん関数型プログラミングではこの副作用を伴う/伴わないって話が重要になってくるんだろうなーというのはどっかで聞きかじった話。おそらく後で出てくる。

#リストのクローン
ループの中でリストを変更する場合、以下の方法でリストのクローンを作って変更の影響を受けないようにする。

- スライス表記を使ってリストの一部をコピーする。
- list(L)でリストの複製を返す。（まんまコピーコンストラクタですな）
- 可変のオブジェクトが含まれる場合は標準ライブラリcopyをインポートしてcopy.deepCopyを使用する

~~コードは後で書こう。~~書いた。

```5-2-1.py
import copy

source = [1, 2, 3, 4, 5]

print('id(source) =', id(source))

#スライス表記を使ったクローン
for value in source[1:3]:
    print(value)

print()

#list(L)を使ったクローン
copied = list(source)
for value in copied:
    print(value)
print('id(copied) =', id(copied))

print()

#copy.deepCopyを使ったクローン
deep = copy.deepcopy(source)
for value in deep:
    print(value)
print('id(deep) =', id(deep))
```

実行結果は以下の通り。

```
id(source) = 1242503195016
2
3

1
2
3
4
5
id(copied) = 1242502800136

1
2
3
4
5
id(deep) = 1242503195656
```

#リスト内包

> 与えられた演算をある順序型の値（例えばリストの要素に対して）に施した結果を各要素とする新しいリストが作り出される

ということらしい。
でもってfor節の中には1つ以上のif文やfor文を続けることも可能で、条件を満たしたデータのみを抽出することも可能である、と。ふむ。

~~これもコードは後で書こう。~~書いた。

```5-2-2.py
def isPrime(target):
    """簡単な素数判定。素数ならTrue、素数でなければFalseを返す"""
    for n in range(2, target):
        if target%n == 0:
            return False
    return True

#リスト内包（単純な演算）
simple = [x**2 for x in range(1, 6)]
print(simple)

#リスト内包（条件によるデータ抽出：素数の2乗をリストに抽出）
onlyPrime = [x**2 for x in range(2, 11) if isPrime(x)]
print(onlyPrime)
```

抽出したデータを2乗しているのは特に意味はなくて演算できますよと示したかっただけ。
実行するとこんな感じ。

```
[1, 4, 9, 16, 25]
[4, 9, 25, 49]
```

三項演算子並みにトリッキーなコードではあるかなー、という印象。
でもたぶんフィルターとして便利なんだろうな。

> 誰かほかの人がそのコードを読む必要があるかもしれないし、その時に「巧妙」であることは望ましくない場合もあることを覚えておこう

基本的にコメント重要なのだろうな、というのはあるね。

今日はここまで。
恒等モナドで分かる、モナドの作り方入門（関手もやるよ！）

#前置き
記事の修正点は、真摯に対応いたします。
よろしくお願いします。
#モナドとは
関数型プログラミング上では、「クライスリ圏」における３則を満たすもののこと…
##ってもっと簡単に（笑）
_プログラミングが分かる人向けの説明にすると…_

ある__値__を__状態__として__保持__しておくことの出来る__計算機構__を、
その言語や環境内部に実装したもの…

と言い換えると、あれってなる人はお察しの通り、
__チューリング完全__
ってやつです。

#モナドの作り方
ある計算機構がモナドである場合、以下の関数を内部に保持しています。

* of
* bind
* join

作る際には __map__（fmap・flatMapとも言う）も必要になります。
つまり、モナドは__functor__（関手）でもあります。
##of
計算機構に対して値を代入します。
言語によっては構造体やオブジェクト、関数なども代入できます。
単なる関数実行の場合を例に上げます。
###実装例
```javascript
function Monad (v) {
  return Object.create(Monad.prototype, {
    v: {
      configurable: true,
      writable: true,
      value: v
    }
  })
}
```
##join
計算機構から値を取り出します。
単なる _get_ の場合は、以下のようになります。
###実装例
```javascript
Object.assign(Monad.prototype, {
  get join () {
    return this.v.valueOf();
  }
});
```
##map（fmap・flat map）
mapは、与えられた無名関数の第一引数に保持する値を代入して無名関数を実行する構造を持っています。
関数を実行後に、新しいfunctorを生成して中の値として保持します。
例としては、Array.prototype.mapがあります。

```javascript
[{a: 1}].map(v => ({a: v.a + 5}))
```
###実装例
```javascript
Object.assign(Monad.prototype, {
  map (f) {
    return Monad(f(this.v));
  }
});
```
これにより、副作用を隠蔽しているわけです。
##bind
ここの実装をすることが中心と言っても過言ではありません。
ここに、モナド則（クライスリ圏における三則）を表現しながら、実装について一緒に考えていけたらと思います。
###左随伴則（Left Identity）
関数 _f_ がモナドを返す時、bindを使って _f_ を実行したときと、_f_ をそのまま実行したときで、保持している値は等しくなっていることを要求します。

```javascript
Monad({a: 1})
.bind(o => Monad({a: o.a + 5}))
.join.a
===
(o => Monad({a: o.a + 5})({a: 1})
.join
.a
```
が true になる事を求められています。
（実際には同じ関数でなければならないので、関数を定数に保存して証明しますが、分かりやすくするために上記のように記述しました。）
擬似コードで表現すると、

```javascript
M(x).bind(f) === f(x)
```
になるということです。
###右随伴則（Right Identity）
これはそれほど難しくありません。
bindをするたびに、

```javascript
Monad({a: 1}).fakeBind(Monad).fakeBind(Monad).fake...
.join.join...
```
と書いていたのではたまりません。

```javascript
Monad({a: 1})
.bind(Monad)
.join.a
===
Monad({a: 1}).join.a
```
になリます。
擬似コードで表現すると、

```javascript
M(x).bind(M).bind(M).bind... === M(x)
```
になるということです。
###結合則（Associativity）
bindを使って連続して関数を実行した場合には、
関数を合成して実行した場合と、
同じ解になることを要求しています。
この恒等関係は右辺と左辺を入れ替えても成り立ちます。

```javascript
Monad({a: 1})
.bind(
  o => (
    Monad({a: o.a + 5})
    .bind(o => Monad({a: o.a * 5}))
  )
)
.join.a
===
Monad({a: 1})
.bind(o => Monad({a: o.a + 5}))
.bind(o => Monad({a: o.a * 5}))
.join.a
```
となリますので、擬似コードで表すと、

```javascript
M(x).bind(
  x => fa(x).bind(
    y => fb(y).bind(
      z => fc(z).bind...
    )
  )
)
=== M(x).bind(fa).bind(fb).bind(fc).bind...
```
となるということです。
###実装例
実装には、__flat map__を利用します。

```javascript
Object.assign(Monad.prototype, {
  bind (f) {
    return this.map(f).join;
  }
});
```

#恒等モナドの完成
```javascript
function Monad (v) {
  return Object.create(Monad.prototype, {
    v: {
      configurable: true,
      writable: true,
      value: v
    }
  })
}
Object.assign(Monad.prototype, {
  get join () {
    return this.v.valueOf();
  },
  map (f) {
    return Monad(f(this.v));
  },
  bind (f) {
    return this.map(f).join;
  }
});
```
となります。
他のモナドは、恒等モナドにside effectを付け加えて実装するだけですので、ぜひ取り組んでみてください。

参考:
[most](https://www.npmjs.com/package/most)
[fantasy land](https://www.npmjs.com/package/fantasy-land)

モナドを利用した自作ライブラリ
[losand](https://www.npmjs.com/package/losand)
[dsand](https://github.com/johnny-shaman/dsand)
Web Authentication API の MDN ドキュメントを翻訳してみた

[Web Authentication API の MDN ドキュメント](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)が翻訳されていなかったので、自己理解のために翻訳した文章を公開します。
後半は要約している部分も多いので、興味をお持ちの方はぜひ原文をお読みください。

NOTE: 2018年8月15日現在、MDN ドキュメントの一部はすでに翻訳されているようです。

## Web Authentication のコンセプトと使い方

Web Authentication API (WebAuthn とも呼ばれる) は、Web サイトでの登録やログイン、二要素認証を行うために、パスワードや SMS メッセージの代わりに非対称 (公開鍵) 暗号方式を用います。これはフィッシング、データ侵害、SMS メッセージやその他の二要素認証方式に対する攻撃といったセキュリティ問題を解決します。また、何十ものパスワードを管理する必要がなくなるため、ユーザビリティも大幅に向上させます。

多くの Web サイトでは、新しいアカウントの登録やログインの手段が既に用意されています。そのため WebAuthn は、これらの代替または補完として機能します。Credential Management API の形式と同様に、Web Authentification API は登録とログインの2つの基本的なメソッドを持っています。

- `navigator.credentials.create()`
  - `publicKey` オプションと共に使用します。新しいクレデンシャルを作成し、新しいアカウントに登録するか、または既存のアカウントに新しいクレデンシャルを関連付けます
- `navigator.credentials.get()`
  - `publicKey` オプションと共に使用します。そのサービスで認証するための既存のクレデンシャルを使用し、ログインするか、または二要素認証の一要素として機能します

NOTE: `create()` と `get()` のいずれも Secure Context (HTTPS か localhost であること) を要求します。ブラウザが Secure Context で動作していない場合は使用できません

最も基本的な方式では、`create()` と `get()` の両方で、サーバからチャレンジと呼ばれる非常に大きな乱数を受け取り、秘密鍵で署名されたチャレンジをサーバに返却します。これは、ネットワーク上に秘密情報を明らかにすることなく、認証に必要な秘密鍵をユーザが所有していることをサーバに証明します。

`create()` と `get()` メソッドがどのように適合するのかをより大きなイメージで理解するには、それらがブラウザ外の2つのコンポーネント間にあることを理解することが重要です。

- サーバ
  - WebAuthn API は、サーバ (サービスまたは Relying Party とも呼ばれる) に新しいクレデンシャルを登録し、その後、同じサーバで同じクレデンシャルを使用してユーザを認証することを目的としています
- 認証器
  - クレデンシャルは作成されると、認証器と呼ばれるデバイスに保持されます。これは認証における新しいコンセプトです。パスワードを用いて認証する場合、パスワードはユーザの頭の中に保持されており、他のデバイスは必要ありません。WebAuthn を用いて認証する場合、パスワードは認証器に保持された鍵ペアに置き換えられます。認証器は Windows のようなオペレーティングシステムに組み込まれていても良く、USB または Bluetooth セキュリティキーのような物理トークンであっても構いません

## Registration
典型的な Registration プロセスは 6 ステップあります。

![MDN Webauthn Authentication (r1).png](https://qiita-image-store.s3.amazonaws.com/0/44003/2f6236d3-4b68-83c9-efd8-5aba270f0d5c.png)


1. サーバはチャレンジ、ユーザ情報、Relying Party 情報を `PublicKeyCredentialCreateOptions` としてクライアントに送る
2. クライアントはチャレンジ、ユーザ情報、Relying Party 情報、`clientDataHash` を認証器に送る
3. 認証器はユーザの検証を行い、新しい鍵ペアとアテステーションを生成する
4. 認証器は新しい公開鍵、クレデンシャルID、アテステーションを `attestationObject` としてクライアントに送る
5. クライアントは `clientData` と `attestationObject` を `AuthenticatorAttestationResponce` としてサーバに送る
6. サーバで検証を行い、登録を完了する

アプリケーションを作成する JavaScript プログラマは、`create()` メソッドが呼び出されて返却される、手順 1,5 だけを意識します。しかしながら、クライアントと認証器で行われる処理とその結果のデータの意味を理解するためには、手順 2,3,4 が不可欠です。


## Authentication
ユーザが WebAuthn による登録を終えた後、サービスで Authentication (ログインまたはサインインとも呼ばれる) を行うことができます。Authentication フローは Registration フローに似ています。最も重要な違いは、ユーザまたは Relying Party の情報を必要としないことです。

![MDN Webauthn Registration (r3).png](https://qiita-image-store.s3.amazonaws.com/0/44003/5f6d4af6-b0fc-6af2-9460-0d6768b049c3.png)

1. サーバはチャレンジを `PublicKeyCredentialRequestOptions` としてクライアントに送る
2. クライアントはチャレンジ、Relying Party ID、`clientDataHash` を認証器に送る
3. 認証器はユーザの検証を行い、アサーションを生成する
4. 認証器は `authenticatorData` と署名をクライアントに送る
5. クライアントは `clientDataJSON` と `authenticatorData`、署名を `AuthenticatorAssertionResponce` としてサーバに送る
6. サーバで検証を行い、認証を完了する
docker-compose 実行時の User interaction is not allowed エラー

リモートのノート（Mac）からホストのマシン（Mac Mini）にログインして、ホストマシンで `docker-compoer` を実行したら、次のようなエラーが出た。
むむむ... `User interaction is not allowed`、Pythonのエラーだと...初見だ...
ホストで直接実行した時にはエラーが出なかったのに...！！

```
$ docker-compose up -d --build
Building xxxxx
Traceback (most recent call last):
  File "site-packages/dockerpycreds/store.py", line 74, in _execute
  File "subprocess.py", line 336, in check_output
  File "subprocess.py", line 418, in run
subprocess.CalledProcessError: Command '['/usr/local/bin/docker-credential-osxkeychain', 'get']' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "site-packages/docker/auth.py", line 129, in _resolve_authconfig_credstore
  File "site-packages/dockerpycreds/store.py", line 35, in get
  File "site-packages/dockerpycreds/store.py", line 87, in _execute
dockerpycreds.errors.StoreError: Credentials store docker-credential-osxkeychain exited with "User interaction is not allowed.".

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 6, in <module>
  File "compose/cli/main.py", line 71, in main
  File "compose/cli/main.py", line 127, in perform_command
  File "compose/cli/main.py", line 1052, in up
  File "compose/cli/main.py", line 1048, in up
  File "compose/project.py", line 471, in up
  File "compose/service.py", line 336, in ensure_image_exists
  File "compose/service.py", line 1067, in build
  File "site-packages/docker/api/build.py", line 251, in build
  File "site-packages/docker/api/build.py", line 306, in _set_auth_headers
  File "site-packages/docker/auth.py", line 96, in resolve_authconfig
  File "site-packages/docker/auth.py", line 146, in _resolve_authconfig_credstore
docker.errors.DockerException: Credentials store error: StoreError('Credentials store docker-credential-osxkeychain exited with "User interaction is not allowed.".',)
[37125] Failed to execute script docker-compose
```

##　解決方法

KeyChainをアンロックすれば良いらしい。

```
$ security unlock-keychain
```

KeyChainのパスワードを入力して無事解決！
TypeORM+ServerlessFrameworkでおのれwebpackなmysqlエラー

みなさんは気づきましたか。
[あら便利カレンダー](https://benri2018.rnd.cloudpack.jp/)の日付と、記事の投稿日付がずれていることを...


さて、TypeORMネタです。

#### 構成
- ServerlessFramework
- serverless-webpack
- TypeORM

あたりを使ってTypeScriptなアプリケーションをAWS Lambda + API Gatewayな感じでデプロイしたいわけです。
これでデプロイするとMySQLドライバーがありません！くそしてねろ！みたいなことを言われます。
仕事なので寝てるわけにはいきません。

### 依存 of 依存をキャッチできない問題
依存物内のランタイムでロードされるような依存物はwebpackでロードされません。
今回のエラーはそれに起因します。

[このあたり](https://github.com/typeorm/typeorm/blob/master/src/driver/mysql/MysqlDriver.ts#L688)のコードです。

```typescript
if (name) {
  return require("mysql");
}
```

みたいなことがされてます。
こうなるとmysqlをwebpackingできなくてくそして寝る羽目になります。


#### 解決策

これはserverless-webpackで強制的にincludeすることで解決できます。

```yml:serverless.yml
custom:
  webpack:
    includeModules:
      forceInclude:
        - mysql
```

たったこれだけ。
知りませんでした。
HTML&CSSについて

#HTML&CSSとは

HTML…web pageを作るための言語
CSS…HTMLのデザインを決める言語

HTMLのFileを保存する際は、「index.html」と名付けるのが一般的。
.htmlをつけなければ、htmlと認識されないので注意。

##要素と空要素
HTMLは、表示したいコンテンツを開始タグと終了タグで囲むことにより表示する機能。
タグと、タグで囲まれたコンテンツ全体のことを、「要素」と言う。
また、囲むコンテンツがない「空要素」と呼ばれるものもある。

##属性
タグには「属性」というものをつけることができる。

代表的なタグ

- `<!DOCTYPE>`…文書の種類を表すもの。DOCTYPE宣言という。慣習的に大文字。

- `<html>`…html全体の親要素になるタグ。Web pageのコンテンツはすべて、この親要素の子にあたる関係にしなければならない。（<html lang=”ja”></html>）

- `<head>`…ページ全体の情報を記す部分。本文には表示されないが、グーグル検索などでクローラーが、web pageを評価する際に必要。

- meta要素…データを記すデータ。文字セット、著者などを記す。　
属性ex.(name,charset)
- title要素…文書の題名。ブラウザーのタイトルバーやページのタブに表示される。

- link要素…現在の文書と外部のリソースとの関係性を表す。
Ex.(<link rel=”icon” href=”favicon.ico”>)

- <body>…文書の本分にあたる部分

- `<h1~h6>`見出し。h1~h6があり、重要度はh1のほうが高い。
- `<p>`段落
- `<img>`…画像を埋め込む空要素。
- 属性alt…画像が表示されなかった際の説明文。
　　	　　width…画像の幅
   	　　height…画像の高さ

メモ：
・字下げは大事。特に子要素。
・メモ書きを入れることができる。コメントという。あとから見たときに分かりやすい。Ex.<!-- メモ --!>
Linux Mysql コマンド//メモ用!

```
Version 基準
CentOS - 6.9
MySQL - 5.6
```

```
linux
ll <=> ls -l
```

```
linux
grep -r 検索語
- 検索語が入ってるファイルの経路と
　検索語が含まれている列が出る。
```


```
linux・mysql
ctrl + u
コマンド入力中、カーソルの前まで消す
```

```
linux

find . -name "ファイル名" | xargs grep ="検索語"
例）find . -name "*.php" | xargs grep = "abcdefg"
grep -n : 行番号が付く

```

```
linux
localhost経路変更
vi /etc/httpd/conf/httpd.conf
```


```
linux
Apache 再起動
service httpd restart
```


```
linux
MySQL 再起動
CentOSで service mysqld restart
```


```
linux
historyに日付を付け方
vi /etc/profile.d/history.sh

HISTSIZE=3000
HISTTIMEFORMAT="%Y/%m/%d %T "
```


```
linux
crontab -e
crontabの一覧表示＆修正
```

```
linux
ssh ip_address -p port番号 -l hostname -i 鍵の経路
```

```
d
```

```sql
MySQL接続
mysql
mysql -u root
```

```sql
SQL終了
￥q
ctrl + c(強制終了）
```


```sql
database保存経路確認
show variables like 'datadir'
```


```sql
limit
select * from filename limit 2;
```

```sql
limit 1\G
select * from filename limit 1\G
```

```sql
SQLファイルインポート
source sqlfileの名

* エラー等でインポートができないと、
1. create database databaseの名 ;
2. CENTOSで　mysql -u username -p database_name < file.sql
```

```sql
d
```


```sql
d
```


```sql
d
```


```sql
d
```
一つのVPSに複数のサブドメインの証明書を置く(at let's encrypt)

ドメイン名：sub.domain.com
DocumentRoot：/var/www/sub.domain.com/index.html

ドメイン名：stage.domain.com
DocumentRoot：/var/www/stage.domain.com/index.html

80ポートを443ポートにリダイレクトしている設定が既にある場合は解除しておく

certbot-autoではうまくいかなかったのでcertbot

`# certbot --apache -w /var/www/sub.domain.com -d sub.domain.com -w /var/www/stage.domain.com -d stage.domain.com`
PythonとGCPの組み合わせでWebサイトを作る【「本棚自慢」サイト開発日誌#1】

# 経緯

業務でPythonとGCPの知識が必要になるのでチュートリアルなどしてみたものの、結局は実戦（実際に動くものを本番（＝インターネット上へ）リリースする）が一番力がつくので、やってみることにする。
業務では、GolangやAngularも必要そうだけど、Golangは２年くらい業務経験あるので優先度下げる。
Angularはチュートリアルを多少やったものの、機能が多く、Python、GCPの勉強と同時並行が難しそうなので、ある程度、Python+GCPの開発が軌道に乗った後でトライする。

# 環境

- 開発端末：Linux（Ubuntu 17.10）
- 言語：Python（v3.6.3）※ pip は v9.0.1
- フレームワーク：Flask（v1.0.2）

## ＜前提＞

- GCPはアカウント取得済み。
- Google Cloud SDK取得・認証済み。

# 今日のお題

- Webサイトの題材を決める。
- Python3で単純にWebページ表示するくらいやってみる。
- GCP上（GAE）にデプロイしてみる。

## ■Webサイトの題材を決める。

前々から「いろんなエンジニアの本棚が見てみたい」と思っていたので、Webサイト名は「本棚自慢」。
ちゃんと検討・設計してから作るというより、とりあえず作って少しずつ拡張・改善。

自分の本棚の写真を撮って投稿してもらう。そしてそれを一覧に表示する。
まずはそれまでを当面の目標にする。

## ■Python3で単純にWebページ表示するくらいやってみる。

以下ソースで実施済み。
https://github.com/sky0621/bicherregal-py/tree/4690e65ae98b243ac38db257466326a711861384

![kjgirm.png](https://qiita-image-store.s3.amazonaws.com/0/180599/52497a41-97fe-eaa6-c61b-3dddc333b23b.png)

【参考】
　http://flask.pocoo.org/docs/1.0/

## ■GCP上（GAE）にデプロイしてみる。

↓のようなYAMLを用意（Pythonプロジェクト直下）すると、作ったPythonのWebアプリがGAE上で起動してくれる。

<pre>
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
  python_version: 3
</pre>

https://github.com/sky0621/bicherregal-py/blob/4690e65ae98b243ac38db257466326a711861384/app.yaml

上記YAMLが存在するパスで以下実行すると、GCP上にデプロイされる。
<pre>
$ gcloud app deploy
Services to deploy:
　　　　　　〜
Do you want to continue (Y/n)?  y
　　　　　　〜
　　けっこう時間がかかる
　　　　　　〜
DONE
　　　　　　〜
</pre>

デプロイ結果の確認。
<pre>
$ gcloud app browse
</pre>

![YCEMYF.png](https://qiita-image-store.s3.amazonaws.com/0/180599/63d95c8a-7e47-b4a6-5004-3ee082466202.png)

★「xxxxxxxx」の部分には、自分のGCPプロジェクトのIDが入る。

【参考】
　https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml?authuser=1&hl=ja
　https://cloud.google.com/appengine/docs/flexible/python/quickstart?authuser=1&hl=ja
fzfを使用してgit grepを行う

# やりたいこと

- `Git grep`をvimから呼び出す
- fzfを使用して検索されたファイルの該当行に飛ぶ

# 準備

fzf, fzf.vimを入れておきしょう。

https://qiita.com/hisawa/items/fc5300a526cb926aef08

環境は

- Mac 10.12.6
- Custom Version 8.0.1633 (KaoriYa 20180324)

# やり方

下記を`.vimrc`に追記して読み込む。
`:Gitgrep hogehoge`で使用できます。

```vim:.vimrc
command! -bang -nargs=+ Gitgrep call fzf#run({
      \ 'source': 'git grep -n -I -i <args>',
      \ 'sink': function('s:line_handler'),
      \ 'dir': s:get_git_base_path(expand("%:p:h")),
      \ 'up': '~40%',
      \ 'options': '+m'
      \ })

" .gitディレクトリがあるパスを取得する
function! s:get_git_base_path(current_dir) abort
  if isdirectory(expand(a:current_dir . '/.git'))
    return a:current_dir
  else
    let sp_dir = split(a:current_dir, '/')
    call remove(sp_dir, -1)
    return s:get_git_base_path('/' . expand(join(sp_dir, '/')))
  endif
endfunction

" 行が選択された時の動き
function! s:line_handler(line)
  let keys = split(a:line, ':')
  " path
  exec 'e '. keys[0]
  " line
  exec keys[1]

  normal! ^zz
endfunction
```

# できなかったこと

- .gitファイルがなかった場合のエラー処理
- `git grep <pattern> <path>`のpath部分の指定

いい方法があれば教えてください。
https://gist.github.com/hsawaji/42a604c955929d26debc44d70885b4f7

# 参考
https://github.com/junegunn/fzf/wiki/Examples-(vim)
https://gist.github.com/drasill/adb258e1363a22e6e433
CSSアニメーションとかいうやつがよくわからない人へ

#CSSアニメーションとかトラなんとかとか・・・
CSS3が広く使われるようになってずいぶん経ちました。
私も重宝してますCSS3。
でもCSSアニメーションがよくわからない。
特にanimation・transition・transformの3つがごっちゃになってる。
いい加減理解しようと決心したので、調べました。
##ごっちゃになってる3つのプロパティ
簡潔に言うとこういうことでした。


| transform | transition | animation |
|:-:|:-:|:-:|
| アニメじゃない  | アニメーション | アニメーション |
| （静的）変形 | 変化 | 複雑な変化も可能  |

なーんだアニメじゃないのかtransform。てっきり動くのかと思ってました（笑）

##つまりこういうことか（動作で確認）

映像イメージで自分の脳みそに記憶させるために、ホバーアクションで実際に動かしてみます。
まずはいつものやつ。**基本のホバー**はこんなんですよね。

<p data-height="265" data-theme-id="0" data-slug-hash="bjadWV" data-default-tab="css,result" data-user="kapeking" data-pen-title="CSS3 アニメーション" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/bjadWV/">CSS3 アニメーション</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ここに**transformプロパティ**を入れてみます。

<p data-height="265" data-theme-id="0" data-slug-hash="BPJNPj" data-default-tab="css,result" data-user="kapeking" data-pen-title="transformのホバーアクション" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/BPJNPj/">transformのホバーアクション</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

今回は「translate（移動）」にしてみました。マウスオーバーでぱっと移動しますね。
これがいわゆる静的変化。昔よくあったホバーで画像が切り替わるボタンとかそんな感じか。ふむふむ。

これに更にcssアニメーションの**transitionプロパティ**を追加してみます。

<p data-height="265" data-theme-id="0" data-slug-hash="MBrajB" data-default-tab="css,result" data-user="kapeking" data-pen-title="transitionのホバーアクション" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/MBrajB/">transitionのホバーアクション</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

transitionプロパティの記述方法知らなかったけど「1秒後にtransformの状態に変化してください」って感じで書いたらちゃんと動きました。
**わたしすごい。**・・・あとで記述方法ちゃんと調べます。
さっきはぱっと移動してたのがぬるっと移動します。これが・・・アニメーション・・・！

さて、最後に**animationプロパティ**。なんかすごいことできるんだろー？（期待）

<p data-height="265" data-theme-id="0" data-slug-hash="rrpOPE" data-default-tab="css,result" data-user="kapeking" data-pen-title="animationのホバーアクション" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/rrpOPE/">animationのホバーアクション</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

ちょっとtransitionより難易度上がった感あったけど、こんな感じになりました。

transitionとanimationを使ってみてわかった違いは

 + transitionは直線アニメーション
 + animationは途中に変化を加えることができる
 + animationは「@keyframes」というものを使う

・・・て感じでした！
これでもう3つのプロパティで混乱しないで済みそうです（笑）
Hyper-V環境GitHub Enterpriseのディスク拡張

# 環境
* Windows Server 2008 R2 Hyper-V
* GitHub Enterprise 2.13.4

# やりたいこと
新規ディスクはアタッチせずに、既存割り当てのディスクを拡張したい

# 手順

以下公式手順を参照しました。
[Increasing storage capacity](https://help.github.com/enterprise/2.14/admin/guides/installation/increasing-storage-capacity/)
ほぼほぼこの通りでいけますが、Hyper-Vであることと、メンテナンスモードに若干戸惑ったので残しておきます。

## GHEをメンテナンスモードに

* GHE管理者画面を開き、[Maintenance]タブを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/65e7dbaf-f5ef-f32f-9241-b6df92f21f37.png)
<br>

* 即時メンテナンスモードにしたい場合は「now」となっているまま、[Enable maintenance mode]のチェックボックスをオンにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/85f55f79-3679-b035-d939-4ec18e2bfe28.png)
<br>

* メンテナンスモードになると、管理者画面はこんな感じになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/34d0ccc3-62a1-0eef-b2ec-7166e69d2a29.png)
<br>

* この状態で利用ユーザがGHEにアクセスすると、メンテナンスモードの画面になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/eba0bc01-17cd-4811-647a-1efec7ba14bb.png)
<br>

## Hyper-V側でVMのディスクを拡張

* Hyper-Vの操作でGHEサーバをシャットダウンします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/0e29a365-1a70-9280-8073-d4b010040a76.png)
<br>

* VMが停止したら、[ディスクの編集]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/20f6e07c-726a-05ad-72ee-be949adaf86c.png)
<br>

* [参照]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/86a7e9cd-6ae5-47a0-a6b2-216c0819d96f.png)
<br>

* 次にvhdファイルを選択します。このときルートディスクではなく、データディスクを選択するようにしてください。

* 拡張するサイズを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a45d150f-9918-0131-2c8c-5adc4920888b.png)
<br>

* ディスク拡張が完了したら、VMを起動します。起動後のGHEはまだメンテナンスモードになっています。

## GHE側でディスク拡張

* TeraTerm等のSSHターミナルソフトでGHEにadminユーザでアクセスします。手順は公式を参照。
[Accessing the administrative shell](https://help.github.com/enterprise/2.14/admin/guides/installation/accessing-the-administrative-shell-ssh/)

* とりあえずdfコマンドで現在のディスクサイズを確認しておきます。

```
$ df -h
Filesystem                                      Size  Used Avail Use% Mounted on
/dev/mapper/ghe_storage_abcdefgh-ghe_user_data  125G  4.1G  115G   4% /data/user
```

* ghe-storage-extendコマンドを実行してディスクを拡張します。

```
$ ghe-storage-extend
  中略
Success: ghe_storage_abcdefgh is 140.00g
```

* ディスクサイズが拡張されたことを確認します。

```
$ df -h
Filesystem                                      Size  Used Avail Use% Mounted on
/dev/mapper/ghe_storage_abcdefgh-ghe_user_data  138G  4.0G  127G   4% /data/user
```

## GHEのメンテナンスモード解除

ここでちょっとハマったんですが、GHE管理画面をいくら探してもメンテナンスモードをDisableするような機能が見当たりませんでした。
調べてみるとコマンドレットが用意されていたので、コマンドでメンテナンスモードを解除しました。

* 現在の状態がメンテナンスモードであることを確認する。

```
$ ghe-maintenance -q
maintenance mode set
```

* メンテナンスモードを解除する

```
$ ghe-maintenance -u
```

* 現在の状態を確認する。

```
$ ghe-maintenance -q
maintenance mode not set
```
配列で円を描く/円の描画プログラム

#0. 概要
ふとプログラムで円の描画をしたくなったが、どうやるんだ？
円の方程式を解いて、ブレゼンハムアルゴリズムでタイルを埋めるのか・・？と悩んでいたところ、以下のサイトを発見。
http://fussy.web.fc2.com/algo/algo2-1.htm

動かしてみたところ簡単に円が描画できるようになった。すごい
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95636/35de54e9-40c5-24f2-bf92-eb54396ed098.png)

備忘録として残しておく。

#1. 実装

```
#include <stdio.h>
#define CANVAS_SIZE_X 20
#define CANVAS_SIZE_Y 20
int canvas[CANVAS_SIZE_X][CANVAS_SIZE_Y];


void set_dot(int _x, int _y) {
	canvas[_x][_y] = 1;
	return;
}

void circle(int x0, int y0, int r)
{
	int x = r;
	int y = 0;
	int F = -2 * r + 3;
	while (x >= y) {
		set_dot(x0 + x, y0 + y);
		set_dot(x0 - x, y0 + y);
		set_dot(x0 + x, y0 - y);
		set_dot(x0 - x, y0 - y);
		set_dot(x0 + y, y0 + x);
		set_dot(x0 - y, y0 + x);
		set_dot(x0 + y, y0 - x);
		set_dot(x0 - y, y0 - x);
		if (F >= 0) {
			x--;
			F -= 4 * x;
		}
		y++;
		F += 4 * y + 2;
	}
}

void disp() {
	printf("---------------------------------------------\n");
	for (int i = 0; i < CANVAS_SIZE_Y; i++) {
		for (int j = 0; j < CANVAS_SIZE_X; j++) {
			printf("%d ", canvas[j][i]);
		}
		printf("\n");
	}
	printf("---------------------------------------------\n");
	return;
}

int main() {

	// Init
	for (int i = 0; i < CANVAS_SIZE_Y; i++) {
		for (int j = 0; j < CANVAS_SIZE_X; j++) {
			canvas[j][i] = 0;
		}
	}
	disp();
	circle(10, 10, 6);
	disp();

	getchar();
	return 0;
}


```
【Xcode】UIButtonのタイトルを改行させる方法

## UIButtonのタイトルを改行したい

UIButtonのタイトルが長くて、↓こんな風に省略されてしまいました。

<img width="240" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/38924/752c691e-852b-ed56-4f82-afb8135f2fdc.png">


そこで、タイトルを改行する方法を調べてみたら、こちらの記事[iOS7.1でボタンのタイトルが改行しなくなったら見るメモ](https://qiita.com/n-shinkai/items/1efec98839d890d41ffb)にたどりつきました。

## タイトルを改行してみよう

基本的には上の記事で紹介されている通りです。
UIButtonの `titleLabel` には `numberOfLines` プロパティがあるので、こちらに `0` を設定します。

``` Swift
    @IBOutlet weak var titleButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        titleButton.titleLabel?.numberOfLines = 0
        titleButton.setTitle("タイトルの文字列です。すごく長いので改行して欲しいのですよ。", for: .normal)
    }
```

すると、こちら↓のように自動的に改行してくれます。

<img width="247" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/38924/e89407da-facb-fe89-36b2-92da8b69a43d.png">

## numberOfLinesとは

numberOfLinesは、UILabelのプロパティです。

アップルの公式ドキュメント[numberOfLines - UILabel | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uilabel/1620539-numberoflines)では、↓こちらのように解説されています。

> This property controls the maximum number of lines to use in order to fit the label’s text into its bounding rectangle. The default value for this property is 1. To remove any maximum limit, and use as many lines as needed, set the value of this property to 0.
> （Google翻訳）このプロパティは、境界矩形にラベルを収めるために使用する行の最大数を制御します。 最大限度を削除し、必要な数だけ行を使用するには、このプロパティの値を0に設定します。

初期値は1が設定されていて1行で表示されます。
2行にしたいときは2を設定します。
テキストに合わせて無制限に改行するときは、0を設定します。

## ボタンのタイトルがふわっとアニメーションしないようにする方法

UIButtonに `setTitle:forState:` でタイトルを設定すると、タイトル文字を表示するときに、自動的にふわっとアニメーションします。

このアニメーションをオフにしたいときは、以下のように一時的にUIViewのアニメーションをオフにします。

``` Swift
    @IBOutlet weak var titleButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        UIView.setAnimationsEnabled(false)
        titleButton.titleLabel?.numberOfLines = 0
        titleButton.setTitle("タイトルの文字列です。すごく長いので改行して欲しいのですよ。", for: .normal)
        titleButton.layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
```
ubuntuでapache2のDocumentRootを変更するまで

sphinxで作成したhtmlファイルを公開する際に
変更したapache2の設定メモ

# 環境
OS:Ubuntu
VERSION:16.04.5 LTS (Xenial Xerus)
apache2 ver:Apache/2.4.18 (Ubuntu)


# やったこと
## apache2インストール
```
apt-get install apache2
```

## apache2の設定
### apache2.conf
apache2.confに下記の設定を追加。

```/etc/apache2/apache2.conf
ServerName hoge
```

hogeのところはなんでも良い

自分の作成したコンテンツのdirを指定する文も追加で記述する。

```/etc/apache2/apache2.conf
<Directory "自分のコンテンツのdir">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
```
上位の文はもともとapache2.conf内に記述されている/var/www/向けの記述をコピペして、""のところを変えただけである。

### 000-default.conf
000-default.confは/etc/apache2/sites-available directory内にdefaultでおいてあるvirtual hostの設定が書いてあるファイル。
今回はこのファイルをそのまま使用したため、こちらも少々変更した。
変更した場所は下記になる

```/etc/apache2/sites-available/000-default.conf
DocumentRoot /var/www/html
↓
#DocumentRoot /var/www/html
DocumentRoot "自分のコンテンツのdir"
```

### service 再起動

```
/etc/init.d/apache2 restart
```

今回はsites-enable内で使用していた000-default.confを使用したが、新たに作成したファイルなどであると
設定ファイルを削除・適用としなければならないケースもあり。
念のためにそのコマンドも記述する。

```
a2dissite "sites-enable内にある.confファイル名"
a2ensite "sites-available内にある.confファイル名"
/etc/init.d/apache2 restart
```

# 今回のハマりポイント
各種qiitaの記事や、ネットの投稿をみて設定を確認したが、だいたいDocumentRootの設定のみで、apache2.conf内に<Directory>節の記述を行わなければならないとは書いていなかった。
そして、localhostで動きを確かめた際に、permission errorのページが出たことから、権限周りを見ていたため問題の本質とは違うところに目をつけて試行錯誤してしまった。
ターミナルエミュレータ内でクリッカブルなリンクを作る方法

iTerm2で下記コマンドを実行すると

```
$ echo -e '\e]8;;http://example.com\aThis is a link\e]8;;\a'
```

`This is a link` というテキストが下線つきで表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79394/faf87bf3-55ce-52cf-6558-84193b3876f5.png)

このテキストをCmdキーを押しながらマウスでクリックすると `http://example.com` が開く。

このエスケープシーケンスは`OSC 8`と呼ばれる（OSCは`Operating System Command`の略で`\e]`を意味する）。
iTerm2以外でもkitty, wezterm, Alacritty, Windows Terminalなどモダンなターミナルエミュレータは対応しているが、古めのものは対応していないようだ。
https://github.com/Alhadis/OSC8-Adoption/

iTerm2でもscreenを実行しているとダメ。

ちなみにiTerm2はこのエスケープシーケンスを使わずとも、URLの上でCmd＋クリックすると開ける。同様の機能はurxvtやminttyなど多数のターミナルエミュレータに実装されている。
Wordpressでブログに動画をアップしようとするとHTTPエラーが表示されアップロードできない場合の対策

## 起こったこと
題名の通り、wordpressでブログの中に動画も入れようとしてアップしたら「HTTPエラー」と表示されアップできなくなった。
前までは普通にアップロードできてたのに、、、動画のサイズにも問題ないし、、、
### 目次

1. 原因
2. 対策

## 1. 原因(僕の場合)

### WP-Optimizeというプラグインを最近入れていた
このHTTPエラーに関してもちろんググったのだが、この記事が出てきた。
https://ja.wordpress.org/plugins/ewww-image-optimizer/
この記事にはこのエラーは「EWWW Image Optimizer」のプラグインが原因だと書かれていた。
ん？？「Optimizerだと？？？」なんか聞いたことある名前だなぁ、、、

そういえば、前にスパムコメントがめちゃくちゃきてて、一つずつ削除するのはさすがにきついのでプラグイン使って一気に削除したいと思って「WP-Optimize」というプラグインをインストールして無事に一括で削除できてテンション上がっていた自分を思い出した。

## 修正したこと
僕が前にインストールしていた「WP-Optimize」も原因の一つなのでは？？？と名推理を働かせて、このプラグインを停止させて、もう一度動画をアップロードして見たら、見事成功！！

またスパムアカウントめっちゃきたら、一時的にあのプラグインを有効化してコメント全て削除して、またプラグイン停止したら大丈夫！と結論がでた。

つまり、新たに入れたプラグインが原因で、何かしらに問題が起こることがあるんだなと知りました。

## 感想
スパムアカウント送ってくる外国人の方々、もうやめて、、、笑
direnvとpiculetを使いAWSのセキュリティーグループを設定する

#はじめに
4月から新社会人になり研修終了後インフラを担当する部署へ配属され、すぐに使う機会があったツールで「最高に便利！！」と感じた2つを簡単にまとめました。
使用PC：Mac　※bundleインストール済み

##direnv
各ディレクトリに環境変数を定義し、作業を行ないたいディレクトリになった時に環境変数が有効になり、そのディレクトリから抜けると無効になるツールです。 なので、プロジェクト固有の環境変数を使用できます。

仕組み
direnvはカレントディレクトリと親ディレクトリに".envrc"ファイルの存在確認が取れると実行できるようになります。なので、実行できるときは設定した環境変数がエクスポートされます。

##piculet
piculetはAWSのセキュリティグループを管理するためのツールで、Ruby DSLを使用し、更新をすることができます。

仕組み
すでに設定している内容をRuby DSLにエクスポートし編集を行うことでAWSのセキュリティーグループを更新します。操作を1回行っても複数回行っても結果が、Ruby DSLの記述通りにAWSが設定されます。

DSLは以下のようになっています。

```ruby:DSL
ec2 "vpc-XXXXXXXX" do
  security_group "default" do
    description "default VPC security group"

    ingress do
      permission :tcp, 80..80 do
        ip_ranges(
          "0.0.0.0/0",
        )
      end
      permission :any do
        groups(
          "any_other_group",
          "default"
        )
      end
    end

```

#AWSのセキュリティーグループを設定
##はじめに**direnv**の設定をします

```ruby:インストール
$brew install direnv
```


AWSのセキュリティーグループファイルを置きたいディレクトリに移動する

```ruby:初期設定
$echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$source ~/.bashrc
```

```ruby:.envrcを作成
$direnv edit .
```
```ruby:環境変数
export AWS_ACCESS_KEY_ID=AWSアクセスキー
export AWS_SECRET_ACCESS_KEY=AWSシークレットアクセスキー
export AWS_REGION=リージョン名
```
```ruby:確認
$env | grep ^AWS
```
###direnvの設定が完了後、AWSセキュリティーグループの設定に入ります。
##piculet

```ruby:インストール
$gem install piculet --no-ri --no-rdoc
```

```ruby:セキュリティグループを取得
$bundle exec piculet -e -o Groupfile
```
※確認・更新するときは毎回実行する。

```ruby:Groupfile編集
$vim Groupfile
```

```ruby:テスト・適用
$bundle exec piculet -a  Groupfile --dry-run
$bundle exec piculet -a  Groupfile
```

#もう**direnv**と**piculet**は手放せません。その理由は

**direnv**
一度設定してしまえばAWSのIAMアカウントが多くても間違えることがほぼ無くなるのでトラブル対策にもなります。AWSセキュリティーグループだけでなく、他にAMIのバックアップをAWS CLIで行うときにも使え、2回目からAWSアクセスキー、AWSシークレットアクセスキーの入力の手間が省けるので良いと感じました。

**piculet**
作業履歴を残したいとき、AWSコンソール画面のスクリーンショット数が増えるとめんどくさいですが、piculetを使えば少なくとも更新前と更新後の結果をコピーするだけでいいからです。私の場合は--dry-runを行なったさいのテスト結果も一度コピーをとるのですが、スクリーンショットするより圧倒的に楽なのでありがたいです。

#参考元
https://so-wh.at/entry/20131105/p1
https://direnv.net/
aws cli で AssumeRole を使用する方法(~/.aws/config & ~/.aws/credentials編）

# 簡単ですが、aws cli で AssumeRole を使用する方法(~/.aws/config & ~/.aws/credentials編）をご紹介します。

## ~/.aws/config と ~/.aws/credentials　への設定追加

```~/.aws/config
[profile iamuser1]
output = json
region = ap-northeast-1

[profile sample1]
role_arn = arn:aws:iam::移譲元アカウントNO:role/AssumeRole名
source_profile = iamuser1

```

```~/.aws/credentials
[iamuser1]
aws_access_key_id = ********************
aws_secret_access_key = ****************************************

[sample1]
role_arn = arn:aws:iam::移譲元アカウントNO:role/AssumeRole名
source_profile = iamuser1
```

## 実行時(例）serverless　deploy

```sample.sh
export AWS_DEFAULT_PROFILE=sample1
sls deploy --profile sample1 --stage staging
```

## 実行時(例）aws s3 ls

```sample.sh
export AWS_DEFAULT_PROFILE=sample1
aws s3 ls
```

## AWS_DEFAULT_PROFILE

使用するコマンドによって、AWS_PROFILE　だったり　AWS_DEFAULT_PROFILE　のどちらかが効くなどに違いがあるので、注意してください