OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon WorkSpaces と Amazon WorkDocs のバックアップやリビジョンについて調べてみる

# ０．はじめに

業務で、Amazon WorkSpaces と Amazon WorkDocs を使い始めたので、それぞれバックアップとか、ファイルのリビジョン管理とか、どうなっているのか調べてみました。

# １．Amazon WorkSpaces

以下のサイトに記載がありました。

* [よくある質問 \- Amazon WorkSpaces \| AWS](https://aws.amazon.com/jp/workspaces/faqs/)

> Q: ユーザーのデータはどのようにバックアップされますか?
> 
> WorkSpace のユーザーボリューム（D:）が 12 時間おきにバックアップされます。WorkSpace に障害が発生した場合、AWS はバックアップからそのボリュームを復旧します。Amazon WorkDocs Sync が WorkSpace で有効になっている場合、ユーザーが同期を選択したフォルダは継続的にバックアップされ、Amazon WorkDocs に保存されます。

<br>
どうやら、

D ドラを12時間おきに自動でバックアップするけど、何かトラブルが起こったら、最大過去12時間分のデータが消えちゃう可能性があるので、Amazon WorkDocs Sync を有効にして同期する様にしてね。

と、いうことみたいです。

<br>
EC2 での AMI と同じ様な位置付けで、カスタムイメージというものもありますが、自動バックアップの機能があるので、こちらはあくまでキッティング時の元イメージとして使うのが良いみたいです。こちらは、逆に C ドラのデータは保存されますが、D ドラのデータは保存されないみたいです。デフォルトの作成上限も５個となっています。

* [Amazon WorkSpaces Limits \- Amazon WorkSpaces](http://docs.aws.amazon.com/ja_jp/workspaces/latest/adminguide/workspaces-limits.html)

<br>
以下、
参考になるサイトです。

* [Amazon WorkSpacesの自動バックアップについて調べてみました ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/workspaces-automatic-backup/)
* [Amazon WorkSpacesの利用上の注意点 \| HIGHWAY for AWS](http://www.h4a.jp/detail/32198)
* [AWSでWindowsが使いたい人へ　EC2とWorkSpacesの違いをまとめました ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/ec2-vs-workspaces-2/)

# ２．Amazon WorkDocs

で、
同期に利用する Amazon WorkDocs はどうなっているの？

<br>
と思い、
ネットで情報を探すもなかなか見当たらず…、問い合わせをしたところ、以下の様な回答を頂きました。

> Amazon WorkDocsは、マネージドサービスとしてWorkDocs上の保存されたデータをリージョン内で冗長性を持たせて管理しており、Amazon S3サービスへのバックアップが必要ないように設計されております。

とのこと。


以下のサイトにも同様の内容の記載がありました。

* [よくある質問 \- Amazon WorkDocs \| AWS](https://aws.amazon.com/jp/workdocs/faqs/#security)

> Q: Amazon WorkDocs はファイルをどこに保存しますか? また、ファイルは安全ですか?
> 
> Amazon WorkDocs は、完全マネージド型のサービスです。ファイルは、ミッションクリティカルなデータが失われないように設計された AWS の高耐久性ストレージインフラストラクチャを使用して保存されます。Amazon WorkDocs に保存されているすべてのファイルとコメントは暗号化されています。

<br>
で、リビジョン管理はというと、
以下のサイトを教えて頂きました。

* [ファイルのバージョン \- Amazon WorkDocs](http://docs.aws.amazon.com/ja_jp/workdocs/latest/userguide/client_file_versions.html)
* [AWS Black Belt Techシリーズ Amazon WorkDocs / Amazon WorkMail](https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-workdocs-amazon-workmail#21)

<br>
とういうことで、
しっかりリビジョン管理もしてくれるみたいです。

<br>
以下、
参考になるサイトです。

* [Amazon WorkDocsの基本をまとめてみた ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/workdocs-group/)


# ９９．ポイント

* Amazon WorkSpaces には自動バックアップの機能があるので、こちら側で何か設定する必要は無い。
<br><br>
* ただ、バックアップの間隔が12時間なので、リビジョン管理もできる Amazon WorkDocs へ同期する様に Amazon WorkDocs Sync を有効にしておく。
<br><br>
* あと、バックアップ対象は D ドラで、C ドラは含まれないので、C ドラにデータ(ファイル)は保存しない。
<br><br>
* キッティング用には、カスタムイメージを利用する。

# ＸＸ．まとめ
ということで、
簡単ですが、まとめてみました。

Amazon WorkSpaces と Amazon WorkDocs をうまく利用して、開発や検証の環境をすぐに用意できる様になって、嬉しい限りですね。

AWS さん、
ありがとう♪
初期状態のRaspberryPi の ネットワークを Mac でセットアップする


### 1. Mac と RaspberryPI を有線接続する
### 2. arp -a コマンドでRaspberryPI を探す

```bash
$ arp -a
raspberrypi.local (169.254.48.22) at (incomplete) on en0 [ethernet]
...
```

### 3. SSHで接続
```bash
ssh pi@169.254.48.22 password: raspberry
```

### 4. Wifiセットアップ
```bash
# SSIDスキャン
sudo iwlist wlan0 scan

          Cell 02 - Address: AC:**:**:**:**:CC
                    Channel:11
                    Frequency:2.462 GHz (Channel 11)
                    Quality=64/70  Signal level=-46 dBm  
                    Encryption key:on
                    ESSID:"見つかったSSID"
                    Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 18 Mb/s
                              24 Mb/s; 36 Mb/s; 54 Mb/s
                    Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 48 Mb/s
                    Mode:Master
                    Extra:tsf=0000000000000000
                    Extra: Last beacon: 50ms ago
                    IE: Unknown: 0006526967687473
                    ...

```

### 5. WLAN接続設定
```/etc/wpa_supplicant/wpa_supplicant.conf

network={
    ssid="上で調べたSSID"
    psk="WiFiのパスワード"
}
```

### 7. NIC再起動

```bash
sudo ifdown wlan0
sudo ifup wlan0
```
C++のプログラムについてです


1〜9までの数値を入力して入力した値の倍数と入力した値がついている値（1〜99まで）を表示して総和を求めるプログラム

int 総和 = 0;
for ( int i = 1; i < 100; ++i ) {
  if ( 入力値がiで割り切れる || iの一の位が入力値と一致する || iの十の位が入力値と一致する ) {
    i を出力する
    i を総和に加える
  }
}
総和を出力する

自分で考えてみましたがこれをプログラムにして欲しいです。お願いします🙇
AmazonLinuxにffmpegをインストールする

AWS-EC2のAmazonLinuxにffmpegをインストールしようと思い、つまずいたところがあったので書き残し。

## 基本的な手順
基本的には公式のCentOS向けの手順を使う。
https://trac.ffmpeg.org/wiki/CompilationGuide/Centos

## つまずいたところ
libx264のインストール途中、./configureでmakefileを作成する時に「nasmのバージョンが低いよ」という旨のエラーが出た。

```
Found no assembler
Minimum version is nasm-2.13
If you really want to compile without asm, configure with --disable-asm.
```
`nasm -v`してみると、`NASM version 2.10.07`みたいな感じで、たしかにバージョンが足りてない。
公式向け手順の最初でnasmのrepoを追加した後に`yum install`しているので、なんでバージョン低いやつが入ってるんだ？となった。

## 解決
結論としては、`yum install`の時にnasmのrepoが参照されておらず、Amazonのrepo(nasmのバージョンが古い)を参照してインストールが走っていたので、最新バージョンが入っていなかった。

調べてみると、AmazonLinuxは初期設定でAmazonのrepoを優先的に参照する設定になっているらしい。
(参照:http://dev.classmethod.jp/server-side/os/amazonlinux-yum-priority/)

解決方法もこの記事に書いてある通りで、`/etc/yum.repos.d/amzn-main.repo`を編集して、AmazonのrepoのPriorityを99(デフォルト)にしてあげる。
これでnasmのrepoとAmazonのrepoの優先度が同じになるので、あとは普通に`yum install nasm`でOK。
Kotlinでbackキー(戻るボタン)のイベントを取る

備忘メモ📝

## Use `setOnKeyListener`

```kotlin
view.setOnKeyListener { v, keyCode, event ->
    if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
        // as you like :)
        dismiss()
        true
    } else {
        false
    }
}
view.isFocusableInTouchMode = true
view.requestFocus()
```

途中まで`view.requestFocus()`を書き忘れていて動かなかったので、お忘れなく。👾

## Use `apply`
Kotlinのスコープ関数`apply`を使うと、よりスッキリ書くことができます。（red_fat_daruma 氏、アドバイスありがとうございます🙇）

```kotlin
view.setOnKeyListener { v, keyCode, event ->
    (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN).apply {
        // as you like :)
        dismiss()
    }
}
view.isFocusableInTouchMode = true
view.requestFocus()
```

## Reference
- Android FragmentでBack key(戻るボタン)のeventをハンドリングする  
http://android.tecc0.com/?p=201
- Android : WebView 覚え書き（ズーム関連の機能の有効化、Progress の表示、Back Key のハンドリングなど）  
http://increment.hatenablog.com/entry/2015/11/03/205049
UiPathでRPAを実践してみる(5) ～セレクタについて～

前回、書いた内容で`Selector`について述べました。
これはUiPathが各要素を認識するための記述で、私の理解ではUiPathにとっての**目**としての機能を果たしていると考えています。
ここを理解する事で、UiPathをきちんと使いこなせるようになります。
早速確認をしていきましょう。
##まずは、問題が発生するケースを見てみましょう。
例えば、下記の様なテーブルがあり、総合計の値(この場合は300)を取得したいとします。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/f17e850d-e332-d67f-32bf-b0de19887f5b.png)

[前回の記事](http://qiita.com/motuo/items/ae5f6b6b47530492b97e)の「テキスト情報の取得」を参考にして、Recordingの機能によりデータを取得する事にしました。
生成される処理は下記の通りです。(最後に取得した値を確認するために、`Message Box`を追加しています。)
![キャプチャ(1).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/512495e7-461a-0429-8292-58535f267e32.png)

実行すると、下記のメッセージボックスが表示されます。無事に、「300」という数字が取れました。
![キャプチャ(2).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/655a1dc4-cd86-1300-9e56-47d711cd13e9.png)

次に、同じテーブルでレコードが1件、追加されたとします。
![キャプチャ(3).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/2d40cdf7-42af-2e94-8723-12afb2d6387f.png)
この状態で、上記で作成した処理を流すと、下記のメッセージボックスが出力されます。
![キャプチャ(4).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/e2ff18e6-0105-b962-29e1-dae048ab1501.png)

残念ながら、「**250**」という数字が抽出されてしまいました。本当は総合計が欲しいのにうまくいきません…

##何故、上手くいかないのか
ここで、Selectorを確認する必要が出てきます。UiPath StudioよりSelectorを確認しましょう。まずは、テキストを取得しているGet Textをフォーカスして、Selectorを確認します。
![キャプチャ(5).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/bed589cc-6377-d7a0-8a58-5558ecb939d5.png)
下記の画面が表示されます。
![キャプチャ(6).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/2b10390f-6b5e-09e3-4481-c771cabca416.png)
見てみると、テーブルの3カラム目(tableCol='3')で、4行目のテキスト(tableRow='4')を取得する様に指定されていることが分かります。

なので上記の例では、このルールに則って4行目の3カラム目にある「**250**」という数字を取得してしまったのです。
##この問題を解消するには？
ここでようやく、Selectorを修正していきたいと思います。これには、`UiExplorer`というツールを使います。そして、これはUiPath Studioには含まれています。ウィンドウズアプリケーションやWebページの構造を表示し、ユーザーによる選択を可能とする機能です。(何だか分かり辛い説明ですね。)
とりあえず、内容を見ていきましょう。
まず、Launch UiExplorerをクリックします。
![キャプチャ(10).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/71ab9480-866c-fa9d-84d8-56c3a8fd09d4.png)
下記の画面が立ち上がるので、矢印をクリック。取得したい要素を選択しましょう。(このケースでは、総合計の数値を選択しています)
![キャプチャ(11).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/65572c33-37a5-972b-3322-5789d6bd6092.png)
下記の様な画面が表示されます。ここでは、TableRow(つまり何行目か)が固定になっていることが問題でしたね。![キャプチャ(12).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/a8b95e88-668e-9d04-84ec-0f17f006eae3.png)
なのでここでは、tableRowのチェックを外して、代わりにrowname(=総合計)をチェックしてあげましょう。
![キャプチャ(13).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/133b3b5c-3638-e5bb-b1be-794eec42738d.png)

最後に、`<webctrl ～`で始まる部分をコピーして、先ほどのアクティビティのSelectorに貼付けましょう。
![キャプチャ(14).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/2ee8347e-1f47-1290-dab0-326fbf8cd887.png)

この作業により、UiPathは「総合計」の行の3カラム目のテキストを取得する事を認識しました。行が増減しても、これで問題ありません。
![キャプチャ(15).PNG](https://qiita-image-store.s3.amazonaws.com/0/154110/e66dfa0a-c21f-cfb4-47e8-49d9540ae707.png)


時に、UiPathを使うときには人間が認識している情報を、上記のような手順により認識させる必要があります。Selectorは変数も使えますし、`*`や`?`といったワイルドカードも利用可能です。
きちんと使いこなすことで、自分が欲しい情報を確実に抽出できるようになりますので、色々と試してみると面白いと思います。
気象庁の風データをダウンロード

気象庁の過去の気象データをダウンロードする．

- http://www.data.jma.go.jp/obd/stats/etrn/

今回は風．PythonのBeautifulsoupを使ってHTMLをパース．

# スクリプト

まずモジュールの準備．

```python:準備
import requests
import bs4
import pandas as pd
import datetime
import time
import numpy as np
from numpy import NaN
```

次は変換ヘルパー．文字列が数字だったらfloatに変換．///は観測データなしという記号．

```python:ヘルパー
def convert(item_str):
    if not item_str:
        return ''
    if item_str.replace('.','').replace('-','').isdigit():
        return float(item_str)
    if item_str == '///':
        return NaN
    return item_str
```

それでは本体．urlには県番号と場所番号を入れておく．それを探すには
http://www.data.jma.go.jp/obd/stats/etrn/
から順に場所を選択していけばよい．最終的なURLをみてそれをコピーする．

日付はURL指定，時刻はhh:mm形式でやってくるので，JSTに変換するためにdatetime+timedeltaで変換．

```python:本体
columns = ('JST', 'time', '降水量', '気温', '平均風速', '平均風向', '最大瞬間風速', '最大瞬間風速時風向', '日照時間')
all_df = []
    
for year in range(2015, 2017): # 2015 ... 2016
    for month in range(1, 13): # 1 ... 12
        for day in range(1, 32): # 1 ... 31

            try:
                this_day = datetime.datetime(year, month, day)
            except ValueError:
                continue # incorrect date; e.g., 2007/2/31 etc.
            print(this_day)

            url = 'http://www.data.jma.go.jp/obd/stats/etrn/view/10min_a1.php? prec_no=44&block_no=47662&year=' + str(year) + '&month=' + str(month) + '&day=' + str(day) + '&view='
            print(url)
            time.sleep(1) # wait for 1 sec
            res = requests.get(url)

            try:
                res.raise_for_status() # check for error
            except Exception as e:
                print('Error: {}'.format(e))
                continue # go to next if error

            res.encoding = 'utf-8'
            soup = bs4.BeautifulSoup(res.text, "lxml")
            tbl = soup.select("#tablefix1 td") # find the table
            n_rows = len(tbl) // 8


            for r in range(n_rows):
                i = 8 * r

                # JST
                hh, mm = tbl[i + 0].getText().split(":") # '00:10' --> '00', '10'
                row_timedelta = datetime.timedelta(hours=int(hh), minutes=int(mm))

                row_time = this_day + row_timedelta # for converting "24:00" to "00:00" of the next day
                row = [row_time]

                # other data
                row.extend([convert(tbl[i + j].getText()) for j in range(8)])

                
                row_df = pd.DataFrame(columns=columns)
                row_df.loc[0] = row
                all_df.append(row_df)


df = pd.concat(all_df, ignore_index=True)        
df.to_excel('wind_data.xlsx')
```
[めも]Android のminimum SDK関連

旧バージョン(Android 2.3.x)の切り捨てが進むようなので、めも。
一部、プレビュー版の情報を含みます。

#Support Library: 26.0.0 Alpha 1 (March 2017) 以降は、minimum SDKが14に
Recent Support Library Revisions
[Revision 26.0.0 Alpha 1](https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0-alpha1) (March 2017)
>Note: The minimum SDK version has been increased to 14. As a result, many APIs that existed only for API < 14 compatibility have been deprecated. Clients of these APIs should migrate to their framework equivalents as noted in the reference page for each deprecated API. 

訳: minimum SDKが14になります。そのため、API 14未満の環境のために存在していた多くのAPIが廃止されます。これらAPIを使用している場合は、リファレンスを参照して、互換性のあるAPIに移行して下さい。

##補足
おそらく、(工数的に)影響が大きい変更かと思います。
影響範囲は未確認ですが、Support Libraryを使う理由の1つである、Activity関連(FragmentActivity、AppCompatActivity)などのクラスもAPI廃止の影響を受けるかと思います。
当該クラスのリファレンスをdeprecatedで検索しても、26.0.0関連は1件しか出てこないのが怖い所・・
>`FragmentActivity.supportInvalidateOptionsMenu()`
This method was deprecated in API level 26.0.0-alpha1. Call invalidateOptionsMenu() directly. 

#Google APIs for Android: February 2017 - version 10.2 以降は、minimum SDKが14に

[February 2017 - version 10.2](https://developers.google.com/android/guides/releases#february_2017_-_version_102)
>・Android version 2.3.x (Gingerbread) Deprecation
Google Play services 10.2.x is the first release that no longer includes full support for Android version 2.3.x (Gingerbread). Apps developed using SDK release 10.2.x and later require a minimum Android API level of 14 and cannot be installed on devices running an API level below 14. 

訳: Google Play services 10.2.xは、Android version 2.3.x (Gingerbread)のフルサポートをしない最初のバージョンです。minimum Android API levelが14となり、それ未満の端末にはインストールできなくなります。

##補足: Firebaseのリリースノートには関連情報が明記されていないようなので注意しましょう

Firebase
[Release Notes](https://firebase.google.com/support/releases)、[Firebase Android Release Notes](https://firebase.google.com/support/release-notes/android)

>February 15, 2017
The Firebase Android SDK (v10.2) is now available as part of the Google Play services 10.2 release.

>November 21, 2016
The Firebase Android SDK (v10.0) is now available as part of the Google Play services 10.0 release.

----
#ライブラリの取得方法が変わります。
はまりそうなので、これも。

Recent Support Library Revisions
[Revision 26.0.0 Beta 2](https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0-beta2) (June 2017)
Revision 25.4.0 (June 2017)
Revision 26.0.0 Beta 1 (May 2017)
> Important: The support libraries are now available through Google's Maven repository. You do not need to download the support repository from the SDK Manager.
systemdの WantedBy 動作確認

# サマリ

親のunitがrestartやstop/startしたら、依存するunitも起動しておいてほしい。
子のunitに親への`Requires`と `After` つけるだけだと、親のrestartで子もrestartしたけど、親のstop/startでは再起動しなかった。ググッても `PartOf`使えなど諸説ありで腑に落ちない。

動かして確認→`WantedBy`で解決できた。

# 検証

動作確認のため、parent, child, child-wanted-by-parent という3つのunitを作りました。

```parent.service
[Unit]
Description=parent

[Service]
ExecStart=/bin/bash -c 'trap "echo exited parent" EXIT; echo started parent; sleep infinity'
```

```child.service
[Unit]
Description=child
Requires=parent.service
After=parent.service

[Service]
ExecStart=/bin/bash -c 'trap "echo exited child" EXIT; echo started child; sleep infinity'
```

```child-wantedby-parent.service
[Unit]
Description=child wanted by parent.
Requires=parent.service
After=parent.service

[Service]
ExecStart=/bin/bash -c 'trap "echo exited child wanted by parent" EXIT; echo started child wanted by parent; sleep infinity'

[Install]
WantedBy=parent.service
```

以下に、親・子の状態が"親の状態", "子の状態"であるときに、systemctl で"親を操作"すると、
"WantedBy無しの子", "WantedByありの子"がどうなったかをまとめました。

※"-" は、変化なしを表す

| 親の状態 | 子の状態 | 親を操作 | WantedBy無しの子 | WantedByありの子 |
|:-:|:-:|:-:|:-:|:-:|
| <font color="SlateGray">stopped</font>  | <font color="SlateGray">stopped</font> | <font color="DarkGreen">start</font> | -  | started  |
| <font color="SlateGray">stopped</font>  | started |  <font color="DarkGreen">start</font> | -  | -  |
| started | <font color="SlateGray">stopped</font> | <font color="Red">stop</font>  |  - | -  |
| started | <font color="SlateGray">stopped</font> | restart |  - | started  |
| started | started | <font color="Red">stop</font>  | stopped | stopped  |
| started | started | restart | **restarted**  | restarted  |


# 環境
確認はdebian jessieで行いました。用いたスクリプト(vagrant/ansible)を下に配置しましたので、よろしければどうぞ。
https://github.com/sumomoneko/test-systemd-unit-dependency

# 動機など

dockerコンテナをsystemdで管理しようと考えた際、親のdockerデーモンがdebアップデートなどで再起動した場合の挙動がわからず、調査しました。
ただ、本家dockerの最近の考えとしては、systemdでコンテナを管理するのではなく、[`--restart`つかってね](https://docs.docker.com/engine/admin/start-containers-automatically/)ということだそうです。(s.a. [docker run --restart=alwaysがどれくらいrestartしてくれるか調べた](http://qiita.com/manabuishiirb/items/f7edf11572f9256018b2) )

もっとも、 `--restart` は コンテナを毎回破棄する `-rm`とは相容れないので、「[unit起動ごとにコンテナ作りなおすよ！](http://qiita.com/74th/items/e8dc1ac1295140413dc8)」という場合は、本記事が役に立つのかなと思います。

# 終わりに

この方法がsystemd的に正しいのかどうか、いまいち確信がは持てていません。
「普通はこうだ」など指摘などありましたら、ソフトビニール製のモヒカンお願いいたします。

# 参考記事

- https://www.freedesktop.org/software/systemd/man/systemd.unit.html
bash メモ

ちょこちょこ使うけど忘れてしまうので追記しながら書いていく。

# シェルってなんだ？
UNIXを構成しているカーネル(Kernel)を操作するためのインターフェイス的存在。
[1. シェル](http://www.ep.sci.hokudai.ac.jp/~inex/y2002/1101/1101_shell.html#shell1.5)

FTPソフトに「FFFTP」とか「FileZilla」があるみたいに、
シェルにもいくつか種類があって、そのうちのひとつがbash。


# コマンド
雑多に書いていく。

## ls
list?
今いるディレクトリのファイルを表示。

## cd
Change Directory
ディレクトリの移動。

## 実行権限を与える
`chmod +x (ファイルパス)`
実行権限を与える

## 実行中のプロセスを終了する

### 1. すべてのプロセスの詳細を表示

`$ ps alx`

オプション

- a : 自分以外のユーザーのプロセスも表示する
- l : 標準のPID，TTY，TIME，CMDに加え，F，S，UID，PPID，C，PRI，NI，ADDR，SZ，VSZ，RSS，WCHAN，STATも表示する
- x : 制御端末のないプロセスの情報も表示する

### 2. 特定のプロセスを指定して終了

`$ kill (特定プロセスのPID)`

psで調べたPID(process ID)を入力。実行権限が無いと言われたら頭にsudoをつける。
果たしてこれでいいのかな？
[【 ps 】 実行中のプロセスを表示する](http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230860/)

### [RasPi]特定のプロセスを自動起動
/etc/rc.local
を実行権限(sudo)で開いて
`exit 0`
の前に実行プロセスを記入。
e.g.

```shell-session
\#!/bin/sh -e
\#
\# rc.local
\#
\# This script is executed at the end of each multiuser \runlevel.
\# Make sure that the script will "exit 0" on success or any \other
\# value on error.
\#
\# In order to enable or disable this script just change the \execution
\# bits.
\#
\# By default this script does nothing.

\# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

omxplayer --refresh --loop -o both /home/pi/Desktop/TestMovie.mp4

exit 0
```
ファイルディスクリプタが読み書き可能かどうかを判定する

ファイルディスクリプタに対して、読み書き可能かどうかを即時チェックする関数です。

```c
int isReadable(int fd) { 
   fd_set fdset;
   struct timeval t = {0, 0};

   FD_ZERO(&fdset);
   FD_SET(fd, &fdset);

   return select(fd + 1, &fdset, NULL, NULL, &t) > 0;
}
```

```c
int isWritable(int fd) { 
   fd_set fdset;
   struct timeval t = {0, 0};

   FD_ZERO(&fdset);
   FD_SET(fd , &fdset);

   return select(fd + 1, NULL, &fdset, NULL, &t) > 0;
}
```

戻り値は読み書き可能なら 1 が、そうでなければ 0 が返ります。

もともとソケット用に作った関数ですが、引数はファイルディスクリプタなので UNIX ならデバイスなども対象に含まれます。
WordPressの移管方法（PhpMyadmin）

wordpressのサイトを別ドメインに移管する場合の方法です。

移管元
http://aaa.com/

移管先
http://bbb.com/

phpmyadminを使用します。

# 概念

wordpressはphpファイルと、DBからなります。
そのため、FTPなどでファイルのみを移行しても、表示されません。ファイルと、DBの移行が必要です。
データベースはサーバーによる設定が入っているため、移管後に再設定する場所があります。

# 移行方法

## ファイルの移行

FTPなどで、wordpressのファイル一式をダウンロードします。
新しいサーバーに上記のファイルをアップロードします。

## データベースの移行

### 移管元のPhpMyadminからデータベースをダウンロードします

1. phpmyadminにアクセスします。
例）http://aaa.com/phpmyadmin
サーバーによってはコントロールパネルからアクセスするサーバーもあります（さくらのレンサバなど）。

2. Phpmyadminから、エクスポートしたいデータベースに移動し、上部メニューから「エクスポート」をクリックします。
3. 「Export method」→「詳細」をクリックします。
4. テーブルを全選択し、「出力」→「出力をファイルに保存する」→圧縮「zip形式」を選択します。
（容量が多くない場合は、圧縮しなくて大丈夫です。）

5. 「DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER コマンドを追加する」にチェックを入れます。
6. 「実行」をクリックします。
ファイルがダウンロードさます。


### 移管先のデータベースにデータをインポートします

1. phpmyadminにアクセスします
例）http://bbb.com/phpmyadmin

2. DBを作ります。
3. DBへ移動し、「インポート」をクリックします。
4. 先ほどダウンドーロしたファイルを選択し、インポートします。

※下記エラーメッセージが出た場合は、再度インポートすると完了することがあります。

```
Script timeout passed, if you want to finish import, please resubmit same file and import will resume
```


### データベースの情報を新サーバー用に編集します

1. phpmyadminにアクセスします
例）http://bbb.com/phpmyadmin

2. 「検索」に「http://aaa.com/」を入力、テーブルを全選択して「実行」します
3. 検索結果が表示されたら、optionのテーブルの「aaa.com」を「bbb.com」に変更します（2箇所）

## アップロードしたconfig.phpファイルの新サーバーに合わます

config.phpはサーバーの情報とwordpressの情報を同期するファイルです。
この情報を新サーバーに合わせます。
以下の箇所の情報を環境に合わせて書き換えます。

```config.php
/** MySQL データベースのユーザー名 */
define('DB_USER', 'root');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'root');

/** MySQL のホスト名 */
define('DB_HOST', 'localhost');

/** データベースのテーブルを作成する際のデータベースの文字セット */
define('DB_CHARSET', 'utf8mb4');

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', '');
```

## データベースの情報を上書きします
現状のままではwordpressのパーマリンクの情報が旧サーバーのままなので、新サーバーに合わせます。

### wordpressのパーマリンクを更新

1. wordpressへアクセス
http://bbb.com/wp-admin/

2. 「設定」→「パーマリンク設定」を保存し、設定を更新します
JavascriptでPromiseを使って非同期処理を逐次実行する方法


# 概要

タイトルの通り。

Javascriptで配列に詰めたパラメータを１つずつ、ajaxなどの非同期処理を含む関数に渡して実行する場合
なにもしないと並列（配列に入ってる分、ajax関数が同時実行）で実行されます。

サーバ負荷などの考慮で、これを並列でなく逐次（同時に実行する処理が１つずつだけ）にする方法です。


```es2016``` とかであれば ```async``` ```await``` を使うと簡単です。

今回はあえてPromiseを使う方法の紹介です。

> ```aws Lambda``` のnodeを使っていたら```async``` と arrow Functionの組み合わせで
文法エラーになってしまっていたのでPromiseを引っ張り出してきました。
> 調べたらnode7.6からasyncとawaitが標準でサポートされた模様


# 例１

配列分、thenの連鎖を作っておく方法

> @mpyw さんにコメント頂いた方法
> すっきり書けるのでこっちの方が好みです。ありがとうございます。


```javascript
const resolveAfter = (args) => {
  return new Promise((resolve) => {
    console.log(args);
    setTimeout(resolve, 1000);
  });
};

const argsList = [
  { id: 1, name: 'taro' },
  { id: 2, name: 'jiro' },
  { id: 3, name: 'saburo' }
];

let p = Promise.resolve();

argsList.forEach((args) => {
  p = p.then(() => resolveAfter(args));
});


```

イメージとしては
* 非同期処理を含む関数（でPromiseされてないもの）はPromiseで括る
* パラメタを配列に入れ、forEach等で回す（処理順を確保）
* 再代入するpを定義、pに配列分非同期処理のthenの連鎖を詰める感じ


# 例２

reduceを使う方法
letはちょっと・・・な人はこちら


```javascript
argsList.reduce((current, args) => {
  return current.then(() => {
    return resolveAfter(args);
  });
}, Promise.resolve());
```

イメージとしては

* 非同期処理を含む関数（でPromiseされてないもの）はPromiseで括る
* パラメタを配列に入れ、reduceで回す（処理順を確保）
* reduceのinitialに ```Promise.resolve()``` を入れることでPromiseObjectが入る
	* これによりreduceのiterateの都度、Promise.thenされるようになる
	* reduceを使うことで１つ前のpromiseオブジェクトを取得できるのでそれを利用した方法
プログラミング速度はどうやったら上がるのか


# はじめに

　新人エンジニアとなり、気付けば3か月が過ぎようとしていました。
　今まで大学時代から「どうやってもっと早くしていくか」を考え続け、実践して、それなりの効果がありました。
　そうしたことは、同期にも伝えられる部分があるんじゃないかと思い、記事にしました。


# 勝手に公式

　プログラミング速度　＝　タイピング速度　×　編集速度　×　理解度

　編集速度　＝　Vimへの理解度　+　コマンドの省略化
　理解度　＝　経験値 + 知識量


## なんとなく解説

　タイピングが早ければ、コーディングも早くなるのは当然。
　Vimエディタに慣れれば慣れるほど、早くなるのも当然。

　そして、この2つは基礎体力として、PGとして動く以上ほぼどんな場面でも生かせるものではないかと思います。
　（Vim使えない場合は泣きます）


　3つ目の理解度というは、「そのプログラミング言語への理解度」というものです。

　「こういう場合はアレが使えたな」「アレが使えそうかも」なんていう事をなんとなく思い出せるのが経験値。
これがあると検索時間に費やさなくて良くなったり、調べた時も「これかな」と使えそうなものを見つけやすくなるように思えます。

　知識量とは、「こういう場面で使える関数、メソッド、クラスはなんだっただろうか」と、調べずともしっかり覚えてる量です。

　似たようなものが多いので「調べりゃ良いでしょ。そっちの方が確実だし」と思っておりましたが、振り返ってみると週2回3回ペースで同じこと調べることありました。アホかな？
　そういう使用頻度が高いものは、自分でしっかりまとめて、完璧な記憶しておかないといけないですね……。
　反省です。


# まとめ

　Vimを使おう。
　使いまくるものは、ドキュメントにまとめて、しっかり記憶しよう（>>俺）
lambdaをAPI gateway経由でcurlから呼び出す

### このドキュメントは
- 2017/6時点で、ウェブコンソールからaws lambdaの設定をする場合、コンソールがAPI gatewayからlambdaを呼び出せるように設定をするものの、そのままでは手元のcurlから呼べない、つまり任意のクライアントから呼び出せない状態になっているので、ある程度のセキュリティを残しつつ呼べるようにするために必要な作業について書いたメモ。
- このやり方で試しに公開する場合にはあらかじめrequestのrate/quota制限などはちゃんとやっておいたほうが安全です

### 目標
- 以下のようなcurlコマンドでどこからでもAPIを呼び出せる(例はPOST)
 
```
curl -X POST -d $DATA -H "x-api-key: $API_KEY" https://$APP_ID.execute-api.$REGION.amazonaws.com/$STAGE/$METHOD
```

### 作業内容
- APIの認証をAWS_IAMからなしにする。([ここ](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html)の[Authorization Settings] セクションの画像のAuthorizationというプロパティの値を変更。この画像ではすでにNone(なし）になっている）
- [API KEYを必須にし、API KEYを作成](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html)する
- 必要に応じて[APIのデプロイステージを作成](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/stages.html)する(dev/test/prod)
- [使用量プランを作成](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-api-usage-plans.html)し、API KEYを関連づけてAPIのステージにアタッチする
任意の文字列をコピーするテクニック

そろそろ決定版が欲しいな。

# 前置き

今までは

* [Qiitaのコードにコピーボタンを追加するユーザースクリプト - Qiita]
* [Togetterからツイートをコピーするボタンを追加するユーザースクリプト - Qiita]

と既存のものを選択してコピーするか、無いものをコピーしたいときは

* [PHPマニュアルから関数をコピーするボタンを追加するユーザースクリプト - Qiita]

とコピーしたいDOMを作ってそれを選択するというまどろっこしい方法を取っていた。

Qiitaにも色々記事はある。

でもこれらの方法は主にRangeの処理がとてもとても面倒なので、最近は使っていない。

目新しい内容ではないが、使用頻度が高いのでまとめる。

# 要件

* 任意のJS側で用意した文字列をクリップボードに保存させる。
* 動作のトリガーは主にボタンクリックのイベント駆動
* 通常のコピー動作を阻害しない
* 複数のコピー処理を追加したときに互いに干渉しない
* 後処理が楽であって欲しい

# コード

```js:好きなイベントに好きなコピーイベントを設置するjs

// 登録したい要素
const element = document.createElement('hoge'); // document.querySelector('hoge')
element.addEventListener('click', (e) => {
  document.addEventListener('copy', (e) => {
    e.preventDefault();
    e.clipboardData.setData('text/plain', 'コピーしたい文字列');
  }, {once:true});
  document.execCommand('copy');
});
```

これだけ。
何かのイベントを契機にcopyイベントを登録して、`document.execCommand('copy');`で即座に手動実行。
`clipboardData.setData()`で選択中文字列ではなく色々手動で設定できる。
もちろんコールバック中にDOM操作ができるので、欲しい文字列はDOM中から自由に取ってきて加工できる。

イベントに`once`オプションをつけることで、実行後にイベント登録は解除される。
よってコピー後も通常のコピーが出来るし、別のcopyイベントも登録できるし、当然再度同じイベントを登録することもできる。
後腐れなし、と思っている。

# (オマケ)Bootstrapなどがあるときの視覚的補助

自分で作っているならば動作に不安は無いが、知らぬ人にはコピーが起きても変化が無いので味気ない。

```js

// ツールチップの遅延非表示。クリックで表示を前提にしている(delayオプションが効かないのでやむなく)
const hideTooltipDelay = (element, dilay) => {
  setTimeout(() => {
    // ツールチップはBootstrap(jQuery)の機能なので、Qiitaが読み込んでいるものを使う
    $(element).tooltip('hide');
  }, dilay);
}

// クリックすることで指定のstringをクリップボードにコピーするElementを返す関数
const createCopyButton = (string, tag = 'span') => {
  if (typeof string == 'function') {
    string = string();
  }
  const element = document.createElement(tag);
  element.addEventListener('click', (e) => {
    document.addEventListener('copy', (e) => {
      e.preventDefault();
      e.clipboardData.setData('text/plain', string);
    }, {once:true,});
    document.execCommand('copy');
    hideTooltipDelay(e.target, 1000)
  });

  element.dataset.toggle        = 'tooltip';
  element.dataset.originalTitle = 'Copied';
  element.dataset.trigger       = 'click';
  return element;
}

```

褒められたコードではないのだが、ツールチップでcopyされたことを目視することができる。
が、本当に処理周りの理解が追いついてなくて、消し方や2回めのクリック時にtooltipが出ない問題を抱えている。(manual triggerで作ったほうがよかったかな)

![commentcopy.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/fda0d9b4-f626-bd9f-0364-34efee7c68e6.gif)

# <i class="fa fa-book"></i> 参考

* [copy - Web 技術のリファレンス | MDN]





[Togetterからツイートをコピーするボタンを追加するユーザースクリプト - Qiita]:http://qiita.com/khsk/items/785202bb70646029193e

[Qiitaのコードにコピーボタンを追加するユーザースクリプト - Qiita]:http://qiita.com/khsk/items/27a80755d883521ecd73


[PHPマニュアルから関数をコピーするボタンを追加するユーザースクリプト - Qiita]:http://qiita.com/khsk/items/b78315e7024107008956

[copy - Web 技術のリファレンス | MDN]:https://developer.mozilla.org/ja/docs/Web/Reference/Events/copy
ReactのPropTypes Validator


## PropTypes Validator

コンポーネントは最初から再利用する目的で作らなければならない。
コンポーネントに__どんな属性を持っていて、どんな属性が必須で、どんなタイプの値を貰わなければならないのか__などの明細を残せば色んな意味で便利でしょう。
そのためにReactではPropTypesを提供する。
PropTypesは次のような長所がある。

* コンポーネントを開くことだけで、どんな属性が必要で、属性の形式は何なのか把握できる。
* 属性が漏れたり間違った場合は、consoleにエラーメッセージを出力してくれる。

## JavaScript Primitives PropTypes

| Validator        | 説明                               |
| ---              | ---                                |
| PropTypes.array  | Propはarrayでなければならない。    |
| PropTypes.bool   | Propはbooleanでなければならない。  |
| PropTypes.func   | Propはfunctionでなければならない。 |
| PropTypes.number | Propはnumberでなければならない。   |
| PropTypes.object | Propはobjectでなければならない。   |
| PropTypes.string | Propはstringでなければならない。   |
| PropTypes.symbol | Propはsymbolでなければならない。   |

\:bulb: arrayやobjectは使わない方がいい。
属性のタイプを特定するためにPropTypesを使っているのに、arrayやobjectはその範囲が広すぎて特定することができない。
arrayやobjectを使った場合、eslintからエラーが出る。

* PropTypes.arrayは非推奨。代わりにPropTypes.arrayOfを使う。
* PropTypes.objectは非推奨。代わりにPropTypes.objectOf又はPropTypes.shapeを使う。

## Combined Primitives PropTypes

| Validator           | 説明                                                                                                                               |
| ---                 | ---                                                                                                                                |
| PropTypes.oneOftype | Propは色んなタイプの一つだ。<br>PropTypes.oneOftype([<br>PropTypes.string,<br>PropTypes.number,<br>PropTypes.instanceOf(Message)]) |
| PropTypes.arrayOf   | Propは特定タイプのarrayでなければならない。<br>PropTypes.arrayOf(PropTypes.number)                                                 |
| PropTypes.objectOf  | Propは特定タイプの属性値を持つobjectでなければならい。<br>PropTypes.objectOf(PropTypes.number)                                     |
| PropTypes.shape     | Propは独特な形態を待つobjectでなければならない。<br>PropTypes.shape({<br>color: PropTypes.string,<br>fontSize: PropTypes.number})  |

## Special PropTypes

| Validator            | 説明                                                                                                                    |
| ---                  | ---                                                                                                                     |
| PropTypes.node       | Propはレンダリングができるどんな値もできる。numbers, strings, elements, array                                           |
| PropTypes.element    | PropはReact elementでなければならない。                                                                                 |
| PropTypes.instanceOf | Propは指定されたクラスのインスタンスでなければならない。<br>jsのinstanceof演算子を使用<br>PropTypes.instanceOf(Message) |
| PropTypes.oneOf      | Propはenumのような特定な値の範囲で制限される。<br>PropTypes.oneOf(['News', 'Photos'])                                   |

## 参考

* https://facebook.github.io/react/docs/typechecking-with-proptypes.html
react-devtools


## react-devtoolsとは

* facebookで開発
* chromeのdeveloper toolsをreactまで拡張した感じ
* コンポーネントの階層構造、propsやstateの確認ができる。

## 設置

* [chrome extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
* [firefox extension](https://addons.mozilla.org/firefox/addon/react-devtools/)
* safariやreact nativeなどは[standalone app](https://github.com/facebook/react-devtools/blob/master/packages/react-devtools/README.md)を使う。

## standalone app

chromeやfirefoxはextensionを提供しているので、説明は割愛する。
次はstandaloneタイプのreact-devtoolsの設置手順だ。
React DOMだけではなくReact Nativeにも対応されているので、こっちも悪くないかも。

react-devtoolsをグローバルで設置する。

```sh
% yarn global add react-devtools
```

react-devtoolsを実行する。

```sh
% react-devtools
```

react-devtoolsが実行されてreactとのコネクションを待っているとメッセージが表示される。
React Nativeの場合は自動でconnectされるが、React DOMの場合はtopページに次を追加しなければならない。

```html
<script src="http://localhost:8097"></script>
```

![スクリーンショット 2017-06-26 11.44.10.png](https://qiita-image-store.s3.amazonaws.com/0/93752/7d953728-8f57-b905-0d73-c410112aaa99.png "スクリーンショット 2017-06-26 11.44.10.png")

![スクリーンショット 2017-06-26 11.52.14.png](https://qiita-image-store.s3.amazonaws.com/0/93752/97d727f5-411d-d1dc-8660-1561f0692fab.png "スクリーンショット 2017-06-26 11.52.14.png")


次からはreactアプリケーションが起動されている場合はReact DOMも自動でconnectしてくれる。
Tensorflow API: FLAGS

## FLAGSとは

https://www.tensorflow.org/api_docs/python/tf/flags

* Tensorflowで使用する定数を定義する
* 実行時に、コマンドラインからパラメーターを与えることができるようになる 
 
> $ python file.py --[parameter_name]

* 定数の説明を与えると、実行時に--helpで定数の説明を見ることができる  

> $ python file.py --help

## 使い方

~~~ python
# 定義用のflagを作成
flags = tf.app.flags

# 参照用のflagを作成
FLAGS = flags.FLAGS

# stringの定義
flags.DEFINE_string(定数名, 初期値, 説明文)

# floatの定義
flags.DEFINE_float(定数名, 初期値, 説明文)

# intの定義
flags.DEFINE_integer(定数名, 初期値, 説明文)

# boolの定義
flags.DEFINE_boolean(定数名, 初期値, 説明文)

# 定数の参照
print(FLAGS.定数名)

~~~
ベンチマーク : public static function __callStatic($method, $args)

#目的
マジックメソッドは遅い遅い言われていたので、フレームワークなどでよく使われる__callStaticはどれくらい遅いか試してみた。

##実行コード

```php
<?php

class A
{
    public function test()
    {
        return 1.5 * 100 * 10;
    }
}

class Test extends A
{
    public static function __callStatic($method, $args)
    {
        return (new self)->$method($args);
    }
}

$start = microtime(true);

for ($i = 0; $i < 1000000; $i++) {
    Test::test();
}

print microtime(true) - $start . PHP_EOL;

$start = microtime(true);

for ($i = 0; $i < 1000000; $i++) {
    (new A)->test();
}

print microtime(true) - $start . PHP_EOL;
```

##結果
```sh
// call staticの場合
1.6370959281921
// 通常呼び出しの場合
1.0607688426971
```

##結論
5割り増しぐらい。
元々の関数呼び出しが早いのでそんなに気にするほどの遅さではないですね。
参考材料にでも。
AWS Lambda で動的HTMLコンテンツを配信する(Lambdaプロキシ統合を利用)

静的な内容ならS3に置いてWEBホスティングを有効にすればいいのですが、動的にHTMLを生成する場合にLambdaでHTMLを生成してレスポンスする方法です。この方法だとEC2等のサーバを運用する必要がありません。

## Lambda

例として適当なHTMLの内容を返すコードは次のとおりです。

```javascript
exports.handler = (event, context, callback) => {
  // もしQueryStringから値を取り出したい場合はevent.queryStringParametersから取得する

  // 動的にHTMLの内容を作成
  const html = `
  <html>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8">
    <body>
      <h1>Test Page</h1>
      こんにちわ！
    </body>
  </html>`;

  // Lambdaプロキシ統合の場合は下記のようなObjectでレスポンスを返せる
  const response = {
    statusCode: 200,
    headers: {
      'Content-Type': 'text/html',
    },
    body: html,
  };

  callback(null, response);
};
```

## API Gateway

`Lambdaプロキシ統合の使用`にチェックをつけて、先程 作成したLambdaを指定します。

![スクリーンショット_2017-06-26_11_05_26.png](https://qiita-image-store.s3.amazonaws.com/0/35733/11c657d4-2a8e-4f9a-2e09-d22baf08e8df.png)

## 動作確認

上記のAPIをAWSのコンソールからデプロイして、

![スクリーンショット 2017-06-26 11.12.27.png](https://qiita-image-store.s3.amazonaws.com/0/35733/67a8484b-e92b-153c-007e-227a5ede9cad.png)

ブラウザでアクセスしてみます。

![スクリーンショット 2017-06-26 11.14.52.png](https://qiita-image-store.s3.amazonaws.com/0/35733/deca495f-ed2f-e130-a3ef-fdfe26cda761.png)

## 補足

Lambdaが起動するのに時間がかかるので、実際の運用で利用する場合はAPI Gatewayでキャッシュを設定するか、CloudFront等のCDNを利用するのがよいかと思います。

以上
AWS・RDSのインスタンスを起動してみる。

今回初めてRDSのインスタンスを立ててみることになりました。
かなーり基本的なことなので備忘録として流れをまとめたものになります。

#RDSインスタンスの起動

まずはAWSのコンソールへログイン。

数あるサービスの中からRDSを選択。

![RDS起動01.png](https://qiita-image-store.s3.amazonaws.com/0/174392/6c8ba74e-13cd-37a4-df86-520255fa862c.png)

ダッシュボードからインスタンスを選択し、[DBインスタンスの起動]をクリック。

![RDS起動02.png](https://qiita-image-store.s3.amazonaws.com/0/174392/ae6f7c49-a596-8413-8599-eb14928745df.png)

エンジンの選択。今回はMySQL。

![エンジンの選択.png](https://qiita-image-store.s3.amazonaws.com/0/174392/b8d03c43-aa4f-5b91-1ad2-ca3bca7bda84.png)

今回は、試しにRDSを起動してみる段階なので全て無料利用枠で使えるもののみ選択していきます。
ストレージは、他のタイプを利用する理由が特にない場合は汎用(SSD)を利用するので汎用を選択。

![reDB詳細.png](https://qiita-image-store.s3.amazonaws.com/0/174392/4c06d704-69e4-2e60-2c62-5776ff6148de.png)

VPCやサブネットグループは事前に作成しておいたもの、流用しているものがあればそちらを指定する。
![詳細設定.png](https://qiita-image-store.s3.amazonaws.com/0/174392/ca10ac5c-0864-2b6d-7729-755c0de49f4e.png)

最後にバックアップ期間や日時について設定すれば完了です。

![バックアップの指定.png](https://qiita-image-store.s3.amazonaws.com/0/174392/b4ef21b8-2ff3-d59e-5ec7-30e70e289faa.png)

注意する点としては、[マイナーバージョン自動アップグレード]の項目。
ここを[はい]に設定している場合、AWS側の任意のスケジュールでアップグレードされます。マルチAZ配置にしていない場合、アップグレードの間インスタンスは停止した状態になるため、
自分でスケジュール調整等行いたい場合等は[いいえ]にしておいた方が無難です。

入力が完了したらインスタンスを作成！
しばらく待つとインスタンスが起動します。

記事や本を参考にしながらさらっとRDSインスタンスを起動してみました。
流れとしてはあっという間。手軽に作れるんだなーと思いましたが、今回ネットワークやセキュリティのあたりは、もともと設定されていたものを流用しているので詳しい部分には触れていません。
この辺りもおいおいやっていこうと思います。


#用語メモ

途中不明な用語もあったので、忘れないように記録↓


**AmazonAurora**
RDSのデータベースエンジン。MySQL互換の高速データベースサービス。

**マルチAZ配置**
インスタンス起動時に、プライマリDBを作成すると同時に別のアベイラビリティゾーンにDBが複製される。
プライマリDBに障害が発生した場合、自動的にフェイルオーバーが行われDBの動作が再開する。
エンドポイントが変更されることもないので、人の手を介することなくDBの動作を再開することができる。

**フェイルオーバー**
稼働中のシステムに障害が発生した際に、代替システムがその機能を自動的に引き継ぎ、処理を続行する仕組み。
引用元：[IT用語辞典](http://e-words.jp/w/%E3%83%95%E3%82%A7%E3%82%A4%E3%83%AB%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC.html)

**アベイラビリティゾーン(AZ)**
同一のリージョンで内で物理的に数十キロ以上離れ、電源、ネットワークなどが独立したデータセンター群のことをいう。

**サブネットグループ**
一つの大きなネットワークを細分化するための小さなグループ。

**DBパラメーターグループ**
confファイルに相当し、DBの動作について設定をするもの。

**オプショングループ**
データとデータベースの管理を容易にしたり、データベースのセキュリティを強化したりするための、追加の機能があり、オプショングループでこれらの機能を設定し実行可能なようにしている。
DOMエレメントにid属性を付けたときのSafariの挙動

W3CにDOMエレメントのidがグローバル変数になる仕様があるそうです。
つまり、

```html
<div id="hoge"></div>
```
とした場合に

```javascript
window.hoge === document.getElementById("hoge")
```
がtrueとなります。

そこまではいいとして、そのあとの挙動が他のブラウザとSafariで異なりました。

もう一度

```html
<div id="hoge"></div>
```
のとき、

```javascript
const hoge = "yeah!";
console.log(hoge);
```
Chrome, FireFox等は "yeah!" と表示できますが、
Safariではconstで二重宣言した場合と同じエラーが出ます。

仕様にないからなのか、Safariのバグなのか…？
これを知って迂闊にidを命名できなくなりました…

# 追記 (2019/06/21)
Safari が修正してくれました

> 仕様にないからなのか、Safariのバグなのか…？

どうやらバグだったようです
idと同名の変数を宣言してもエラーは出なくなりました

例えば、

```js
const hoge = 1
console.log(hoge)
```

としてもエラーは出ず、

```shell
1
```

ちゃんと返ってきます:tada:

### 余談

ではこうしてみましょう

```js
console.log(hoge)
const hoge = 1
console.log(hoge)
```

```shell
Uncaught ReferenceError: Cannot access 'hoge' before initialization
```

不思議なことに、ちゃんとエラーが出ます ( Safari, Chrome, Firefox ともに同じ挙動です )
同名の変数が宣言されているプログラム内では明示的に `window.hoge` としないと呼び出せなくなるようです

( 苦し紛れの対応に見えます……？ )

### さらに余談

windowオブジェクトのプロパティ群を探していたのですが、hogeは見当たりません
直下にないなら \_\_proto\_\_？ prototype？ document下？ などと探してみても見当たりません
一体どこに格納されているのでしょう…？
Elasticsearchの自動マッピングの一部を上書きする方法

Elasticsearch(ES)が使いやすい理由の一つとして、スキーマの自動マッピング機能があります
生データを送れば、型を推測してくれるわけです

ただし `geo_point` などの一部の型は自動マッピングしてくれない、という課題があります
かといって `PUT _mapping/INDEX_NAME` でスキーマ定義をやるのもスマートじゃないです

## 解決方法

ESのテンプレート機能を使いましょう
これにより、ESの自動マッピングの一部を上書きできます。それ以外は自動マッピングに任せることができるので、最小限の指定でOKです

## テンプレートを使う

* 対象Indexは **`my_map_index` から始まるインデックスすべて** (例 `my_map_index0` など)
* 対象Typeは **`waypoints`**
* 対象Fieldは **`payloads.data`** で、認識する型は **`geo_point`** とする場合のテンプレートは下記のようになります

```json
{
  "template": "my_map_index*",
  "mappings": {
    "waypoints": {
      "properties": {
          "payloads": {
            "properties": {
              "data": {
                "type": "geo_point"
              }
            }
          }
      }
    }
  }
}
```

## 実際の操作

※最初のDELETEは念のため。操作はお気をつけて

```console
$ curl -X DELETE https://$ES_HOST/my_map_index0
$ curl -X DELETE https://$ES_HOST/_template/my_map_tpl
$ curl -X PUT -H "Content-Type: application/json" -d @- <<EOT https://$ES_HOST/_template/my_map_tpl
{
  "template": "my_map_index*",
  "mappings": {
    "waypoints": {
      "properties": {
          "payloads": {
            "properties": {
              "data": {
                "type": "geo_point"
              }
            }
          }
      }
    }
  }
}
EOT
```

### データ投入してみる

```console
$ curl -X POST -H "Content-Type: application/json" -d @- <<EOT https://$ES_HOST/my_map_index0/waypoints
{
  "payloads": {
    "number": 1,
    "data": [35.680962, 139.766778]
  }
}
EOT
```

Kibanaでインデックスをつくると、下記の通り `payloads.data` が `geo_point` として認識されています。指定が無かった `payloads.number` は `number` として自動認識されています

ちなみに geo_point として認識されるフォーマットは複数あります。[ドキュメントをご覧ください](https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html)。ちなみに、配列で渡す場合は `[経度, 緯度]` の順番ですので、お気を付けください

![kibana-index.png](https://qiita-image-store.s3.amazonaws.com/0/22754/70277289-ae3c-a530-760c-b449a04c37ef.png)

# あとがき

`geo_point` は認識したけど、肝心の地図が表示されない！というときは[こちら](http://qiita.com/ma2shita/items/1288d64c90821960b5c9)をご覧ください

EOT
レスポンシブスライダー

よく使うスライダー一覧

# Slick
よく使うスライダー
http://kenwheeler.github.io/slick/


# FlexSlider 2
wordpressプラグインもあるスライダー
http://flexslider.woothemes.com/

# Swiper
斜めに表示するスライダー
http://idangero.us/swiper/#.WVBrx1PyhN1

# Fullscreen Slit Slider
面白い動きをするスライダー
https://tympanus.net/Tutorials/FullscreenSlitSlider/
[ARDUINO]Q-TABLE作り。

I think the Q-Table is a important part of Reinforcement Learning or Q-Learning.

Row is States, Column is Action. 


#Code 

```c

int Q_table[3][4] = {};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  rand_input();
  view_table();
  
}
void view_table(){
  Serial.println("Q-table");
  for(int i = 0; i < 3; i++){ 
    for(int j = 0; j < 4 ; j++){
      Serial.print(Q_table[i][j]);
      Serial.print("\t");
    }
    Serial.println();
  }
}
void rand_input(){
  Serial.println("input random number");
  for(int i = 0; i < 3; i++){ 
    for(int j = 0; j < 4 ; j++){
      Q_table[i][j] = random(10,20);
      Serial.print(Q_table[i][j]);
      Serial.print("\t");
    }
    Serial.println();
  }
  delay(1000);
}

```

#Result 

![01.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/864ca74b-8671-a715-9f26-8e9072b03832.jpeg)

If you have any other nice code, 
pls, do leave a comment below.

**Dreamwalker**
SPAのページ遷移した時の画面位置がおかしいのをなんとかしたい

## 背景

ReactとReduxを使って業務効率化アプリを作っていて、タイトルの内容でもやもやした時のお話です。
機能もある程度実装して、レスポンシブ対応をして、あとはテストをすればリリースだー！

…と思いきや、スマホの画面を見てみようと実機で触ってみるとページ遷移するたびに画面が変なところにスクロールした状態でレンダリングされてしまう…

## 原因不明

原因を追求する為にググってみるもなんの成果もなし。（ググり方がいけないのかもしれない）

ただ、SPAって実際にページ遷移してるわけじゃないから、スクロール位置がそのまま維持されてるんじゃないか説は割と濃厚そうな予感はしてる。

## なんとかしたい（した）

Reactを使っているので、react-routerでルーティングを行なっています。
react-routerには`onEnter`というページ遷移時のミドルウェアを挟むための便利な属性があるみたいで、これを用いてなんとかしました。

```js:app.jsx
// 省略

<Provider store={ store }>
  <Router history={ history }>
    <Route path="/" component={ App }>
      <Route path="/hoge" component={ hoge } onEnter={ checkEnter } /> // ページ遷移した時に呼び出される
    </Route>
  </Router>
</Provider>

function checkEnter() {
  window.scroll(0, 0); // ページの一番上に移動
}
```

これで解決✨
ただ原因はちゃんと掴めていないし、その場しのぎ感が否めないので、もしこうなってしまう原因をご存知の方がいらしたらご教授いただけたらと思います…

それにしてもこの`onEnter`とても便利だ。
色々なことに使えそう。
形態素解析・Ngramとbag-of-words

形態素解析・Ngramとbag-of-words
===

引き続き、機械学習やその他色々について得た知識を
復習and記事作成の練習and個人の備忘録としてまとめていきますよん！

今回も前回と同様、自然言語処理の分野です！
タイトルの内容について、ざっくりといろいろ書いていきます！

⚠︎※※注意※※⚠︎  

・出来るだけ専門知識のあまりない人に対して、分かりやすく書くことを目標にしています。
　そのため、厳密に言うと間違っている部分があると思いますがご容赦ください。

・また、ネットで調べたレベルの知識がほとんどなので、
　"厳密に言うと"レベルではなく間違っている箇所があるかもしれません。。
　その場合は非常に申し訳ないです。指摘していただけると幸いです！

##### 参考

[自然言語処理の仕組みと手順](https://www.slideshare.net/kazoo04/ss-56821735)
[日本語形態素解析の裏側を覗く！MeCabはどのように形態素解析しているか](http://techlife.cookpad.com/entry/2016/05/11/170000)

##### 前回までの記事

・[機械学習について](http://qiita.com/AwaJ/items/950953a9c20f391e72cf)
・[教師あり学習　〜回帰〜](http://qiita.com/AwaJ/items/78de8b4738e87a57addd)
・[教師あり学習　〜分類〜](http://qiita.com/AwaJ/items/b769a5461e33ea8437a5)
・[Random Forest](http://qiita.com/AwaJ/items/3c02ff64b6a89e1a96f1)
・[階層型クラスタリング](http://qiita.com/AwaJ/items/ab43ce47817b3b864b9e)
・[非階層型クラスタリング k-means](http://qiita.com/AwaJ/items/1cd3eeef497c93a6a053)
・[主成分分析](http://qiita.com/AwaJ/items/1dcb703781349204213d)
・[TF-IDF](http://qiita.com/AwaJ/items/5937665d5a4152cc24cf)

形態素解析
---
日本語の文章と英語の文章では、決定的な違いが一つあります。

それは、「半角スペース(など)で区切られていないこと」です。

文章を分析する時に、文章の形のまま色々な処理を行うことは非常に難しいので、
適当な部分列に区切ってやる必要があります。

英語だと、半角スペースで区切ってしまえばそれでことは足りるのですが、日本語だとそうはいかないのでなんらかの手法を使って意味のある部分列に区切らなければなりません。

その手法として多く使われるのが、「形態素解析」と呼ばれる手法です。

形態素解析を使うと、文章を以下のように分けることができます。

「すもももももももものうち」
→すもも(名詞,一般)/も(助詞,係助詞)/もも(名詞,一般)/も(助詞,係助詞)/
　もも(名詞,一般)/の(助詞,連体化)/うち(名詞,非自立)

このように文章を形態素単位に分割した上で、名詞のみを選択してみたり、出現回数をカウントしてみたり、その他色々な処理を行なって分析をします。

分割の方法として、Mecabという形態素解析のライブラリでは、単語に関する品詞など様々な情報の載っている辞書を参照することで、文字列の並びをパターン化し最適なルートを選択しているようです。

例えば「東京都」という単語を、

・東/京/都
・東/京都
・東京/都

のように、辞書に載っている単語で全ての組み合わせを検討し、コストが最小となる「東京/都」となるみたいです。

Ngram
---
Ngramも同じく、文章を分割するための手法ですが、形態素解析より至って単純です。

単語単位で区切った形態素解析とことなり、Ngramでは任意の連続したN文字単位で区切ります。
1文字で区切る"unigram"、2文字で区切る"bigram"、3文字で区切る"trigram"などが存在します。

例えば「たこ焼きが食べたい」という文章をunigram・bigram・trigramであらわすと、

unigram: た-こ-焼-き-が-食-べ-た-い
bigram: たこ-こ焼-焼き-きが-が食-食べ-べた-たい
trigram: たこ焼-こ焼き-焼きが-きが食-が食べ-食べた-べたい

となります。

形態素解析に比べて、辞書のアップデートが不要であったりするメリットがあったり、ノイズが多く含まれてしまうというデメリットがあったりします。

また、形態素解析と組み合わせて使うこともあります。

bag-of-words
---
文章は、どの単語がどこに出てくるか、そもそも文の構成はどうなっていたか、
など色々な要素で一つの文章として成り立っていますが、ひとまずそれらの構造は全て無視し、
「どの単語が含まれているか」のみに注目したのが、bag-of-wordsという考え方です。

そうして、出現したかどうかを0/1で表したり(One-Hot表現)や、
出現頻度としてベクトル化することで、機械学習などで分析することが可能になります。

<img width="800" alt="スクリーンショット 2017-06-29 9.45.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/185346/87330afb-e3ee-0846-df0b-9ac0ae9beea8.png">

まとめ
---
・日本語の文章は半角スペースで区切られていないため、分析前になんらかの分割処理が必要。

・"形態素解析"では、辞書を用いてコストが最小となるように文章を形態素に分割する。

・"Ngram"では、任意のN文字の連続として文章を分割する。

・"bag-of-words"では文章の構造は全て無視し、「どの単語が含まれているか」だけに注目する。

あとがき
---
形態素解析の例文として出てくる、今回も出てきた、「すもももももももものうち」。
初めて形態素解析してみた時本当にキッチリ分割してくれて、感動しました。笑

文章が文章として成り立っているものを分析するときは形態素解析で十分なのですが、
WEBサイトのテキストなど文章ではなくノイズの非常に多いものを分析するとき何かいい方法はないですかね。。
日々悩まされています。

ここまで読んでいただき、ありがとうございました！
TF-IDF

TF-IDF
===

今日も、機械学習やその他色々について得た知識を
復習and記事作成の練習and個人の備忘録としてまとめていきます！

今回は、TF-IDFという自然言語処理の分野でよく使われる手法について説明します！

⚠︎※※注意※※⚠︎  

・出来るだけ専門知識のあまりない人に対して、分かりやすく書くことを目標にしています。
　そのため、厳密に言うと間違っている部分があると思いますがご容赦ください。

・また、ネットで調べたレベルの知識がほとんどなので、
　"厳密に言うと"レベルではなく間違っている箇所があるかもしれません。。
　その場合は非常に申し訳ないです。指摘していただけると幸いです！

##### 参考サイト
[TF-IDFで文書内の単語の重み付け](https://takuti.me/note/tf-idf/)

##### 前回までの記事

・[機械学習について](http://qiita.com/AwaJ/items/950953a9c20f391e72cf)
・[教師あり学習　〜回帰〜](http://qiita.com/AwaJ/items/78de8b4738e87a57addd)
・[教師あり学習　〜分類〜](http://qiita.com/AwaJ/items/b769a5461e33ea8437a5)
・[Random Forest](http://qiita.com/AwaJ/items/3c02ff64b6a89e1a96f1)
・[階層型クラスタリング](http://qiita.com/AwaJ/items/ab43ce47817b3b864b9e)
・[非階層型クラスタリング k-means](http://qiita.com/AwaJ/items/1cd3eeef497c93a6a053)
・[主成分分析](http://qiita.com/AwaJ/items/1dcb703781349204213d)

TF-IDFとは
---
TF-IDFとは、Term Frequency(TF)と、Inverse Document Frequency(IDF)のことです。

文書の中から、その文書の特徴語を抽出する時に使う値です。

いくつかの文書があったときに、それらに出てくる単語とその頻度(Frequency)から、
ある文書にとって重要な単語はなんなのかというのを数値化します。

### TF

TFは、単語の文書内の出現頻度です。
ある文書中に出現する頻度が多ければ多いほど、その単語は重要である可能性が高い！というわけです。

```math
\textrm{tf}(t,d) = \frac{n_{t,d}}{\sum_{s \in d}n_{s,d}}
```
$\textrm{tf}(t,d)$ : 文書 $d$ 内のある単語 $t$ のTF値

$n_{t,d}$ : ある単語 $t$ の文書 $d$ 内での出現回数

$\sum_{s \in d}n_{s,d}$ : 文書 $d$ 内のすべての単語の出現回数の和

### IDF

IDFは、ある単語が出てくる文書頻度の逆数です。
多くの文書中に登場する単語は、一つの文書の特徴語にはなりにくいというわけです。

```math
\textrm{idf}(t) = \log{\frac{N}{df(t)}} + 1

```
$\textrm{idf}(t)$ : ある単語 $t$ のIDF値

$N$ : 全文書数

$df(t)$ : ある単語 $t$ が出現する文書の数

対数をとっているのは、文書数の規模が大きくなっても値があまり変化しないようにするためです。
また、１を足しているのは、全文書に登場する単語のTF-IDFが強制的に0になってしまうのを防ぐためです。

### 例

これらTFとIDFをかけあわせることによって、ある文書において、

その文書内での出現回数が多い(TFの値が大きい)　かつ、
他の文書であまり出てこない(DFの値が小さい＝IDFの値が大きい)　

という単語ほど、値が大きくなり、その文書を特徴付ける単語を抽出できるというわけです。

実際に計算してみましょう。

[文書A] スポーツ 野球　野球 バット
[文書B] サッカー サッカー サッカー スポーツ ゴール

という二文書があったとします。
たった二文書ですし簡易にするため、今回IDFは、

$\textrm{idf}(t) = \log{\frac{N}{df(t)}} + 1$ ではなく、 $\textrm{idf}(t) = \frac{N}{df(t)}$として考えます。

$\textrm{tf}(スポーツ,文書A)$ * $\textrm{idf}(スポーツ)$ = 0.25 * 1 = 0.25
$\textrm{tf}(野球,文書A)$ * $\textrm{idf}(野球)$ = 0.5 * 2 = 1.0
$\textrm{tf}(バット,文書A)$ * $\textrm{idf}(バット)$ = 0.25 * 2 = 0.5

$\textrm{tf}(サッカー,文書B)$ * $\textrm{idf}(サッカー)$ = 0.6 * 2 = 1.2
$\textrm{tf}(スポーツ,文書B)$ * $\textrm{idf}(スポーツ)$ = 0.2 * 1 = 0.2
$\textrm{tf}(ゴール,文書B)$ * $\textrm{idf}(ゴール)$ = 0.2 * 2 = 0.4

両方の文書に登場している「スポーツ」という単語のスコアは小さく、
自文書にしか登場しない、かつ出現回数の多い「野球」や「サッカー」といった単語のスコアが高くなっていることがわかります。

まとめ
---
・TF-IDFは、その文書の特徴語を抽出する時に使う値。

・TFは、Term Frequencyで文書内の出現回数。一つの文書内で出現する回数が多ければ重要である可能性が高い！

・IDFは、Inversed Document Frequencyで単語の出現文書数。多くの文書に出現している単語は重要である可能性が低い！

あとがき
---
シンプルかつ理にかなっている！僕はTF-IDFはなんだか結構好きです。笑

もちろん、文書の特徴語ってだけでなく、文書をカテゴリに分類した後に、カテゴリの特徴語みたいなのも同じく抽出できます！

ここまで読んでいただき、ありがとうございました！
Asset Bundle をビルドして Google Cloud Storage にアップロードする



[[Unity] Asset Bundle をビルドしてAWS S3 にアップロードする](http://qiita.com/tkyaji/items/3a7b92b4835bf671a754) を参考にして Google Cloud Storage にアップロードするエディタ拡張を作ってみた。

https://github.com/nirasan/unity-asset-bundle-upload-to-google-cloud-storage-example

# 使い方

* [ドキュメント](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount) を参考に Google のサービスアカウントを作成する
  * サービスアカウントとはスクリプトなどから GCP にアクセスするためのアカウント
  * サービスアカウントごとに秘密鍵が発行されその秘密鍵で署名された JWT によって認証を行う
  * サービスアカウントはプロジェクトに関連付けられるので必要であればここでプロジェクトも作成する
  * サービスアカウントには Google Cloud Storage の読み書き権限を付けておく
* P12 形式の秘密鍵をダウンロードする
  * パスワードは必要になるのでメモしておく
  * 秘密鍵は Assets 直下に保存する（他の場所に移動したい場合はスクリプトを更新する必要がある）
* Asset Bundle をアップロードするバジェットはあらかじめ作成しておく
* スクリプト中の "keyFile", "keyPassword", "email", "badgetName" を設定する
* メニューから "Build/Build AssetBundles And Upload GCS" を選択すると Asset Bundle のビルドとアップロードが実行される

# 補足

* JWT が正常に作れているかは [JWT公式サイト](https://jwt.io/) で確認することができる
* 発行されたアクセストークンの内容の確認は `https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ACCESSTOKEN` でできる
* `GoogleJsonWebToken.Create` で GoogleJWTPayload の scope を変更すれば他の GCP のサービスも利用できる
  * 利用できるスコープの一覧は https://developers.google.com/identity/protocols/googlescopes から確認できる

# 追記

* AssetBundle をダウンロードするのに `WWW.LoadFromCacheOrDownload` を使う場合はヘッダーを設定することができないためアップロード時のように認証用の JWT を指定することができない。
* そのため `WWW.LoadFromCacheOrDownload` を利用する場合は Google Cloud Storage 側でファイルの権限を全公開にする必要がある。
* ~~この対応については後ほど追記するが https://cloud.google.com/storage/docs/access-control/making-data-public に従って公開設定をすれば良さそう~~
* ファイルアップロード後にファイルの公開権限を全公開にするように変更した