OmniAICreator/Qiita-1.07M huggingface dataset:
HTML&CSSノートfrom Progate1

# はじめに

Progate で勉強した html&css の勉強のメモ
コース１の序盤です
##HTML

###見出しタグ

h タグで文字の大きさを決めることができます。
文字の大きさの範囲には`<h1>`から`<h6>`までの 6 段階があります。
`<h1>`が一番大きくて`<h6>`が一番小さいです
マークダウンでいう`#`のようなものです

```html
<h1>this is h1 tag</h1>
<h2>this is h2 tag</h2>
<h3>this is h3 tag</h3>
<h4>this is h4 tag</h4>
<h5>this is h5 tag</h5>
<h6>this is h6 tag</h6>
```

結果
#this is h1 tag
##this is h2 tag
###this is h3 tag
####this is h4 tag
#####this is h5 tag
######this is h6 tag

###段落タグ

p タグは段落を追加することができます

```html
<h1>hello</h1>
<p>world</p>
```

###コメント

html でコメントを書くには`<!----->`を使います

```html
<!--this is comment-->
```

### リンクタグ

a タグをつけることでリンクテキストのように表示することができます
a タグの中に`href`を追加することで URL の関連付けができます

```html
<a>link</a>

<a href="https://www.google.com">Link to Google</a>
```

####属性について
html の属性には上記の`href`のようにダブルクォーテーション`""`を付けます

###画像タグ

画像を張り付けるには img タグを付けます
属性には`src`(画像へのパス)や`url`(画像へのリンク)を追加できます
画像タグは必ず閉じてある必要はありません

```html
<img scr="path" /> <img url="url" />
```

###リスト

文字を li タグで囲むことでリストを作成できます
文字の前に`・`を追加するには`<li>`を`<ul>`で囲みます

```html
<ul>
  <li>tag1</li>
  <li>tag2</li>
</ul>
```

実行結果

- tag1
- tag2

##CSS
html 要素の色や大きさ、余白などの設定を行うのに使います

タグに対して適用させるには以下のように記述します

```css
/*h1タグに対して*/
h1 {
  /*いろいろ*/
}
/*pタグに対して*/
p {
  /*いろいろ*/
}
```

###色の設定

色を変えるには`color`を使います
`#RRGGBB`で色の要素を指定して設定をします

```css
/*h1タグを赤色にする*/
h1 {
  color: #ff0000;
}
/*pタグを緑色にする*/
p {
  color: #00ff00;
}
```

###文字の大きさ

フォントの大きさを変えるには`font-size`を使います
大きさは`px`や`em`などの単位があります

```css
/*h1タグのフォントの大きさを10ピクセルにする*/
h1 {
  font-size: 10px;
}
/*pタグのフォントの大きさを40ピクセルにする*/
p {
  color: #00ff00;
  font-size: 40px;
}
```

###フォントの設定

フォントをデフォルトのものから変えるには`font-family`を使います
フォントの名前に空白を含む場合には`""`で囲む必要があります

```css
/*h1タグをのフォントをserifにする*/
h1 {
  font-family: serif;
}
/*pタグのフォントをAvenir Nextにする*/
p {
  font-family: "Avenir Next";
}
``
```

###背景の色

背景の色の設定をするには`background-color`を使います。
色の指定は`#RGGBB`の他に`#RGB`のように指定できます。

```css
/*h1タグの背景を赤色にする*/
h1 {
  background-color: serif;
}
/*pタグの背景を緑色にする*/
p {
  background-color: "Avenir Next";
}
```

###要素の大きさの指定

要素の横幅を指定するには`width`、高さを指定するには`height`を指定します

```css
/*h1タグの大きさ80px*500pxにする*/
h1 {
  height: 80px;
  width: 500px;
}
/*pタグの大きさを200px*1000pxにする*/
p {
  height: 200px;
  width: 1000px;
}
```

###タグをクラスでラベリングする

タグの中に`class`を追加してラベリングすることでラベリングした範囲のみに css を適用することができます
指定するには`.`をクラスの前につけます

```html
<ul>
  <li class="select">HTML</li>
  <li>CSS</li>
  <li>Javascript</li>
</ul>
```

```css
.select {
  color: red;
}
```

上記のコードでは HTML だけ赤色になります
同じ class 名にすることで同じ CSS を反映できます
関数テンプレート


###関数テンプレートを使うと、型が異なる場合の関数定義をテンプレートとして、まとめて定義できる

```main.cpp
#include<iostream>

using namespace std;
//テンプレート宣言
template <typename T>
T add(T x1, T x2) { return x1 + x2; }
int main()
{
	int a = add(1, 2);//実行結果：3
	//float b = add(1.0F, 2);//第一引数がfloat型,第二引数がint型だから判断できない
	float b = add(1.0F, 5.0F);//これなら、型が判断できるからOK‼//実行結果：6

	cout << a <<endl;
	cout << b;
}
```
引数の型(int,float)</font>から<font color="GREEN">T型(template T)</font>を推測する
<font color="RED">**注意**</font> 引数の型が２つ混在すると、型の判断ができなくなって、エラーになる

型が混在する場合、明示的具現化を行う

```main.cpp
#include<iostream>

using namespace std;
template <typename T>
T add(T x1, T x2) { return x1 + x2; }

template<typename T1,typename T2>
T2 average(T1 x1, T1 x2) { return (x1 + x2) / 2.0; }
int main()
{
	//明示的具現化
	int c = add<int>(50, 60.0F);//計算結果がint型で返ってくる
	cout << c << endl;//結果110
	double d = average<float, double>(10.0F, 20.0F);
	cout << d << endl;//結果15.00000以下略
}
```
cのように、型を関数名の後に指定してあげると、その型で返すことができる
**dはfloat型で受け取った値をdouble型で返している( T1→float,T2→double)**
**返り値がT2なので、double型となる**

```main.cpp
#include<iostream>

//名前空間
using namespace std;

template <typename T3>
bool equal(T3 a, T3 b)//二つの値が等しいかどうか比較する
{
	return a == b;
}
int main()
{
	int a = 3;
	int b = 3;
	cout<<equal(a, b)<<endl;//trueが返ってくる

	//文字列の場合
	//文字列リテラル同士の比較
	cout<<equal("ABC", "ABC")<<endl;//trueが返ってくる

	//文字列のポインタ同士の比較
	char str1[10] = "ABC";
	char str2[10] = "ABC";
	cout<<equal(str1, str2)<<endl;//falseが返ってくる

	
}
```
なぜリテラル同士だと正しく結果が返ってくるのに、文字列ポインタ同士だと、正しい結果が返ってこないのか
<font color=BLUE>**文字列ポインタ同士だと、アドレスの比較を行ってしまうからです**</font>
文字列ポインタ同士を比較したい場合→完全特殊化を行う

```main.cpp
#include<iostream>

//名前空間
using namespace std;

//完全特殊化
template<>
bool equal(char* A, char* B)//引数で指定している方の場合のみ、この動作を行う
{
	return strcmp(A, B) == 0;//strcmp関数で文字列の大小を比較(A<Bなら負の値、A==Bなら0、A＞Bなら正の値が返ってくる)
}
int maih()
{
       char str1[10] = "ABC";
	char str2[10] = "ABC";
	cout << equal(str1, str2) << endl;//trueが返ってくる


}
```
完全特殊化を行うと引数で指定した型の場合のみ、その動作を行ってくれる
Ubuntu 16.04にCaffeをインストールする

# はじめに
Ubuntu 16.04にCaffeをインストールするときに，そのままではうまく行かなかったので，色々と調べたことをまとめました．
また，今回の手順ではPythonではPython 2でのみ使用できます．
注意として，CUDA，cuDNN以外はほぼまっさらな状態で作業をしています．


# 環境

- Ubuntu 16.04
- CUDA 10.0.130
- cuDNN 7.6.0.64

CUDAやcuDNNのパスの設定は一通りやってあるとします．

恐らくCUDAやcuDNNのバージョンの違いはそこまでないかと思います．

# インストール手順
## 依存環境のインストール

試行錯誤しながらの作業だったので，必要のないものもあるかもしれません．

```
sudo apt update
sudo apt install -y --no-install-recommends libboost-all-dev build-essential cmake git pkg-config vim \
libprotobuf-dev libleveldb-dev libsnappy-dev libhdf5-serial-dev protobuf-compiler \
libatlas-base-dev libjasper-dev libgflags-dev libgoogle-glog-dev liblmdb-dev \
python-pip python-dev python-numpy python-scipy libopencv-dev python-skimage python-protobuf
```

## Caffeのダウンロード
Caffe本体をダウンロードします．
特定のバージョンをインストールしたい場合は各自そちらをダウンロードしてください．

```
git clone https://github.com/BVLC/caffe.git
```

## Makefile.configの編集

Makefile.configの編集をしていきます．

```
cd caffe
cp Makefile.config.example Makefile.config
```

Makefile.configを以下の変数を編集します．

```
USE_CUDNN:= 1
CUDA_DIR := /usr/local/cuda 
PYTHON_INCLUDE := /usr/include/python2.7 /usr/lib/python2.7/dist-packages/numpy/core/include
PYTHON_LIB := /usr/lib/x86_64-linux-gnu
WITH_PYTHON_LAYER := 1
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial
CUDA_ARCH := -gencode arch=compute_30,code=sm_30 \
                -gencode arch=compute_35,code=sm_35 \
                -gencode arch=compute_50,code=sm_50 \
                -gencode arch=compute_52,code=sm_52 \
                -gencode arch=compute_60,code=sm_60 \
                -gencode arch=compute_61,code=sm_61 \
                -gencode arch=compute_61,code=compute_61
```

## Makefileの編集

MakefileのNVCCFLAGSの行を以下のように編集します．

```

NVCCFLAGS += -D_FORCE_INLINES -ccbin=$(CXX) -Xcompiler -fPIC $(COMMON_FLAGS)
```

## hdf5の調整

Caffeがhdf5を読み込めるようにシンボリックリンクを作ります．

```
sudo ln -s /usr/lib/x86_64-linux-gnu/libhdf5_serial.so.10.1.0 /usr/lib/x86_64-linux-gnu/libhdf5.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libhdf5_serial_hl.so.10.0.2 /usr/lib/x86_64-linux-gnu/libhdf5_hl.so
```

## Pythonパッケージのインストール
最新のバージョンではPython2系に対応していないパッケージがいくつかあるので`python/requirements.txt`の中身を以下のように編集します．

```
Cython>=0.19.2
numpy>=1.7.1
scipy==0.17.0
scikit-image==0.9.3
matplotlib==1.5.3
ipython==5.0.0
h5py>=2.2.0
leveldb>=0.191
networkx==2.2
nose>=1.3.0
pandas>=0.12.0
python-dateutil>=1.4,<2
protobuf>=2.5.0
python-gflags>=2.0
pyyaml>=3.10
Pillow>=2.3.0
six>=1.1.0
```
その後以下のコマンドでインストール．

```
pip install -r python/requirements.txt --no-dependencies
```
## make

makeしていきます．

```
make all
make test
make runtest
make pycaffe
make distribute
```

すべての`make`コマンドでエラーが出なければビルド成功です．
最後にbashrcに以下の行を追加すれば終了です．
{path-to-caffe}はCaffeをインストールしたディレクトリを絶対パスで指定してください．

```
export PYTHONPATH="/usr/lib/python2.7:{path-to-caffe}/caffe/python:$PYTHONPATH"
```
jQueryで追加したHTML要素にクリックイベントが発動しない

##はじめに
プログラミングにふれて１ヶ月
jQueryでクリックイベントなら`click()`だよねーと使ってたら・・・

**jQueryでhtml要素の追加はできたけど、クリックしてもイベントが走らない！**

なんでだろー、とググってみても検索ワードがうまくヒットせずにハマったのでメモ。

##わかったこと
- `click()`と`on('click',〜)`があるよ
- **動的生成**のワードを入れると検索ヒットしたよ

##メモ
###環境
- jQuery3.2.1

###やりたかったこと
本の検索サイトで検索ワードの履歴を付箋で残し、クリックすると履歴のワードで再検索ができる
（下記gifが完成形）

![本の検索サイト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443038/1d1bf779-ba0a-fdae-9c52-c0b53eb5f5c1.gif)

###問題点
履歴クリックを`click()`で記述したけど発動しない

```js:sample1.js
    $('.history_btn').click(function (event) {
    //処理
    });
```

###気づき

- 元々htmlで履歴を作っておくと`click()`が発動する
    - 新しく作ったhtml要素には発動しない

### 解決
`on()`で記述すると追加した要素に発動する

```js:sample2.js
    $(document).on('click', '.history_btn', function () {
    // 処理
    });
```

### 参考サイト
https://qiita.com/tksnino/items/a5f33ac1b107f660c449
https://uxmilk.jp/10065
http://hayeta.hatenablog.com/entry/2017/09/29/%E3%80%90Javascript%E3%80%91%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AEonchange%E3%81%A7%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%8C%E7%99%BA%E5%8B%95%E3%81%97
http://creator.aainc.co.jp/archives/6611#section3
JavaScriptでArray<Object>をuniqにする

```javascript
const images = [
 {url : 'hoge.jpg'},
 {url : 'hoge.jpg'},
 {url : 'fuga.jpg'},
];
const condition = (a, b) => a.url === b.url;
const uniqImages = images.filter(
  (elem, index, self) => self.findIndex(
    (e) => condition(elem, e)
  ) === index
);

console.log(uniqImages);
```

findIndexはindexOfと同様に最初に見つかった要素のindexを返すので、それ以外のindexをフィルターすると条件に対してユニークになる。

![スクリーンショット 2019-06-21 19.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47823/a975e0e0-8f24-c3ba-8290-8a5bca783a62.png)

via 
https://qiita.com/piroor/items/02885998c9f76f45bfa0
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
[Ruby] クラス定義の終了後に特定の処理を行う

# 結論

`TracePoint.trace(:end)` を使う。

# 例

## 問題

Rails でモデルのバリデーションが少なくとも 1 つは定義されることを保証するためのモジュールを実装したい。実装は次のイメージ。

```rb
module WithSomeValidators
  extend ActiveSupport::Concern

  class NoValidatorError < StandardError; end

  included do
    # バリデータが存在しない場合は NoValidatorError を発生させる。
    raise(NoValidatorError) unless validators.present?
  end
end

class Girl < ApplicationRecord
  include WithSomeValidators

  validates :name, presence: true
end
```

しかし、このコードでは Girl クラスでバリデーションを定義しているにもかかわらず NoValidatorError が発生してしまう。これは `include WithSomeValidators` を呼んだ時点、つまり validates を呼ぶ前にバリデータの存在を確認してしまうためだ。

```rb
class Girl < ApplicationRecord
  include WithSomeValidators # この時点ではバリデータ (Girl.validators) は存在しない。

  validates :name, presence: true # ここでバリデータが追加される。
end
```

しかし、だからといって

```rb
class Girl < ApplicationRecord
  validates :name, presence: true

  include WithSomeValidators
end
```

のように、バリデーションの定義漏れを避けるためのモジュールをバリデーション定義後に include するのは本末転倒だ。

## 解決策

Girl クラスの定義が終わった後に `Girl.validators` を確認できればよい。これを実現するために [TracePoint.trace](https://docs.ruby-lang.org/ja/latest/method/TracePoint/s/trace.html) を使い、`end` イベントをトレースする。

```rb
module WithSomeValidators
  extend ActiveSupport::Concern

  class NoValidatorError < StandardError; end

  included do
    TracePoint.trace(:end) do |tp|
      break unless tp.self == self

      tp.disable # トレースを有効にしたままにするとパフォーマンス低下を招く。

      raise(NoValidatorError) unless validators.present?
    end
  end
end

class Girl < ApplicationRecord
  include WithSomeValidators # NoValidatorError は発生しない。

  validates :name, presence: true
end
```

# 参考

* [class TracePoint](https://docs.ruby-lang.org/ja/latest/class/TracePoint.html)
* [TracePoint.new](https://docs.ruby-lang.org/ja/latest/method/TracePoint/s/new.html)
  * トレース可能なイベントの一覧が記載されている。
direnvをMacに設定して環境変数を切り替える

# はじめに
Go1.11以降を使うときに、パッケージの依存管理にはGo Modulesが必要になるそうです。
（それまでのバージョンでは、glideやdepを使用していました）
今回は、`GO111MODULE`とうい環境変数を指定してGo Modulesを有効にしたいので、direnvを使用することにしました。
direnvを使うと、環境変数をディレクトリ毎に設定できるようになります。


# 実行環境
OS:Mac OS X / 10.14.5
Shell:bash

# direnvのインストール

## インストール
MacなのでHomebrewから失礼します。

```
$ brew install direnv
```

## .bashrcの設定
zshでも他のshでもかまいません。

```
# 設定の追加
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
echo 'export EDITOR=$(which vim)' >> ~/.bashrc

# 反映
$ source ~/.bashrc
```

## ディレクトリ毎の設定
今回は、Goのプロジェクトが置いてあるディレクトリ名`cellar`を対象にしてみます。

```
# 設定したいディレクトリに移動
$ cd go/src/cellar

# 個別設定するために編集（vimが立ち上がります）
$ direnv edit .

# vimで以下を追記して保存
export GO111MODULE=on
```
保存後に、以下のようなメッセージが表示されます。これで追加は完了です。

```
direnv: loading .envrc
direnv: export +GO111MODULE
```
# 確認
先ほど設定したディレクトリから離れると、以下のようなメッセージが表示されます。

```
$ cd ..
direnv: unloading
```
設定したディレクトリに戻ると、設定したよって教えてくれます。

```
$ cd cellar/
direnv: loading .envrc
direnv: export +GO111MODULE
```
いちいち教えてくれるところが、かわいい弟のようです。

# さいごに
今回は、一つの環境変数を設定したいが為に、direnvを導入してみました。
まだまだ他の使い方もあるかもしれませんが、もしあればまた次回に。
Single Responsibility Principle(単一責務の原則)について考えた

# はじめに
前回こちらの記事で、SOLID原則について調べつつまとめていきました。
https://qiita.com/kkkkkkkkkkk/items/ad5a7aeaee16bf55b3e2

今回は、SOLID原則のうちのひとつである**Single Responsibility Principle**(単一責務の原則)について考えていきたいと思います。


# Single Responsibility Principleの復習

**Single Responsibility Principle**とは、日本語で**単一責務の原則**で、**クラスを変更する理由は1つでなければならない**という意味でした。

そもそも**クラスを変更する理由が1つではない場合**ってどんなものなのか気になりましたので考えてみました。

## ダメな例
**クラスを変更する理由が1つではない場合**について調べていくと、**God object**という単語に行き着きました。

**God objectとは？**
> In object-oriented programming, a God object is an object that knows too much or does too much. The God object is an example of an anti-pattern.
引用: https://en.wikipedia.org/wiki/God_objectK

**God object**とは、アンチパターンのひとつで、大量のメソッドなどを保有して非常に多く事をやりすぎてしまう万能なオブジェクト(クラス)ということですね。

God(神)のオブジェクトって別にいい意味ではなく、むしろ悪い意味なんですね。


次に示すのがこの**God object**の例で、**単一責務の原則**に違反していると考えられます。

```php5

<?php
ini_set( 'display_errors', 1 );

class Person {
    private $name;
    private $email;

    public function __construct(string $name, string $email){
        $this->name = $name;

        if($this->validateEmail($email)) {
            $this->email = $email;
        }
        else {
            throw new Exception('Invalid Email');
        }
    }

    private function validateEmail(string $email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

    public function greet() {
        echo("Hello");
    }
}


$person = new Person("test", "test@test.com");
$person->greet();
```



別に**大量のメソッド**を保有しているわけではありませんが、PersonクラスでEmailに関する処理も行っていて、Personクラスで多く事をやりすぎてしまっています。




## 良い例(さらに改善の余地はあるかと思いますが、、、)
```php5
<?php
ini_set( 'display_errors', 1 );

class Person {
    private $name;
    private $email;

    public function __construct(string $name, Email $email){
        $this->name = $name;
        $this->email = $email;
    }

    public function greet() {
        echo("Hello");
    }
}

class Email {
    private $email;

    public function __construct(string $email){
        if($this->validateEmail($email)) {
          $this->email = $email;
        }
        else {
            throw new Exception('Invalid Email');
        }        
    }

    private function validateEmail(string $email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
}

$email = new Email("test@test.com");
$person = new Person("test", $email);
$person->greet();
```




これでPersonクラスでは、Personに関する処理、Emailクラスでは、Emailに関する処理になりました。
ざっくりですが、**単一責務**にはなりました。

もっと色々リファクタリングの余地はあるのかとは思いますが、**単一責務の原則**を説明する上では、割と上記のような単純なサンプルがわかりやすいですね。


# 最後に
今回は、**Single Responsibility Principle(単一責務の原則)**についてまとめました。

業務の関係で執筆時間がなくなってしまいましたが、なんとか短時間で書き終わって良かったです。

**OOP(オブジェクト指向)**は苦手分野なので、地道にがんばります。
ドメインとDNSについてあれこれ基本

##アドレスとドメインについて

そもそもDNSとは、
`「192.168.1.1」`などで示されるIPアドレスを、`「http://www.○○○.com」`のような分かりやすい文字で表してくれるサーバさんのことです。
このサーバにIPアドレスとFQDN(アドレス）を紐づけることで○○○.comとブラウザに入力したときに該当サーバにアクセスできるようになります。

所謂URLとよばれるアドレスについて説明します。
https://english-bootcamp.com/

=名称について=

com = トップレベルドメイン
english-bootcamp = 第２レベルドメイン
english-bootcamp.com = ドメイン名（FQDN)

レベル　ドメインは、右から左で順番にトップレベル・第２レベルと呼びます。
ちなみにwwwが付いていればwwwは第３レベルドメインとなる。

FQDNは、Fully Qualified Domain Nameの略称です。
一意にきまるレコードとして登録されるフルネームと覚えておけば良いと思われます。

<img width="600" alt="domain.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/7f623366-71ef-3f0e-9be9-7459f70c6dd1.png">

##ドメインを取得後　DNSサーバで必要となる設定について
DNSサーバにAレコード

###*Aレコード
IPアドレスとドメイン名を紐づけているレコード
1:1で紐づいています。

###*CNAME
FQDNとドメイン名を紐づけているレコード
ドメインの別名です。
english-bootcamp.comという名前でレコード登録したものの、
e-bootcamp.co.jpやenglishbootcamp.jpというアドレスしたい場合
CNAMEにレコードを登録することで別名として、紐づいているアドレスにアクセスさせることができます。

english-bootcamp.com:e-bootcamp.co.jp
english-bootcamp.com:englishbootcamp.jp

Aレコードと異なり、1:複数　で紐づきます。

###*MXレコード
Mail Excange からきています。


DNSサーバの詳細とMXレコードについては別記事にて
「Cannot call non W3C standard command while in W3C mode」を解決する

chromeとchromedriverを最新の75にアップデートしたら、capybaraのfeature specで以下のエラーが出るようになりました。

```rb
     Failure/Error: Unable to infer file and line number from backtrace

     Selenium::WebDriver::Error::UnknownCommandError:
       unknown command: Cannot call non W3C standard command while in W3C mode
```

・・・なんのこっちゃい :innocent: 

調べてみると、v75からW3CモードがデフォルトONになったそうです :point_down: 
>The most noticeable change is ChromeDriver now runs in W3C standard compliant mode by default. Other changes include:
[Downloads \- ChromeDriver \- WebDriver for Chrome](http://chromedriver.chromium.org/downloads)

## 解決策
今回、chromedriverのオプションに`w3c: false`を追加することで解決できました。

```rb:spec/support/capybara.rb
Capybara.register_driver :headless_chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w[headless disable-gpu window-size=1680,1050],
      w3c: false
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end
```

以上です :hugging: 

## 参考
- [Cannot call non W3C standard command while in W3C mode \(Selenium::WebDriver::Error::UnknownCommandError\) with Selenium ChromeDriver in Cucumber Ruby \- Stack Overflow](https://stackoverflow.com/questions/56111529/cannot-call-non-w3c-standard-command-while-in-w3c-mode-seleniumwebdrivererr)
- [ChromeDriver \- WebDriver for Chrome](http://chromedriver.chromium.org/home)
13桁のISBNコードを10桁に変換するコードをコードゴルフする

# はじめに

気分転換にQiitaの記事を漁っていたら、こちらの記事に目が止まりました。

* [僕も13桁のISBNコードを10桁に変換するコードを（実質）1行で書いてみた - Qiita](https://qiita.com/jnchito/items/b8be26ce87b56c9341ae)

関連する記事を調べてみると、同様の試みが最近立て続けに投稿されているようです。

* [私もisbn13をisbn10に変換する。 - Qiita](https://qiita.com/benridane/items/7e5398114ef796fc9d16)
* [Rubyでisbn13からisbn10へ1行で変換する - Qiita](https://qiita.com/110416/items/9c627b2c06ae192ce586)

どうやら、[ISBM](https://ja.wikipedia.org/wiki/ISBN)という規格でISBM13からISBM10に変換するタスクで、__これを1行で実装するcode golf的タスク[^1]__が俄に流行っている(？)ようです。しかも言語はcode golfによく使われる[Ruby](https://www.ruby-lang.org/)ではありませんか！

code golf好きとして、これは見逃せないということで自分も挑戦してみました。

[^1]: code golfは、特定のアルゴリズムをできるだけ短いコードで実装することを競う遊び [(wikipedia)](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B4%E3%83%AB%E3%83%95)

# code golfされたコード

と言っても、調べてみたら既に[ほとんど同じ試み](https://codegolf.stackexchange.com/questions/153624/converting-isbn-13-to-isbn-10)が、かなり最適化された形でなされていました __(64 byte)__。

```ruby:convert.rb
->n{v=n[3,9];c=11;v+"#{(c-v.chars.map{|i|i.to_i*c-=1}.sum)%11}"}
```

剰余が10ならば"x"に変化させるという条件を加えて、いくつか手直しすると以下のような形になります__(68 byte)__。

```ruby:convert_rev.rb
->n{a=n[3,9];a+"#{b=11;(c=-a.chars.sum{|d|d.to_i*b-=1}%11)>9?:x:c}"}
```

# まとめ
最終的に__68 byte__まで削減できました。これならば、冒頭にラムダ式の変数への代入を含めても、「[1行は80字以内に抑えるべきという古代からのしきたり](https://softwareengineering.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width)[^2]」をちゃんと守ることができます。めでたし、めでたし。

[^2]: IBMの計算機で、80カラムのパンチカードが利用されていたことから来ているそうです

※余談
code golf用に作られた言語は別にして、相変わらず[Perl](https://www.perl.org/)は変態ですね…

```perl:convert.pl
s/^...|.$//g;$\=(eval s/./"-$&0+".$i++*$&/ger)%11
```
【Unity】文字列から１文字ずつオブジェクト生成したい（"ただいま"→'た','だ','い','ま'）

##経緯
音声認識で取得した文字列から、**１文字ずつにして、ばらばらにアニメーションさせたい**と思った。

##流れとしては
InputField(とりあえず)で、入力した文字列から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306317/3d0aa295-9fae-e211-cddb-f0ba8c920c2b.png)

1文字ずつのオブジェクトをつくる！！！！('◇')ゞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306317/bb599a60-f106-2e13-dee9-f1a85b78e5fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306317/9aefd219-fc8c-8939-5337-5a4945c31168.png)

##実装内容
```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public InputField inputField;
public GameObject innerBox; //文字たちを格納するための親オブジェクト（空オブジェクト）
private string speakText;

public void Generate3DText()
{
        Debug.Log("Generate3DTextStart()");

        speakText = inputField.text;

		for(int i = 1; i <= speakText.Length; i++)
		{
			Debug.Log("i = " + i + ", speakText.Length = " + speakText.Length);
			// プレハブ生成(この時点では、まだ、空のText)
			GameObject word = (GameObject)Resources.Load("Word");
			var newObj = Instantiate(word, new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity) as GameObject;
			// 生成された各オブジェクトに文字を1文字ずつ入れる
			newObj.GetComponent<TextMesh>().text = speakText.Substring(i-1,1);
			// 生成された各オブジェクトの名前を変更
			newObj.name = "word" + "(" + speakText.Substring(i-1,1) + ")";
			// 各文字の位置を調整
			newObj.transform.parent = innerBox.transform;
			newObj.transform.localPosition = new Vector3(160.0f*(i-1), -151.0f, 0.0f);
			innerBox.transform.localPosition = new Vector3(-80.0f*(i-1), 0.0f, 0.0f);
		}
}
```

##補足
"Word"という名前のプレハブを用意してます。（Wordの中身は、ただのTextMeshでok）
3D空間に表示したかったので、TextMeshを使ってますが、Textに直しても使えます。
（speakTextという名前なのは、音声認識からとってきた文字列だったからです…('◇')ゞ（InputField用にスクリプトを変えたなごり…））
AtCoder Beginner Contest 116  C grand garden

atcoder beginners contestのC問題を解いてみた。[grand garden](https://atcoder.jp/contests/abc116/tasks/abc116_c)

言語はpython。





```python
def dfs(n):
    if len(set([i for i in n])) == 1:
        cnt = int(n[0])
    #　植物の長さが全部同じ時は、いずれかの要素の長さをとる。
        return cnt
    else:
        min_str = str(min([int(i) for i in list(n)]))
    # 植物の長さが全部同じではない時は、最小の要素の長さを取る
        spl_str = n.split(min_str)
    # 最小の要素でsplitして、それぞれに再帰
        spl_str = [i for i in spl_str if i != '']
        cnt = 0
        for i in spl_str:
            cnt += dfs(i)
        return cnt


```

間違っているところ、もっとこうしたらいい、というのがあったら教えてください。
CircleCIのOrbsを使ってchrome/chromedriverをインストールする

CircleCI 2.1から使えるOrbsを使って、chrome/chromedriverをインストールします。

ぼくが携わってるプロジェクトは、2.0以前からあるものなので`orbs`を使うためにはひと手間必要でした。
といっても、Advanced Settings > Enable pipelines を ONするだけです :ok_hand: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611/fd3887a2-238d-2d3b-04db-d40266f4ee02.png)

で、こうなりました :point_down: 

```diff:.circleci/config.yml
-version: 2
+version: 2.1
+orbs:
+  circleci-images: circleci/circleci-images@0.7.0
defaults: &defaults
  parallelism: 2
  working_directory: ~/my_project
  docker:
-    - image: circleci/ruby:2.5.0-node-browsers
+    - image: circleci/ruby:2.5.0-node
    <<: *defaults
    steps:
      - checkout
+     # これをしないとchromedriverインストール時に依存関係を解決できなかった
+     - run: sudo apt-get update

+     # chrome, chromedriverをorbsコマンドでインストール
+     - circleci-images/install-chrome
+     - circleci-images/install-chromedriver

```

簡単やーん！！ :tada: 

他にもslackやherokuのorbもあるみたいです。便利ですね！

以上です :hugging: 

## 参考
- [Orbs を使う \- CircleCI](https://circleci.com/docs/ja/2.0/using-orbs/)
- [CircleCI Orb Registry \- circleci/circleci\-images](https://circleci.com/orbs/registry/orb/circleci/circleci-images)
- [Question: When do you updates for google\-chrome and chromedriver? · Issue \#397 · circleci/circleci\-images](https://github.com/circleci/circleci-images/issues/397)
球面上のデータをParaViewで描画

# やりたいこと

ParaViewで絵を描いてぐりぐり回したい。

[ParaViewでVTKレガシーフォーマットを使う その2](https://qiita.com/kaityo256/items/851c559a8f4c43de329e)に，UnstructuredGridの使い方の例がある。
Rubyはできないので，Pythonで真似をする。
誤訳があるかも。

球面上のランダムな節点上にデータがあるとき，
Cellを指定しなくても点を打てて，ベクトルを描けることが分かった。

スカラー量で色を塗りたい。

# Vornoi図

`scipy.spatial.SphericalVoronoi`を使う。
点を与えると，`vertices`に頂点，`regions`にセルに使われている頂点の番号のリストが入る。


# VTKレガシーフォーマット

`CELLS`に与える`size`はセルに使われる頂点の個数+1の和となる。+1はセルを閉じることになる点の分。+1を忘れるとParaView（VTK）がお亡くなりなる。

# 結果

[github](https://github.com/tenomoto/vtk_legacy)に置く。

![random_sphere_cell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130247/1cdfdbe2-261c-e03d-528c-2479be2548f5.png)
【初学者向け】return(返り値)のイメージを掴もう！

#はじめに
初学者向けに書いています。
簡単に返り値の基礎と心がけるべき点を書きました。

# return(返り値)について
返り値は読んで字の如く、メソッドを呼び出した箇所へ返す値である。
"返す"という表現で理解し難い場合は"置き換わる"とイメージした方がわかりやすいかもしれない。
(あくまでイメージ)

```ruby:
def method
  "あ"
  "い"
  return "う"
  "え"
  "お"
end

puts method
```

```ruby:実行結果
う
```
Rubyではreturnは書かなくてもOKで、書かなかった場合はメソッドの最後の行がreturnされる。

```ruby:
def method
  "あ"
  "い"
  "う"
  "え"
  "お"
end

puts method
```
```ruby:実行結果
お
```

#意識して欲しいこと
メソッドではこの返り値が大事で、ちゃんと自分の欲しいものを返さないとどれだけ処理を書こうが台無しになる。

```ruby:
def multi(number)
  number + number
  number * number
  "こんにちは"
end

puts "methodの返り値は『#{method(10)}』です。"
```

```ruby:出力結果
methodの返り値は『こんにちは』です。
```
上記の例は露骨ではあるが、初学者はメソッドをモリモリ書いているうちに何が欲しくてメソッドを書いているか見失うことは良くあることです。
したがってメソッドを描くときは**何が欲しいか(返り値は何か)**を意識して書きましょう！

#最後に
「ここが分かりにくかった」「これは何？」などの質問や、レイアウト等の書き方にアドバイスがある方はお気軽に（優しく）コメントを頂けると助かります。
바카라카지노ヤヤ 784YES.COM ヤヤ바카라카지노사이트

<a href="http://laviolle.com/?s=%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%E2%9E%A0+784YES.COM+%E2%9E%A0%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%A3%BC%EC%86%8C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EC%B9%B4%EC%A7%80%EB%85%B8+%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%9D%B8%ED%84%B0%EB%84%B7" target="_blank">바카라카지노</a>
<br><br>
<a href="http://laviolle.com/?s=%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%E2%9E%A0+784YES.COM+%E2%9E%A0%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%A3%BC%EC%86%8C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EC%B9%B4%EC%A7%80%EB%85%B8+%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%9D%B8%ED%84%B0%EB%84%B7" target="_blank">바카라카지노</a>
<br><br>
<a href="http://laviolle.com/?s=%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%E2%9E%A0+784YES.COM+%E2%9E%A0%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%A3%BC%EC%86%8C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EC%B9%B4%EC%A7%80%EB%85%B8+%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%9D%B8%ED%84%B0%EB%84%B7" target="_blank">바카라카지노</a>
<br><br>
<a href="http://laviolle.com/?s=%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%E2%9E%A0+784YES.COM+%E2%9E%A0%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%A3%BC%EC%86%8C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%B6%94%EC%B2%9C+%EC%B9%B4%EC%A7%80%EB%85%B8+%EC%82%AC%EC%9D%B4%ED%8A%B8+%EB%B0%94%EC%B9%B4%EB%9D%BC%EC%B9%B4%EC%A7%80%EB%85%B8%EC%9D%B8%ED%84%B0%EB%84%B7" target="_blank">바카라카지노</a>
<br><br>
LXDをソースからビルドして実行するまでに困ったことと対処法

# 環境
- Distribution：Ubuntu18.04 LTS
- Linux kernel：4.15.0-51-generic
- golang：1.12.5 linux/amd64
- gcc：(Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

# lxcをビルドするときに困ったこと
lxcビルド時に発生したエラーやその対処方法を記述する

## makeが失敗する
`make`を実行する際に失敗した原因と解決策を記述する

### W: cannot generate system identifier for public text
- 原因：docbookコマンドがインストールされていない  
- 対策： `sudo apt install docbook`を実行して，docbookコマンドをインストールする  
- 結果：makeが完了した

# lxdをビルドするときに困ったこと
lxdビルド時に発生したエラーやその対処方法を記述する

## make depsが失敗する
`make deps` を行う際に失敗することがあるのでまとめておく．

### autoreconf: not found
- 原因：autoreconfコマンドが存在しない  
- 対策： `sudo apt install autoconf` を実行してインストールする  
- 結果：次のエラーが発生した

### error: Libtool library used but 'LIBTOOL' is undefined
- 原因：LIBTOOL環境変数が設定されていない
- 対策： `sudo apt install automake libtool` でインストールする
- 結果：次のエラーが発生した

### configure: error: Package requirements (libuv >= 1.8.0) were not met: No package libuv found
- 原因：libuvが見つからない
- 対策： `sudo apt install libuv1-dev` でインストールする
- 結果：解決した

### raftのmakeができない
- 症状

```
./configure: line 12849: syntax error near unexpected token `UV,'
./configure: line 12849: `  PKG_CHECK_MODULES(UV, libuv >= 1.8.0, , )'
```
- 原因：PKG_CHECK_MODULESという関数が見つからないことが原因であると推測
- 対策：`sudo apt install pkg-config` でインストールする
- 結果：解決した

## makeが失敗する
`make` を行う際に失敗することがあるので，症状と原因と対策を記載する

### fatal error: sys/acl.h: No such file or directory
- 原因：sys/acl.h ファイルが存在しない
- 対策： `sudo apt install libacl1-dev` でインストールする
- 結果：次のエラーへ

### No package 'lxc' found
- 原因：lxcが見つからない  
- 対策：lxcをビルドする
- 結果：ビルドが成功する

# lxdを実行するときにこまったこと
lxdコマンドを実行するときに困ったことを記述する

### lxd: look up error: symbol libdqlite.so.0: symbol: sqlite3_wall_replication_register: no such file or directory

- 原因：lxdはsudoをつけて実行するため，rootで実行する際動的ライブラリの参照先が異なっていることが原因だった．
  - 詳細：

```
yota@yota-MacBookAir:~/go/src/github.com/lxc/lxd$ ldd ~/go/bin/lxd

	~略~

	libsqlite3.so.0 => /home/yota/go/deps/sqlite/.libs/libsqlite3.so.0 (0x00007fc0bf9f0000)

	libdqlite.so.0 => /home/yota/go/deps/dqlite/.libs/libdqlite.so.0 (0x00007fc0bf7d5000)

	~略~

```

```
yota@yota-MacBookAir:~/go/src/github.com/lxc/lxd$ sudo ldd ~/go/bin/lxd

	~略~

	libsqlite3.so.0 => /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007f8b89bab000)

	libdqlite.so.0 => /home/yota/go/deps/dqlite/.libs/libdqlite.so.0 (0x00007f8b89990000)

    ~略~

```
- 対策：LD_LIBRARY_PATHを一般ユーザだけでなく，rootにも反映させる
  - 詳細：/etc/environmentに環境変数を設定する

```
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
LD_LIBRARY_PATH="/home/yota/go/deps/sqlite/.libs/:/home/yota/go/deps/libco/:/home/yota/go/deps/raft/.libs/:/home/yota/go/deps/dqlite/.libs/"
```
- 結果：lxdを実行することができた．


# 感想
実行にかなり手こずってしまった．しかし，バイナリの動的リンクについて詳しくなることができたので良し．
Certbotで取得したfullchain.pemとprivkey.pemをDocker内から使う場合はマウントする範囲を気を付ける

# Certbotで取得したfullchain.pemとprivkey.pemをDockerコンテナ内から使う場合はマウントする範囲を気を付ける
``/etc/letsencrypt/live/{ドメイン名}/fullchain.pem``と
``/etc/letsencrypt/live/{ドメイン名}/privkey.pem``をそれぞれマウントしたら、
``No such file or directory``を食らって解決に少し時間がかかってしまったので、
備忘も兼ねて。

## TL;DR
* /etc/letsencrypt/ごとマウントするのが正しい

## 理由
``/etc/letsencrypt/live/`` の中身はシンボリックリンク。
実ファイルは``/etc/letsencrypt/archives/``以下に格納され、
更新のたびに参照先が変わるようになっている。
よって、``/etc/letsencrypt/archives/``も持っていく必要がある。

archivesの中身をコピーする手も無きにしも非ずだが、
Let's encryptの証明書は有効期間が短く(30日)頻繁に更新が必要である。
定期的に更新コマンドを叩いてシンボリックリンクと共に更新するのが通常の使い方なので、
/etc/letsencrypt/ごと持って行ってしまったほうが吉。
FirebaseのRealtimeDatabaseから新規追加されたデータを逐次取得する

# FirebaseのRealtimeDatabaseから新規追加されたデータを逐次取得する

## はじめに

Firebaseのリアルタイムデータベースを使い、位置情報をリアルタイムで共有するアプリを作りたいと思い作った時に逐次最新のデータを取得する方法がわからずハマったのでここに残します。

## データベースの構造

今回は、このような構造にしました。

**一覧表示用**
<img width="482" alt="スクリーンショット 2019-06-21 1.30.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/6d365366-bf8b-9a59-914b-5117804c0716.png">

**データ格納用**
<img width="388" alt="スクリーンショット 2019-06-20 19.42.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/8adc98bf-bd3b-da99-e66f-ce6564bf6632.png">

## データ格納

### インデックス用のデータ格納

インデックスとしては、日付とUUID(ユニークなID)を格納します。

```Swift
writeUUID = UUID().uuidString
if let writeUUID = writeUUID {
    let value: [String:Any] = [
        keyDate:Date().timeIntervalSince1970,
        keyUUID:writeUUID
    ]
    fireDatabase.child("index").childByAutoId().setValue(value)
}
```

### 位置データの格納

緯度と経度をインデックス用のUUIDと一緒に格納します。

```Swift
let value: [String:Any] = [
    keyDate:Date().timeIntervalSince1970,
    keyLatitude:latitude,
    keyLongitude:longitude
]
fireDatabase.child("data").child(writeUUID).child("location").childByAutoId().setValue(value)
```

## データの取得

### インデックス用のデータ取得

ここでは、一覧として既存の格納されているインデックス用のデータを一括で取得します。

```Swift
fireDatabase.child("index").observeSingleEvent(of: .value, with: { (snapshot) in
    // Get user value
    guard let values = snapshot.value as? [String:Any] else { return }
    values.forEach({ (key,value) in
        guard let record = value as? [String:Any] else { return }
        guard let timeInterval1970 = record[self.keyDate] as? TimeInterval else { return }
        let date = Date(timeIntervalSince1970: timeInterval1970)
        guard let uuid = record[self.keyUUID] as? String else { return }
        // ここに何か処理を書く
    })
}) { (error) in
    print(error.localizedDescription)
}
```

### 位置データの取得

位置データはリアルタイムで格納されると１件づつ取得できます。
ここでは、`queryOrdered(byChild: "date")`を使い日付で並び替えています。


```Swift
fireDatabase.child(keyData).child(writeUUID).child("location").queryOrdered(byChild: "date").observe(.childAdded) { (snapshot) in
    guard let record = snapshot.value as? [String:Any] else { return }
    guard let latitude = record[self.keyLatitude] as? CLLocationDegrees else { return }
    guard let longitude = record[self.keyLongitude] as? CLLocationDegrees else { return }
    guard let timeInterval1970 = record[self.keyDate] as? TimeInterval else { return }
    let date = Date(timeIntervalSince1970: timeInterval1970)
    print("date:\(date) latitude:\(latitude) , longitude:\(longitude)")
    // ここに何か処理を書く
}
```

## 最後に

いかがでしたでしょうか？意外と簡単にリアルタイムデータベースを活用できました。
日付順に並び替えするポイントさえ掴めば意外と簡単に実装できます。
Word2Vecのモデルを軽量化する方法

Pythonのgensimを使ってWord2Vecのモデルを作成すると、
何GBというファイルが出来上がり、実際に使用する際にもメモリをかなり消費する。

https://radimrehurek.com/gensim/models/keyedvectors.html
gensimの公式ドキュメントによると、
Word2Vecのモデルには追加学習に必要なデータも一緒に保存されているので、その分データが重くなっている。

<code>KeyedVectors</code>を使うことで、学習に必要なデータを除いた形で保存できる。

```python:save_keyedvectors.py
from gensim.models import word2vec

# W2Vモデルの読込
model = word2vec.Word2Vec.load('word2vec.model')

# keyedvectorsとして保存
model.wv.save('keyword.kv')
```

実際に使うときには、

```python:load_keyedvectors.py
from gensim.models import KeyedVectors

# keyedvectorsの読込
wv = KeyedVectors.load('keyword.kv', mmap='r')

# 類義語出力
wv.most_similar('Qiita')
```
はじめてのLinux(CentOS)サーバ構築 〜SSH接続、IP制限〜

#背景

先日、「Linuxサーバ構築」というテーマで
社内で勉強会が行われましたので、メモを残しておきます。

そもそも、、、
日常の業務ではDockerを触ってはいるものの、
DockerFileを一から自分で構築したことはありませんでしたし、
構築するにしてもそのファイルは`Linuxコマンド`で書かれています。

なので、Dockerの理解を深めるためにも、とても良い機会となりました。

# 環境構築

まず、下記のdocker-compose.ymlを作業ディレクトリに追加します。
（docker-compose.ymlについての説明は割愛させていただきます。）

```docker-compose.yml
version: '3'
services:
  host_server:
    image: centos:7
    command: /usr/sbin/init
    privileged: true
    ports:
      - 38080:80
  client_machine1:
    image: centos:7
    command: /usr/sbin/init
    privileged: true
  client_machine2:
    image: centos:7
    command: /usr/sbin/init
    privileged: true
```
ここからはターミナルで作業を行います。

作業ディレクトリに移動し、Dockerコンテナを作成し、起動させます。

```
docker-compose up -d
```

ターミナルを3つ用意し、それぞれのターミナルで各serviceのコンテナに入ります。

```
docker-compose exec host_server /bin/bash
docker-compose exec client_machine1 /bin/bash
docker-compose exec client_machine2 /bin/bash
```

host_serverでOpenSSHサーバ、net-tools、vimをインストールします。

```
yum install -y openssh-server net-tools vim
```
同様に、client_machine1,2でもOpenSSHクライアント、net-tools、vimをインストールします。

```
yum install -y openssh-clients net-tools vim
```

SSH接続するためにサーバ(host_server)側でパスワードを設定しておきます。（パスワード確認のため再入力もあります。）

```
passwd
```
host_serverを立ち上げます。

```
systemctl start sshd.service
```

ここで、host_serverのIPアドレスを確認しておきましょう。

```
ifconfig
=> 172.20.0.3
```

同様にclient_machineのIPも確認しておきます。

(`host_server: 172.20.0.3`)
`client_machine1: 172.20.0.4`
`client_machine2: 172.20.0.5`

#SSH接続

それでは、クライアント(client_machine1)からサーバ(host_server)にSSHで接続してみましょう。（ここではパスワード認証で接続していますが、脆弱性があるらしいので公開鍵認証の方が良いみたいです。）

```
ssh 172.20.0.3
=> Last login: Wed Jun 19 22:01:33 2019 from linux_test_client_machine1_1.linux_test_default
```

Last loginが表示されれば成功です。接続に成功したらログアウトしておきます。

```
exit
```

また、client_machine2でも接続ができることを確認しておきましょう。

（ここではパスワード認証で接続しているので、接続の度にパスワードを求められますが、公開鍵認証接続であればそれは必要なくなります。）

# IP制限
それでは、サーバ(host_server)に接続できるIPアドレスを制限してみます。

### 指定したIPアドレスを拒否する

サーバ側でhosts.denyファイルを変更します。

```
vim /etc/hosts.deny
```

```hosts.deny
ALL:ALL
```
この設定では、すべてのIPアドレスからの接続を拒否しているので
client_machine1、client_machine2 どちらからとも接続できないことを確認します。

```
ssh 172.20.0.3
=> ssh_exchange_identification: read: Connection reset by peer
```
接続できないことが確認できました。

### 指定したIPアドレスを許可する

次は、`client_machine1: 172.19.0.4`のIPアドレスのみ許可してみます。
先程と同様に、今度は`hosts.allow`ファイルを変更します。

```
vim etc/hosts.allow
```
```hosts.allow
ALL:172.19.0.4
```
接続してみます。

client_machine1: 172.19.0.4 => success
client_machine2: 172.19.0.5 => failed

期待通りの結果になりました。

# おわりに
普段はソフトウェア開発をしているので、サーバやネットワークといったインフラ周りは慣れないですね。

次回のテーマは「ユーザに権限を付与する」です。
igraphのオブジェクト同士を2つ以上足すと、色情報が消える

igraphで多重グラフを描きたくて苦戦中に気づいたこと。

まず、ノードA、B、Cをもつグラフgがあったとする。

```r
library("igraph")
g <- make_empty_graph()
g <- g + vertices(c("A", "B", "C"))
```

このオブジェクトに、後からtmpg1やtmpg2といった、別のオブジェクトを足し合わせていくことで、異なる色のエッジを持つ多重グラフが描けるのではと期待していた。

どういうことかと言うと、例えば、ここでは、tmpg1はA->B、B->C、tmpg2はA->B、A->C、B->Bというエッジを各々持っており、各々のエッジは赤と青だとする。

```r
tmpg1 <- g
# Set the edge color as red
tmpg1 <- tmpg1 + edges(c("A", "B", "B", "C"), directed=TRUE)
tmpg1 <- set_edge_attr(tmpg1, name="color", value="red")

tmpg2 <- g
# Set the edge color as blue
tmpg2 <- tmpg2 + edges(c("A", "B", "A", "C", "B", "B"), directed=TRUE)
tmpg2 <- set_edge_attr(tmpg2, name="color", value="blue")
```

g自体には、エッジがないのでこのような図だが、

```r
plot(g, vertex.size=40,
    layout=layout_in_circle(g, order=1:3))
```
![スクリーンショット 2019-06-21 18.36.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/5dd683cd-bab8-4add-e0ef-dfdf0f4d679e.png)

tmpg1には赤いエッジが、

```r
plot(g + tmpg1, vertex.size=40,
    layout=layout_in_circle(g, order=1:3))
```

![スクリーンショット 2019-06-21 18.37.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/a80875bc-11da-aa21-b5fb-0e65221e8d5c.png)

tmpg2には青いエッジがあるので、

```r
plot(g + tmpg2, vertex.size=40,
    layout=layout_in_circle(g, order=1:3))
```

![スクリーンショット 2019-06-21 18.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/aab96ced-ed4a-aeae-3518-31649626178f.png)


これらを足しあわせたら、うまいこと、赤と青のエッジが共存したり、または赤と青が混じって紫のエッジが出てきたりすることを期待していたのだが、正解は、

```r
plot(g + tmpg1 + tmpg2, vertex.size=40,
    layout=layout_in_circle(g, order=1:3))
```
![スクリーンショット 2019-06-21 18.37.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/00483133-9d14-0d4b-a7be-f21db645c636.png)


**グレーだった。**

igraphオブジェクト同士の足し算で、エッジのカラー属性が受け継がれるのは知っていたが、2つ以上足すと、NULLになるらしい

```r
E(g)$color
# NULL
E(tmpg1)$color
# "red" "red"
E(tmpg2)$color
# "blue" "blue" "blue" "blue" "blue"
E(g + tmpg1)$color
# "red" "red"
E(g + tmpg2)$color
# "blue" "blue" "blue" "blue" "blue"
E(g + tmpg1 + tmpg2)$color
# NULL
```

[multigraph](https://www.karada-good.net/analyticsr/r-553)とか使ったほうがいいかもしれない
Watson Discovery Serviceのコレクションに登録できるトレーニングデータの文字数制限

# IBM Watson™ Discovery サービスのトレーニングについて

Watson Discoveryサービスのトレーニングの詳細についてはチュートリアルを参照してください。
>[ツールを使用した結果関連性の改善](https://cloud.ibm.com/docs/services/discovery?topic=discovery-improving-result-relevance-with-the-tooling)
>[API を使用した結果関連性の改善](https://cloud.ibm.com/docs/services/discovery?topic=discovery-improving-result-relevance-with-the-tooling)

>>IBM Watson™ Discovery サービスでトレーニングを使用して、自然言語照会の関連性を改善することができます。 Discovery ツールまたは Discovery API のいずれかを使用して、プライベート・コレクションをトレーニングすることができます。

# トレーニングデータの文字数制限

Watson Discoveryサービスのコレクションに学習させる自然言語のトレーニングデータには以下の文字数制限とトークン数の制限があります。両方とも満たしている必要があるため、片方が制限に達した場合はそこでトレーニングデータが切れることになります。

文字数制限：2048文字
トークン数：約250トークン

また、日本語、英語、簡体中国語、韓国語のトレーニングデータにおいて、いずれも上記の制限があります。

# トークンの制限について

Watson Discoveryサービスのトレーニングデータには形態素解析エンジンによってトークン化されます。日本語のトレーニングデータを使うことを前提に、APIを使用してトレーニングさせる場合などには、kuromojiなどを使用してトークン数をカウントして制限内でおさまるようにするなどして実装することが考えられます。



実装例

```wds.js
   const kuromoji = require('kuromoji');
   const util = require('util');
   const builder = kuromoji.builder({
        dicPath: 'node_modules/kuromoji/dict'
    });
    const builderAsync = util.promisify(builder.build).bind(builder);
    const tokenizer = await builderAsync();
    const tokens = tokenizer.tokenize(text);
    if(tokens.length > 250){
        text = text.substr(0, tokens[250].word_position);
        console.log('Reduced to 250 tokens (because long text causes Error)\nfaq_id: %s, %s',faqId, text);
    }

```
RESTful APIのPOSTやPUTのレスポンスで、なんで登録や更新した情報を返すの？

前回に引き続き、会社恒例の3泊4日のプログラミングキャンプで、
`RESTful API`の設計の際に`RESTful API`の`POST`や`PUT`のレスポンスについて、
思ったことがあったので投稿してみました。

`RESTful API`の設計をチームの先輩が`Swagger`で作成してくれるということで、
完成したものを確認していると...

（ふむふむ、一覧を取得するときの`path`はこれで、一覧のレスポンスはこんな感じで返せばいいのか）
（新規作成するときの`path`はこれで、新規作成が成功した場合のレスポンスはこんな感じで返せばいいのか）

（ん？あれ、新規作成のレスポンスに、**登録した情報**をレスポンスとして返してるな）
（でも、新規作成した後は、一覧画面に遷移するから、登録した情報を返しても使わないんじゃないか？)

っと思ったので、作成してもらった先輩に質問してみた。

僕 「すみません、新規作成が成功した場合に、登録した情報をレスポンスとして返しているのですが、どうしてでしょうか？」

先輩 「今回の作成するシステムでは使用しないけど、**一般的**に`RESTful API`の`POST`や`PUT`の場合は結果のリソースを返すことはよくあるんだよ」

僕　「そうなんですね！ありがとうございます！」

（`RESTful API`にそんなルールがあったなんて、知らなかった...）

##`RESTful API`の`POST`や`PUT`のレスポンスについて調べてみた

https://docs.microsoft.com/ja-jp/azure/architecture/best-practices/api-design#post-methods
>**POST メソッド**

>POST メソッドは、新しいリソースを作成すると、HTTP 状態コード 201 (Created) を返します。 新しいリソースの URI は、応答の Location ヘッダーに含まれています。 応答本文には、リソースの表現が含まれています。

https://developer.ntt.com/ja/blog/741a176b-372f-4666-b649-b677dd23e3f3
>5\. POST/PUTでもレスポンスボディを返す

>APIを使った開発においてよくあるのがPOST/PUTでデータを更新した時に、最新のデータをGETで取り直すというものです。これは2回APIアクセスする必要があってムダです。POSTで作った、PUTで更新したデータについて、その最新の状態をレスポンスに含めるようにしましょう。

>特にサーバ側で処理されるデータがある場合、クライアント側ではデータがどういった値を持つかは分かりません。その結果、GETでアクセスする必要が生じてしまいます。ネットワークはボトルネックになりやすいので、クライアントからのアクセスを少なく済むようなサーバ側の実装を心がけましょう。

#調べてみて

そもそも、`RESTful API`の設計は複数のシステムから呼ばれることを想定しないといけないらしい、
すぐに登録した情報や更新した情報を取り直す場合があるから、レスポンスに登録した情報や更新した情報を入れておいたほうが、使いやすい場合があるんだなと勉強になりました。
InstaLift Serum : Beautiful and younger looking skin for a lifetime

InstaLift Serum : That should be needed in order that I've gotten a little of fine outcomes. This installment goes to strive to induce you back on the right track if you have got lost your approach somewhat. I'm certain where Anti Aging & Anti wricle serum is heading however that is going to be a fun ride. I can get connoisseur help on skin care. Despite everything, once reading this, you'll be ready to try to to it. Despite that, you may be interested. This was validated by outsiders. There is an endless give of Anti Aging & Anti wricle formula data. I'm quite the wheeler dealer once I would possibly would like to be. They were going like hotcakes. Did you are doing the correct factor? There's some doubt that there's a Anti Aging & Anti wricle formula like that. That's the right time for Anti Wrincle Formula. You would possibly reckon that I'm taking the scenic route. Anti Wrincle Formula uses that moreover. I will accelerate your Anti Wrincle Formula. 
I'm not the best speaker. That doesn't resolve that. Most lovers relish that nuisance each now and then. In a very few cases, this would possibly never return in any respect. It's how to end being nervous regarding what others suppose. This was profitable. That is what you may would really like to 

attempt and do. What if the Anti Aging Cream you're using is sweet enough to urge the duty done? I sometimes surprise if it's best to focus on Anti Wrincle Formula or skin care. The fairly Anti Aging & Anti wricle serum you wish absolutely depends on your preference.Anti Aging & Anti wricle serum will never be finished in a moment. 

That is how to wash your Anti Aging & Anti wricle serum. You are doing not have to own coaching to be prepared to use Anti Aging & Anti wricle formula. I will serve it up. I can see it being rather handy for a lot of organizations. As you may see now, a range of them have been intelligent. Once I came back home last week I noticed my Anti Aging & Anti wricle serum was missing. I might be a small amount confused per Anti Aging Cream. You want to offer the membership in Anti Aging & Anti wricle formula of the Month Club. This is usually not very robust. 



https://www.dragonsdendiet.com/instalift-serum/
Sewa Mobil Bandung

<a href="https://tourbandung.id/sewa-mobil-bandung/">sewa mobil bandung</a> Di Bandung, kelompok etnis terpadat adalah Urang Sunda atau Sunda. Orang-orang Sunda bangga akan masakan mereka dengan bahan-bahan segar dan makanan yang bersih, dibandingkan dengan kekayaan dan kepedasan hidangan yang ditemukan di seluruh negeri. Warung makanan jalanan dapat ditemukan di hampir setiap sisi jalan, gang atau sudut, sementara kota ini juga menjadi sarang bagi kafe hipster dan kedai kopi kecil. Adegan restoran dan bar, sementara berkembang, tidak mendekati standar negara-negara seperti Singapura, Hong Kong atau Thailand.

Meskipun demikian, masih ada banyak tempat keren untuk makan dan minum, dan inilah tempat teratas kami untuk check-out:

Nasi Timbel - Nasi kukus dibungkus dengan daun pisang dan dipasangkan bersama daging seperti ayam goreng, bebek atau merpati untuk kelezatan lokal ini. Itu diisi dengan bumbu seperti tahu (tahu), tempe (kue kacang kedelai) dan sambal (cabai).

Sayur Asem - Sup asam berbasis asam. Hidangan yang sangat populer di Bandung.
Soto Bandung - Hidangan ini adalah versi Bandung dari soto - sup tradisional Indonesia yang berbeda dari satu daerah ke daerah lainnya. Soto Bandung terdiri dari daging sapi dan lobak iris.
map関数のメモ

map関数を使えばリストの値を一括で更新できる。

```python:test.py

num_list = ["1", "2", "3", "4"]

result = map(int, num_list)

print(sum(list(result)))

```

```python:test2.py

def add_word(x):
    
    return str(x) + "だよ"
    

num_list = [1, 2, 3, 4]

result = map(add_word, num_list)
print(list(result))

```

イテレータが返ってくるのでリストに変換する。

```
#結果
10
['1だよ', '2だよ', '3だよ', '4だよ']
```
API Blueprintを使ってみ（ようとし）た

最近、業務でよくAPI仕様書を作っています。

markdownでせっせと書いていたのですが、同チームのエンジニアから`ドキュメント作成ツールとか使ってみると便利だよ`とアドバイスをいただきました。

「そんなものあるのかー」と思い、気になったので調べてみました。

## [API Blueprint](https://apiblueprint.org/)
APIドキュメントを書くツール。markdownに慣れている人にとっては使いやすいと思いました。

## 実際に試してみた
ググりながら試しに使ってみます。
環境構築：https://qiita.com/takahyon/items/399e3d5781e0f6c73e06
記法：https://dev.classmethod.jp/server-side/api-document-with-api-blueprint/

表示するだけならhomebrewが導入済みなら数分で完了しました。記法については、markdownに似ているので、あまり違和感なく操作できました。
ただ、API Blueprint独特の書き方も存在するので、細かく書くには多少勉強が必要になりそうです。

下記は[公式sampleの出力結果](https://apiblueprint.org/documentation/examples/01-simplest-api.html)です。

<img width="975" alt="スクリーンショット 2019-06-21 17.53.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186181/a906eef2-943f-724a-f620-5fb77b09fc03.png">

## 感想
作成したドキュメントをhtmlファイルに出力することも可能なので、ドキュメントを気軽に共有することができます。また、API Blueprintを調べる中で"一般的なドキュメントの構成"も合わせて調べることができたので、ドキュメント作成の学びになりました。
今回のドキュメント作成は慣れているmarkdownで作成しましたが、機会があれば実際にAPI Blueprintを導入してみたいと思います。
[PHP]環境変数を設定して本番とローカルの設定を切り分ける

#$\_SERVER['SERVER\_NAME']での環境の切り替え

```php
<?php
if (\filter_input(INPUT_SERVER, "SERVER_NAME") === "sample.com") {
    // 本番での設定
} else {
    // ローカルでの設定
}
```

https://www.php.net/manual/ja/reserved.variables.server.php
>注意: Apache 2 では、UseCanonicalName = On と ServerName を設定する必要があります。 そうしなければ、この値はクライアントが提供するホスト名を指すようになってしまい、無意味です。 また、セキュリティ的な意味合いでこの値に頼ってはいけません。

サーバーの設定によっては$_SERVER['SERVER_NAME']は取得できない場合もある。

#$\_ENVでの環境の切り替え

```:.htaccess
# 本番環境の.htaccess
SetEnv Env production
```

```php:
<?php
if (\getenv('ENV') === 'production') {
    // 本番での設定
} else {
    // ローカルでの設定
}
```

# 参考（さらにクラスの静的変数に依存）
@suin さん
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんなかんじで環境を切り替えます <a href="https://t.co/IUkirRdvEP">pic.twitter.com/IUkirRdvEP</a></p>&mdash; suin❄️PHPでオブジェクト指向 (@suin) <a href="https://twitter.com/suin/status/1133973179628544005?ref_src=twsrc%5Etfw">2019年5月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>