OmniAICreator/Qiita-1.07M huggingface dataset:
Node-REDでWEB API（お天気Webサービス）を試す

#お天気Webサービスから情報を取得する
Livedoor のお天気Webサービス（Livedoor Weather Web Service / LWWS）を利用してみます。
全国の地点定義表で取得したい地域のidを確認してください。
livedoor お天気Webサービス仕様
http://weather.livedoor.com/weather_hacks/webservice
全国の地点定義表（RSS）
http://weather.livedoor.com/forecast/rss/primary_area.xml
（例）「福岡県・久留米の天気」を取得する場合
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

#ノードの配置
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/49178357-04c3-d1c2-882e-8a567b4ecdd4.png)
地域（400040は福岡県・久留米）を指定して天気予報を教えてもらいます

#injectノード
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/3f29ece2-70db-d0a3-ab16-07054f543db2.png)
ペイロードに地域IDをセット

#http requestノード
```
http://weather.livedoor.com/forecast/webservice/json/v1?city={{payload}}
```
ペイロードの地域IDをパラメータにセットしてGETコマンド送信

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/1d01675a-8d74-d78e-60ee-dff5866b89cc.png)

#実行結果
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/240467/f6679c16-ce28-d286-ac7c-0bcb619eee52.png)
ATOMでpop clipが動かなくなった > 2分で解決した

High Sierraにしてからか、
ATOMでpop clipが動かなくなったことに気づいた。

2分で解消できるので方法をシェア。

## 解決方法

1、ATOM上で何か単語を選択（この時クリックしたままにする）
2、クリックしたままcaps lockを押す
3、pop clipの[Learn]というウィンドウが出てくるのでクリック
4、pop clipが動くことを確認


### 参考
「Popclip not working?」
https://discuss.atom.io/t/popclip-not-working/30897/5
不思議マーケット


## 問題

https://yukicoder.me/problems/no/679

## 解法

h->gではなくg->hの向きに辺を張るなら、グラフ中の有向閉路および **閉路につながる** ノードがfalse、他のノードはtrueです。逆向きに辺を張るのは、閉路につながるノードをfalseにする処理はDFSにより容易に書けるからです。

https://yukicoder.me/submissions/254817

```rb:tyama_yukicoder679.rb
def cycle(c,m,f,h)
	return f[c] if !f[c].nil?
	f[c]=h[c].all?{|e|
		!m.has_key?(e) && (m[e]=1;k=cycle(e,m,f,h);m.delete e;k)
	}
end
n,m=gets.split.map &:to_i
h=Hash.new{|h,k|h[k]=[]}
m.times{
g,r=gets.split.map &:to_i
h[g]=gets.split.map(&:to_i)
}
f=[nil]*-~n
(1..n).map{|i|cycle(i,{i=>1},f,h)}
p f.count(true)
```

## 感想

トポロジカルソートと聞いて、身構えてしまった。「品物の並び替え」や「[おいしい好みの順番](https://qiita.com/cielavenir/items/96a4baf104f3311eeccb)」の経験上、どうしても拒否反応が出てしまうのである。
しかし、~~DAGにするために取り除くのが辺ではなく頂点自体なら~~ DAGをなしている頂点を探すだけなら高速に解けることがわかり、勉強になった。
Karabiner-ElementsでJISキーボードがUSキーボードとして認識される問題

macOS High Sierra + Karabiner-Elements をインストールすると、JIS配列キーボードがUSキーボードとして認識されてしまうようです。

High Sierraが出た当初からあった問題のようで、色々な対処方法が既に各所で紹介されていますが、Karabiner-ElementsやOSのバージョンごとに設定方法が異なるようです。

最新版 Karabiner-Elements では多少対象方法が楽になっています。

# 環境
- macOS High Sierra 10.13.3
- Karabiner-Elements 12.0.0

# 手順
Karabiner-Elements Preferences を開いて、Virtual Keyboard > Country Code に **45** を入力
<img width="1112" alt="スクリーンショット 2018-05-01 0.34.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/8399/1cbcfbb7-80e9-a05b-3ed5-f8acb4eda94d.png">
参考：
- https://qiita.com/naoya_t/items/45f0557cb29f2c2e8e3c#強制的にusキーボードになる問題の回避
- https://pqrs.org/osx/karabiner/history.html#history

システム環境設定 > キーボード > 左下に[キーボードの種類を変更]ボタンが表示されるのでクリック
<img width="780" alt="スクリーンショット 2018-05-01 0.34.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/8399/99719fb2-258b-ce7e-8274-4d07498010cc.png">

ウィザードに沿ってキーボードを認識させる
<img width="728" alt="スクリーンショット 2018-05-01 0.34.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/8399/aab0d2bf-9a2f-6a8a-7f02-fe4795251b9c.png">

JISを選択して完了
<img width="728" alt="スクリーンショット 2018-05-01 0.34.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/8399/3e23e938-305a-00af-0a93-8a05664c2019.png">

これでKarabiner-Elementsを使いつつ、ただしくJISキーボードとして認識されます。
アプリ内ボタンにマテリアルデザインアイコンを使う [Android]

###やりたいこと
Androidアプリでよくあるこんな感じのアイコンを使いたい
<img width="102" alt="スクリーンショット 2018-05-01 0.12.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/213957/b5571337-93c6-0aea-f8ea-408e007f8a45.png">

##開発環境
OS: macOS HighSierra
Android Studio: 3.0.1

##手順
###**・使いたいアイコンを探す**
Android Studioの
画像を配置したいフォルダで右クリック(app > res > drawableなど)

New>VectorAssetを選択
<img width="539" alt="スクリーンショット 2018-05-01 0.22.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/213957/b054a448-0658-07af-24d8-17d980baa44f.png">

以下のような画面が開く。
<img width="812" alt="スクリーンショット 2018-05-01 0.24.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/213957/d6eed6fa-03ed-1dd4-bd98-e166586734d2.png">
iconのボタンをクリックすると、
以下のような画像選択ウインドウが開く。検索も可能。
<img width="800" alt="スクリーンショット 2018-05-01 0.37.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/213957/98f4685b-3645-3b47-440b-b0c8ab47ca68.png">


以下のURLで同じ画像一覧を確認できる。
https://material.io/icons/
AndroidStudioのデフォルトでは黒いアイコンだが、
こちらから白いアイコンもDLできる。
DLしてきた場合は、Vector Assetの画面で「Local file(SVG,PSD)」を選択して画像のパスを入れる。

##選択した画像をボタンに設定
####Designタブから設定する場合
　何かしらのボタン等を設置しておく。
　対象物を選択して、Attributes > srcCompatから配置したい画像を選択する。
<img width="487" alt="スクリーンショット 2018-05-01 0.51.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/213957/4ac460f7-2f38-cd0d-e809-aa8b706dd274.png">


####Textタブから設定する場合

```xml:~~~.xml
<android.support.design.widget.FloatingActionButton
...
app:srcCompat="@drawable/ic_create_white_24px" />
```
　対象のボタン内の`srcCompat`で画像名を入力
Alibaba CloudのContainer Service(Kubernetes版)のクラスタを操作する

[前回](https://qiita.com/yoshidashingo/items/0806502d23eeb63db24d) の続き

## クラスターの操作

### ホストのスケール変更
- ホストのスケール変更はコンソールから簡単に変更できる (例でワーカーに「20ノード」を設定している)
![alik8s003.jpg](https://qiita-image-store.s3.amazonaws.com/0/11653/73fc2f2e-33c9-ca17-e44e-6d32f6626b95.jpeg)

### クラスター上の操作
- まずはじめにクラスターを操作するためのクレデンシャル情報などをマスターノードからscpで取得して配置する

```shell
$ scp root@<マスタインスタンスのIPアドレス>:/etc/kubernetes/kube.conf $HOME/.kube/config
```

- podやserviceに対する操作は通常のkubectlの操作で問題ない

```shell
$ kubectl get pods
NAME                            READY     STATUS    RESTARTS   AGE
frontend-685d7ff496-2fwvq       1/1       Running   0          4h
frontend-685d7ff496-hw5m6       1/1       Running   0          6s
frontend-685d7ff496-tbmtr       1/1       Running   0          4h

　　<中略>

$ kubectl scale deployment frontend --replicas=3
deployment "frontend" scaled

$ kubectl get pods
NAME                            READY     STATUS    RESTARTS   AGE
frontend-685d7ff496-2fwvq       1/1       Running   0          4h
frontend-685d7ff496-c92jm       1/1       Running   0          4h
frontend-685d7ff496-tbmtr       1/1       Running   0          4h
http-svc-26brj                  1/1       Running   0          6h
http-svc-pqz27                  1/1       Running   0          6h
redis-master-7bd4d6ccfd-x2msr   1/1       Running   0          5h
redis-slave-84845b8fd8-28hqb    1/1       Running   0          4h
redis-slave-84845b8fd8-lzc9m    1/1       Running   0          4h

$ kubectl get services
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
frontend       NodePort    172.19.0.61     <none>        80:32701/TCP   4h
http-svc       NodePort    172.19.11.17    <none>        80:30301/TCP   6h
kubernetes     ClusterIP   172.19.0.1      <none>        443/TCP        6h
redis-master   ClusterIP   172.19.9.128    <none>        6379/TCP       4h
redis-slave    ClusterIP   172.19.13.106   <none>        6379/TCP       4h
```

## その他
- Helmが統合されているので汎用的なツールは簡単にデプロイすることができる

![スクリーンショット 2018-05-01 0.22.10.png](https://qiita-image-store.s3.amazonaws.com/0/11653/ad742604-2139-3f64-7adc-c841cb66909c.png)
MacでRuby on Railsを立ち上げる方法

#目標
Mac環境でRuby on RailsのインストールからWebサーバー(以下の画面)を起動させるまでの設定方法メモ

![スクリーンショット 2018-04-30 23.09.39.png](https://qiita-image-store.s3.amazonaws.com/0/253923/7f855baf-e3ee-b915-694e-5520d361e64e.png)


#SPEC
macOS Sierra 10.12.6

```
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]
```
>macOSではデフォルトでrubyがインストールされています。バージョンアップする方法は以下参照
[Macのターミナルでrubyをバージョンアップする方法](https://qiita.com/Ficus/items/bdef5c2b504d7a4008fb)

#Railsをインストール
gemを使います

```
$ gem install rails
```

Railsがインストールされたことを確認

```
$ rails -v
Rails 5.2.0
```

#Railsのアプリケーションフォルダを作成

今回は以下のコマンドで`test_app`というアプリケーション名のフォルダを作ります。

```
$ rails new test_app
```

自動でフォルダが作られるのでtest_appに移動します

```
$ cd test_app
```

#RailsのWebサーバーを起動
そのためにまず、IPアドレスを確認

```
$ ifconfig
```

結構たくさん文字が出てくるのですが
inetという文字の横にある`192.168.3.107`のような数字が今使っているIPアドレスです。
分かりにくければMacの環境設定からネットワークを開いた画面にもIPが表示されています。

```
$ rails server -b 192.168.3.107 -d
=> Booting Puma
=> Rails 5.2.0 application starting in development
=> Run `rails server -h` for more startup options
```
最後の`-d`オプションはサーバーをバックグラウンドで立ち上げるためのものです。


#Webサーバーが起動しているか確認

ブラウザのアドレスバーで
`http://`のあとに先ほどのIPアドレスを入れて、最後に`:3000`と入力して検索すると
Railsのページが表示されます。
例：[http://192.168.3.107:3000](http://192.168.3.107:3000)




#**Webサーバーを切りたい場合**

Webサーバーを動かしているプロセス番号を調べます。
切断するアプリケーションのディレクトリで以下のコマンドを実行

```
$ cat tmp/pids/server.pid
44647
```

この`44647`がプロセス番号です。これをコピーして

```
$ kill -9 44647
```
とコマンドを打てばサーバーが止まります。
Alibaba CloudのContainer Service(Kubernetes版)のクラスタを作成する

2017.11.11の独身の日(シングルデーとかダブルイレブンとも言う)に中国のT-mallの基盤として利用されていたAlibaba CloudのContainer Service。10万以上のコンテナでピーク時に毎秒32万5千トランザクションさばき、1日で3兆円弱の取引を行ったと発表されています。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/11653/4403d861-be93-6385-e46d-9bfcfc7315eb.png)

https://speakerdeck.com/ddbmh/container-service-at-alibaba-cloud

少し前にこのContainer ServiceのKubernetes版を試したのでメモしておきます。

## 制約事項
- Alibaba Cloudは契約者の住所(電話＋クレジットカード)でアカウント種別が3種類に分かれるが、Kubernetes版は現在「中国」および「国際」アカウントのみ提供されており、日本アカウントはまだ。
- Linuxコンテナのみサポートしており、Windowsコンテナは将来的にサポート予定。
- VPC環境のみサポート：新規VPC作成あるいは既存VPCを選択する必要あり
- インスタンスの支払方法は従量課金のみサポート(ECSやSLB)されており、月額/年額サブスクリプションは将来的にサポート予定。
- マスターノードは3台構成のみサポートされており、これら3台分のインスタンスも課金対象。

## 準備作業
- 以下のサービスを有効にする
    - Resource Access Management (RAM)
    - VPC
    - Resource Orchestration Service (ROS)
- ローカル環境のセットアップ
    - Docker (イメージのビルド用)
    - Kubectl (AlibabaのContainer Service(Kubernetes版)がサポートするクラスタ側のバージョンは現在1.9.3のみなのでクライアントも不整合がないものをセットアップする)
    - Aliyun CLI (GUIでも操作できるので任意)

## クラスタの作成
- コンテナーサービス > Kubernetes > Kubernetesクラスターの作成 を選択し、「クラスターの作成」画面を表示する
- 「基本情報の設定」で以下を入力/選択して「クラスターの作成」を押下する
    - **クラスター名を入力**
    - リージョン/ゾーンを選択
    - **ログオンパスワードを入力**
    - マスターのインスタンスの選択(3台)
    - ワーカーのインスタンスを選択(3台)
    - 上級設定はデフォルトのまま
- Resource Orchestration Service (ROS)によってクラスターがデプロイされる
![alik8s001.jpg](https://qiita-image-store.s3.amazonaws.com/0/11653/e45692fb-c321-95c3-8cb9-405e164e681e.jpeg)
- 以下のようにマスター3台/ワーカー3台の最小構成がデプロイされていることを確認する
![alik8s002.jpg](https://qiita-image-store.s3.amazonaws.com/0/11653/15290ed1-91ff-1e17-d9f0-756e95cc6d0b.jpeg)
Genymotionで日本語入力を出来るようにする

# 環境

- Genymotion 2.12.0
- Android 8.0

# 日本語化手順

- 上部のステータスバーからメニューを引き出して「歯車アイコン」を選択してSettingを表示
- メニュー最下段の「System」を選択
- メニュー最上段の「Languages & input」を選択
- 「Languages」を選択して「Add a language」を選択
- 「日本語」を選択して追加
- 「日本語（日本）」が２番目に追加されるので並び替えて１番目に変更

# 仮想キーボード追加

- 日本語化によりタイトルの表示が「言語と入力」になっている
- 「仮想キーボード」を選択
- 「キーボードを管理」を選択
- 「Japanese IME」をONに変更
- 再起動後にロック解除するまでアプリを起動出来ない旨のポップアップが出るので「OK」を選択

# Genymotionのバーチャルキーボード表示設定変更

- 仮想端末を１回終了
- Genymotionの「Your Virtual devices」から対象端末のレンチアイコンを選択
- 設定画面が出るので「Use virtual keyboard for text input」のチェックをONに変更
- 仮想端末を起動
Etherpad-lite インストール方法とCentOS6での注意点

# Etherpad-lite インストール方法とCentOS6での注意点

## これは何？
 * Etherpad-liteの紹介
 * Etherpad-liteのインストール方法概要
 * CentOS6に最新版を入れるときの注意点 

## Etherpad-lite とは
 * ドキュメントの同時編集ツールです。
 * node.js, express, WebSocket(socket.io)あたりをつかっているようです。
  * この辺の勉強にはいいのではないでしょうか？
 
## 参考URL
 * 公式サイト  http://etherpad.org/
 * Github  https://github.com/ether/etherpad-lite
 * qiita内の記事  https://qiita.com/tags/etherpad-lite

## 以下で利用したバージョン

* Etherpad 1.6.5
* nvm 0.33.1
* node 8.11.1

* CentOS7の場合
  * Apache 2.4.6
  * MariaDB 5.5.56

* CentOS6の場合
  * Apache 2.2.15
  * MySQL 5.1.73

## インストール方法
 * 詳しくは上記のURLを参照してください。さしてむずかしくはありません。
 * 詳細はいろんな方が紹介されていますので以下は概要のみ。
 * ちょっと使い勝手を試したいというだけならdockerでサクッと動くのが用意されているようです。 
   * ここを見てください。https://github.com/ether/etherpad-docker
   * こちらも参考になると思います。 
 https://qiita.com/nihongi/items/04f0ad4f7f3301bd40cc
 * インストール方法　概要
  * nvm, node.js, etherpad と順にインストールでとりあえず動きます。
  * setting.jsonで管理画面に入るためのアカウント設定をしてください。
  * その後は必要に応じて下記を実施。
   * SSL化（リバースプロキシ）
     * https://github.com/ether/etherpad-lite/wiki/How-to-put-Etherpad-Lite-behind-a-reverse-Proxy
   * MySQL利用
     * https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL
   * サービス化
     * https://github.com/ether/etherpad-lite/wiki/How-to-deploy-Etherpad-Lite-as-a-service
     * CentOS6の場合 http://aikotobaha.blogspot.jp/2012/12/etherpad-lite-on-centos6.html

  * プラグイン導入 管理画面から簡単に導入できます。
     * 以下が参考になります。 https://qiita.com/nihongi/items/6b9b453ba26d1ddd3ec0
   
## CentOS6の場合の注意点
 * CentOS7ではEtherpad-lite最新版インストールにさして問題はありません。
 * CentOS6の場合、若干の注意が必要です。
 * nvmの導入
  * CentOS6のgitのバージョンが古く、nvmの最新版では中で使っているgitコマンドのオプションがないといって怒られます。v0.32.1あたりを使いましょう。
  * nvmを使わず、software collectionのnodeを使うと、Etherpad-liteは一見、うまく入りますが、管理画面からプラグイン導入しようとするとこけるようです。nvmでバージョンを縛って使う方が吉です。
 * MySQL化
  * Etherpad-liteではMySQL5.5以降の対応のutf8mb4が使われているため、CentOS6でMySQL5.1とかの場合、使えません。
     * settings.json, src/node_modules/ueberdb2/mysql_db.js
にべた書きされているSQLを編集しutf8にすると動きます。

 * Apacheでのリバースプロキシ化
    * CentOS6でApache2.2の場合、websocketに対応していないのでwebsocketで本来通信するところもHTTPS通信になるようです。(polingになるみたい)
        * 参考：https://qiita.com/yuba/items/00fc1892b296fb7b8de9 CentOS7のApache2.4ではWebSocketに対応しているらしい。
    * WebSocketにならないとEtherpad-liteを使っている旨味がなさそうなのでリバースプロキシにつかうApacheは注意が必要です。

## 最後に
 * なんだかんだ面倒なのでCentOS7をおすすめします。
 * 次回はAPI周りをいじってみたいと思います。
SaasのR&DプロジェクトPMが、本業が忙しいときに敢えてRailsに触れてみた


#Ruby on Railsを導入したくなった
時は2018年2月。
巷では[猫も杓子もrailsという噂](https://techacademy.jp/magazine/8735)※を聞いたので、
そんならいっちょやってみるかと(職場の)自分のパソコンに導入してみた。

本記事はその所感と解説である。

※リンク先では一番人気の言語ではないですね。
　ちなみに[ここ](https://www.freee.co.jp/)もRailsという話です。無料利用もできますので、気になる方は是非**(宣伝)**。

# 環境
- Windows10

#やったこと
- [ここ](https://qiita.com/jnchito/items/08b5be458134073c60e3)を見てruby + railsをインストール
- [あとここも](http://itmemo.net-luck.com/windows-rails-environment-2/)見た。上より分かりやすいかも。
- 下記Rails Tutorialの実施

# Rails Tutorialの実施
書籍化している内容をWEBで無料公開している[Rails Tutorial](https://railstutorial.jp/)。
下記の内容が含まれています。

- [x] Railsのインストール手順
- [x] もちろんRailsの使い方が満載！ Hello,worldからルーティング、他多数 
- [x] コマンド一発でDB、画面UI、アクセス可能ページが作成できるScaffoldオプション 
- [x] [AWS Cloud9](https://goo.gl/kjL71M)　クラウド上のIDE。Tutorialの開発は全てこれを使います。
- [x] [Bitbucket](https://bitbucket.org/product)　個人利用であれば無料かつソース非公開で利用できるGit管理サービス。ちなみに有名な[Github](https://github.com/)はソース公開必須(無料利用)なので、使い分けができます。
- [x] [テスト駆動開発(TDD)](https://dev.classmethod.jp/study_meeting/read/what-tdd/)　まず(単体)テストありきという思想。実装前にテストモジュールを作成しFALSEを得、実装後にTRUEを得ることを一連の流れとしている。またRuby拡張機能により既存テストモジュールの一括自動実施が可能なので、デグレが防止できます。あくまで単体レベルですが。
- [ ] またRails tutorialはRaisのバージョンアップごとに改訂が行われるため、いつでも新鮮な内容が保たれている

**私は4章途中までしかできていませんが…**(全12章くらい)


# Railsってどんな書き方するの？
```ruby:ImagesController.rb
class ImagesController < ApplicationController
  def index
    page = Mechanize.new.get "https://www.google.co.jp/search?q=#{params[:q]}&tbm=isch"
    image_path = page.at('img').get_attribute :src
    render json: { image_path: image_path }
  end
end
```
[CodeZine](https://codezine.jp/article/detail/10354?p=3)から引用

# 結論
**Rails楽しい**
新しい技術、言語って素晴らしい。
次は何を学ぼうか。
画像から輪郭を抽出して重ね合わせる

画像から輪郭を抽出して重ね合わせる方法についてメモ
※opencv-python 3.4にて動作確認済み

# サンプル画像

昔非常にお世話になったこの画像に今回もお世話になります。

|入力画像|![a.jpg](https://qiita-image-store.s3.amazonaws.com/0/227399/c2c5184e-6f63-4766-96e3-37193d881202.jpeg)
|---|---|
|グレースケール|![b.jpg](https://qiita-image-store.s3.amazonaws.com/0/227399/24de038b-aef2-5fa9-f751-49ce09201c5a.jpeg)
|dilate⇒diff|![c.jpg](https://qiita-image-store.s3.amazonaws.com/0/227399/58b11834-6a0a-7b35-8ff9-ba26e5ac474f.jpeg)
|二値化|![d.jpg](https://qiita-image-store.s3.amazonaws.com/0/227399/2a290998-bbe8-3b5b-a3d9-b04ec7b320d0.jpeg)
|重ね合わせ|![e.jpg](https://qiita-image-store.s3.amazonaws.com/0/227399/7607d080-1f5b-3fa8-31ab-538dc49636c8.jpeg)

# ソースコード

```python3
import cv2

def edgeDetect(color):

    # カーネルサイズの設定
    kernel5 = np.ones((5, 5), np.uint8)
    # [1] 画像のグレースケール化とノイズ除去
    gray = cv2.fastNlMeansDenoising(
        cv2.cvtColor(color, cv2.COLOR_BGR2GRAY), h=20)
    # [2] dilate -> diff で線抽出
    dilation = cv2.dilate(gray, kernel5, iterations=1)
    diff = cv2.subtract(dilation, gray)
    diff_inv = 255 - diff
    # [3] 線を単色 -> 2値に
    _, edge = cv2.threshold(diff_inv, 225, 255, cv2.THRESH_BINARY)
    # [4] 線画とモノクロ2値を重ねる
    edge = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
    img = cv2.bitwise_and(color, edge)

    return img
```

# 各工程の解説

## [1] 画像のグレースケール化とノイズ除去

輪郭抽出するためにまず画像をグレースケール化する。ついでに`cv2.fastNlMeansDenoising()`を使用してノイズを除去することでゴミを輪郭として残さないようにする。ノイズの除去量は`h`を増やせば増えるが、やりすぎに注意。

**fastNlMeansDenoisingの詳細**
<https://docs.opencv.org/3.0-beta/modules/photo/doc/denoising.html#fastnlmeansdenoising>

## [2] dilate -> diff で線抽出

`cv2.dilate()`と`cv2.subtract()`を使うと輪郭がいい感じに抽出できる。最後に`255 - diff`で白黒反転している。

## [3] 線を単色 -> 2値に

`cv2.threshold()`で抽出した線を二値化する。

**thresholdの詳細**
<https://docs.opencv.org/3.0-beta/modules/imgproc/doc/miscellaneous_transformations.html#threshold>

## [4] 線画とモノクロ2値を重ねる

最後に抽出した輪郭をカラー画像に重ね合わせる。ただし、輪郭はグレースケール画像なので`cv2.cvtColor()`を忘れないようにする。

以上
Atomで自動保存する方法 package[autosave]


最初からインストールされている[autosave]をenableにするだけでOK。

[Preference>Packages]で「autosave」を検索、
[Settings]でEnabledにチェックを入れる。

![screenshot-2018-04-30-232648.png](https://qiita-image-store.s3.amazonaws.com/0/145707/20b1e2be-8124-d4dc-ff3f-813377ac6876.png)


## 気になる事を
一つずつ地道に減らしていくと、集中しやすい環境が作れるかなと思っています。

以下の記事おすすめ。
macOSでディスプレイ1枚で作業する技術
https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60
Kotlinでテストコードを書く

# ０．はじめに
　最近テストコードに興味を持っているので、少しずつ書いていこうかなと思っています。
今回は、IntelliJでテストコードを通したところまで記事にします。

※IntelliJ導入方法は省略しています。

#１．プロジェクト作成
メニューバーより　[File] -> [New] -> [Project]　の順でプロジェクトを作成
![0.png](https://qiita-image-store.s3.amazonaws.com/0/243974/a864a5f5-b0fb-5195-5363-cee19a7f6201.png)

新規プロジェクト作成ウィンドウから以下を選択
・Java
・SDK(Java9.0)
・Kotlin/JVM

![1.png](https://qiita-image-store.s3.amazonaws.com/0/243974/b44f140f-9681-86ae-a946-466a8ffc17b5.png)

[Next] ボタンを押してプロジェクト名を入力
![2.png](https://qiita-image-store.s3.amazonaws.com/0/243974/b5c30544-e783-9793-5073-822c0d68c629.png)

#２．ファイル作成

フォルダ構成(？)より [src] -> [New] ->[Kotlin/Class] を選択

![3.png](https://qiita-image-store.s3.amazonaws.com/0/243974/5c0dc49b-f8ae-6818-07c8-a90e62effe3f.png)

クラス名を入力
・Sampleとしました。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/243974/034a9fa0-168e-7442-2f45-dd121b2c657f.png)

同じ様にしてSampleTestクラスも作成しておきます。

#３．ソースコードの書き出し
簡単なエコーを確認していきます。

Sampleクラス
　・エコー(引数をそのまま返す)メソッドの実装

``` Kotlin:Sample.kt
class Sample {
    fun echo(value : Int) : Int {
        return value
    }
}
```
SampleTestクラス
　・エコーメソッドのテストコードを実装

``` Kotlin:SampleTest.kt
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals

class SampleTest {

    // OKケース１
    @Test
    fun SampleTest001 () {
        var sample = Sample()
        assertEquals(10,sample.echo(10))
    }

    // OKケース２
    @Test
    fun SampleTest002 () {
        var sample = Sample()
        assertEquals(-15,sample.echo(-15))
    }

    // NGケース１
    @Test
    fun SampleTest100 () {
        var sample = Sample()
        assertNotEquals(10,sample.echo(20))
    }

}
```
※　import kotlin.test.assertEquals　手書きが必要かも

#４．実行

[右クリック] -> [Run 'SampleTest'] よりテスト実行

![6.png](https://qiita-image-store.s3.amazonaws.com/0/243974/94e261cf-8cbb-aadf-f11a-91bce5b7a742.png)

実行結果はこの通り

![5.png](https://qiita-image-store.s3.amazonaws.com/0/243974/75aab761-c384-8974-f7de-d0d04c48a4e9.png)


#５．感想とか
　テストコードを実行する開発環境が提供されていたので特に詰まることなく進められた。
ただし、assertEqualsメソッドのインテリジェンスが最初だけ効かないので打ち込むのが少し面倒。

今回は３ケースで書いたけど、カバレッジとか観点とかは今後のタスクとして覚えておこうと思う。
2年目が思うタスク管理方法

今年の4月で業界経験が2年目になり新人感覚が抜けてきたので私が後輩に指導しているタスク管理の考え方を共有できればと思います。


#パーセント大好き思考を捨てる
タスク管理表やスケジュールを提出してもらう時、こちらがフォーマットを指定しなければ必ずと言っていいほどそれぞれのタスクやステップの横に進捗率なるなぞのパーセンテージをつけたがります。そして、その進捗率の粒度を聞いても特に答えを持っていない場合が多いです。

粒度に対する基準が明確でない場合の評価基準は**「仕事が終わった」か「仕事が終わってない」**の2択であり、むやみにパーセンテージにしないようにと指導しています。

#タスクの粒度を自分で決める
WBSが作りこまれているプロジェクトならばステップ(=WBSの最少単位)通りにタスクをこなしていれば間違いないと思います。しかし、プロジェクトによってはPMがやっつけで作ったWBSをもとにタスクをこなさなければいけないこともあります。(私の場合、WBSが存在しない奇跡のプロジェクトに参画したことがあります、、、)

そこで、後輩には**与えられたタスクを可能な限り切り分ける**ように指導しています。

たとえば、私が「商品情報の一覧を表示する機能」というようにタスクを振られた場合、(1)商品の一覧情報などのHTMLを表示、(2)フォームのボタン、(3)JSによる動的処理部分というようにタスクを切り分けていきます。

#まとめ
とりあえず、**「タスク管理は人に与えられた物差しではなく自分の物差しで測って、進捗報告は出来たか出来てないかだけ報告してね」**という当たり前のことをいうだけの内容となってしまいました。


以上、ここまで記事を読んでいただきありがとうございました。
ElasticBeanstalk custom platformでcontainer_commandの実行ディレクトリを設定する

## TL;DR
platform.yaml で`app_staging_dir`を指定するだけでOK。

```yaml
container:
  app_staging_dir: "/var/app/staging"
```

## 詳細
Elastic Beanstalkで選択できるプラットフォームでは、アプリのデプロイ時に実行するcontainer_commandはサーバ上に展開したアプリのソースコードのルートで実行される。と、[AWSのドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-container-commands)にもそんな様なことが書かれている。

私の知る限り少なくともPHPのプラットフォームではそうなっており、container_commandにで`ls`すると、ログにソースコードのファイルがちゃんとでてくる。

しかし、[Elastic Beanstalkのドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/custom-platforms.html)にあるサンプルNodePlatform_Ubuntuでカスタムプラットフォームを作成したら、container_commandの実行ディレクトリがソースコードが展開される場所ではなく`/tmp`になってしまう。

デプロイ時にソースコードに含んだファイルでなにかしようと思ったらこれは不便極まりない。

いろいろ調べていたら、インスタンス上で`get-config container`を実行することで確認できる`app_staging_dir`がどうもこのワーキングディレクトリを決めているっぽい。でも、どうやってそれを設定するかは結局どこっにも見つけることは出来なかった。

```shell
ubuntu@ip-xxxxxx:~$ sudo /opt/elasticbeanstalk/bin/get-config container --output YAML
---
app_staging_dir: "/tmp"
instance_port: '80'
config_staging_dir: "/tmp"
common_log_list:
- "/var/log/eb-activity.log"
log_group_name_prefix: "/aws/elasticbeanstalk"
source_bundle: "/opt/elasticbeanstalk/deploy/appsource/source_bundle"
```

万策尽きて、`get-config`のサブコマンドが`container`であることから、ダメ元で、カスタムプラットフォームを作成するファイルの platform.yaml に`container`セクションを追記してみたら・・・、あっさりできてしまった。

```yaml
version: "1.0"

provisioner:
  type: packer
  template: custom_platform.json
  flavor: ubuntu1604

metadata:
  maintainer: pikanji
  description: Ubuntu nginx PHP7.0 php-fpm
  operating_system_name: Ubuntu
  operating_system_version: 16.04
  programming_language_name: PHP
  programming_language_version: 7.0
  app_server_name: "none"
  app_server_version: "none"

container:
  app_staging_dir: "/var/app/staging"
```

いやー、これくらいドキュメントに書いておいてよAmazonさん・・・。
DynamoDBのキャッチアップに参考になった記事(個人用)

# DynamoDBのキャッチアップの参考になった記事

半年ぶりにDynamoDB触ることになり、すっかり忘れていたため、
以下の記事を見てキャッチアップしました。毎回ぐぐるのも辛いので備忘します。

- １．ありがたいまとめ記事で効率よく良記事をピックアップ
  - [DynamoDBでのポイントまとめ](https://qiita.com/yoskhdia/items/6897f66bdf93017ca033)
- ２．基本/概念をおさらいする。
  - [AWS Black Belt Techシリーズ Amazon DynamoDB](https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-dynamodb)
  - [DynamoDBの設計力をあげたい](http://www.ketancho.net/entry/2018/01/30/075500)
  - [AWS Summit 2014 Tokyo「Amazon DynamoDB テーブル設計と実践 Tips」レポート](https://dev.classmethod.jp/cloud/aws/aws-summit2014tokyo-dynamo/)
- ３．テーブル設計やアーキ設計の参考になった記事
  - [DynamoDBによるソーシャルゲーム実装 How To](https://www.slideshare.net/itoyusaku/jawsug-201303)
  - [DynamoDB ベストプラクティス](https://qiita.com/inouet/items/bcf9467a65b27c362ecf)  
└ SortKeyをカラムと時系列系のカラムを連結して管理する話参考になりました。
  - [AWS公式Doc-テーブルのベストプラクティス](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GuidelinesForTables.html#GuidelinesForTables.CachePopularItems)  
└ 上のQiitaの記事の元記事かなさらっと見ておく。

# SQSを挟んで失敗した時に備えよう

登録リクエストがこけることもあるため、リトライできるようSQSを挟むケースをよく聞きます。

登録に時間をかけられる場合は、SQSから取り出す量を一定にすることで、
プロビジョニングしたスループットにギリギリに保ってコストを節約することもできます。

以下、プロビジョニングスループットを最低の1に抑えるため、
１分間に60items（10items×6）のみSQSから取り出し登録し続けた例。

<img width="891" alt="スクリーンショット 2018-04-30 22.59.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/51734/2343757b-5b32-1cac-545f-eb318720bde0.png">
Railsでi18n化した時は本番環境の設定にも注意が必要

Railsでi18n化した際、開発環境と本番環境で翻訳文に差異が出てしまったので、その解消法メモ。

# 環境
- Ruby 2.4.1
- Rails 5.1.4

# 概要
Railsガイドの[2.3 ロケールの設定と受け渡し](https://railsguides.jp/i18n.html#rails%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%9B%BD%E9%9A%9B%E5%8C%96%E5%90%91%E3%81%91%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B-%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A8%E5%8F%97%E3%81%91%E6%B8%A1%E3%81%97)に従いi18n化し、ローカルの開発環境では実装通りの英語表記がされるようになった。
しかし本番環境のHerokuにデプロイ後、例えばブログ一覧画面において、下記のようになぜか中途半端な英語表記になってしまった。

| ローカルでの表示 | 本番環境(Heroku)での表示 |
| --- | --- |
|![Achieve 2018-02-16 22-20-24.png](https://qiita-image-store.s3.amazonaws.com/0/110452/a0d4af08-7b13-cdf1-fc98-42d1439ee384.png)|![Achieve 2018-02-16 01-18-15.png](https://qiita-image-store.s3.amazonaws.com/0/110452/17740a79-e506-80c0-99d5-3cb7f1dcc7e6.png)|


## Viewの記述

ブログ一覧を表示する `index.html.erb` の記述は以下の通り。
文言に関する部分をtメソッドで記述し、具体的な文言を`ja.yml`や`en.yml`で定義する、という感じ。

```
<h1 class="title"><%=t :blog_list %></h1>
<div class="container">
  <div class="row">
    <% @blogs.each do |blog| %>
      <div class="col-xs-12 col-md-6 blog-panel">
        <h2><%= blog.title %></h2>
        <p><%= blog.content %></p>
        <p><%=t :author %>:<%= blog.user.name %></p>
        <p><%=t :created_at %>:<%= blog.created_at %></p>
        <div class="blog-link">
          <%= link_to t(:detail), blog_path(blog.id), class: "btn btn-default" %>
          <% if blog.user == current_user %>
            <%= link_to t(:edit), edit_blog_path(blog.id), class: "btn btn-info" %>
            <%= link_to t(:delete), blog_path(blog.id), method: :delete, data: { confirm: "削除しますか？" }, class: "btn btn-danger" %>
          <% else %>
            <%= link_to t(:edit), '', class: "btn btn-info", disabled: "disabled" %>
            <%= link_to t(:delete), '', class: "btn btn-danger", disabled: "disabled" %>
          <% end %>
        </div>
      </div>
    <% end %>
  </div>
</div>

```

`I18n.load_path`してみた結果、返って来た配列の要素に以下が含まれているため、ロケール設定のymlファイルは正しく読み込めている様子。

```
"/app/config/locales/en.yml", "/app/config/locales/ja.yml", "/app/config/locales/model.en.yml", "/ap p/config/locales/model.ja.yml"
```

## 結果
`config/environments/production.rb`の`config.i18n.fallbacks`の値を`true`から`false`に変更することで解決した。

```
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found). |
config.i18n.fallbacks = false
```

デフォルトコメントの上２行にヒントが隠されていて、`fallbacks = true`の時は、
`en.yml`から翻訳文が見つからない場合は、検索対象をデフォルトのロケール(この場合はja)に戻していた模様。

私の場合、`en.yml`には最低限の訳文しか書いておらず、例えば「ブログ一覧」のような見出しの英訳が見つからず、デフォルトである日本語の見出しが表示されていた…ということだと思われる。

`fallbacks = false`とすると、`en.yml`で指定がない限りはtメソッドの引数を**(snake_case)->(Camel Case)**に変換した文字列が表示されるため狙い通りの表記となるようです。

上記の仕様を把握していれば`en.yml`に余計な訳文を書く必要はないが、理解が曖昧なままであれば大人しく`en.yml`にもきっちり訳文を記述しておいた方がいいでしょう。
Actions on Googleで'final_response' must be set.エラーの対処法

Actions on GoogleでSimulatorを使おうと思ったら**'final_response' must be set.**でハマったのでメモ。

##前提
Google Cloud Functionを**使わず**、Webhookを使って自宅LANのRaspberry Piでやり取りの場合。

##これにハマった
Simulatorからテストしようとしても、'final_response' must be set.で起動できない。もちろんGoogle Homeから呼びかけても同じ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/8734f6e4-31a7-6741-b0c9-793566f57017.png)

####ログを見てもよくわからず・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/ed636ab7-8095-c5af-73b8-4efa55ee5aed.png)

####サーバーは"500 INTERNAL SERVER ERROR"とあるがよくわからず・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/0773d98a-8bfd-cfd5-02f4-b42d8eca9f9c.png)

####DebugモードにしていたPythonの画面もイマイチわからず・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/52234b45-573d-f07c-1245-38586751fd1f.png)


##原因と解決法
結論から。いろいろ試した結果、ラズパイなどローカルのAPIを使おうとすると、API VersionがV2だとダメらしい。
（英語だからちゃんと読んでなかった・・・）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/804a50ba-510b-ec97-cef3-bd66603d7a2c.png)


これを以下のようにV1にしてSAVEすると、いけるようになるんですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253915/429405a2-0092-20b9-238a-cad79df4e422.png)


###V1とV2の違い
[V1 & V2 comparison](https://dialogflow.com/docs/reference/v2-comparison)にありました。認証時、V2になっているとGoogle Cloud Service Account経由になってしまうので、今回のようにローカルでやり取りするときはV1にする必要があるということでしょう。
Linux ext4パーティションをWindows 10にマウントする方法

UbuntuとWindow 10をデュアルブート環境で利用していますが、Windows 10からUbuntu側のファイルが読み書きできないと何かと不便なときがあります。
[Ext2Fsd](http://www.ext2fsd.com/)というツールをインストールすると、Ubuntu側のext4パーティションを読み書きできるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/100712/89dcfa07-1f70-10ec-4733-2fd4f447a793.png)

#ダウンロードとインストール
[Ext2Fsd公式サイト](http://www.ext2fsd.com/)の左にある「Download」リンクから最新のインストーラ(Ext2Fsd-0.69.exe)をダウンロードしてきます。
ダウンロードが完了したら、インストーラを起動してインストールします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100712/f3482624-d306-1770-4345-85202dc8bd85.png)

※2018/04/30時点では、0.69が最新でした。
※0.68以前のバージョンはext4に対応していないため、使わないで下さい。

#マウント方法
インストーラーが終了すると、「Ext2 Volume Manager」が起動します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100712/c9336238-3fd2-3e23-511b-f73a0d185821.png)

マウントしたいボリュームを選択し、ダブルクリックすると設定画面が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100712/05d9c14e-ffea-1464-cae7-ab5e405e917a.png)

リムーバブルストレージの場合は「Automatically mount via Ext2Mgr」を、内蔵ストレージの場合は「Mountpoint for fixed disk, need reboot」をチェックして、ドライブレターを選択、「Apply」ボタンを押せば完了です。

以上
web extension開発ことはじめ

# 何故？
* chrome拡張機能の開発環境の整え方はよくあるが、firefoxのaddonの開発環境については特に記事が見当たらなかったため。  
基本的にはchromeの拡張機能開発と**ほぼ一緒です**。
ここでは主に拡張機能の開発環境の整え方について書いていきます。


# web extensionsとは？
firefox用のアドオンです。

# 開発環境
必要なものは`generator-web-extension`のみです。githubは[ここ](https://github.com/HaNdTriX/generator-web-extension)

# インストール

## 前提
`node.js`,`nvm`が必要です。

## インストール方法

```
npm install -g yo generator-web-extension
```

# 使い方

```sh

#ディレクトリの作成
mkdir ./testextensions

#ディレクトリに移動
cd ./testextensions

#エクステンションの雛形作成
yo generator-web-extension
```

いくつかの質問に答えたら雛形が形成されます。下図のようなかんじ。
browser actionを利用したかったので今回は`pages`ディレクトリもできちゃっています。

![20180426130149.jpg](https://qiita-image-store.s3.amazonaws.com/0/136336/ea4d7954-851c-b1e7-0bdc-601c75cedf06.jpeg)

`scripts`ディレクトリ以下にスクリプトを書きます。

また、見ての通りnode_modulesディレクトリもできていますので、`npm install --save [package]`すれば

モジュールのインポートもできます。

## テストの仕方

以下のコマンドでテストができます。

```sh
npm run dev firefox
```

`./testextensions/dist/firefox`配下にアドオンができます。
**ホットリロードになってますので保存したら自動的にオートリロードされます。**便利！

## 最終的な拡張機能のパブリッシュ

```sh
npm run build firefox
```

`./testextensions/dist/firefox`配下にファイルができます。


それではよいアドオンライフを！！
PythonでSeleniumの実施

## PythonでSeleniumの実施

自動テストツールSeleniumをPythonで実施する方法

## テスト環境

  - OS
    Windows10(64bit)
  - Selenium実行ツール
    Python(3.6.5)
  - ブラウザ
    Chrome

## ドライバーの準備

ドライバーの準備を行います。
今回はChromeでテストを行うため、
Chrome用のドライバーを用意します。
下記からドライバーをダウンロード。
http://chromedriver.storage.googleapis.com/index.html?path=2.38/

## Pythonファイルの作成

Seleniumを実施するPythonファイルを作成します。
今回はamazonで「お茶」と検索するとこまで実施します。

  - Pythonファイル作成
    任意のディレクトリにPython(.py)を作成します。

  - サイトに遷移するまでの準備
    対象サイトまで遷移するためのコードを記載します。

```
from selenium import webdriver

#ChrmoeDriverサーバーのパスを引数に指定しChromeを起動
driver = webdriver.Chrome("[ダウンロードしたドライバーのパス]chromedriver.exe")

#指定したURLに遷移する
driver.get("https://www.amazon.co.jp/ref=ap_frn_logo")
```

## 要素の取得

要素を取得するため下記のコードを記載します。

```
#検索欄のテキストボックス要素をid属性値から取得
element = driver.find_element_by_id("twotabsearchtextbox")
```

今回はid属性から取得しますが、name、classからでも取得できます。

```
#nameで取得
element = driver.find_element_by_name("xxx")

#classで取得
element = driver.find_element_by_class_name("xxx")
```

## 検索ワードの入力～ボタン押下

検索ワードの入力から検索ボタンのクリックまで
下記のコードで実施します。

```
#テキストボックスに検索ワードを入力
element.send_keys("お茶")

#検索ボタンの要素をclass属性値から取得
element = driver.find_element_by_class_name("nav-input")

#検索ボタンを押下
element.click()
```


今回使用したコードの全量。

```
from selenium import webdriver

#ChrmoeDriverサーバーのパスを引数に指定しChromeを起動
driver = webdriver.Chrome("[ダウンロードしたドライバーのパス]chromedriver.exe")

#指定したURLに遷移する
driver.get("https://www.amazon.co.jp/ref=ap_frn_logo")

#検索欄のテキストボックス要素をid属性値から取得
element = driver.find_element_by_id("twotabsearchtextbox")

#テキストボックスに検索ワードを入力
element.send_keys("お茶")

#検索ボタンの要素をclass属性値から取得
element = driver.find_element_by_class_name("nav-input")

#検索ボタンを押下
element.click()
```
各iOSバージョンで追加された新機能を速攻で試せる アプリRepository まとめ

各iOSメジャーバージョンごとに、新規で追加された機能をサンプル実装しているリポジトリをリストアップしました。

バージョンアップの時に、顔認識やアニメーション周りなど何らかの新機能が追加されますが、
新機能を一個ずつサンプル実装、動作確認をするのはとっても大変です。

新しいアプリを開発する時に、使えるネタが見つかるかも知れませんので、
エンジニアだけでなく、Xcodeを使える方は、iOSの新機能を軽く眺めてみたい時にビルドして動作確認すると面白いものが見つかるかも知れません。

※各項目を紹介されている記事を項目の横にリンクしています。

## [iOS-11-by-Examples](https://github.com/artemnovichkov/iOS-11-by-Examples)

「iOS 11 新機能のサンプル寄せ集めアプリ」です。

* Core ML([Core MLで焼き鳥を機械学習させてみた](https://dev.classmethod.jp/smartphone/iphone/ios-11-core-ml-2/))
* Vision(顔認識ができるそうです。[[iOS 11] 画像解析フレームワークVisionで顔認識を試した結果](https://dev.classmethod.jp/smartphone/iphone/ios-11-vision/))
* ARKit([[iOS 11] ARKitでソファー設置からあの子の身長測定まで色々やってみた](https://dev.classmethod.jp/smartphone/iphone/ios-11-arkit-2/))
* MapKitの新機能
* Core NFC([iOS11 新機能「Core NFC」を試してみる](https://marunouchi-tech.i-studio.co.jp/4405/))
* DeviceCheck([[iOS 11] 初回起動判定などに使える DeviceCheck フレームワークとは ](https://dev.classmethod.jp/smartphone/iphone/ios-11-device-check/))

など、新機能を一覧で見ることのできるアプリが、プロジェクトとしてgithubで管理されています。

## [iOS-10-Sampler](https://github.com/shu223/iOS-10-Sampler)

「iOS 10 新機能のサンプルコード寄せ集めアプリ」です。

* リアルタイム一般物体認識
* 手書き数字認識
* ブラーをアニメーション
* 画像付きローカル通知

など、新機能を一覧で見ることのできるアプリが、プロジェクトとしてgithubで管理されています。

## [iOS-9-Sampler](https://github.com/shu223/iOS-9-Sampler)

「iOS 9 新機能のサンプルコード寄せ集めアプリ」です。
これから、iOS9のおさらいとして使わせてもらうといい感じでした。
Reactアプリケーションで動画や音楽ファイルを扱うために「react-player」を使用する

# Reactで音楽ファイルを扱いたい！

~~そもそもWebサービスで音楽ファイルをバリバリ扱う事自体が悪手だという意見は置いておいて，~~
Webサービス，特にReactを使用したUI開発を行っていて，音楽ファイルや動画ファイルを扱いたくなるときがあると思います．

Reactは周辺ライブラリが多く，「あれやりたいなー」と思ったら大体OSSを使用すれば実現する環境が整っています．
動画・音楽ファイルに関しても同じで，ブラウザ上でサウンドを再生したい，もしくは動画埋め込みコンポーネントを作りたいときに使用できるOSSが存在します．

それが**react-player**です．

# react-playerとは

https://www.npmjs.com/package/react-player

動画や音楽ファイルをコンポーネントとして操作することができるようになるライブラリです．
というか，どちらかというと動画ファイルを簡単に扱うためのライブラリで，Youtube動画の埋め込みはもちろん，Facebookに投稿された動画やvimeo,twitchなどに投稿された動画をコンポーネントとしてUIに簡単に埋め込むことができます．
音声ファイルに関してはSoundcloudやMixcloudにアップロードされているものを埋め込むことが可能です．
ローカルファイルにおいてはmp3,mp4などが使用できます．

※IEで動作を保証するためには[babel-polyfill](https://babeljs.io/docs/usage/polyfill)を導入する必要があります．IE対応，難しいね…

使用できるファイルや動作確認については[公式で用意されているデモページ](https://cookpete.com/react-player/)を参照してください．

## インストール

npmコマンドやyarnコマンドで簡単に導入することが可能です．

```sh:install
$ npm install react-player --save #npmを使用するとき
$ yarn add react-player #yarnを使用するとき
```

## 使い方

ベーシックな使い方は以下のような感じになります．

```js:reactPlayer.js
import React, { Component } from 'react'
import ReactPlayer from 'react-player'
 
class App extends Component {
  render () {
    return <ReactPlayer url='ここにファイル名を入れる' playing />
  }
}
```

### propsについて

urlには，

* ストリーミングサービスからの埋め込みの時：使用したい動画や音楽の配信URL
* ローカルファイルを使用する場合：音楽ファイルもしくは動画ファイルを置いているパス

を記載します．

※ストリーミングサービスからの埋め込みでないローカルファイルを使用する場合，音楽や動画などのデータはAmazon S3やGoogle Cloudなどのオンラインストレージサービスにアップロードしておく必要があります

他，以下のprops（パラメータ）を渡すことで動画・音楽ファイルを制御することができます．
(よく使用しそうなもの一例)

| props名|処理|
|:--|:--|
|url|動画・音楽ファイルのパス|
|playing|動画・音楽を再生するかどうか|
|loop|ループするかどうか|
|controls|ユーザーが動画ファイルをサービス固有のコントローラーで操作できるようにするかどうか(Vimeo,Twitchは設定に関係なくサービス特有のコントローラが表示される)|
|volume|音量(0.0~1.0の間で設定)|
|muted|音をミュートにするかどうか|
|playbackRate|プレイバックレートを設定する(Youtube，Wistia,ローカルファイルのみサポート)|
|width|動画や音楽ファイルを埋め込むときの横幅|
|height|動画や音楽ファイルを埋め込むときの縦幅|
|style|スタイルシートで装飾する場合に使用|
|config|使用するストリーミングサービスやファイル別にオーバーライドして使用したい設定を追加する|

### Facebookから動画を取得してコンポーネント化する場合

Facebookから動画を取得するには，[FacebookのアプリIDを作成・登録](https://developers.facebook.com/docs/apps/register#app-id)する必要があります．
アプリIDを作成したら，`config`propの`facebook`内にappIdというpropsがあるので，ここに取得したappIdを記入します．

```js:facebookConfig.js
<ReactPlayer
  url={'hogehoge'}
  config={
    facebook: {
      appId: '123456'
    }
  }
/>
```
Javaでファイルのclose忘れて失敗した話

# はじめに
Java何年もやっててclose忘れてエラー起こしたアホは私です。

# 発生した問題
開発中のサーバーで連続負荷テストを実施していると、時間がたつにつれてアプリケーションの動作がおかしくなる現象が発生した。
CPUやメモリの使用率に問題は見られず原因が分からないままだったが、1～2週間ほど放置し続けるとログに「もうファイル開けません」的なエラーを出してアプリケーションが死んでいた。
その後アプリケーションが開いているファイルディスクリプタ数を確認すると、1プロセスあたりに開けるファイルディスクリプタ数の上限に達しているのを確認した。

# 問題となったコード
```java
return Files.list(Paths.get(dirPathStr)).map(path -> path.getFileName().toString())
            .collect(Collectors.toSet());
```
問題となったコードは上記。Stream APIを使用してディレクトリ内のファイル名一覧を返すメソッドだが、`Files.list()`でオープンしたディレクトリがcloseされていない。
closeを忘れてもGCによってメモリ自体は解放されると思うがファイルディスクリプタの方は解放されないようなので、実行されるたびにファイルディスクリプタの数が増え続けることになった。
ちなみに開発環境にEclipseを使っていると（Scannerクラス等）ファイルを開くクラスのインスタンスでcloseを忘れると警告を出してくれるが、（Eclipse 4.7時点において）上記コードは警告を出してくれない。何故……

# 修正したコード
```java
try (Stream<Path> paths = Files.list(Paths.get(dirPathStr))) {
	return paths.map(path -> path.getFileName().toString()).collect(Collectors.toSet());
}
```
ちゃんとcloseするようにした。ファイルディスクリプタの増加も起きなくなり、アプリケーションも問題なく動作するようになった。

# おわりに
以下教訓

* テストするときはCPUやメモリ使用率以外も確認する
* ちゃんとJavadoc確認する
* IDEに頼りすぎない
バージョンにより異なるメソッドをoverrideする方法に関して

## はじめに

https://github.com/joker1007/activerecord-cause を詠んでいて、以下のような箇所にでくわした。

`get_binds`、 `name_with_color` `sql_with_color`は、activerecord-cause独自のメソッドではなくて、
ActiveRecordのメソッドです。

```ruby
def get_binds(payload)
  raise NotImplementedError
end

def name_with_color(payload_name)
  raise NotImplementedError
end

def sql_with_color(payload_sql)
  raise NotImplementedError
end
```

その後のコードで、このメソッドたちを持つクラスを継承したクラスでoverrideしています。
イメージとしては以下のサンプルのような感じです。



## サンプル

```ruby
module Test
  class HogeVer0
    def basic_method
      puts "このメソッドはversionに関係なく呼び出せます"
    end

    # メリットは？
    def special_method
      raise "VERSIONが正しくありません"
    end
  end

  class HogeVer1 < HogeVer0
    def special_method
      puts "form ONE!!"
    end
  end

  class HogeVer2 < HogeVer0
    def special_method
      puts "form TWO!!"
    end
  end
end

def set_test_obj(version)
  case version
  when 1
    Test::HogeVer1.new
  else
    Test::HogeVer2.new
  end
end
```

結果はこんな感じ。

```
obj = set_test_obj(1)
obj.basic_method          #=> このメソッドはversionに関係なく呼び出せます
obj.special_method        #=> form ONE!!

obj = set_test_obj(2)
obj.special_method        #=> form Two!!

obj = set_test_obj(100)
obj.special_method        #=> form Two!!
```

##おそらく結論

将来的に新しいバージョンが登場した場合、新しいクラスでそのメソッドが不要になるシチュエーションもあったっりする。

そうしたケースを考えると、このようにバージョンによって異なるメソッドは、activerecord-causeが行ったように、継承前のクラスでエラー処理を行うことで拡張性と柔軟性を与えるのかもしれない。たぶん。
ツイッターの Account Activity API 使ってみた

前日ツイッターのAccount Activity APIを使ってみました、この API が一つ webhook 登録が可能です、アカウントのリアル活動（ツィート、通知、設定）を受信します。

以下のものが含まれます：
- ツィート
- at 通知
- リプライ
- リツイート
- 引用リツイート
- いいね
- ダイレクトメッセージとその受信
- フォロー
- ブロック
- ミュート

使う時実際起こった問題を書きました。

<!-- more -->

# アプリを作ります

まずここで https://apps.twitter.com/ チュートリアルに従ってアプリを作って、アプリの key と secret を取得します。

# Account Activity API を申請します

https://developer.twitter.com/en/apply
ここで権限を申請します，app ID の添付を忘れずに（app ID について：https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview ）

申請成功したらメールが来ます
![申請成功のメール](https://qiita-image-store.s3.amazonaws.com/0/204638/99a2bbc0-8fcf-4755-0928-d33238395b6f.png)

# webhook URL を登録

## CRC テスト
webhook は CRC テストを合格しなければ登録できない、具体的な要望はここに書いている -> 
https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/securing-webhooks

自分もNode.jsのdemoを書きました、一応参考になれば：
https://github.com/xingoxu/twitter-like-downloader/blob/master/routes/twitter.js#L13-L23

## postman でリクエストを送って webhook URL を登録します

```
POST:
https://api.twitter.com/1.1/account_activity/all/env-beta/webhooks.json?url=${あなたのwebhook URL}

Header:
Authorization: Bearer TOKEN
```

`Bearer TOKEN` は`https://api.twitter.com/oauth2/token`で取得できます。

注意
- webhook URL は https と 443 ポートのみサポートします（https://twittercommunity.com/t/how-to-register-a-webhook-url-in-twitter/86096/36 ）

## postman でリクエストを送って subscription に webhook を登録します

```
GET:
https://api.twitter.com/1.1/account_activity/all/env-beta/webhooks.json

Header:
Authorization: Bearer TOKEN
```
さっきの webhook の id を取って

```
POST:
https://api.twitter.com/1.1/account_activity/all/env-beta/subscriptions.json

Header:
Authorization: OAuth 1.0

Body:
webhook_id: さっきの webhook の id
```
注意すべきところ：ここAuthorization は OAuth 1.0（user id 認識ため）

リスポンス内容はない、`HTTP Code: 204 No Conent`

登録したらここに見えます

```
GET：https://api.twitter.com/1.1/account_activity/all/env-beta/subscriptions/list.json

Header:
Authorization: Bearer TOKEN
```

これを受けれます

```json
{
    "environment": "env-beta",
    "application_id": "12345678",
    "subscriptions": [
        {
            "user_id": "12345678"  // <- 自分のuser_id
        }
    ]
}
```


# テスト

好きなツイートをいいねすると

ツイッターサーバーから webhook object 受けれます。

最後、Account Activity API使ってる自家用ツイッターBotです、参考になればぜひ
https://github.com/xingoxu/twitter-like-downloader


最後まで閲覧いただきありがとうございました。


オリジナルリンク：https://blog.xingoxu.com/ja/2018/04/twitter-account-activity-api/
外部結合について解説

## 簡単にいうと

- 内部結合（Inner Join)の対義語
- 基準となるテーブルにデータがあれば、もう一方のテーブルになくても取り出す

## 右外部結合と左外部結合の違いは？

基準がどちらになるかの違いがあるだけです。

- 右外部結合は右のテーブルを基準にして結合
- 左外部結合は左のテーブルを基準にして結合

## SQL文はどうなっているのか？

```sql
SELECT カラム名1, カラム名2, ...,FROM 左に当たるテーブル
LEFT(RIGHT) OUTER JOIN 右に当たるテーブル ON 結合の条件
```

左とか右がややこしいですが、

- 最初にSELECT文で取ってきたテーブルが左
- JOINのところで取ってるテーブルが右

に該当すると覚えておくといいでしょう。

---
それでは左（右）外部結合に関して詳しくみていきます。

### 左外部結合について解説

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/37808156-fecd-9ed5-173f-702182a87093.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/0c190a72-43c8-d3d5-e0ed-385e00914ad1.png)

こんなテーブルがあったとします。
authorsテーブルをbooksテーブルに左外部結合します。

```sql
SELECT * FROM books
LEFT OUTER JOIN authors ON books.author_id = authors.id
```

こう書くと、

- booksテーブルが左
- authorsテーブルが右
- 左を基準にして結合

という意味になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/1290a84b-18d9-aa9e-90d6-ae44969ce3ad.png)

左外部結合後のテーブルを見てみると、

- booksテーブルのレコードは全て残っている
- 該当するbookがなかったauthorは削除されている
- 該当するauthorがいなかったbookに結合したレコードは値がnilになる（オレンジ色で色付けしているセル）

ってことがわかると思います。

### 右外部結合について解説

```sql
SELECT * FROM books
RIGHT OUTER JOIN authors ON books.author_id = authors.id
```

次は右（authorsテーブル）を基準に外部結合していきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202653/f9288705-0950-a4f3-3e5b-022cac4402db.png)

これは左外部結合が理解できていれば、問題ないですね。
気をつける点は、テーブルのレコードの並びがauthorテーブルを基準にしているところくらいでしょう。


## 参考にさせていただいたサイト

[SQL素人でも分かるテーブル結合(inner joinとouter join)](https://qiita.com/naoki_mochizuki/items/3fda1ad6594c11d7b43c)
jupyter-notebookでElixirを実行する


https://github.com/pprzetacznik/IElixir


上記にある通りですが、メモとして残します。


環境を整えるのに、Erlangのビルドツールrebarが必要なので、事前にインストールします。

```
mix local.rebar --force
```
デフォルトで、~/.mixに格納されるのでパスを通しておきます。
環境変数 MIX_HOME を事前に設定しておくと、その場所に格納されます。


IElixirのコンパイル

```
git clone https://github.com/pprzetacznik/IElixir.git
cd IElixir
mix deps.get
mix test
MIX_ENV=prod mix compile
```

jupyterに登録

```
./install_script.sh
```

あとはいつも通りjupyter-notebookを実行するだけです。
mkdirでディレクトリが存在しない時だけディレクトリを作成する方法

便利系コマンドの備忘録。
こういうの結構パッと出てこないからいつかまとめたい（目標）

####対処法
単純にオプション-pをつける。

```:terminal
$ mkdir -p hogeA/hogeB/hogeC
```

昔は一生懸命test -dで検索をかけてやっていた…けど、それはpathを引数に渡していろんなことが出来たりするので、便利だったりするので使い分けると良いかも。
セミナー、LT ネタ

##やったことがあるセミナーネタ
ストロータワーによるチームつくり
かんばんワークショップ
モティベーションポーカー
スキルマップとチーム力向上
[価値観ババ抜き](http://myvaluecard.com/)
(セミナーよりは実践の形で）Value Stream Mapping

##LT のたね
全日本恐妻組合
GTCメモ
[エンゲージメント 働く人の幸福度をはかるたった12の質問 | プレジデントオンライン](http://news.livedoor.com/article/detail/14043733/)
　エンゲージメントは、仕事や会社に対するワクワク感のこと
エンジニアリングマネージャーがおさえておきたい臨床心理学
　認知行動療法、認知と行動：どうとらえるか
　家族療法
　精神分析と認知行動療法・家族療法のちがいなどなど
ドゥンカーのロウソク問題 と ８つのコイン問題
プロジェクトにかかわるコミュニケーションについて（ガンダム）

##やってみたい・取り入れてみたいネタ
[3/3 モブプログラミングを実践してみよう!! 〜アジャイルモンスターのモブプロ入門〜　に参加した](https://qiita.com/warumonogakari/items/f213c9524d1792f0089a)
[紙ヒコーキワークショップをやりました](https://dev.classmethod.jp/etc/scrum-training-airframe/)
[スクラム体験ゲーム ~チーム開発の光と闇~ を開催してみた](https://qiita.com/shoki_kitajima/items/1016b934c328bbd92495)
[リフレクションカード](https://www.manacre.com/reflectioncard-copv)
[IKIGAIカードゲーム](https://nuworks.jp/ja/product/ikigai-game/)

##スライドデザイン参考資料
[100万点以上の高品質なフリー画像素材 - Pixabay](https://pixabay.com/ja/)
[エンジニアのためのスライドデザイン実践講座](https://speakerdeck.com/ken_c_lo/how-to-design-presentations-for-engineers)
[ライトニングトーク準備の参考資料まとめ](https://qiita.com/moomooya/items/45398e06f189d4a26227)
[プレゼンテーションに使う画像の探し方](https://qiita.com/TAKAKING22/items/20c006206d2ce23a5608)
[登壇用スライドの背景にいい感じに画像を設定する方法 - 青空な日々](https://fortegp05.hatenablog.com/entry/2018/12/28/213356)
[大体いい感じになるKeynote・Googleスライド用無料テンプレート『Azusa 3』作った - SANOGRAPHIX BLOG](https://text.sanographix.net/entry/azusa3-google-slides-keynote-template)
OTRS6をインストールしてみた

##■はじめに
仕事で使用してるOTRSについて備忘録的メモです。

##■環境
・OTRS-6.0.6
・CentOS7.4
　→SELlinux無効
　→Firewalld無効


##■インストーラーのダウンロード
OTRSポータルのユーザ登録をしてインストーラを入手
ユーザ登録：https://otrs.com/product-otrs/trial-version/
入手ファイル：otrs-6.0.6-01.noarch.rpm
もしくは

~~~
wget http://ftp.otrs.org/pub/otrs/RPMS/rhel/7/otrs-6.0.6-01.noarch.rpm
~~~
##■インストール
~~~
yum -y install mariadb-server
yum -y install --nogpgcheck otrs-6.0.6-01.noarch.rpm
yum -y install "perl(Text::CSV_XS)"
~~~

##MariaDBのチューニング

/etc/my.cnf.d/zotrs.cnf 

~~~
[mysqld]
max_allowed_packet   = 64M
query_cache_size     = 32M
innodb_log_file_size = 256M
character-set-server = utf8
~~~

##■起動
mariadbとapacheを起動

~~~
systemctl restart httpd mariadb
systemctl enable httpd mariadb
※mariadb が起動しない場合はログをクリア
　rm /var/lib/mysql/ib_logfile*
~~~

##■インストールウィザード
ブラウザからOTRSにアクセスして順に進む。
http://ServerIP/otrs/installer.pl

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/dc6ad430-6b77-c60f-08d7-408b394d662e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/14725ece-f476-1c49-562d-1d6220210202.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/dbeff61d-9767-3191-ded1-9f5ca92551d3.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/e0ae6974-9d3c-441d-c127-78063669ad4b.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/f6e2c083-e124-9ce0-182b-e2659edb1a6e.png)

##■バックグラウンドプロセスの起動
~~~
su - otrs
/opt/otrs/bin/otrs.Daemon.pl start
/opt/otrs/bin/Cron.sh start
~~~

##■ログイン
http://ServerIP/otrs/index.pl?
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/daa4d8dc-700e-560c-aa62-cda80b31a5ef.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/f6292acf-30fb-ce1d-b05f-81d24ba2c616.png)

※メモ
ユーザー:root@localhost
パスワード:8nTIFoxDGHklVNMk

以上です。
"warning: command substitution: ignored null byte in input"の対処法

bash 4からは、外部コマンド呼び出しの結果をキャプチャする際に、 (`$(command)`とかのあれ) 出力にヌルバイトが含まれていると警告が出るようです。

ヌルバイトはターミナル上では目に見えないので、出力のどこにヌルバイトが潜んでいるのかは、結果のバイナリを直接見るのがよいでしょう。

`command | hexdump -C`

ヌルバイトを出力しないようにすれば、表題のwarningは消えるはずです。

参考 https://stackoverflow.com/questions/46163678/get-rid-of-warning-command-substitution-ignored-null-byte-in-input
chart.jsのデータ更新でメモリリークが発生する問題と解決方法

ちょっとハマったので記録しておきます。

## 問題点

[Chart.js](https://www.chartjs.org/)というjavascriptライブラリを使用し、以下のようにデータ更新のたびにチャートをインスタンス化すると徐々にメモリがリークします。

```js
let chart = new Chart(canvasContext, options);
```

Chartコンストラクターの第一引数はCanvasエレメントのCanvasRenderingContext2D、第二引数がチャートの描画オプションとなります。

このnew Chartをデータの更新のたびに叩くと、チャートオブジェクトがメモリから完全に消えなくなります。

## 解決方法

1 : チャートのインスタンスを変数に保存しておいて、データだけを書き換える。
<http://www.chartjs.org/docs/latest/developers/updates.html>

```js
if (!chart) {
 chart = new Chart(canvasContext, options);
} else {
 //データのみ更新
 chart.data.datasets = options.data.datasets;
 chart.update();
}
```

2 : チャートの更新時に、以前のチャートを明示的に破棄する。
<https://www.chartjs.org/docs/latest/developers/api.html#destroy>

```js
if (chart) {
 chart.destroy();
}
chart = new Chart(canvasContext, options);
```

## 教訓

公式ドキュメントはちゃんと読みましょう。
サーバーの基本（１．サーバーとは何か）

こんにちは。
今月から現場に入ったばかりの文系未経験者です。

3ヵ月間の研修を経て、現在保守として現場に入って早１ヵ月。
恥ずかしながら、これまで当たり前のようにインターネットを使用してきて、
サーバーとは何か、ネットワークの仕組みはどうなっているのかあまり気にしたことがありませんでした。
そして、当然ながら、現場に入り頭が？？？？？？？？？？なことがたくさんあったので、勉強したことを忘れないようにまとめておきたいと思います。
もし、私のようにITの世界に入ったばかりであわわわわ....となっている方がいれば、
この記事が少しでも救いになれば嬉しいです。
ITの先輩方、もしよろしければ、間違っている認識、誤った記載があれば、ご教授頂ければ幸いです。

今回記載するのは、
1. サーバーとは何か
2. サーバーの種類
3. パーミッションについて
4. RAIDについて
5. TCP/IPについて

です。
長くなるので、項目ごとに投稿を分けようと思います。

こちらの記事では、１．サーバーとは何かについて記載していきます。

現場に入ってまず、これがこのシステムのデータベース用のサーバーで、これがこのシステムの...といった説明を受け、まあ、システムのデータベースがこの中にあるんだろう。
うむうむ。としたものの、あれ、そもそもサーバーっていったい？？

## 1. サーバーとは何か
　調べると、「サーバとは、コンピュータネットワークにおいて、他のコンピュータに対し、自身の持っている機能やサービス、データなどを提供するコンピュータのこと。また、そのような機能を持ったソフトウェア。」（IT用語辞典から引用　http://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%83%90.html）
という説明があります。

身近な例でいうと、サーバーは英語でserver、つまり「供給者」という意味になります。
日常生活で使われるサーバーといえば、「ビールサーバー」や「ウォーターサーバー」がありますね。

ビールをserve（供給）するビールサーバー、水をserve(供給）するウォーターサーバーといったように、何かを供給する装置という意味で、ITの世界で使用されるサーバーもファイルやメールなどのデータを供給する装置というように考えることができます。


もう少し詳しく書くと、

前提として、私たちがWebページを閲覧するとき、HTTPという通信プロトコルにより、自分のパソコンから「このページが見たいのでください。」とサーバにお願いします。そうすると、サーバーが「いいよ～。これだよ～！」とページを返してくれます。このおかげで、私たちは、Webページを閲覧することができます。
![リクエスト＆レスポンス.jpg](https://qiita-image-store.s3.amazonaws.com/0/232451/6c188452-3cd0-c1a3-d2e3-cfe83c73447c.jpeg)

イラストの青い矢印が表す、PCからサーバーに欲しいページやファイルなどの情報をお願いすることを「リクエスト」といい、イラスト水色の矢印が表す、サーバーがPCにお願いされたものを返すことを「レスポンス」といいます。

このことを踏まえて、初めに記載したサーバーの説明を読んでみると、「他のコンピュータに対し、自身の持っている機能やサービス、データなどを提供するコンピュータのこと。」という部分がしっくりきますね。

つまり、ざっくりいうと、目の前のパソコンにない機能を供給するのがサーバーです。

これまで1対1の条件で説明してきましたが、サーバーは1対1ではなく、1対多で使用してこそ意味が出てくるものです。
例えば、私たちが日常的に使用しているwebサービスやスマートフォンのアプリでも、サーバーが使用されているケースが多くあります。

たとえば、Gmailです。
Gmailでは、自分のアカウントにログインして、メールを受け取れます。
その時何が起きているかというと、ログインで認証し、パソコンやスマートフォンから、Gmailのサーバーに対して、「メールをください」とお願いします。
そうすると、Gmailサーバーが、「はい、あなたのはこれね～！」とパソコンやスマートフォンに対して返してくれます。
つまり、Gmailに登録している人のメールのデータがGmailのサーバーに保管されており、ログインで認証することで、その人宛てのメールを返してくれるようになっています。
そのため、全てのメールデータがサーバーが保管されているので、原則として自分のスマートフォンのアプリやパソコンにはメールのデータは保管されず、Gmailに登録しているそれぞれの人が様々なデバイスから閲覧できる仕組みになっています。

このように多数とやりとりすることでサーバー本来の役割が果たせます。

読んでいただき、ありがとうございます。
間違っている点があればご指摘頂ければ幸いです。

## 参考図書
・「おうちで学べるサーバのきほん」著：木下肇　翔泳社出版　2017年
・「スラスラわかるネットワーク＆TCP/IPのきほん　第２版」著：リブロワークス　SBクリエイティブ株式会社出版 2018年