OmniAICreator/Qiita-1.07M huggingface dataset:
（追記あり）「OSError: Could not find libspatialindex_c library file」発生時の対処法(MacOS環境）

# 発生した問題について
## 実行環境
|名前|環境|
|---|---|
|OS  |mac OS 10.13.6 |
|プログラム言語  |Python 3.5.2 |




## 発生した問題の概要
GISを使わずにPythonのみで地理空間データを可視化するために[【脱GIS】Pythonとかで地理空間情報、位置情報を扱うための情報まとめ【随時更新】
](https://qiita.com/aimof/items/b4e4551d27abaf5bb258)より以下のようなソースコードを作成しました．

```python:main.py
import osmnx as ox
import matplotlib.pyplot as plt
shinjuku = ox.gdf_from_place('Shinjuku')
shinjuku.plot()
plt.show()
```
これを実行させたところ次のようなエラーが発生しました．

```
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import osmnx as ox
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/osmnx/__init__.py", line 9, in <module>
    from .buildings import *
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/osmnx/buildings.py", line 9, in <module>
    import geopandas as gpd
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/geopandas/__init__.py", line 1, in <module>
    from geopandas.geoseries import GeoSeries
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/geopandas/geoseries.py", line 12, in <module>
    from geopandas.base import GeoPandasBase, _series_unary_op, _CoordinateIndexer
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/geopandas/base.py", line 14, in <module>
    from rtree.core import RTreeError
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/rtree/__init__.py", line 1, in <module>
    from .index import Rtree
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/rtree/index.py", line 5, in <module>
    from . import core
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/rtree/core.py", line 125, in <module>
    raise OSError("Could not find libspatialindex_c library file")
OSError: Could not find libspatialindex_c library file
```

# 問題の解決
## 解決方法
homebrewにて`brew install spatialindex`を叩きインストールすることで解決しました．

## 「 spatialindex」ってなんぞや
[こちら](http://libspatialindex.github.io/#id1)を和訳してもよく理解できなかったです・・・・どのようなものか理解したら追記しようと思います．

# 追記（2018/09/19）
MacOS環境では上記ソースコードの最後に`plt.show()`をつけないと地図が表示されませんでした．

```python:correct_main.py
import osmnx as ox
import matplotlib.pyplot as plt
shinjuku = ox.gdf_from_place('Shinjuku')
shinjuku.plot()
plt.show()#追加箇所
```
反復処理はもっと詳細に分類されるべき

# はじめに
「全てのプログラムは 逐次・反復・分岐 で実現できる」と言われる（構造化定理）。多くの場合「逐次」は (`do`もしくは該当する syntax なし)、「反復」は `for`、「分岐」 `if` があてられる。

ただ、実際プログラミングをすればわかるけど、「逐次」と「分岐」のバリエーションが多くないのに対して、「反復」のバリエーションが多すぎるのに気づく。

# 市民権を得た map reduce
色々な言語で `map`, `reduce`, `filter` などなどが使えるようになった。これらによって今まで `for` を使っていた処理（の一部）は前述の関数にとってかわられるようになった。

これが示すのは、反復処理はより粒度の細かい処理に分類できるということだ。「**反復して何がしたいのか？**」 という観点で処理を詳細化・具体化できるともいえる:

- 「この配列を `for` で回して `fn` かました結果で配列をつくっといて」
- 「この配列に `fn` を `map` しといて」

二つ目の指示の方が簡潔だし、本質を捉えている


# 知る人の少ない juxt
前章では反復操作に `map` という名前を付け、見通しをよくした。このように、**反復操作の各種処理パターンに名前を付けて再利用化することはプログラムを簡潔に記述する**のに有効な方法論となる。

反復処理に関連する典型的な処理パターンに名前を付けることができるが、`map`, `reduce` が有名になった程度で、まだまだ知られていない・なじみの薄い名前がたくさんある。

これらの 名前 = 処理パターンをしっかり身に着ける必要があるのではないか？`zip`, `interleave`, `juxt`, `aperture` ...他にも山ほどある:

- 「この `x` に`f`と `g`と `h`をそれぞれ独立に適用して、得られた3つの結果を配列に詰めておいて」
- 「この `x` を`f`, `g`, `h` で `juxt` しといて」

よく出てきそうな処理パターンなので `juxt` を覚える価値があるといえる

# 関数型プログラミングの勉強
操作を抽象化し名前を付けるのは、関数型プログラミング言語が得意とするところ。これらを勉強することは非常に良いと思う。今勉強している Clojure はこういった処理パターンに名前を付けるものが多くて非常におススメ。
初めてのアプリ制作 ~カレンダー~

#はじめに

私はC言語を約２年勉強していましたが、
*"人の役に立つサービスやアプリを作りたい*:relaxed:"と思い
一番身近な姉が欲しいという**カレンダーアプリ**を作ってみようと思います:open_hands_tone2:

##まずはヒアリング

アプリを作っていく上で
姉が欲しい機能や色味などをヒアリングします。

姉の意見はこう:point_down_tone2:

欲しい機能：予定の日時、内容、一緒にする人　を入力し見れる機能
一目で見れる日の範囲：一ヶ月
始まりの曜日：月曜日
全体の雰囲気：シンプル
全体の色：基本色なしで、もし入れるなら紫

最初の段階で姉から聞いたのはこのくらいです。

今回は初めてのアプリ作りということもあり、
色や始まりの曜日を変更する機能はつけないことにします。
shellでcurlコマンドを使って無理やりURLエンコードする方法

# はじめに
みなさん、シェルでURLエンコード、したくないですか？
私は（必要ないなら）したくないです。
が、そうも言ってられない時、ありますよね？（えっ、Python使えば一瞬だろ?・・・せやな)

と、いうことで、シェルしか使えない縛りにあった時のために、curlコマンドを使って無理やりURLエンコードをする方法です。

# コマンドの全容

最終的なURL`https://sample.co.jp?p=あいうえお&q=かきくけこ`

```text:sample_query
p=あいうえお&q=かきくけこ
```

```shell
HOST="https://sample.co.jp"
URL=""
while IFS='\&' read P1 P2;do
  # curlのrequestログを一時的なファイルに書き出す
  curl ${URL} -v --verbose --get --data-urlencode "${P1}" --data-urlencode "${P2}" 1> /dev/null 2>temp_log
  # curlのログからurlEncodeされたリクエストを取り出し、Hostとくっつける
  while read Q1 Q2 Q3 Q4;do
    URL=`echo ${HOST}${Q3}`
  done <<< `grep -E "> GET .+ HTTP/1\.[0-9]" temp_log`
done <<< `sample_query`
rm temp_log
```

結果`https%3A%2F%2Fsample.co.jp%3Fp%3D%82%A0%82%A2%82%A4%82%A6%82%A8%26q%3D%82%A9%82%AB%82%AD%82%AF%82%B1`

## やってること
`sample_query`を読み取って、`&`で文字列分割。各クエリをcurlを`--data-urlencode`オプションつけて叩く。requestの出力を一旦`temp_log`に格納。`temp_log`を分割してエンコードされた部分を抜き取って`HOST`とくっつけて`URL`に格納

# 終わりに
Python使えるならそのほうが(きっと)楽。
【Android Kotlin】Spinnerを関数化して使いまわす

初投稿です。お手柔らかにお願いします。
1画面で複数のSpinnerを設置するために、Spinnerを関数で使い回す方法が調べても出なかったので記述します。
え、ダイアログフラグメントのほうがメジャーだって？~~こまけぇことは(ry~~

##参考情報
[スピナー(Spinner)を使用するには](http://www.adakoda.com/android/000074.html) 
[文字列からリソースIDを取得する](https://qiita.com/t-kashima/items/9462af782fb5f1a2a7da)

##前提条件
「array1」「array2」という配列と、「spinner1」、「spinner2」というIDのSpinnerを用意(細かいコードは割愛)


##Kotlinで書くと以下の通り
```MainActivity.kt
class MainActivity : Activity() {
  public override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    fun spinner(itemArray: Array<String>, spinnerName: String){
          val adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, itemArray)
          adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
          //引数のStringを使ってリソースのViewIDを抽出
          val viewId = resources.getIdentifier(spinnerName, "id", packageName)
          val spinner = findViewById<Spinner>(viewId)
          //アダプターを設定
          spinner.adapter = adapter
          // スピナーのアイテムが選択された時に呼び出されるコールバックリスナーを登録
          spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
                      override fun onItemSelected(parent: AdapterView<*>, view: View,
                                                                       position: Int, id: Long) {
                              val spinner = parent as Spinner

                       }

                       override fun onNothingSelected(arg0: AdapterView<*>) {}
          }
    }

          spinner(array1, "spinner1")
          spinner(array2, "spinner2")
    }
}
```

配列とViewIDを引数に入れることで無理くり関数にする事が出来ました。しかし冗長な気が。。。
もっとスマートに出来るぜ！という方は是非コメントいただけたら助かります。
VagrantfileでNetworkManagerを何とかする

## 概要

先程、[vagrant upがコケる問題について](https://qiita.com/shohe_zsm/items/4baffd67b05d7ee13388)という記事を書いたので、
ついでにvagrantのVMでNetworkManagerが邪魔でネットワーク設定がうまいこと行っていない。
という時に私が試している方法を書いてみます。役に立つかはわかりません！

※以下、centos6を想定して書いています。

## 状況

以下の条件で治る場合に試す価値があるかもしれません。

* VM接続してもネットワークの設定がうまく出来ていない。
* systemctlやserviceコマンドでNetworkManagerの状態を確認し、起動している。
* /etc/sysconfig/network-scripts/ifcfg-〇〇のnm_controlledの値をyesにして、NetworkManagerを再起動すると直る。

## 原因

vagrantは起動時にifcfg-〇〇を書き換えるので、
その際に nm_controlled が No に設定されてしまう。

## Vagrantfileでなんとかする

```
config.vm.provision "shell", run: "always", inline: <<-SHELL
    nic_path=/etc/sysconfig/network-scripts/ifcfg-eth1
    if grep 'nm_controlled'
    then
      sed -i 's/nm_controlled=no/nm_controlled=yes/g' $nic_path
    else
      echo 'nm_controlled=yes' >> $nic_path
    fi
    service NetworkManager restart
SHELL
```

※centos7だと nm_controlled はデフォルトで NM_CONTROLLED になっているようなので、上記の書き換えも大文字としてください。

スクリプトを晒すの恥ずかしい。。。けど慣れるまで頑張ります。

## 2018/9/25追記

どうやら、
[Vagrant 1.7.2 + CentOS 7.1.1503 で、private_networkの ip address が消える](https://qiita.com/kutsushitaneko/items/18ed70bdc6075c1d46df)
や、
[Vagrantのprivate_networkをCentOS7.0で設定](https://qiita.com/ftakao2007/items/b332f562b0ea74e9f97e)
等に有るように、VagrantとNetworkManager関連の話は色々合ったようですね。

ただ、私の場合、vagrant1.9辺りを使用していてもnetwork周りがうまく設定されていないことが有ります（治っていそうなものですが...パッチ適用しないとだめなのかな）。

private-ipが振られていなかったり、指定のアドレスとは別のアドレスが振られていたりします。
別のアドレスが振られている場合は、
（ https://github.com/hashicorp/vagrant/issues/2968 に書いてあったのを後で見つけましたが、）
if down && if up で今の所解決します。

「CentOS6+NetworkManager」
という構成がややこしいのかもしれません（未だにCentOS6を使うことも多いです）。
MVCフレームワークって？

すでに一定量以上のコードで組まれたプログラムを読み込むのがつらい。


本当に１行だけ直せば済むような修正であっても、どこをどう直せば間違いなく正しく動いてくれるのか・・・
プログラミング初心者の自分にとっては、砂漠に落ちた指輪を探すような途方の無さがあります。


そんな弱音を吐いていた所、
そもそもさぁ、「MVC」って知ってる？
虚を突かれたような思いがしました。


また、よくわからないアルファベットの組み合わせ・・・。
頭に来たので、調べた内容をいかにまとめます。



- MVCフレームワークとは
-
ある程度以上、規模のあるプロジェクトにおいて、

「どんな機能が、どこに格納されているか」

わかりやすくする為の、整理整頓術です。
正確に記述すると、設計思想の一つです。

- MVCの３要素
-
MVCの基本機能は、以下の３つから成り立ちます。まずは、教科書通りの正確な定義から。

- Model・・・一般的にビジネスロジックと呼ばれる機能
　　
- View・・・ユーザーに触れる部分、見た目やレイアウトに関わる機能

- Controller・・・ModelとViewの仲介役、作業やデータのやりとりの処理を制御する機能


- レストランでの食事におけるMVC
- 



まず、出だしのModelの説明「ビジネスロジック」からなんのことやらさっぱりわかりません。

以下に様々な記事を読んで、自分なりの解釈をお送りします。

プログラムが実行する処理をレストランで、「料理を作って、お客さんの口に届くまで」の工程で例えてみます。

Model　→　コックさん
Controller　→　ホールスタッフ
View　→　料理を食べるお客さん

次に具体的な説明で、各要素がどのような働きをしているか詳しく見ていきます。

- 美味しい食事が届くまで
-

<ol>
<li>料理を注文する（View）
→多くの場合、ユーザーが視覚的に触ることのできるViewからプログラムに指示が入って来ます。

<li>注文をコックに伝える（Controller）
→Viewから入って来た指示をControllerが受けて、最も処理機能が得意なModelに伝えます。

<li>注文を受けたコックさんが料理を作る（Model）
→処理機能に特化したModelが実際に処理します。この時、データベースを使って処理することも。

<li>できた料理をお客さんに持っていく（Controller)
→処理が終わったデータや結果を、Viewに渡します。

<li>出て来た料理を、ナイフで切ったり箸でつまんだりして食べられる形に処理する（View)
→最終的に、ユーザーが見られる（食事を楽しめる）形に処理をして、無事「食べる」ことができました。

- MVCに分けるメリット 
-

この例では実際に、キッチン担当/ホール担当/お客さんにやってもらうセルフの作業　など、作業者が異なります。
このように作業の役割をあらかじめ分けて整理しておくことで

<ol>
 <li>どこを直せばいいのかわからない
 <li>担当が分かれていないから、同時に複数の問題を直せない

などの問題をあらかじめ防ぐことができます。
MVCフレームワークは歴史が古く、多くのプロジェクトの基礎になっていることが多いです。


今日はこのあたりで、失礼します。
C++ - Something about "const"

Many Many conditions...T_T

https://www.ptt.cc/bbs/C_and_CPP/M.1328444899.A.8CA.html
http://blog.xuite.net/tsai.oktomy/program/65131235-const+%E6%94%BE%E7%BD%AE%E4%BD%8D%E7%BD%AE%E7%9A%84%E6%84%8F%E7%BE%A9
RubyMineでindexを再構築してもダメなら…

いろいろやって何度も試みてそれでもダメで🤮吐きそうだったけど、あっさり片付いたのは結局こういうことだった。

[RubyMine]-[Preference]-[Project Structure]-[+ Add Content Root]が空っぽ。
これにコンテンツのルートを指定して[Add]。

が～っと動いて解決。

やれやれ。
MacOSでの解決策なので、他OSは他詳しい方に譲ります。
BabySqueelのwhere条件を外部から与える

Squeelから移行するときに地獄を見て、ほとんどやけくそ気味にいろいろ試したらできた備忘録。

頭が悪いクエリで恐縮だが、シンプルな例として「IDが1または2」という条件をwhereの外部から与える場合について考える。

### 今はなきsqueelの場合

```by_squeel.rb
where = { id: 1 } | { id : 2 }
User.where(where).to_sql
```
実はこのコードを今動かしたところ、 `|` がSyntaxエラーを起こして動かない。これに近いクエリが今まで何故動いていたのかわからず戦慄する。
実際のコードではif文の条件付きで連結されていたが、連結したら動かなかったのではないかとすら思わせられる。
さすがに今からこれを検証する気は起きないので、これが動く環境があったのかもねくらいに捉えていただきたい。

### baby_squeelの場合

```by_baby_squeel.rb
where_block = Proc.new{ (id == 1) | (id == 2) }
User.where.has(&where).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE (\"users\".\"id\" = 1 OR \"users\".\"id\" = 2)"
```

注目すべきはProcを使って渡すことで、ラムダ式では引数の数が合わず、 `wrong number of arguments (given 1, expected 0)` になるためダメだった。
つまりはProcの性質で引数の数が合っていないのを強引に解決しているようだ。明らかに力技じゃん。

[参考]Rubyの ブロック、Proc.new、lambdaの違い
https://qiita.com/ryo-ma/items/24c46592b45775e8644d

### [追記]baby_squeelでラムダ式を使う場合

```by_baby_squeel_using_lambda.rb
where_block = ->(dsl){ (dsl.id == 1) | (dsl.id == 2) }
User.where.has(&where).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE (\"users\".\"id\" = 1 OR \"users\".\"id\" = 2)"
```

引数が合わないなら合わせてみようじゃんとやってみたらこうなった。
`dsl` には `BabySqueel::DSL` のインスタンスが含まれている。まだ全然コード読めていないが、squeelのDSLはevalする際にブロックに与えられた引数によって動きが変わるようだが、BabySqueelにはそのようなロジックが見当たらないのでラムダ式かつ引数ゼロの場合に正しく解釈できなかったのかはそこらへんが関係しているのだろうか。今度読む。
C++ - How to use std::tr1 as delegate?

It likes callback...

http://allenchou.net/2012/04/easy-c-delegates/
https://stackoverflow.com/questions/9568150/what-is-a-c-delegate


Before used delegate, you must need know ***function pointer***.
1. https://kheresy.wordpress.com/2010/11/03/function_pointer/
2. https://kheresy.wordpress.com/2010/11/09/function_object/
3. https://kheresy.wordpress.com/2010/11/12/function_object_tr1/


Open Source:
http://marcmo.github.io/delegates/
Ubuntu 18.04 への HipChat4 の導入

先日 ( 2018年9月16日 ) 、自端末に表題の HipChat4 をインストールしたのですが、その際に少し問題が発生したため備忘録としてまとめます。発生した問題は以下の2つです。

[`1. Ubuntu 18.04 LTS "Bionic Beaver" への HipChat4 のインストール`](#1)
[`2. HipChat4 起動後のネットワークエラー`](#2)

###1.
使用している ubuntu の codename が[ここ ( レポジトリのdistsディレクトリ直下 ) ](https://atlassian.artifactoryonline.com/atlassian/hipchat-apt-client/dists/)に存在していれば、[HipChatのサイト](https://www.hipchat.com/downloads)に記載されている指示に沿って操作を行います。

使用している ubuntu の codename は次のコマンドで確認できます。

```bash
$ lsb_release -c
```
私が使っている ubuntu の codename は bionic なのですが、バージョンが新しいせいかディレクトリが用意されていませんでした。なので、次のコマンドを実行して HipChat4 をインストールしました。

```bash
sudo sh -c 'echo "deb https://atlassian.artifactoryonline.com/atlassian/hipchat-apt-client xenial main" > /etc/apt/sources.list.d/atlassian-hipchat4.list'
wget -O - https://atlassian.artifactoryonline.com/atlassian/api/gpg/key/public | sudo apt-key add -
sudo apt update
sudo apt install hipchat4
```
xenial は bionic の1つ前の LTS ( Long-term support ) 版です。

###2.
インストールが完了して HipChat4 を開き、自分の HipChat アカウントでログインすると、"Unable to access hipchat.com ・・・" とエラーが出てきました。

これを解決するために以下のコマンドを実行しました。

```bash
sudo rm /opt/HipChat4/lib/libcrypto.so*
from=/usr/lib/x86_64-linux-gnu/
to=/opt/HipChat4/lib/
sudo ln -s ${from}libcrypto.so.1.0.0 ${to}libcrypto.so.1.0.0
if [ ! -e ${to}libssl.so.1.0.0 ]; then
    sudo ln -s ${from}libssl.so.1.0.0 ${to}libssl.so.1.0.0
fi
if [ ! -e ${to}libssl.so ]; then
    sudo ln -s ${from}libssl.so.1.0.0 ${to}libssl.so
fi
```

最後に再起動をして、HipChat4にログイン出来るようになりました。

問題の解決に当たって以下のページを参考にしました。
[Installing on Ubuntu 18.04](https://community.atlassian.com/t5/Hipchat-questions/Installing-on-Ubuntu-18-04/qaq-p/779966)
gitをソースコードからインストールしたメモ

古いサーバに入ったら git が古くて `GIT_SSH_COMMAND` 環境変数が使えず不便なので、ソースコードから git を入れた。curl のソースが必要だったので curl も入れた。

```sh
curl https://curl.haxx.se/download/curl-7.61.1.tar.bz2 | bunzip2 | tar xvf -
cd curl-7.61.1
./configure --prefix=/home/me/local
make install
~/local/bin/curl -V
```

curl 7.61.1 が入った。

```sh
curl -o git-master.zip https://codeload.github.com/git/git/zip/master
unzip git-master.zip
cd git-master
make configure
./configure --prefix=/home/me/local
make -i install
~/local/bin/git --version
```

git version 2.19.GIT が入った。
AlibabaCloud初見勢が初めの第一歩で色々調べてみた

# はじめに
色々な場所で話を聞いたり、セミナー出たりしてみたので、
情報を過剰書きでまとめてみた。
ちなみに中の人はIoT関係のためにAWSは２年くらい触ったことありますが、
AlibabaCloudはまるっきりの初心者です。

ちなみに運営してる会社さんを漢字で書くと<b>阿里巴巴集団</b>とのこと。

巴里歌劇団みたいだなぁとか思ったのは内緒


# アリクラウド色々箇条書き
・アリクラウドとAWSでだいたい同じことできる。が、アリババは中国には強い
・function ConputeがLambdaなことできる
・アリクラウドは現地法人いらない。ただし中国の情報を出すとかは無理→サーバーたてるだけならやれる
・中国がIoTで海外に５０万件出すと、法律に引っかかるようになるらしい（今年の12月ぐらい？）
・日本人で登録できるアリクラウドは６０サービスくらいしか使えない→今後どんどん増えるらしい
・中国や日本以外でできる（インターナショナル）でも６０ちょいぐらい
・色々なサービスがAWSより安い...らしい

# アリクラウドのサービス＜ET Brain＞箇条書き
・ET Brain：いろいろなことを数学的にやろう
・ビッグデータを可視化する：DataV インターフェースを色々できる
・だいたいのデータ形式（JSON）でいける
・CSVデータ→データベース→DATAVの流れ
・BIとの違いはリアルタイム性
・PAI：機械学習のモデル
・DATAVが月３万、DBが月２万。総額で月５〜１０万。

# AWSに対応するサービス一覧
主に自分が使ったことのあるサービスで、セミナーとかで出てきた名前だけ
色々まだまだ調べてるので割と疑問形多し。スマネェ。

<table>
<tr><td>Alibaba</td><td>AWS</td><td>備考</td></tr>
<tr><td>Elastic Compute Service</td><td>EC2</td><td>なんか類似サービスが色々ある？</td></tr>
<tr><td>Function Compute</td><td>Lambda</td><td></td></tr>
<tr><td>Server Load Balancer</td><td> ELB </td><td></td></tr>
<tr><td>Table Store</td><td> DynamoDB </td><td>NoSQLなだけで実際は別物？</td></tr>
<tr><td>Object Storage Service</td><td>S3</td><td></td></tr>
</table>

dynamoDBとLambdaっぽいやつがあるので、だいたいのことはできそう。

# 日本での動向について
http://j.people.com.cn/n3/2018/0725/c94476-9484646.html
ソフトバンクと提携してIoTをやろうとしているみたい。
SORACOMのようなサービスを提供されるっぽい？
この辺り頑張ってくれると色々夢が広がりそう。

# まとめ
AWSを目標にしてるっぽく、サービスがAWSにかなり近い感触。
まだまだ日本ではサービスは全体の1/3程度だが最低限開発で必要なものは全て揃っているし、
今後どんどん日本向けでサービスを追加していくとのこと。
（ちなみに１年前はElastic Compute Serviceぐらいしかなかったらしい）。
最大のメリットは中国企業のためのグレートファイヤーウォールで超有利なことなのは間違いないので、
今後中国向けのサービスを考えているのであればアリババ一択ではないだろうか。
価格面でも中国らしく？かなり安いとのことなので、
サービスが十分提供されればクラウドの選択肢の１つになるのではないだろうか。

# まとめのまとめ
中国向けサービスならアリババ使っとけ！
PHP テキストファイルを読み込み、配列に格納し、表示させる。(※1行ずつの内容がそれぞれ配列の要素となるように)

```test.txt
aaa
bbb
ccc
```
このテキストファイルを読み込み、各行を配列に格納し、表示する。

```
<?PHP
  $file_name = "test.txt"; /*読込ファイルの指定*/

  $ret_array = file( $file_name ); /*ファイルを全て配列に入れる*/

    print_r($ret_array);
?>
```
ブラウザ上で実行すると以下のように表示される。
![スクリーンショット 2018-09-18 16.23.30.png](https://qiita-image-store.s3.amazonaws.com/0/290560/5d923033-98c4-273c-819b-ceab9cae030c.png)

今回使用したfile関数は、テキストファイルを行ごとに配列にして返すという特徴を持つ。
npm vs yarnどっち使うかの話

### [記事を移転しました](https://blog.minimalcorp.com/posts/w8XX5Is7NOO5ZE9imK7fcw)。

概要を読んでみて、気になる方は続きをご覧ください。

## 結果だけ書くと

`yarn`　の方が速くて簡潔です。

また必要な状況はかなり限定的ですがyarnにあってnpmにない機能も存在します。それに関する内容に[この記事](https://blog.minimalcorp.com/posts/LisaFQmT1N2KwGE-S3IqlA)で若干触れました。気になる方はご覧ください。

(比較した方法・バージョンとかは下を読んでください。誤りがあれば意見いただけると嬉しいです。）

[続き -> https://blog.minimalcorp.com/posts/w8XX5Is7NOO5ZE9imK7fcw](https://blog.minimalcorp.com/posts/w8XX5Is7NOO5ZE9imK7fcw)
ActiveRecordのバリデーションコンテクストを同時に複数付与する方法

- さりげにどこにも知見がなかったのでメモ。

## 結論
- `first`と`second`コンテクストがあるとした場合、二つのコンテクストを同時に付与するためにはこうする。

```rb
@user.attributes = user_params
if @user.save(context: [:first, :second])
  # 成功処理
else
  # 失敗処理
end
```

- ポイントは、**たとえupdate時であっても、コンテキストを使うためにはsaveを使うということ。**
Ruby の ensure が実行される条件のメモ

rescue 節内で raise したときに ensure が実行されるのかされないのか、いつも思い出せないのでメモっておく
（下記の irb を実行するのはもう4回目くらいになると思う）

実行したのは

```bash
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17]
```

です。

```ruby
irb(main):016:0> begin
irb(main):017:1*   raise "a"
irb(main):018:1> rescue => e
irb(main):019:1>   puts "in rescue"
irb(main):020:1>   raise
irb(main):021:1> ensure
irb(main):022:1*   puts "in ensure"
irb(main):023:1> end
in rescue
in ensure
RuntimeError: a
	from (irb):17
	from /usr/bin/irb:11:in `<main>'
```

これを見るに、rescue 節で raise すると、 ensure を通りつつ例外があがっていくようである。
ISUCONで話題になったWebサーバー、h2oをUbuntu 18.04で動かしてみる

# はじめに
この文書は怪文書です。

- Ubuntu 18.04で
- できるだけ労力を少なく
- h2oを動かしてみる

をやってみようと思います。

CentOSの場合は[RPM](https://github.com/tatsushid/h2o-rpm)が、Dockerの場合はDocker Hubに[イメージ](https://hub.docker.com/r/lkwg82/h2o-http2-server/)があるのでそれを使ってあげるとよさそうです。

## 事前準備
1. Ubuntu 18.04のマシンを用意する

以上。

## インストールをやってみる
[これ](https://gist.github.com/inductor/e88f99ecd47615573220d32b0b3a6010)を実行するだけです。

```install_h2o.sh
#!/bin/bash
## apt update && apt upgrade -y && apt autoremove -y
## やろうとしたらlockファイルがあって死んだのでlockファイルを消した
## rm -rf /var/lib/dpkg/lock
apt update && apt upgrade -y && apt autoremove -y
apt -y install locate git cmake build-essential checkinstall autoconf pkg-config libtool python-sphinx wget libcunit1-dev nettle-dev libyaml-dev libuv-dev libssl-dev zlib1g-dev
git clone https://github.com/tatsuhiro-t/wslay.git
git clone https://github.com/h2o/h2o.git
cd wslay/
autoreconf -i
automake
autoconf
./configure
make
make install
cd ../h2o/
cmake -DWITH_BUNDLED_SSL=on .
make
make install
```

## Systemdに突っ込んでみる

3年前の記事ですが[これ](https://negima.mobi/2015/10/2092)が使えます。

```/lib/systemd/system/h2o.service
[Unit]
Description=H2O the optimized HTTP/1, HTTP/2 server
After=syslog.target network.target remote-fs.target nss-lookup.target
 
[Service]
Type=forking
PIDFile=/var/run/h2o/h2o.pid
ExecStartPre=/usr/local/bin/h2o -c /etc/h2o/h2o.conf -t
ExecStart=/usr/local/bin/h2o -c /etc/h2o/h2o.conf -m daemon
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
 
[Install]
WantedBy=multi-user.target
```

```/etc/h2o/h2o.conf
user: nobody
hosts:
#  "www.example.com:443":
#    listen:
#      port: 443
#      host: 0.0.0.0
# Let's Encryptを入れる場合
#      ssl:
#        certificate-file: "/etc/letsencrypt/live/www.example.com/fullchain.pem"
#        key-file: "/etc/letsencrypt/live/www.example.com/privkey.pem"
#    paths:
#      "/":
#        file.dir: /var/www/html
  "www.example.com:80":
    listen:
      port: 80
      host: 0.0.0.0
    paths:
      "/":
        file.dir: /var/www/html
access-log: /var/log/h2o/access.log
error-log: /var/log/h2o/error.log
pid-file: /var/run/h2o/h2o.pid
```

コンフィグを突っ込んだら以下のコマンドを叩きます

```
systemctl enable h2o.service
systemctl start h2o
```
iOS ”ショートカット"からMS Flowを呼んでみた

##ことの背景
iOS12用に「ショートカット」というアプリが出たようなので、インストールしてみたところ、HTTPの要求もワンクリックで実行できるようでしたので、試してみました。
※ショートカットに関する解説は[こちら](http://arigato-ipod.com/2018/09/apple-siri-shortcuts-app-for-ios-12.html)から。

今回は、最近よく使うMicrosoft Flowの実行トリガーにする場合の例を記載します。

##iOS ショートカット側
ショートカット側では、さまざまなアクションを選択可能です。今回は最新の写真を取得して、OneDriveにコピーする例です。
![shortcut.png](https://qiita-image-store.s3.amazonaws.com/0/202779/4b4f6052-635a-0a87-2963-1b2b2f685352.png)

上から順に、
1. 最新の写真を端末から取得
2. (後述の)MS FlowのリクエストURLを設定
3. URLに対して1.の写真をPOST

としています。
HTTPの要求を行う際には必ず、最初にURLを定義して、その後ろに「URLの内容を取得」をつける必要があります。

##MS Flow側
次に、リクエストを受け取る側、Microsoft Flow側を紹介します。
![flow側.png](https://qiita-image-store.s3.amazonaws.com/0/202779/3ce5ff1e-ee51-0c7b-660b-c2b470492f2d.png)
「HTTPリクエストの要求」というトリガーがあるので、これを定義しておきます。
作成後にURLが発行されるので、ショートカット側に登録しましょう。
あとは単純に、OneDriveに対して、POSTされた内容のbodyにあるコンテンツ（写真）を、OneDriveコネクタの「ファイルの作成」で登録します。

##結び
どちらも似たようなワークフローアプリですが、組み合わせることで、使い道が広がるかもしれません。
特にMS FlowはモバイルのFlowアプリから渡せるものに限りがあるので、前段で何かを処理したい場合には、このようにHTTPリクエストを行うことも有効だと思われます。
PHP フォームから受け取った文字列をテキストファイル に追記保存する

※フォームのコードは省略。POSTでテキストを送信したとする。

```
<?php
 $name = $_POST['name'];

    $a = fopen("test.txt", "a"); /*”a”でfopenすることで追記できる*/

    fwrite($a,$name." \n"); /*改行するために" \n"を入力する*/

    fclose($a);
     ?>
```
aaa、bbb、cccの順でフォームから送信すると以下のようにテキストファイル(test.txt)に保存される。
![スクリーンショット 2018-09-18 16.17.37.png](https://qiita-image-store.s3.amazonaws.com/0/290560/01531dee-2fda-48f2-4e1d-ecce72cae43a.png)
vagrant upがコケる問題について

## はじめに

最新版では起こらないかもしれません。
昔の記憶を基に書いていますが、

* vagrant : 1.9.2 (古い。。。)
* VirtualBox : 5.1.22

で再現しました。
vagrantのVMをいじって新たなboxを作った後の話です。

## 問題の説明

box準備して、Vagrantfile編集して、いざvagrant up!!!

1. 固まる
2. Authentication failure retrying...
3. vagrant ssh出来ない

よくあると思います。
vagrantは、VirtualBoxとのバージョンの相性がデリケートな印象なので、
1. とかの場合はバージョンを下げたりすると治ったりします。
3. のエラーは個人的にはネットワーク設定をいじるとそこそこ治ります。
（よく [nm_controlledをyesに書き換えるスクリプトをVagrantfileに書いて、
NetworkManagerサービスで管理されるよう](https://qiita.com/shohe_zsm/items/61c15958996978fec06f) にする、という対応をしています。）

問題は2.です。
google大先生に聞くと、結構ヒットして、

* insecure key をgithubから持ってくる
* authorized_keysの設定をちゃんとする
* ~/ と ~/.ssh と ~/.ssh/authorized_keys のパーミッションをちゃんとする

なんかが出てきます。そして大体↑の対応で直るんですが、以前、上記対応を全て実施したのにも関わらず鍵認証がうまく出来ないことがありました。

## 回避策

vagrantのVMから新たにboxを作る際、

```
vagrant package
```
でpackage.boxを作り、boxをaddするかと思いますが、この時

```
vagrant package ID
```
として、**ID指定でboxを作ると、上記のような問題が起こります。**
（IDは vagrant global-status で表示されるID）

そこで、vmを立てたディレクトリで

```
vagrant package
```
のみとするか、

```
vagrant package VM名
```

とすることで回避出来ます。
（VM名は ~/VirtualBox VMs/ に有るもの）

原因は不明です。。。
at coder beginner 018

A
太郎君と次郎君と三郎君の 3 人の人が豆まきで対戦をした。得点が高いほうが上の順位である。それぞれの得点が与えられるので、それぞれの順位を答えよ。

```
#include <bits/stdc++.h>
using namespace std;
int main(){
    int a,b,c;
    cin >> a >> b >> c;
    int x=1,y=1,z=1;
    if(a>b) y++;
    else x++;
    if(a>c) z++;
    else x++;
    if(b>c) z++;
    else y++;
    cout << x << endl << y <<endl << z << endl;
}
```

```
include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int a[3];
	for (int i = 0; i < 3; ++i) {
		cin >> a[i];
	}
	for (int i = 0; i < 3; ++i) {
		if (a[i] == max({ a[0],a[1],a[2] })) {
			cout << 1 << endl;
		}
		else if (a[i] == min({ a[0],a[1],a[2] })) {
			cout << 3 << endl;
		}
		else {
			cout << 2 << endl;
		}
	}
	return 0;
}
```
B
半角の小文字アルファベットのみからなる文字列 S が与えられる。 文字列 S に対して以下の操作 1 から操作 N までを番号の昇順に行う。
操作 i : 左から li 番目の文字を左端、左から ri(1≦li<ri≦|S|) 番目の文字を右端とした部分文字列を逆順にする。
例えば，文字列 abcdef に対して、左から 3 番目の文字 c を左端、左から 5 番目の文字 e を右端とした部分文字列を逆順にすると、文字列 abedcf が得られる。
操作 1 から操作 N までを番号の昇順に行った後の文字列を出力せよ。

```
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main() {
	string S;
	int N;
	int l, r;
	cin >> S;
	cin >> N;
	for (int i = 0; i < N; ++i) {
		cin >> l >> r;
		reverse(S.begin()+l-1,S.begin()+r);

	}
	cout << S << endl;
	return 0;
}
```
ZephirでPHPExtensionを作ってみる

公式マニュアルを参考に。
https://github.com/phalcon/zephir/blob/master/WINDOWS.md
事前にVisual Studio 2015をインストールしている必要があります。

# PHP，PHP SDK，PHP Developer Pack，Zephirをインストールする
今回はx86バージョンを使用しています。
PHPディレクトリに`PHP SDK`，`PHP Developer Pack`，`Zephir`を配置する。

```
C:\php-7.2.10-Win32-VC15-x86
C:\php-7.2.10-Win32-VC15-x86\php-sdk
C:\php-7.2.10-Win32-VC15-x86\php-devel-pack
C:\php-7.2.10-Win32-VC15-x86\zephir
```

# Zephir ParserをPHPに組み込む
`php_zephir_parser.dll`を`ext`にコピーして
`zephir_parser`を`php.ini`に追加する。

```conf:php.ini
extension=zephir_parser
```

# コマンドプロンプトで環境変数を設定する

Winodwsの環境変数に登録しないようにしたいので、必要なパスをコマンドプロンプトから設定する。

```
# Visual Studio 2015 にパスを通す
set VS140COMNTOOLS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\"
call %VS140COMNTOOLS%\VsDevCmd

# PHP，SDK，Develop，Zephirにパスを通す
set PHP_HOME=C:\php-7.2.10-Win32-VC15-x86
set PATH=%PATH%;%PHP_HOME%
set PHP_SDK=%PHP_HOME%\php-sdk
set PHP_DEVPACK=%PHP_HOME%\php-devel-pack
set PATH=%PATH%;%PHP_HOME%\zephir\bin

# SDKの環境変数を設定する
%PHP_SDK%\bin\phpsdk_setvars
```

これをバッチファイルにまとめておくと便利。

# Zephirプロジェクトを作成してビルドする

`zephir init`でプロジェクトを作成する。

```
zephir init test
```
その配下のある`test`フォルダに`sample.zep`を作成する。

```php:sample.zep
namespace Test;
 
class Sample
{
    public static function say()
    {
        echo "hello world!";
    }
 }
```

`zephir build`でビルドする。

```
zephir build
```

プロジェクトの`ext\Release_TS`にDLLが作成されるので、`php.ini`に`extension`を追加する。

```conf:php.ini
extension="C:\php-7.2.10-Win32-VC15-x86\test\ext\Release_TS\php_test.dll"
```

あとは確認用のスクリプトから実行されるかを確認する。

```php:sample.php
<?php
Test\Sample::say();
```
`hello world!`が表示されたらok！

```
>php sample.php
hello world!
```
PowerShell で Ctrl+C で終了する時に任意の処理をしたい

# 結論

処理を Try で囲み、Finally に終了する時の処理を書くと出来た
以下に PowerShell だけでなく、様々なプログラミング言語などでのシグナルハンドルの例があった

[Handle a signal - Rosetta Code](https://rosettacode.org/wiki/Handle_a_signal#PowerShell)

# 環境

```powershell
PS C:\Windows\system32> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14393.2395
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.2395
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

```

# やってみた

以下を参考にファイルを作ってみた

[powerShellで無限ループと待機処理](http://harikofu.blog.fc2.com/blog-entry-77.html)

```powershell
try
{
  while(1){
    Write-Output ('hi')
  }
}
finally
{
  Write-Output ('exit')
}
```

しかしながら、これだとCTRL+Cで終了した時に「exit」が表示されない
ただし、以下だとうまくいく

[Handle a signal - Rosetta Code](https://rosettacode.org/wiki/Handle_a_signal#PowerShell)

```powershell
$Start_Time = (Get-date).second
Write-Host "Type CTRL-C to Terminate..."
$n = 1
Try
{
    While($true)
    {
        Write-Host $n
        $n ++
        Start-Sleep -m 500
    }
}
Finally
{
    $End_Time = (Get-date).second
    $Time_Diff = $End_Time - $Start_Time
    Write-Host "Total time in seconds"$Time_Diff
}
 
```

やってみる。

```powershell
PS C:\Users\Administrator> .\mugen.ps1
Type CTRL-C to Terminate...
1
2
3
Total time in seconds 2
```

うまくいった。

よく見ると`Write-Output`と`Write-Host`という点が違う。
試しに`Write-Output`に変えてみたら「Total time in seconds 2」が表示されなくなった。

[Write-HostとWrite-Outputの違い](https://blog.shibata.tech/entry/2016/01/11/151201)

`Write-Host`の方が直接的にはコンソール出力だから適切ということなのだろうか。
この辺りもし知見のある方など居ましたら教えて頂けますと幸いです。。。
Setting a timer for a long period of timeのコンソールのwarnを非表示にする。


```console
> react-native -v
react-native-cli: 2.0.1
react-native: 0.55.4
> exp -V
56.0.0
```

```console
Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
```

https://github.com/facebook/react-native/issues/12981
アプリ側の画面に表示されるYellowBoxは上記のURLにある方法で消えるみたいだが、
コンソール側では消えないようす。
しかも、定期的に流れてくるから邪魔。

```react
  constructor(props) {
    super(props)
    
    global.__old_console_warn = global.__old_console_warn || console.warn;
    global.console.warn = (...args) => {
      let tst = (args[0] || '') + '';
      if (tst.startsWith('Setting a timer')) {
        return;
      }
      return global.__old_console_warn.apply(console, args);
    };
  }
```

App.jsなどに記入し、無理やり非表示にする。

*Expo.jsが同じことをisMounted()でやっていたのでパクってきた。*
Kubernetesの用語あれこれ

前の記事（[（僕にとって）はじめてのKubernetes](https://qiita.com/mochimoching/items/bf1eefff761f9c110457)）で雑な紹介しかしてなかったので少しだけ詳しく書く（足りてるとは思ってない）。

## Kubernetes

* コンテナ管理ツール（オーケストレーションツール）
* Kubernetesはmasterサーバとnodeサーバ（n台）のクラスタで構成されている

## Container

* コンテナ。Dockerコンテナと同じ（と考えて支障ないよね？）
* アプリケーションはコンテナにデプロイする

## Pod

* 1つ以上のコンテナを含む入れ物
* Pod単位でデプロイ、起動、停止、削除をする
* PodにはIPアドレスが振られていて、Pod同士はKubernetes上の仮想NWでつながっている

## Service

* 複数Podを束ねたもの。サービスディスカバリやロードバランシングを提供する
* MSA文脈におけるマイクロサービスがこれ
  - ちょっと良く分かってない：DBは別Servceにする？
     - Persistent Volumeで永続化？
* Pod群の論理的な管理単位であり、Serviceというものがどこかで動いているわけではない
* Service呼び出し側からみれば、Servce内のPodが物理的にどこにあるかとか知らなくて良い
* Service作成時に「Cluster IP」と呼ばれる仮想IPが割り振られ、サービス間通信ではこのIPでアクセスする
* ServiceとPodの紐付けは、Podについているラベルを指定する

## apiserver

* Kubernetesのリソースを管理し、もろもろの操作をする

## kubelet

* 各nodeサーバで動作し、Podの操作（作成・削除など）を行う

## kube-proxy

* 各nodeサーバで動作し、ロードバランシング時の各Podへの転送処理を担う

## ネットワーク

* （もやもや）Kubernetesクラスタ内部の仮想NWには二種類ある？
  - サービス間通信用のネットワーク
     - Cluster IPの振られたServiceが属するNW
     - Service間通信はこっちを使う？
  - コンテナ間通信用のネットワーク
     - flannnel


## Podの作成

* 設定ファイルを書く(yaml)
* kubectl createコマンドでapiserverに登録する

## Serviceの作成

* Podは作成済
* 設定ファイルを書く(yaml)
* kubectl createコマンドでapiserverに登録する
  - kube-dnsにService名が登録される
     - kube-dnsはmasterサーバで稼動するPod
     - Service名で名前解決すると簡単なサービスディスカバリを実現できるらしい

## 参考URL

* [メモ：Google製DockerクラスタツールKubernetes](https://qiita.com/shouta-dev/items/ad876e6bd256d5d58ebb)
  - 少し古いけど基本はおさえられる
* [Kubernetes: 構成コンポーネント一覧](https://qiita.com/tkusumi/items/c2a92cd52bfdb9edd613)
* [Kubernetes "サービス"の概要についての自習ノート](https://qiita.com/MahoTakara/items/d18d8f9b36416353066c)
* [Kubernetesの主な機能一覧 (v1.5時点)](https://qiita.com/tkusumi/items/e37fca3084050ccc74d1)
* [kubernetesによるDockerコンテナ管理入門](https://knowledge.sakura.ad.jp/3681/)
* [Kubernetes連載記事（サイバーエージェント青山さん）](https://thinkit.co.jp/author/13290)
* [Kubernetes Advent Calendar 2016](https://qiita.com/advent-calendar/2016/kubernetes)
* [lestrrat 氏に Kubernetes を教えてもらいました](http://blog.cybozu.io/entry/2017/03/17/080000)
Windowsでgulp + babel + webpack 環境作ってみた


# Windowsでgulp + babel + webpack 環境作ってみた

今までmacを使ってたのですが、この度Windowsを使うことになったのでまとめてみます。
なんかWindowsと関係ないところではまったりもしたのですが・・・；

## まずは node.js のインストールから

何も考えずに公式ページからインストーラーを落としてきてインストールすることもできますが、今後のことを考えるならnode.js用のパッケージ管理ソフトを入れて管理ソフトからバージョン指定してインストールしたほうがよさそうです。
https://qiita.com/satoyan419/items/56e0b5f35912b9374305

ということで上記ページを参考に、nodistを入れて現在の推奨バージョン8.12.0を入れてみました。
あとは対象プロジェクトのフォルダでコマンドラインから`npm init`して初期化完了。

*※Gitを使ってプロジェクト管理をするなら、.gitignoreには /node_module/を入れるべき。*


## gulpとbabelとwebpackをインストールする

ここは参考サイトの通りにまずやってみる
https://glatchdesign.com/blog/web/tools/1724


## 問題点１：警告が表示している

npm install 終了後、３つほど警告が出ていました。そのうちの一つがこちら

### オプション設定足りないエラー
```
 Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with.
```
どうやら、nodistを使ったことで表示する警告の様子。npm で指定されたオプションをオンにするようにという警告だったので、以下ページを参考にオプションを変更。
https://qiita.com/isamusuzuki/items/738a2736a746b67bd977

残り２つの警告はこちら

### サポートしてないプラットフォームエラー
```
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\ch
okidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@
1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}
)
```
この２つの警告は関係してそうなので検索して以下ページを発見。
https://stackoverflow.com/questions/46929196/how-to-solve-npm-install-throwing-fsevents-warning-on-non-mac-os
単純に、Windowsに対応してない機能が入らなかったという警告っぽいのでこっちは無視しました。


## 問題点２：gulpがコマンドとして認識されない

コマンドプロンプトを管理者として実行し、 `npm i -g gulp` でグローバルインストールするとうまくいきました。
https://skyblue-js.com/post-56/


## 問題点３：webpack.optimize.UglifyJsPlugin has been removed

webpack3から4に移行したタイミングで、webpack.optimize.UglifyJsPluginは廃止になって、モード変更するだけで有効化するようになったとのこと。
https://qiita.com/shisama/items/730e7a2e6a3090a63a38#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%93%E3%83%AB%E3%83%89
UglifyJsPluginを削除して、とりあえずmode: developmentにしました。（このモードだとUglifyは有効化しないけど、これから開発なので）


## 問題点４：Cannot find module '@babel/core' babel/core

問題点１のときの警告で、見逃していたけど最後にこの警告がありました。

```
npm WARN babel-loader@8.0.2 requires a peer of @babel/core@^7.0.0 but none was installed.
```
babel/core入れたはずなのに・・・と思ってpackage.json確認したところ、必要バージョンより低いbabel/coreが入ってた様子。
じゃあ、と思ってバージョン指定を^7.0.0に指定したらエラー。
babel公式ページを見たら最新バージョンは7.1.0。何かおかしいと思っていろいろ調べてみたところ、npm installするときのパッケージ名指定が参考サイトだと低いバージョン用のパッケージ名だった様子。
https://github.com/babel/babel-loader
このページにある以下のインストールコマンドを指定したところ、問題なくエラーが消えました。

```
npm install -D babel-loader @babel/core @babel/preset-env webpack
```


**やっと・・・
gulpが通った・・・！**

あとは、 /src/js/以下のjsファイルが変更かかれば自動ビルドしてbundle.jsにまとめてくれる安心環境。
有効期限が無期限のFacebookページアクセストークンの取得方法

有効期限が無期限のFacebookページアクセストークンの取得手順が分かりづらかったのでまとめておきます。

今後のバージョンアップや仕様変更により、取得方法が変わることもあるのでご了承ください。

# 使用ツール（サイト）
- [Facebook for developers](https://developers.facebook.com/apps/)
- [Graph API Explorer](https://developers.facebook.com/tools/explorer/)
- [Access Token Debugger](https://developers.facebook.com/tools/debug/accesstoken/)

# 手順
1.Graph API ExplorerでUser Access Tokenを取得する
2.長い期限のUser Access Tokenを取得する
3.長い期限のUser Access Tokenを元に無期限のPage Access Tokenを取得する

## 1.Graph API ExplorerでUser Access Tokenを取得する
[Graph API Explorer](https://developers.facebook.com/tools/explorer/)を開き、対象ページを選択して「ユーザーアクセストークンを取得」をクリック
![_スクリーンショット_2018-06-08_15_13_29.jpg](https://qiita-image-store.s3.amazonaws.com/0/6380/a3d8bcbb-b956-0e96-114c-24221c62bd29.jpeg)
必要なアクセス権限にチェックを付け「アクセストークンを取得」をクリック
![スクリーンショット 2018-06-08 15.14.34.png](https://qiita-image-store.s3.amazonaws.com/0/6380/b7558160-99b2-5d79-5f80-6d4e0c810a0e.png)
有効期限の短いUser Access Tokenが生成される。

## 2.長い期限のUser Access Tokenを取得する
[Graph API Explorer](https://developers.facebook.com/tools/explorer/)で`oauth/access_token`に以下パラメータを渡して「送信」。

```
oauth/access_token
	?client_id={app_id}
	&client_secret={app_secret}
	&grant_type=fb_exchange_token
	&fb_exchange_token={access_token}
```


- {app_id}：アプリID。[Facebook for developers](https://developers.facebook.com/apps/)の対象アプリ設定画面から取得
- {app_secret}：[Facebookアプリのapp secretの確認方法 - Qiita](https://qiita.com/unsoluble_sugar/items/70496f1dcc089e67f01a)
- {access_token}：1.で取得した有効期限の短いUser Access Token

JSONレスポンスの「access_token」に有効期限の長いUser Access Tokenが入ってくる。

## 3.長い期限のUser Access Tokenを元に無期限のPage Access Tokenを取得する
2.で取得した有効期限の長いUser Access TokenをGraph API Explorerの「アクセストークン」欄に入力。
URLに`me/accounts/`と入力し「送信」。

JSONレスポンスの「access_token」に有効期限が無期限のPage Access Tokenが入ってくる。
### 有効期限を確認する
Access Token Debuggerを使って、取得したPage Access Tokenが無期限になっているか確認する。
[Facebook APIのアクセストークンのタイプや有効期限を確認する方法 - Qiita](https://qiita.com/unsoluble_sugar/items/8c2a4003878098959724)

有効期限が「受け取らない」となっていれば、無期限のFacebookページアクセストークンの完成です。
C++ - How to use std::map?

https://stackoverflow.com/questions/15451287/what-does-iterator-second-mean
http://mropengate.blogspot.com/2015/12/cc-map-stl.html
https://blog.csdn.net/suool/article/details/16806713
https://zh.cppreference.com/w/cpp/container/map
https://www.jianshu.com/p/5ec8bf995a64
PythonでCSVファイルをS3 SELECTする

# 概要
- AWSのS3バケットに保存したCSVファイルをクエリします
- 実際に使う場面の方法を少し確認した感じです
- リンク
    - [S3 Selectの概要](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/selecting-content-from-objects.html)
    - [APIリファレンス](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/RESTObjectSELECTContent.html)
    - [SDK(boto3)のselect_object_contentメソッド](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.select_object_content)

# サンプルデータを準備

- なんでもいいんですが、ちょっとした大きさのテストファイルを作成します

```python3:make_testfile.py
import hashlib

with open('testfile.csv', 'w') as f:
    for i in range(10000):
        f.write('{},{}\n'.format(i, hashlib.sha512(str(i).encode()).hexdigest()))
```

- 連番＋適当なハッシュ文字列の2カラム、1万行のファイルができます
- ファイルサイズは1.3MB程度です

```csv:testfile.csv
0,31bca02094eb78126a517b206a88c73cfa9ec6f704c7030d18212cace820f025f00bf0ea68dbf3f3a5436ca63b53bf7bf80ad8d5de7d8359d0b7fed9dbc3ab99
1,4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a
2,40b244112641dd78dd4f93b6c9190dd46e0099194d5a44257b7efad6ef9ff4683da1eda0244448cb343aa688f5d3efd7314dafe580ac0bcbf115aeca9e8dc114
（省略）
```

- S3バケットへアップロードします
- マネジメントコンソールからでもOKです

```bash
$ aws s3 cp testfile.csv s3://my-s3select/
upload: ./testfile.csv to s3://my-s3select/testfile.csv
```

# SELECTするコード

- 返される結果は65000バイトに分割されるようです
- 結果の意味にかかわらずブツ切りにされるので、一旦全体を受け取って結合して使用する必要がありそうです
- ここではローカルファイルとして出力します
    - 実際は[tempfile](https://docs.python.jp/3/library/tempfile.html)を使う感じかなと思います
    - 巨大にならない場面ならメモリ上で処理するかも

```python:s3select.py
import boto3

s3 = boto3.client('s3')
response = s3.select_object_content(
    Bucket='my-s3select',
    Key='testfile.csv',
    ExpressionType='SQL',
    RequestProgress={'Enabled': True},
    Expression="SELECT * FROM S3Object",
    InputSerialization={'CSV': {}},
    OutputSerialization={'CSV': {}},
)

end_event_received = False
with open('output.csv', 'wb') as f:
    for event in response['Payload']:
        if 'Records' in event:
            f.write(event['Records']['Payload'])
        elif 'End' in event:
            end_event_received = True
if not end_event_received:
    raise Exception('処理が不完全です')

# あとはoutput.csvを開き直して処理する
```
独自 (カスタム) AMI 作成手順

## 参考文献

- [Creating an Amazon EBS-Backed Linux AMI - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html)
- [11.2. Sealing Virtual Machines in Preparation for Deployment as Templates](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Virtualization/3.5/html/Administration_Guide/sect-Sealing_Virtual_Machines_in_Preparation_for_Deployment_as_Templates.html)
- [Chapter 7. Templates - Red Hat Customer Portal](https://access.redhat.com/documentation/en-us/red_hat_virtualization/4.0/html/virtual_machine_management_guide/chap-templates)
- [Deregistering Your Linux AMI - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/deregister-ami.html)

## 今回のユーザーデータ

```bash
#!/bin/bash
echo -e "Defaults:centos\t\!requiretty" | sed -e 's/\\//' > /etc/sudoers.d/ansible
```

## 作成手順

1. 基にするインスタンスを作成する。
   - 今回は以下の通りとする。
      - AMI: **CentOS 7 (x86_64) - with Updates HVM (1805_01)**
      - インスタンスタイプ: **t2.micro**
      - インスタンス詳細設定: **(前述のユーザーデータ)**
      - ストレージ: **合わせて削除** にチェックを **入れる。**
      - タグ: (今回は無し。)
      - セキュリティグループ: (今回は内部のみアクセス可能とする。)
1. インスタンスに SSH 接続し, 以下のコマンドでシーリングする。

    ```
    $ sudo rm -rf /etc/ssh/ssh_host_*
    $ sudo hostnamectl set-hostname localhost.localdomain
    $ sudo rm -rf /etc/udev/rules.d/70-*
    $ sudo sed -i -e '/HWADDR/d' -e '/UUID/d' /etc/sysconfig/network-scripts/ifcfg-eth0
    $ sudo cp -fv /dev/null /etc/machine-id
    $ sudo find /var/log -type f | sudo xargs rm -v
    $ HISTFILESIZE=0
    $ HISTSIZE=0
    $ sudo systemctl poweroff
    ```

1. **ELASTIC BLOCK STORE - ボリューム** を開く。
1. 対象のボリュームを選択し, **アクション - スナップショットの作成** をクリックする。
   - 内容は適宜入力する。
1. **ELASTIC BLOCK STORE - スナップショット** を開き, スナップショットが作成されるまで待機する。
1. **アクション - イメージの作成** をクリックする。
   - 仮想化タイプは **ハードウェアアシストの仮想化** を選択する。
   - それ以外は適宜入力する。
1. しばらく待機してから, **イメージ - AMI** を開き, AMI が作成されていることを確認する。
1. 最初に作成したインスタンスを削除する。

## 削除手順

1. **イメージ - AMI** を開く。
1. **アクション - 登録解除** をクリックする。
   - バックエンドで解除処理が進む。しばらくすると画面から消える。
1. **ELASTIC BLOCK STORE - スナップショット** を開く。
1. **アクション - 削除** をクリックする。

どっとはらい。
PostgreSQL で偏差値を計算する

PostgreSQL のユーザ定義集約関数の練習に、集約後のグループごとに偏差値計算してみた。

* サンプルサイズが１しかない場合は分散が０で偏差値出せないのでNULLにしといた。
* 一様分布の場合は分散が０で偏差値出せないけど、こっちは50にしといた。
* `variance` で返ってくるのは不偏分散みたいなので、 `stddev` も不偏標準偏差になってるので検算するときとかは注意。  
https://www.postgresql.jp/document/9.6/html/functions-aggregate.html


## サンプルデータ１００件

### 要件

`id_N` で group by してグループごとに偏差値を算出してみる。

```sample.tsv
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_5	1
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_3	14
id_3	1
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_1	3
id_7	2
id_2	3
id_2	1
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
id_6	3
id_6	2
id_6	4
id_7	2
id_6	7
id_6	3
id_6	2
id_6	4
id_4	3
id_6	7
id_6	3
id_6	2
id_6	4
id_6	7
```

## 投入

```sql
create table sample(
	id varchar,
	val integer
);

\copy sample from /tmp/sample.tsv (DELIMITER E'\t', FORMAT CSV, HEADER true);
```

## 実行

```sql
create or replace function _sigma (numeric[]) returns numeric
    language sql as $$
select stddev(v) from (select unnest($1) v) a;
$$;

create aggregate sigma(numeric)
(
  sfunc     = array_append
 , stype     = numeric[]
 , finalfunc = _sigma
);

create or replace function _mean (numeric[]) returns numeric
    language sql as $$
select avg(v) from (select unnest($1) v) a;
$$;

create aggregate mean(numeric)
(
  sfunc     = array_append
 , stype     = numeric[]
 , finalfunc = _mean
);


with d as (
select
  id,
  count(*) size,
  sigma(val) sigma,
  mean(val) mean
from sample
group by id
)

select
  *
  , CASE sigma
    WHEN 0 THEN 50
    ELSE 50 + 10 * (val - mean) / sigma
  END as 偏差値
from sample as a
join d
  on a.id = d.id
order by a.id
;
```

## 参考

https://www.postgresql.jp/document/9.6/html/sql-createaggregate.html
http://d.hatena.ne.jp/EulerDijkstra/20130508/1368003441
Githubで[Error: Key already in use]と表示された場合の複数リポジトリのSSH鍵の使い分け方

# 前提

検索してもなかなかまとまった情報が出てこなかったため、自分用のメモです。

リポジトリAは設定済み。リポジトリBを作成したがリポジトリAで登録済みの重複した鍵は `Error: Key already in use` と表示されるのでここからどうやって鍵を設定したかを書きます。

## 目次

1. 鍵を作る
2. Githubに鍵を登録する
3. `~/.ssh/config` ファイルに設定を書く
4. ローカルにあるcloneしたディレクトリに行き、remoteのurlを書き換える

## 手順

### 鍵を作る
- `ssh-keygen -t rsa` コマンドでリポジトリB用の鍵を作成。 ファイル名を聞かれるので任意のファイル名を入力する。(今回はtest) 

```zsh
❯ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ユーザー名/.ssh/id_rsa): /Users/ユーザー名/.ssh/test
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/ユーザー名/.ssh/test.
Your public key has been saved in /Users/ユーザー名/.ssh/test.pub.
```

### Githubに鍵を登録する
- GitHubで作成した鍵を登録する。任意のリポジトリのページの `Settings→Deploy keys` の `Add deploy key` を押下する。
<img width="819" alt="スクリーンショット 2018-09-18 14.59.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/264910/d2d77bab-9d60-bc48-9072-facaae307adc.png">

- `title` にわかりやすいように鍵のファイル名と同じ名前を入力。その後 `Key` に `test.pub` の中身を全てコピペし `Add key` を押下。
<img width="838" alt="スクリーンショット 2018-09-18 15.02.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/264910/1d9b7caf-a80f-9ff0-3273-5f50c0d304c5.png">


### `~/.ssh/config` ファイルに設定を書く
- `sudo vi ~/.ssh/config` でssh configファイルを編集。(なければ作成)

```config
Host github-任意の名前
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/test(ssh-keygenで作った鍵のファイル名)
  TCPKeepAlive yes
  IdentitiesOnly yes
```
こんな感じで記述して保存。

### ローカルにあるcloneしたディレクトリに行き、remoteのurlを書き換える
- `git remote -v` すると多分 `git@github.com` と付いてると思うので、ssh configファイルに記述した宛先に書き換える。

```zsh
❯ git remote -v
origin	git@github.com:ユーザー名/リポジトリ名.git (fetch)
origin	git@github.com:ユーザー名/リポジトリ名.git (push)

❯ git remote set-url origin git@github-任意の名前:ユーザー名/リポジトリ名.git
↓(例)
❯ git remote set-url origin git@github-flower:SugarShooting
Star/FlowerPhotoScore.git
```

### 終了

- 適当にファイルを編集してaddして、commitしてみて `git push` できればOK。
- pushがrejectされた場合、`git fetch` して `git merge` した内容をコミットしてから `git push` すれば解決できる。
Spring mvn installコマンドエラー

#開発環境
- Windows10 64bit
- Java8
- Spring5
- Maven 3.5.4
- コマンドプロンプト

[STS編のエラー](https://qiita.com/iGlobo/items/f7d47c87bf9333ae111a)

#mvn installエラー
あるSpring Framework5参考書の手順通りするとSpringプロジェクト内でmvn installコマンドを打つと以下のエラーが発生した。
原因はJDKのパスを通さなかったこと。

```cmd:mvn_install
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.804 s
[INFO] Finished at: 2018-09-18Txx:xx:xx+09:00
[INFO] ------------------------------------------------------------------------
```

JDKのインストール時にパス通す選択肢があったはず。
インストール後にパスが通っていることを確認するコマンドを打った。

```cmd:java_version
>java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
```

正常にJavaのバージョンが表示されたので、JDKインストール後にパスが通ったと勘違いしていた。

mvn installのエラー内容は「この環境ではコンパイラは提供されません(No compiler is provided in this environment)」と書かれていたのでパスを通すことにした。

JAVA_HOMEを作る。
![JAVA_HOME.png](https://qiita-image-store.s3.amazonaws.com/0/289168/f30b0292-2829-dd88-39a6-dfd15984bd09.png)
pathの内容を変更する。
binまでパスを通す。
![JAVA_HOME_PATH.png](https://qiita-image-store.s3.amazonaws.com/0/289168/ba3a0651-e85f-9b72-0738-217eed6fb505.png)


JDKのパスを通したら、正常にmvn installが完了できた。

```cmd:mvn_install
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.464 s
[INFO] Finished at: 2018-09-18Txx:xx:xx+09:00
[INFO] ------------------------------------------------------------------------
```

以上、「いいね」ボタンをよろしくお願いします。
Go言語を真剣に勉強してみた〜基本構文編①（変数、定数、条件分岐、繰り返し処理）〜

#はじめに
こんにちは。某学校でプログラミング等の勉強中のサーバーサイドのプログラマーのワタタクです。:relaxed:
さて今回は「Go言語を真剣に勉強してみた〜基本構文編〜」と」言うことなのですが、記事が長ったらしくなる為何回かに分けて出来たらなと思います。
では、早速いってみましょう:point_up:
#変数
変数は以下のとうりで宣言します。
**＊ちなみにGo言語ではセミコロン(;)はいりません！！**

```
var 変数名　データ型
```
またこのような書き方もあります。

```
var 変数名　= 初期値
```
さらにこのような書き方もできます。

```
変数名　:= 初期値
```
3番目の記述方法が多く使われていて、参考書とかもこの書き方が多い。

```golang:variable.go
var a int
a = 10

var b = 20
b := 20 //上のvar b = 20と意味は同じ。
```
#定数
定数は以下のように記述します。

```
const 定数名　= 初期値
```
定数も変数と同じく肩指定できるが、通常は型を指定しません。
####定数の連番定義
定数ジェネレータの iota を使用すると、連番からなる定数を簡単に定義することができます。

```golang:const.go
const (
	_      = iota //=> 0
	FAST          //=> 1
	NORMAL        //=> 2
	SLOW          //=> 3
)
```
#条件分岐
１）if文

```
if 条件式 {
    //処理
} else if 条件式 {
    //処理
} else {
    //処理
}
```

```golang:if.go
a := 22

if a > 20 {
    fmt.Println("成人")
} else {
   fmt.Println("子供")
}
```
このように他の言語と同じくelse ifがなかったりelseがない場合は書かなくていい。

2）switch文

```
switch 条件の値 {
    case 値１:
         //処理
    case 値２:
         //処理
    case 値３:
         //処理
        ・
        ・
        ・
　　　　　　　　default:
　　　　　　　　　　　　　　　　　　//処理
}
```
また以下の例みたいにcaseの値を式にも出来ます。その場合、条件の値のところには何も記述しません。

**＊CやJavaなどのswitch文は，1つのcaseが実行されるとその次のcaseに処理が移るため，単一のcaseの実行で終わらせたい場合に，caseごとにbreakを書く必要がありました。しかしGoのswitch文では，caseが1つ実行されると次のcaseに実行が移ることなくswitch文が終了するため，breakをいちいち書く必要はありません。**

ただ，caseの処理が終わったあとに，次のcaseに処理を進めたい場合もあります。そうした場合はcase内にfallthroughを書くことで，明示的に次のcaseに処理を進めることができます。

```golang:switch.go
    n := 10

    switch {
        case n % 15 == 0:
          fmt.Println("FizzBuzz")
        case n % 5 == 0:
          fmt.Println("Buzz")
        case n % 3 == 0:
          fmt.Println("Fizz")
        default:
          fmt.Println(n)
    }
```
#ループ処理
**＊Goでのループはwhile文がなくfor文のみ。**

```
for 初期値; 条件式; 初期値をどうする？ {
    //処理
}
```
```golang:for.go
   for i := 1; i < 10; i++ {
        if i % 2 == 0 {
             continue
        }
        fmt.Println(i)//1,3,5,7,9
   }
```
他の言語と同じく**break文**や**continue文**も使える。
####無限ループ
無限ループを作る場合は以下の通り

```
for ;; {}
```
条件を適切に扱う必要がある。
以下例

```golang:for.go
   for value := 0;; {
       value++
       fmt.Println(value)//1,2,3,4,5,6
       if value % 6 == 0 {
           break
       }
    }
}
```
以上。
もし何か間違っている等のご指摘があればご連絡ください。
最後まで読んで頂きありがとうございました。
次回は「Go言語を真剣に勉強してみた〜基本構文編②（配列）〜」です。

よろしければ、[Go言語を真剣に勉強してみた〜環境構築編〜](https://qiita.com/watataku/items/c2b25ace1aeaaf0b75c0)もご覧ください。