OmniAICreator/Qiita-1.07M huggingface dataset:
Azure上に機械学習する環境を構築してみた

###AzureにVMデプロイ

これまで（機械学習test03まで)はローカルで動かしていたのだけれども、せっかくなのでAzureに環境構築してみました。

OSはcentOSの最新バージョン（CentOS-based 7.4）を選択。
<img width="1278" alt="スクリーンショット 2018-03-29 23.39.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/223989/8be93f27-9d69-dbb9-bbf7-af608d68f8b6.png">

基本設定に続いて、ずんずん進めていく。
<img width="1280" alt="スクリーンショット 2018-03-29 23.09.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/223989/21806aab-4d87-7b85-83c2-76462f5f880f.png">

ssh公開キーはあらかじめ取得しておく。
```$ ssh-keygen -t rsa
Generating public/private rsa key pair.
```

保存場所を聞かれるのでエンタ。
```Enter file in which to save the key (/Users/yuni/.ssh/id_rsa): ```

パスフレーズを入力。
秘密鍵を盗まれた時に、秘密鍵をすぐには使えないようにするのが目的みたい。
```Enter passphrase (empty for no passphrase): 
Enter same passphrase again: ```

作成されました。
id_rsa：秘密鍵
id_rsa.pub：公開鍵
```Your identification has been saved in /Users/yuni/.ssh/id_rsa.
Your public key has been saved in /Users/yuni/.ssh/id_rsa.pub.
The key fingerprint is:XXXXX```

sshでVMに接続。
（ssh公開キー取得時に設定したパスフレーズを忘れて、10回以上パスフレーズ入力した(汗)）
```$ssh <ユーザ名>@<VMのパブリック IP アドレス>
Enter passphrase for key '/Users/yuni/.ssh/id_rsa': 
[yuni@machinelearningvm ~]$```
接続できました。

###VM上にpythonの環境構築

VM上で実行。まずはリポジトリの追加
```[yuni@machinelearningvm ~]$ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm
```
python3.6のインストール
```[yuni@machinelearningvm ~]$ sudo yum install python36u python36u-pip python36u-devel```

#####ローカルに作ったファイルをVMにコピーしてみる
ローカルにたくさんファイル作ってたからねっ！
ローカルのtest.pyをVMにコピー（ローカルで実行）
```$ scp test.py <ユーザ名>@<VMのIP>:<VMの保存先path>```

ちなみに中身は、tensorflowでHello world。
```$ cat test.py
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!2nd')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(5)
print(sess.run(a+b))
```

これを動かすために、VMにtensorflowのインストール
```[yuni@machinelearningvm ~]$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.0.1-cp36-cp36m-linux_x86_64.whl
[yuni@machinelearningvm ~]$ pip install --ignore-installed --upgrade $TF_BINARY_URL
```

VMでtest.pyの実行
```[yuni@machinelearningvm ~]$ python3 test.py
Hello, TensorFlow!2nd
15
```
よくできました。パチパチ
「ポ」「プ」「テ」「ピピック」をランダムに出力して「ポプテピピック」が完成したら竹●房を破壊するC#

# 概要
[「ポ」「プ」「テ」「ピピック」をランダムに出力して「ポプテピピック」が完成したら竹●房を破壊するJavaScript](https://renidentia991.bitbucket.io/pptp.html)
をC# + WPF + Reactive Extensions で書いてみました。

C#でもすでに先達がおられる
https://qiita.com/ruhiel/items/c98451e4700344654f25

今回コンソールじゃなくてWPFにしたのはAAをきれいに表示するため。WinFormsでも同じようにできます。

# コード
AAは改行が含まれていてい直接コードに書きづらいので、Resourceに`Take`で登録しておきます。
NugetでReactive Extensions(System.Reactive)を導入します。

WindowのXamlではAAが正しく表示されるようTextboxのフォントを「MS PGothic」に設定しています。

```MainWindow.xaml
<Window
    x:Class="PopTeamEpicWpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="「ポ」「プ」「テ」「ピピック」をランダムに出力して「ポプテピピック」が完成したら竹●房を破壊するC#"
    Width="900"
    Height="600">
    <ScrollViewer>
        <TextBox
            x:Name="textBox"
            FontFamily="MS PGothic"
            FontSize="16"
            IsReadOnly="True"
            TextWrapping="Wrap" />
    </ScrollViewer>
</Window>
```

コードビハインドでは主に以下の2つを行っています。

- ランダムに「ポ」「プ」「テ」「ピピック」が流れてきて、「ポプテピピック」に一致したらCompleteするIObservableの生成
- それを購読してOnNextではそのまま、CompleteではAAをTextboxへ出力

注意点は一致判定のために`Buffer`でまとめている部分で、あえてBufferの長さを余分にしていることです。
これは一致した時の最後のOnNext「ピピック」を流すためです。

```MainWindow.xaml.cs
public partial class MainWindow : Window
{
    static string[] pops = new[] { "ポ", "プ", "テ", "ピピック" };

    public MainWindow()
    {
        InitializeComponent();

        CreateRandomPops()
            //Textboxにアクセスするので、UIスレッド上で購読
            .ObserveOn(this.Dispatcher)
            .Subscribe(
                //OnNextは流れてきた文字をそのままTextboxに書き足す
                x => this.textBox.Text += x,
                //CompleteしたらリソースからAAを取得してTextboxに書き足す
                () => textBox.Text += Properties.Resources.Take);
    }

    /// <summary>
    /// ランダムに「ポ」「プ」「テ」「ピピック」がOnNextに流れてきて、「ポプテピピック」に一致したらCompleteするIObservable
    /// </summary>
    private static IObservable<string> CreateRandomPops()
    {
        int maxCount = pops.Count();
        var random = new Random();
        IObservable<string> randomPop = Observable
            //10msecごとに
            .Interval(TimeSpan.FromMilliseconds(10))
            //ランダムに「ポ」「プ」「テ」「ピピック」のどれか
            .Select(_ => pops[random.Next(maxCount)]);
        //※テスト用　最初がいきなり「ポプテピピック」になる
        //.Select(i => pops[i % maxCount]);

        //バッファを空白で埋めておく (["","","","",""])
        return Observable.Repeat("", maxCount)
            .Concat(randomPop)
            //最後の「ピピック」をOnNextに流すために1つ余分にBufferをもつ
            .Buffer(maxCount + 1, 1)
            //Bufferの前が「ポプテピピック」に一致する状態(["ポ","プ","テ","ピピック",*])になるまで続行 
            .TakeWhile(x => !x.Take(maxCount).SequenceEqual(pops))
            //Bufferの最後をOnNextに流す  ([*,*,*,*,○]　の　○)
            .Select(x => x.Last());
    }
}
```

# 実行結果例

![スクリーンショット 2018-03-30 01.00.14.png](https://qiita-image-store.s3.amazonaws.com/0/120077/bb11ea56-ef48-892d-7cb0-70c7a70e3e9d.png)


# 参考
[Reactive Extensions再入門](http://blog.okazuki.jp/entry/20120305/1329923070)
https://qiita.com/amay077/items/85dfc4bd194f57c52c57#_reference-557477ce374f1a552c5c

# 環境
System.Reactive 3.1.1
VisualStudio2017
.NET Framework 4.7
C#7.1
起動スクリプト/停止スクリプトをサービス化

#1.起動スクリプト/停止スクリプトを作成する。
```startHoge.sh
#!/bin/bash
echo start-hoge >> /tmp/hoge.log
```

```stopHoge.sh
#!/bin/bash
echo stop-hoge >> /tmp/hoge.log
```

ここではサンプルのため「start-hoge」「stop-hoge」がファイルに出力されるものを作成する。

#2.実行権限を付与
```
chmod 777 startHoge.sh
chmod 777 stopHoge.sh
```
#3./etc/systemd/system/xxx.serviceに定義を設定
```
[Unit]
Description = hoge daemon
After=syslog.target network.target

[Service]
ExecStart = /home/startHoge.sh
ExecStop = /home/stopHoge.sh
Restart = no
Type = simple
User = user

[Install]
WantedBy = multi-user.target

```
ExecStartに起動スクリプト、ExecStopに停止スクリプトを設定する。

#4.確認１
systemctl list-unit-files --type=service | grep xxx.service を実行する。

以下が出力されればサービス登録できている。

```
xxx.service                      disabled
```

#5.確認２
systemctl start xxx.service
systemctl status xxx.service
systemctl stop xxx.service
AWS CLIでEC2のバックアップをとる

先日EC2インスタンスの定期バックアップスクリプトを組んだので、aws-cliコマンドのメモついでに公開。
セキュリティ面・エラー処理周りの実装があまいので流れとコマンドだけ。

## やりたい事
- ローカルや他サーバから特定のEC2インスタンスのバックアップをとる
- 世代管理をしたい
- 削除処理はAMI解除 → スナップショット削除とする


## 処理の流れ
1. AMIを作成する
	+ 名前は「ホスト名_日付」みたいな感じにしておく 
1. AMI名を利用して解除したいAMIのIDを取得する
	+ 世代数と日付の演算を利用して削除したいAMI名を決定する
1. AMIの解除をする
1. AMI_IDを使ってスナップショットのIDを取得
1. スナップショットを削除する

### 定期実行したい場合
- 管理サーバあたりのcronにセットしとくといいかも？
- Lambdaを利用した実装方法を模索しましたがデフォルトだとaws-cliを使えない(Lambda側)のでめんどくさいです

### 複数管理したい場合
- 名前の配列を用意して上記の流れをループさせればOK


## 使用するコマンド
### AMIの作成
```
$ aws ec2 create-image --instance-id --name AMI_NAME --no-reboot
```
※再起動してでも正確にバックアップをとりたい場合は「--no-reboot」を外す

### AMI_IDの取得
```
$ aws ec2 describe-images --owners self --query 'Images[?Name==`AMI_NAME`].[ImageId]|[0]|[0]' --output text
```

### AMI解除
```
$ aws ec2 deregister-image --image-id AMI_ID
```

### スナップショットIDの取得
```
$ aws ec2 describe-snapshots --owner-ids AWS_ACCOUNT_ID --query 'Snapshots[?contains(Description, `AMI_ID`)].[SnapshotId]' --output text
```

### スナップショットの削除
```
$ aws ec2 delete-snapshot --snapshot-id SNAPSHOT_ID
```
sympyあるある

独立した記事にするにもなあと思ったsympyの情報

## sqrt(x**2) = x (x > 0) とか

既に言及している記事があるように, `assumption`を指定すれば, よしなにしてくれる.

```python
>>> from sympy import symbols, sqrt
>>> from sympy.abc import x
>>> sqrt(x**2)
sqrt(x**2)
>>> y = symbols('y', positive=True)
>>> sqrt(y**2)
y
```

それ以外にも [`sympy.assumptions.refine.refine`](http://docs.sympy.org/latest/modules/assumptions/refine.html#sympy.assumptions.refine.refine) を使う方法もある.
こちらの方が自由度が高くて便利そう.

```python
>>> from sympy import refine, sqrt, Q
>>> from sympy.abc import x
>>> refine(sqrt(x**2), Q.real(x))
Abs(x)
>>> refine(sqrt(x**2), Q.positive(x))
x
```

```python
>>> from sympy import refine, Q
>>> from sympy.abc import x
>>> refine((-1)**x, Q.real(x))
(-1)**x
>>> refine((-1)**x, Q.even(x))
1
>>> refine((-1)**x, Q.odd(x))
-1
```

## 無理数の範囲での因数分解

[`sympy.polys.polytools.factor`](http://docs.sympy.org/latest/modules/polys/reference.html#sympy.polys.polytools.factor)を見る限り整数(`domain='ZZ'`)と有理数(`domain='QQ'`), 有理数係数の複素数?(`gaussian=True`)しかできない.

```python
>>> from sympy import sqrt, factor, solveset
>>> from sympy.abc import x
>>> factor(x**2 - 5, extension=solveset(x**2 - 5).args[0])
(x - sqrt(5))*(x + sqrt(5))
```

ということは出来ないこともないが, 意味や実用性は多分ない.

## 分数を期待しても小数が来る

[SymPy Tutorial > Two Final Notes: ^ and /](http://docs.sympy.org/latest/tutorial/gotchas.html#two-final-notes-and)

分数を期待して`/`を書いても右辺左辺共に`int`や`float`だと分数になりません.

```python
>>> from sympy import Rational
>>> 1/2
0.5
>>> Rational(1, 2)
1/2
```

`type`を見るとなんとなくわかるかも

```python
>>> from sympy import S, Rational
>>> type(1/2)
float
>>> type(Rational(1, 2))
sympy.core.numbers.Half
>>> type(S('1/2'))
sympy.core.numbers.Half
>>> type(S(1)/2)
sympy.core.numbers.Half
>>> type(1/S(2))
sympy.core.numbers.Half
```

思いついたら追記します.
プログラムど素人がWebdriverIOでChromeを動かす

# はじめに
前回はselenium + nodejsでChromeを動かしましたが、今回はWebdriverIOで動かしていきます。本稿ではwebdiverioでChromeを動かすのがメインになるので、細かいことは省略して最低限動かすだけに必要なことだけを記載します。

# 環境
* VSCode : 1.20.1
    * 拡張機能
        * npm commands for vscode : 3.3.0
* macOS : 10.13.2 

# npmでインストールするもの

* "chai": "^4.1.2",
* "chromedriver": "^2.37.0",
* "mocha": "^5.0.5",
* "wdio-chromedriver-service": "^0.1.2",
* "wdio-mocha-framework": "^0.5.13",
* "webdriverio": "^4.12.0"

# 下準備

まずはnpmでwebdriverioをインストールします。

```terminal:webdriverio
$ npm install --dev-save webdriverio
```

次に以下のパッケージをインストールします。
※自分はVSCodeの `npm commands for vscode`の`npm: install and save dev.dependency`というコマンドでインストールしていますが、以下はターミナルで叩くことを想定して記載しています。

```terminal:chrmedriver
$ npm install --dev-save chromedriver
```

```terminal:mocha
$ npm install --dev-save mocha
```

```terminal:chai
$ npm install --dev-save chai
```

あと少し。
以下のwebdriverに対応するためのパッケージをインストールします。

```terminal:wdio-chromedriver-service
$ npm install --dev-save wdio-chromedriver-service
```

```terminal:wdio-mocha-framework
$ npm install --dev-save wdio-mocha-framework
```

# 実際に動かすその前に
全パッケージのインストールがうまく行ったら `wdio.conf.js` というコンフィグファイルを設定していきます。
当該ファイルの`capabilities`の中身と `services` `port` `path` を追記すればChromeが起動できます。

```javascript:wdio.conf.js
exports.config = {
    capabilities: [{
        browserName: 'chrome',
        chromeOptions: {deviceName: 'Nexus 5X'}
    }],

    services: ['chromedriver'],
    port: '9515',
    path: '/'
}
```

# Chromeを実際に動かす！
とうとうChromeを動かします！
以下のコードを記述したjsファイルを`./tests/specs/`においてwdioコマンドを実行します。

```javascript:yahoo.js
const chai = require('chai');

describe("Yahoo Test", function(){
    it("Yahoo Search", function(){
        browser.url('https://www.yahoo.co.jp/');
        browser.element('input[name="p"]').addValue('Qiitaとは');
        browser.element('input[type="submit"]').click();
        browser.waitForExist('body',3000);
        
        chai.expect(browser.elements('span[class="smrArt"').getText()).to.include('Qiita');
    })
})
```

すると、Chromeがエミュレート状態で起動し、Yahooを開いた後キーワード検索を自動で行います。
検索結果の中に `Qiita` の文字があるかどうかを検証して終わります。

あとは、webdriveioのサイトでAPI Documentを見つつ、色々と動かしていきないと思います。
GCP上にRabbitMQを構築し管理画面へアクセスする

# 1. RabbitMQを構築
GCP Launcherから簡単にRabbitMQをGCE上にデプロイできます。
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/f6fbb0b7-3ff6-91a2-f1f6-f9722fdd9437.png)

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/119a0f94-29bb-acd2-3fab-93acde03c88e.png)

※念のためZoneは東京リージョン（asia-northeast1）を選択しておきます。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/f270cb01-9536-5a4b-1c46-7122ee727c8f.png)

以下のように正常にデプロイが完了すればOKです。
以下のキャプチャは名前が「rabbitmq-4」となっていますが、初めて作成する場合は「rabbitmq-1」になると思います。また、「Admin user」と「Admin password (Temporary)」はログインする時のID/PWになるので控えておきます。
![fafafa.png](https://qiita-image-store.s3.amazonaws.com/0/23101/132d08fb-9e68-975d-4882-a2a5e5ffdf0e.png)

# 2. SSHポートフォワードの設定（SSHトンネルの作成）
RabbitMQ bitnamiで構築した場合、SSHトンネルを作成しそれ経由で管理画面へアクセスすることが推奨されています。
[How To Connect To The RabbitMQ Management Panel?](https://docs.bitnami.com/google/infrastructure/rabbitmq/#how-to-connect-to-the-rabbitmq-management-panel)
>(Recommended): Access the RabbitMQ management panel through an SSH tunnel (refer to the FAQ for more information about SSH tunnels).

そのため、管理画面へアクセスするにはSSHトンネルを作成する必要があります。

### GCP側でSSHポートフォワードの設定

Cloud Shellを起動し、以下のコマンドを叩きます。

```
gcloud compute ssh example-instance --project my-project --zone asia-northeast1-a -- -L 2222:localhost:15672
```

* example-instanceは接続先のインスタンスの名前を指定します。
* my-projectは各自のGCPプロジェクトIDを指定します。
* asia-northeast1-aはインスタンスが稼働しているゾーンを指定します。
* 2222はリッスンするローカルポートを指定します。
* 15672は接続先のリモートポートを指定します（RabbitMQの管理画面のデフォルトポートは15672です）。

以下のように表示されればGCP側の設定は完了です。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/24bbbd3e-0af7-ea04-7e32-07ee88088873.png)

### ローカルの設定

まずは、事前に以下の設定(ローカルPCからGCPへSSH接続設定)を行う必要があります。
[PuTTYでGCPのインスタンスにSSH接続する](https://qiita.com/NagaokaKenichi/items/79f82c83a99830e9fd46)

上記が完了したら、「Connection」→「SSH」→「Tunnels」で以下のように設定します。
![sssa.png](https://qiita-image-store.s3.amazonaws.com/0/23101/a658398b-a879-85c0-3a4a-b4ad6c47c9e0.png)

Source portとDestinationは、「GCP側でSSHポートフォワードの設定」にてCloud Shell上で叩いた以下と合わせます。

```
-L 2222:localhost:15672
```

Source portとDestinationを入力したら「Add」ボタンを押下します。
以下のようなメッセージが出てきたら「はい」を選択します。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/23101/2cdf4f55-5e2e-ee43-765d-8624cb11aa6a.png)

以下のように接続が成功すればローカル側の設定完了です。
![sssssssssa.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/34941c75-1f5c-e3bc-96a3-d4df9d2e6651.png)
上記が確認できても、PuTTYは閉じないでください。PuTTYを閉じてコネクションを切断するとアクセスできなくなります。

# 3. 動作確認
ブラウザで「http://localhost:2222/」 へアクセスします。
以下のように管理画面が表示されれば成功です。
![aaa.png](https://qiita-image-store.s3.amazonaws.com/0/23101/735a46c7-3a0c-2f0c-0344-311ed241c394.png)

実際にログインしてみます。UsernameとPasswordはRabbitMQ構築時に控えていたものを利用します。
![fafafa.png](https://qiita-image-store.s3.amazonaws.com/0/23101/9855ac00-1b75-211c-0191-6c34d05dce75.png)

以下のようにOverviewが表示されればログイン成功です。
![asasa.png](https://qiita-image-store.s3.amazonaws.com/0/23101/e0bd8ca6-175f-6c36-bc32-33278b0fd0dc.png)

以上です。

# 参考
* [Bitnami RabbitMQ For Google Cloud Platform](https://docs.bitnami.com/google/infrastructure/rabbitmq/)
* [SSH 上のポート転送](https://cloud.google.com/solutions/connecting-securely?hl=ja#port-forwarding-over-ssh)
[XcodeTip]ワンライナーでxcodeprojとxcworkspaceを開き分ける

# はじめに
Cocoapodsを使っているとxcworkspaceから開かなければいけませんが、
そうでない場合はxcodeprojを開かなければいけません。
どっちを開くんだっけと迷っている時間、勿体なくないですか？
ということで、ワンライナーで開き分けるコマンドを自作しました！

# レシピ

## zshの方
`~/.zshrc`にこれを記述してください。

```zsh
function openxc() {
    if [ -e *.xcworkspace ]; then
        open *.xcworkspace
    elif [ -e *.xcodeproj ]; then
        open *.xcodeproj
    else
        echo "xcode file does not exist."
    fi
}
```

記述したら`~/.zshrc`をして読み込み直しましょう。

## zsh以外の方

### 1. 下準備
シェルスクリプトを追加するディレクトリにパスが通っているか確認します。
以下のパスをいい感じに出力してくれるコマンドを実行し`/usr/local/bin`にパスが通っているかを確認します。
`/usr/local/bin`が表示されれば大丈夫です。

```bash
echo $PATH | perl -pe 's/:/\n/g'
```

### 2. ファイルの配置
/usr/local/binに`openxc`という名前で以下のファイルを置きましょう。

```bash:openxc
#!/bin/sh

if [ -e *.xcworkspace ]; then
    open *.xcworkspace
elif [ -e *.xcodeproj ]; then
    open *.xcodeproj
else
    echo "xcode file does not exist."
fi
```


### 3.実行権限を与える
ファイルを置いただけだとターミナルで実行することが出来ないので、以下のコマンドで権限を与えます。

```bash
chmod a+x /usr/local/bin/openxc
```

---
以上の３ステップで実装は完了です！
Xcodeのプロジェクトが置いてある場所で`openxc`と入力して実行するとプロジェクトをワンライナーで開き分けることができます！

# おまけ
最近ハッカソンでメリーさんというホラーゲームを作りました。
メリーさんが迫ってくるので巧みなセリフでメリーさんを惚れさせて退散させたらクリアです。
リンクは[こちら](https://itunes.apple.com/jp/app/%E3%83%A1%E3%83%AA%E3%83%BC%E3%81%95%E3%82%93/id1355473554?mt=8)
Google Homeを遊びたおす会いってきたよ



Google Home買ったはいいけれど、
買ったそのまま使っています。
赤外線の学習リモコンでいろいろしたかったれど、失敗したくないし、でもいろいろ調べるの面倒だし、、
でもGoogleHomeで家電を操作したりしたかったのですよね。

そんな折、こんな勉強会に突然出会いました。
**Google Homeを遊びたおす会**
https://kotodama.connpass.com/event/79768/
内容をみると

```
Google Homeを使ってスマートじゃない家電を音声操作したり、
Google Assistantアプリを作ってみたりと
Google Homeを遊びたおしてみようという会です！
```
めちゃくちゃ楽しそうー！
ということで行ってきました。

## Google Homeでつくるスマートホーム 
個人的にはこれがいっちゃん気になるお話しでした。

この記事を書いた方らしく、相当なことをやっておられる。
https://qiita.com/miso_develop/items/99624915d3d6e41a5fb3
ちなみに登壇者の田中みそさん、GoogleHome購入を機にITにめざめたらしい...
（エンジニアではないのか?）
予想通り話は楽しかった。

お話しされてた内容のスライドはこちら
https://speakerdeck.com/player/7c2dcf717eb94a77a1d1e1ad51184817#

もう、僕がここに書くより、ぜひ上記2つのURLを読んでほしい。

赤外線リモコンは、eRemote miniつかってるとのこと。
7000円切ってる。
https://www.amazon.co.jp/dp/B01MA4W1YD
こんなやすいのでいいんだ。買おうかな〜

## Actions on Googleでできること
サーバーからの応答を会しさせたかったらActions on Google使った方が良さそうっすね。
IFFFTだとできないみたいだし。
話されていた内容はこちらに書かれてます。
https://docs.google.com/presentation/d/1uisVtlrBxOrlB4E1j3sFjJ3CgW_xJDFOzQpp5gK-1AA/edit#slide=id.p

サンプルコードとかも載ってていい感じです

## Dialogflow tips
何気にこのお話も気になってました。
こちらもスライド公開してくれてるのでURL貼っておきます。
https://www.slideshare.net/tsudakyohei/dialogflow-tips

めちゃくちゃ簡単に作れるGoogleHomeアプリの作り方とかも教えてくれたので、
非常に初心者にも優しい内容でよかったですね。

またイベントがあれば、ぜひまた行きたい。
PHPで簡単なページ内検索の作り方

小さな掲示板を作成し、そこでスレッドの検索機能が必要と感じたため、実際に検索機能を実装して見ました。
<h1>検索機能の実装</h1>


必要知識
- MySQL
- PHP
MySQLに登録したデータをLIKE句を使用して検索していきます。
事前にいくつか登録したデータを出力しておきます。
<img width="409" alt="スクリーンショット 2018-03-29 22.54.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/d2c15917-ee58-b22d-40a4-814fa288dd72.png">

```php:index.php
<?php
 ini_set('display_errors',1);
 require_once('db_info.php');

if (isset($_GET['search'])) {
  $search = htmlspecialchars($_GET['search']);
  $search_value = $search;
}else {
  $search = '';
  $search_value = '';
}
 $sql = "SELECT * FROM 画像 where nam LIKE '%$search%' order by ban";
 $stmt = array();
 foreach ($db->query($sql) as $row) {
   array_push($stmt,$row);
 }
 ?>
 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8">
     <title>記事の検索</title>
   </head>
   <body>
     <form action="" method="get">
       <p>記事の検索</p>
       <input type="text" name="search" value="<?php echo $search_value ?>"><br>
       <input type="submit" name="" value="検索">
     </form>
     <?php foreach ($stmt as $key): ?>
       <p><strong>記事の名前</strong><br>
         <?php echo $key['nam'] ?><br>
         <?php echo $key['dat']; ?></p>
     <?php endforeach; ?>
   </body>
 </html>

```
中はこのようなコードになっております。
LIKE句を使用して文字列の一致を検索してきます。
input type="text" name="search" value=""
の部分にもじが入っていれば＄_GET['search']で文字を取得し$searchに格納します。

そしてLIKE %$search%の部分で部分一致検索をします。
入力した文字と一致すればtrue 一致しなければfalseを返してくれます。

実行例
<img width="326" alt="スクリーンショット 2018-03-29 23.23.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/240422/0dfe46f3-e790-5cb1-891d-561f90045eaa.png">
UnityでスクリプトからUVを操作する

#初めに
　例えば、キャラクタの表情をテクスチャで貼って、UV座標を変更することで表情を変える、というようなケースがあるかと思います。最近、このようなものに取り組んでいたのですが、自分が引っ掛かった点をご紹介いたします。

1.ボーンの入ったキャラクタはSkinnedMeshRendererのsharedMeshを使う。
2.インスタンス化したsharedMeshを使う。
という２点です。

#MeshRendererがアタッチされているオブジェクトの場合
　例えば、CubeのようなプリミティブをUnityのエディタ上で作成すると、このようにMesh FilterとMeshRendererが自動的にアタッチされています。![201803282220.png](https://qiita-image-store.s3.amazonaws.com/0/245844/cb9e76c7-abac-500f-a82a-cccff3f46e0b.png)
　この場合は、MeshFilterコンポーネントからmeshを取得することができます。meshクラスのメンバにUVがVector2の配列として定義されているので、それを操作すればよいです。

```C#:meshUV.cs
一部抜粋
private Mesh myM;
void Start () {
        myMesh = gameObject.GetComponent<MeshFilter>().mesh;
}
void Update(){
        Vector2[] nUV = myMesh.uv;
        for (int i=0; i < myMesh.uv.Length; i++)
        {
            nUV[i].x *= 0.99f;
            nUV[i].y *= 0.99f;
        }
        myMesh.uv = nUV;
}
```
![201803282256.png](https://qiita-image-store.s3.amazonaws.com/0/245844/99d9d9be-9517-7ffa-9665-b6b6b98ba380.png)
![201803282257.png](https://qiita-image-store.s3.amazonaws.com/0/245844/7420834d-a457-8c64-1dbe-28703dc4ecab.png)
このように貼られたテクスチャが変化していきます。

#SkinnedMeshRendererがアタッチされているオブジェクトの場合
　多くの場合、キャラクターとして使用したいオブジェクトはボーンで動かすものです。例えば、キャラクターのFBXファイルをインポートして、そのメッシュオブジェクトを見ると、先ほどのMeshFilterやMeshRendererは見当たりません。![201803282242.png](https://qiita-image-store.s3.amazonaws.com/0/245844/aeedd1e9-b67a-af10-e4cd-c0dbd1cb74ca.png)
よって、先ほどのように、MeshFilterのMeshからUVを操作することはできません。
そのかわり、ボーンで変形されるキャラクタでは、このSkinnedMeshRendererが用いられます。SkinnedMeshRendererからSharedMeshを取得することができ、このSharedMeshのメンバにUVがあるので、それを操作します。

```C#:meshUV.cs
    private Mesh myM;
    private Mesh Imesh;
    // Use this for initialization
    void Start()
    {
        myMesh = gameObject.GetComponent<SkinnedMeshRenderer>().sharedMesh;
    }

    // Update is called once per frame
    void Update()
    {
        Vector2[] nUV = myMesh.uv;
        for (int i = 0; i < myMesh.uv.Length; i++)
        {
            nUV[i].x *= 0.99f;
            nUV[i].y *= 0.99f;
        }
        myMesh.uv = nUV;
    }
```

ところが今回は、このようにUVを操作すると問題が起きます。
UVを操作できるのですが、スクリプトを実行して一度UVを変更してしまうと、実行を停止しても元には戻りません。先ほどのCubeの場合は停止して再実行するとスクリプトによるUVの変更がリセットされているのですが、SkinnedMeshRendererの場合はそうはいかないようです。

#インスタンス化したものを使用することで、元のデータを操作せずに保存しておく
　そこで、先ほどのスクリプトに少し手を加えます。

```C#:meshUV.cs
    private Mesh myM;
    private Mesh Imesh;
    // Use this for initialization
    void Start()
    {
        myMesh = gameObject.GetComponent<SkinnedMeshRenderer>().sharedMesh;
        Imesh = Instantiate(myMesh);
        gameObject.GetComponent<SkinnedMeshRenderer>().sharedMesh = Imesh;
    }

    // Update is called once per frame
    void Update()
    {
        Vector2[] nUV = Imesh.uv;
        for (int i = 0; i < Imesh.uv.Length; i++)
        {
            nUV[i].x *= 0.99f;
            nUV[i].y *= 0.99f;
        }
        Imesh.uv = nUV;
    }
```
sharedMeshをInstantiate()でインスタンス化して、sharedMeshの参照先をインスタンスに変更します。
こうしてから、インスタンスを操作すれば先ほどのような問題は起こらず、実行を停止すれば、UVへの変更はリセットされます。
　余談ですが、これで、UVだけでなく頂点も弄り放題です。
　また、UVを変更する場合に限らず、色々な場合に応用できると思われます。
JavaScriptのもう少し奥地へ行くよ

[1.あなたのコードで決定を下す — 条件](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/conditionals)←ifとelseを学んだ。
[2.ループコード](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Looping_code)

```ループの擬似コード.js
ループ(食料 = 0; 必要な食料 = 10) {
  if (食料 = 必要な食料) {
    ループを終了;
    // 十分な食料が集まりました。家に帰りましょう
  } else {
    食料 += 2; // 1 時間経って 2 つの食料を集めました
    // ループはさらに続きます
  }
}
```
VagrantでMailCatcher環境構築(CentOS6 + PHP)

## 全体の流れ
1. Ruby2系を入れる
1. GemでMailCatcherを入れる
1. PHPで動くように設定
1. VagrantのIPを指定して起動

## Ruby2系のインストール
標準リポジトリではRuby1.8が入ってしまうためRHSCLを利用する
rbenvを使おうかと思ったが設定周りで事故りそうなので今回はRHSCLを利用する事にする

### RHSCLからRuby2.3をインストールしPATHを通す
```
# yum install centos-release-scl
# yum install rh-ruby23 rh-ruby23-ruby-devel
# ln -s /opt/rh/rh-ruby23/enable /etc/profile.d/rh-ruby23.sh
```

### PATHが通ってるか確認
```
# ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux-gnu]
```
## GemでMailCatcherをインストール
MailCatcherをインストールするにはまだ必要な物があるため引き続きyumでインストール

```
# yum install gcc gcc-c++ sqlite-devel
```

必要な物が揃ったのでMailCatcherをインストール

```
# gem install mailcatcher
```

## PHPで動くように設定
php.iniのmail関連の設定を下記のように変更(hostやportはライブラリ側で設定しても良い)

```
SMTP = 127.0.0.1
smtp_port = 1025
sendmail_from = no-reply@example.com
sendmail_path = /usr/bin/env /opt/rh/rh-ruby23/root/usr/local/bin/catchmail
```

## VagrantのIPを指定して起動
```
# mailcatcher --http-ip 192.168.33.10
```
確認
http://192.168.33.10:1080
現場で活躍しそうなVBS

## 現場で活躍しそうなVBS

### Part1 ファイルパス、ファイルネーム編

実務なので少し役に立ちそうなのでメモ

現場では見れないブログが多いので有益なブログに記載されているコードを
引用しております。

###### win10 ファイル絶対パスをクリップボードへコピー
```vbs

Set WshShell = Wscript.CreateObject("WScript.Shell")

Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")

strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )

objHandle.Write Wscript.Arguments(0)

Set WshShell = Wscript.CreateObject("WScript.Shell")

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )

```


###### win10 ファイルネームをクリップボードへコピー

```VBS
Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")


strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )

strName = Wscript.Arguments(0)

aPath = Split(strName,"\")

strName = aPath(Ubound(aPath))

objHandle.Write strName

Set WshShell = Wscript.CreateObject("WScript.Shell")

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )
```

###### win10 複数のファイルパスをクリップボードへコピー


```VBS

Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

str = ""

For I = 0 to Wscript.Arguments.Count-1

aData = Split( Wscript.Arguments(I), "\" )

str = str & aData(Ubound(aData)) & vbCrLf

Next

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")

strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )

objHandle.Write str

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )
```


## 引用先

[logical error様](http://logicalerror.seesaa.net/article/118290363.html)
ランダム出力でポプテピピック

# 元ネタ
- [「ポ」「プ」「テ」「ピピック」をランダムに出力して「ポプテピピック」が完成したら竹●房を破壊するJavaScript](https://renidentia991.bitbucket.io/pptp.html)



```csharp
List<string> pptp = new List<string>(){"ポ", "プ", "テ", "ピピック"};
Random r = new Random();

Queue<string> queue = new Queue<string>();
Queue<string> resultQueue = new Queue<string>();
	
IEnumerable<string> PPTP(Random r)
{
	while(true)
	{
		yield return pptp[r.Next(pptp.Count)];
	}
}
void Main()
{

	foreach(var elem in PPTP(r))
	{
		queue.Enqueue(elem);
		resultQueue.Enqueue(elem);
		if(queue.Count >= 4)
		{
			if(queue.Zip(pptp, (first, second) => first.Equals(second)).All(x => x))
			{
				Console.WriteLine(resultQueue);
				break;
			}
			queue.Dequeue();
		}
	}
}
```
GBDKによるゲームボーイソフト制作-2回 文字を出してみる-

前回：[GBDKによるゲームボーイソフト制作-1回 Hello World!-](https://qiita.com/blackpman/items/621d6967b190eeb6f2f9)
次回：[GBDKによるゲームボーイソフト制作-3回 キー入力-](https://qiita.com/blackpman/items/a80fd75b3de9e91d06cd)
## 記事の内容
gbdk\examples\gb内の「filltest.gb」を参考に色々と試してみたのでその記録。
## ソースコード
実際に書いたのは以下のようなプログラム。

```C++:draw_char.c
#include <gb/drawing.h>

void main() {
	UBYTE i,x,y;

	for (i = 0; i < 256; ++i) {
		y = i / 16;
		x = i % 16;
		gotogxy(x, y);
		color(3, 1, SOLID);
		gprintf("%c", i);
	}
}
```

## 実行結果
![result.png](https://qiita-image-store.s3.amazonaws.com/0/246149/6218523c-54b4-5d78-981a-77e106c631f6.png)

## 解説のようなもの
### 1行目
今回使う機能は「gb/drawing.h」内で定義されているため、includeする。
### 4行目 UBYTE
「UBYTE」という型は、「gbdk\include\asm\types.h」で以下の通り定義されている。

```C++
/** Unsigned 8 bit.
 */
typedef UINT8        	UBYTE;
```

つまり、8ビット（0～255）の符号なし整数ということである。
BYTEとしてるのは8bitが1Byteだからかな？
### 8行目 gotogxy
この関数は「gb/drawing.h」で以下のように定義されている。

```C++
/** Sets the current text position to (x,y).  Note that x and y have units
   of cells (8 pixels) */
void
	gotogxy(UINT8 x, UINT8 y);
```

#### ざっくり意訳
テキストが描画される位置を設定する。
引数x,yは8ピクセル単位での座標を意味する。

ゲームボーイの画面解像度は160x144なので、8ピクセルの塊が横に20（0～19）,縦に18（0～17）入ることになる。

### 9行目 color
この関数もまた「gb/drawing.h」で以下のように定義されている。

```C++
/** Set the current foreground colour (for pixels), background colour, and
   draw mode */
void	color(UINT8 forecolor, UINT8 backcolor, UINT8 mode);
```

#### ざっくり意訳
前景及び背景の色と描画モードを設定する。

色の指定はUINT8（8ビット符号なし整数）で定義されているが、ゲームボーイの描画色は白黒の4階調であるため、実際に取り得る値の範囲は0～3である。
第三引数のmodeは以下の指定ができるが、筆者が試した限り変化がなかったので何か使い方があるのだろう。

```C++
	#define	SOLID	0x00		/* Overwrites the existing pixels */
	#define	OR	0x01		/* Performs a logical OR */
	#define	XOR	0x02		/* Performs a logical XOR */
	#define	AND	0x03		/* Performs a logical AND */
```

### 10行目 gprintf
今回のメイン。
この関数もまた「gb/drawing.h」で以下略。

```C++
/** Print the formatted string 'fmt' with arguments '...' */
INT8	
	gprintf(char *fmt,...) NONBANKED;

```

#### ざっくり意訳
フォーマット指定文字列fmtに従って以降の引数で渡された内容を描画する。

簡単に言うとprintfのゲームボーイ版みたいなものだと思う。たぶん。
今回、変数iを0～255までループさせているので、その数字に対応した文字が描画されている。

ということで今回はこれでおしまい。
Google Apps ScriptからJDBCでAzue SQL Databaeにつないでみた

大体これ通りやるとできます。一瞬詰まったので書いておく。
https://developers.google.com/apps-script/guides/jdbc

Azure SQL DatabaeへのアクセスはApps Script's IP addessesから行われるのでIP制限を外す。

``` これ
64.18.0.0 - 64.18.15.255
64.233.160.0 - 64.233.191.255
66.102.0.0 - 66.102.15.255
66.249.80.0 - 66.249.95.255
72.14.192.0 - 72.14.255.255
74.125.0.0 - 74.125.255.255
173.194.0.0 - 173.194.255.255
207.126.144.0 - 207.126.159.255
209.85.128.0 - 209.85.255.255
216.239.32.0 - 216.239.63.255
```

次に接続文字列をJDBCコピーする。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/25104/1dd6b1e9-29aa-91fe-9e22-1c283e1f8af4.png)

```
jdbc:sqlserver://SERVER_NAME.database.windows.net:1433;database=DATABASE_NAME;
```

このオプションは使えないので消す。
user
encrypt
trustServerCertificate
hostNameInCertificate
loginTimeout

ズバリこう

``` jdbcToSqldatabae.gs
// Replace the variables in this block with real values.
var address = 'SERVER_NAME.database.windows.net:1433;databaseName=DATABASE_NAME;';
var user = 'USER_NAME@SERVER_NAME'; // User
var userPwd = 'PASSWORD';

var dbUrl = 'jdbc:sqlserver://' + address;

// Read up to 1000 rows of data from the table and log them.
function readFromTable() {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);

  var start = new Date();
  var stmt = conn.createStatement();
  stmt.setMaxRows(1000);
  var results = stmt.executeQuery('SELECT * FROM [SalesLT].[Address]');
  var numCols = results.getMetaData().getColumnCount();

  while (results.next()) {
    var rowString = '';
    for (var col = 0; col < numCols; col++) {
      rowString += results.getString(col + 1) + '\t';
    }
    Logger.log(rowString)
  }

  results.close();
  stmt.close();

  var end = new Date();
  Logger.log('Time elapsed: %sms', end - start);
}

```

でもこれだとGoogle Apps Scriptからだと入り放題なんだよねー
Raspberry Pi 3をUSBメモリから起動できるように設定する

# はじめに

このコマンドを実行すると、USB機器から起動することができます。

# Raspberry PiをUSBメモリから起動できるように設定する

```shell
$ echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
$ vcgencmd otp_dump | grep 17:
```
`17:3020000a`と表示されていればOKです。

参考：[How to boot from a USB Mass Storage Device on a Raspberry Pi 3 - Raspberry Pi Documentation ](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)

# 終わりに

## USBメモリから起動するためには？
1. microSDカードを抜く
2. USBメモリを挿しておく
3. 起動
4. ちょっと待つ（microSDカードの起動より少々時間かかる）

## microSDから起動するには、いつもどおりのやり方で切り替わります。
1. microSDカードを挿しておく
2. 起動
3. 待つ
LambdaでEC2(Classic)のElasticIP固定

EC2(Classic)の起動/停止自動化で詰まった問題(EC2のElasticIPが割当解除される)とその解決方法を共有します。

## １．EC2のIPアドレス
EC2には、グローバルIPとプライベートIPという2つのIPアドレスが割振られています。
　・グローバルIP：インターネットから参照可能なIP
　・プライベートIP：AWS同一リージョン内で参照可能なIP

プライベートIPは常に変わりませんが、グローバルIPはEC2停止の度に変更されます。
かといってEC2を起動しっぱなしにしては1日中課金され続けます。EC2+ストレージの費用はなかなかの金額です、、
そのため、AWSには**ElasticIP**というグローバルIPを固定するサービスが用意されています。

## ２．ElasticIP
ElasticIPは、固定のグローバルIPを発行/割当できるAWSサービスです。
これによりEC2が停止する度にグローバルIPの変更を避けられます。
ところがEC2のプラットフォームによりElasticIPは効果がなくなります。料金もほぼ無料です。

## ３．EC2のプラットフォーム
EC2には、「EC2-Classic」「EC-VPC」というプラットフォームがあります。
　・EC2-Classic：リージョン内に構築されるEC2
　・EC2-VPC：EC2内の特定のネットワークに構築されるEC2
ElasticIPはどちらのプラットフォームでも使用可能です。
以下の図では１～４がClassic、５～６がVPCです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/174816/ecccd2a6-502e-5534-88bc-ec07e81a71c9.png)

ところが、**EC2-ClassicではEC2停止時にElasticIP割当が解除されます。**
グローバルIPの固定が目的なのに、結果的グローバルIPは変わってしまいます。


## ４．LambdaでElasticIP割当
そこで考えた対策は、**LambdaによるElasticIP自動割当**です。
LambdaでEC2自動起動＋ElasticIP割当まで行いました。
※ソースコードは以下ブログのコードを参考にさせていただきました。
Lambdaなど詳細は以下参考ください。
https://dev.classmethod.jp/cloud/aws/simple-auto-start-stop-for-ec2/

```python
import boto3

def lambda_handler(event, context):
    region = event['Region']
    instances = event['Instances']
    ec2 = boto3.client('ec2', region_name=region)
    if event['Action'] == 'start':
        ec2.start_instances(InstanceIds=instances)
        ec2.associate_address(
            InstanceIds=instances,
            PublicIp='XX.XXX.XXX.XXX',
        )
        print 'started your instances: ' + ", ".join(instances)
    elif event['Action'] == 'stop':
        ec2.stop_instances(InstanceIds=instances)
        print 'stopped your instances: ' + ", ".join(instances)
```
以下がグローバルIP割当部です。  
XX.XXX.XXX.XXXの部分に直接ElasticIPで発行した固定IPを記入ください。  

```python
ec2.associate_address(
            InstanceIds=instances,
            PublicIp='XX.XXX.XXX.XXX',
        )
```

これでEC2-ClassicでもグローバルIPの固定化が実現できました。
Hyper-VでCentOS7をインストールできない 

初めてHyper-Vを使ってCentOS7をインストールしようとしたらインストールメディアを認識してくれなかった。

■状況
世代：第二世代
ブート：DVDドライブ

■解決策
設定のセキュリティから
「セキュア　ブートを有効にする」のチェックを外す
または
テンプレートを「Microsoft UEFI証明書機関」にする

■参考
Running CentOS 7 on a gen2 VM in Hyper-V – vNiklas Cloud and Automation blog : https://vniklas.djungeln.se/2014/06/27/running-centos-7-on-a-gen2-vm-in-hyper-v/
Windows10でクライアントHyper-Vを使ってみる。セキュアブートの無効化は忘れずに！ | あいしんくいっと : https://i-think-it.net/windows10-hyper-v-1/
flask wsgi を paste-deploy 経由で uwsgi にデプロイする例



```hoge.py
from flask import Flask

app = Flask(__name__)

@app.route("/", methods=["GET"])
def hoge():
        return "OK"

def factory(gconf, **conf):
        return app.wsgi_app
```

```ini:wsgi.ini
[uwsgi]
http = 9000
threads = 4

[app:main]
use = call:hoge:factory
```

```bash
PYTHONPATH=. uwsgi --ini-paste wsgi.ini
```
lombokとJSONICでJSONHintアノテーションが動作しない場合の対処

JSONICとlombok併用時に```@JSONHint```アノテーションが上手く動作しなかったので、その回避策に関するメモ。

# 使用バージョン

```xml
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
</dependency>

<dependency>
    <groupId>net.arnx</groupId>
    <artifactId>jsonic</artifactId>
    <version>1.3.10</version>
</dependency>
```

# 現象と回避策

サンプルとして以下の形式の日付文字列を含むJSONをパースしたい、とする。

```java
String json = "{dateTime: \"2018-03-29T11:22:33.123+09:00\"}";
SampleData s = JSON.decode(json, SampleData.class);
```

lombokを使用するクラスはこんな感じ。

```java
import java.time.LocalDateTime;

import lombok.Data;
import net.arnx.jsonic.JSONHint;

@Data
public class SampleData {
	@JSONHint(format="yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ")
	private LocalDateTime dateTime;
}
```

これは以下のような例外となり```@JSONHint```アノテーションが有効になっていないことがわかる。

```
Exception in thread "main" net.arnx.jsonic.JSONException: {dateTime=2018-03-29T11:22:33.123+09:00} は class asdf.asdfasd.SampleData に変換できませんでした: $.dateTime
	at net.arnx.jsonic.JSON$Context.convertInternal(JSON.java:1775)
	at net.arnx.jsonic.JSON.parse(JSON.java:1155)
	at net.arnx.jsonic.JSON.parse(JSON.java:1130)
	at net.arnx.jsonic.JSON.decode(JSON.java:665)
	at asdf.asdfasd.App.main(App.java:15)
Caused by: java.time.format.DateTimeParseException: Text '2018-03-29T11:22:33.123+09:00' could not be parsed, unparsed text found at index 23
	at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1952)
	at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
```

これの原因だが、https://ja.osdn.net/projects/jsonic/ticket/35184 にJSONICはgetter/setterがある場合はそちらのアノテーションを優先する、とある。lombokはgetter/setterを自動生成するが、そちらには```@JSONHint```が無いので、このような状況になる。

というわけで回避策として、対象のプロパティについては自前でgetter/setterを定義してしまうことにした。

```java
@Data
public class SampleData {
	/* このプロパティのgetter/setterは不要なので自動生成を抑制 */
	@Getter(AccessLevel.NONE)
	@Setter(AccessLevel.NONE)
	private LocalDateTime d;

	public LocalDateTime getDateTime() {
		return d;
	}

	@JSONHint(format="yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ")
	public void setDateTime(LocalDateTime dateTime) {
		this.d = dateTime;
	}
}

```
Let's Encrypt で acme.sh を使って ACME v2 でワイルドカード証明書を取得する

ググると日本語の記事もいくつも出てきて、最新のだと 1 ヶ月ほど前の記事（2018年2月末とかの記事）なので倣ってやってみたらうまくいきませんでした。この記事もすぐに古くなる可能性があります。

最初、普段使っている getssl.sh でやろうとしたけど、まだワイルドカード証明書に対応してないらしくしばらくハマってました（ACME v2 には対応済み）。

acme.sh というのが対応してるらしいので、こちらで（certbot は嫌いw）。

```
curl https://get.acme.sh | sh
```

でインストール。ぐぐってやってみたけど、今はマニュアルでの DNS 経由の取得だと `--yes-I-know-dns-manual-mode-enough-go-ahead-please` というオプションが必要な模様（先月の記事をみる限りは不要だったみたいなのですぐ変わってるかも）。

まずはテストで staging で発行。

```
$ acme.sh --test --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --issue -d *.hoge.example.com
  : (snip)
[2018年  3月 29日 木曜日 20:39:29 JST] Add the following TXT record:
[2018年  3月 29日 木曜日 20:39:29 JST] Domain: '_acme-challenge.hoge.example.com'
[2018年  3月 29日 木曜日 20:39:29 JST] TXT value: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  : (snip)
```

このレコードを DNS サーバに追加します（ここは手動です。手順は省略）。ここだと `_acme-challenge.hoge.example.com` の TXT レコードの値を `XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` に設定します。

```

$ dig _acme-challenge.hoge.example.com txt
  : (snip)
;; ANSWER SECTION:
_acme-challenge.hoge.example.com. 86008 IN TXT "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

  : (snip)
```

これを確認してから、`-renew` で発行します。

```
$ acme.sh --yes-I-know-dns-manual-mode-enough-go-ahead-please --renew -d *.hoge.example.com
[2018年  3月 29日 木曜日 20:40:34 JST] Renew: '*.hoge.example.com'
[2018年  3月 29日 木曜日 20:40:36 JST] Single domain='*.hoge.example.com'
[2018年  3月 29日 木曜日 20:40:36 JST] Getting domain auth token for each domain
[2018年  3月 29日 木曜日 20:40:36 JST] Verifying:*.hoge.example.com
[2018年  3月 29日 木曜日 20:40:40 JST] Success
[2018年  3月 29日 木曜日 20:40:40 JST] Verify finished, start to sign.
[2018年  3月 29日 木曜日 20:40:42 JST] Cert success.
  : (snip)
[2018年  3月 29日 木曜日 20:40:42 JST] Your cert is in  /home/hoge/.acme.sh/*.hoge.example.com/*.hoge.example.com.cer 
[2018年  3月 29日 木曜日 20:40:42 JST] Your cert key is in  /home/hoge/.acme.sh/*.hoge.example.com/*.hoge.example.com.key 
[2018年  3月 29日 木曜日 20:40:42 JST] The intermediate CA cert is in  /home/hoge/.acme.sh/*.hoge.example.com/ca.cer 
[2018年  3月 29日 木曜日 20:40:42 JST] And the full chain certs is there:  /home/hoge/.acme.sh/*.hoge.example.com/fullchain.cer 
  : (snip)
```

これで取得できました。で、なぜか軒並み日本語でひっかかる記事はここで終わってるんだけど、これで発行されるのは "Face LE Intermediate X1" とかいうちゃんと使えない Staging の CA 発行の証明書です。なのでちゃんと使おうと思うと、正式なやつを production 環境（っていうのかな？）から取得する必要があります。

Staging で発行していても、Let's 側では発行済とマークされているっぽいので、`--force` をつけて強制再発行します。

```
$ acme.sh --force --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --issue -d *.hoge.example.com
（DNS設定したあと）
$ acme.sh --force --yes-I-know-dns-manual-mode-enough-go-ahead-please --renew -d *.hoge.example.com
```

これで Issuer が `Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3` となった正式な証明書が発行されました。
HTTPのキャッシュに関わるヘッダーについてまとめてみた

# 初めに

そもそも、なぜこのような記事を書くことになったかというとバイト先で「HTTPについて調べます。」と先輩に宣言して、どうやって成果物を出すか迷っていた際に、「記事にすれば、良いんじゃないか？」と思ったからです。
その中でも今回はCacheに関するHTTPヘッダーについてまとめました。その理由はいくつかありますが、

- キャッシュという仕組みをあまり知らなかったから
- Webのパフォーマンスを上げる業務ができるとカッコ良さそうだったから

などが挙げられます。

そして、誤りがある場合は指摘をいただきたいです。もう一度調べ直した上で、修正/加筆を行います。理由は以下の通りです。

この記事を見たHTTPについて知らない人に誤った情報が渡ってしまうことを防ぐため。
私自身の勉強のため。

対象読者は以下です。
- Cacheについて知っている。
- HTTPの構成は何となく分かっている。
- Webアプリケーションを作ったことがある。
- Cache-Control？何それ美味しいの？状態、要するに何も知らない。

HTTPの構成が分からない人はよければ以前書いた記事を読んでください
[HTTPリクエスト/レスポンスの構成要素を初心者にも分かるように解説してみた](https://qiita.com/koheiyamaguchi0203/items/5777c4653a01ae4c7b06)

# Cache-Controlヘッダー
Cache-Controlとはその名の通りキャッシュを制御することを目的としたヘッダーです。では、Cache-Controlが取れる値についていくつか説明します。

- no-cache
キャッシュするかどうかをオリジンサーバーに問い合わせてから、キャッシュデータを返すかどうかを決めます。キャッシュするかどうかはETag/If-Modified-Sinceヘッダーの値とオリジンサーバーがそれぞれに対応する値を比較することで決めています。
問答無用でキャッシュしない訳ではありません。これに関しては誤った記載があった記事がQiitaで多くのいいねがされていますが、それは過ちだと思われるので、注意してください。

- max-age
max-age=nでキャッシュの有効期間を指定できます。例えば、max-age=3600と指定すると3600秒(一時間)の間に同一のリソースにリクエストする際には、キャッシュを使用します。以前にそのリソースにリクエストして、その時に発生するレスポンスから3600秒を数え始めます。
この詳細は[このページ](https://developer.mozilla.org/ja/docs/Web/HTTP/Caching#Freshness)が一番分かりやすかったです。

- no-store
リクエスト/レスポンス時にキャッシュを一切使用しない。

# Last-ModifiedとIf-Modified-Since
Last-Modifiedヘッダーはレスポンスヘッダーの一種です。オリジンサーバーがリソースに対して最後に変更があったと考える日付と時刻を値として持ちます。
If-Modified-Sinceヘッダーはリクエストヘッダーの一種です。Last-Modifiedに設定された値を持ちます。この値とオリジンサーバーが持つリソースの変更日時を比較することでキャッシュするかどうかを決定します。リクエスト時に送信したIf-Modified-Sinceヘッダーの値以降にリソースが変更されているとオリジンサーバーが認識している際に、200(OK)を返します。変更されていなければ、304(Not Modified)が返されます。

# EtagヘッダーとIf-None-Match
ETagヘッダーにはファイルに紐付けられたハッシュ値を持ちます(下記のコード参照)。これがレスポンスとしてサーバーから返されます。この値はサーバーによって決め方が異なります。ファイルサイズ/更新日時/コンテンツの内容等を単体または複数の組み合わでハッシュ化していることが多いようです。

```HTTP:レスポンス
ETag: "3ca531-1f467-5683773bfe880;56888f86e23bd"
```

レスポンスで返ってきたEtagの値をIf-None-Matchヘッダーの値として持たせて、リクエストを送信します。

```HTTP:リクエスト
If-None-Match: "3ca531-1f467-5683773bfe880;56888f86e23bd"
```

サーバーが保持するリクエストされたファイルに紐付けられているハッシュ値とIf-None-Matchの値が同じであれば、キャッシュします。異なる場合はサーバーからデータを返します。

# Expiresヘッダー
下記のように日時が値として設定されます。

```bash
Expires: Wed, 04 Apr 2018 08:26:45 GMT
```

[RFC7234](https://tools.ietf.org/html/rfc7234)に2018/03/29 16:02(何秒かは忘れた)にアクセスした際にはこのようなExpiresが返ってきました。この場合は2018/04/05 07:17:38秒までに同一のリソースにリクエストした際には強制的にキャッシュされます。実際にアクセスすると304が返ってきます。ちなみに、RFCではExpiresの期限は最大でも一年の寿命にするように指定されています。

# 個人的な疑問~ETagとIf-Modified-Sinceって同じことしている様に見えるのになぜ共存しているのか~
これがよく分かっていません。キャッシュという仕組みを実行するだけなら、If-Modified-Sinceを使用すれば、実現できる気がしています。どなたか分かる方にコメントを頂けると幸いです。

いくつか調べてみると、具体例が出てきた。
「同一のURLで日本語版サイトと英語版サイトが用意されている場合に、それぞれは別々のリソースであり、同一のリソースとしてキャッシュしてはいけない。そのためには日本語サイトに紐づくETagの値、英語サイトに紐づくETagの値を用意することで、日本語サイトでキャッシュするのか、英語版サイトでキャッシュするのかを決める。」
というものだったが、いまいち分からなかった。

# 最後に
キャッシュは文面上の理解に留まっており、正直、伝えきれていない箇所が多いように思えました。これからは実際にサーバー(Nginx,Apache等)の設定を調べたり、クラウドサービス(AWS)のインプットとアウトプットをすることでキャッシュの理解を少しづつ深めたいと思っています。そして、その時にまたこの記事をリライトしたいです。ただ、この記事でも誤っている箇所はないと思っているので、参考になれば幸いです。
もちろん、誤っている箇所があった場合はすぐにコメントを頂きたいです。宜しくお願い致します。

# 参考文献
- Real World HTTP　歴史とコードに学ぶインターネットとウェブ技術
- Webを支える技術
- HTTPの教科書
- MDN
- RFC
フォルダーアクセス権限の変更

os.chmod('フォルダー名',num)

| num    |        |
|:-------|:------:|
| 0      |  —     |
| 1      |   –x   |
| 2      | -w-    |
| 3      | -wx    |
| 4      |    r–  |
| 5      |    r-x |
| 6      | rw-    |
| 7      | rwx    |

例：フォルダーaaaに実行権限のみ付与
os.chmod('aaa',0755)

*実行環境によりoを入らないと実行できない場合がある
os.chmod('aaa',0o755)
気づけばプロ並みPHP　ショッピングカート作りにチャレンジ！＃１【日記】(2018-03-28)

ＸＡＭＰＰでapache、MySQLを利用してみる
データベースの作成を始める。

Terapadインストールしてphpなどのコーディングに利用。
普通のテキストエディタとの違いで今のところ気付いたのが
スペース全角を空白と違う記号に出来ること？

「PHPを隅から隅まで理解する」というよりは「とりあえずショッピングカートを作ってみてそこで基礎を少しずつ覚えていく」というコンセプトかな？

XAMPPに関して結構大きなバージョンアップがあったようで、検索したりして不具合を解消。システムと違うドライブにインストールしてやってみたけど、今のところはそれで動く。もしだめなことがあればCドライブにインストールしなおしが必要か。
BPMsCHAT

業務フローを元にした開発
PROCESSMAKER サイト　https://www.processmaker.com/

テストからかな

技術という　意味でなく、何を作りたいか？

業務を自分で作り考える。

そこで必要なものはでてくる。

だが伝えるというのは難しい。
BPMS（ビジネスマネージメントルール）で流れを作り
BRMS（ビジネスルールマネージメントシステム）で一連の動作

その元で　各技術

業務と技術　業務があり技術がある
＊）売り上げがあり　それを　効率化するために技術がある

目的というと、会社の売上げ

流れ、ルール、金額計算　

＊）


1,業務フローベースの開発
　プロセス
2,業務フローで　必要な事
　業務
3.各業務での作業
　ケース
4.それぞれの場合による必要技術
　QIITAなど

業務があり　ビジネスができて物があり。繋げれると面白い

ものは作れるけど。全体の業務はわからない。

業務があって、売り上げがあり、開発がある。

それに対して、BPMS,BRMS

1.BPMS
ビジネスマネージメントシステム

2,BRMS
ビジネスルールマネージメントシステム

3.1,2があって技術をいれる

森と木かかな　流れ　自動処理　技術


[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/xq1I65OxmKo&feature/0.jpg)](http://www.youtube.com/watch?v=xq1I65OxmKo&feature=youtu.be)
![BPMCHATメーカー.JPG](https://qiita-image-store.s3.amazonaws.com/0/37985/01b6d85a-401a-7536-d4ab-df3099028946.jpeg)
Kubernetes: kubectl にエイリアスを設定して生産性を上げよう

## はじめに

Kubernetes なみなさん、日々どのくらい kubectl とタイピングしてますか？ OpenShift 方面の方はニヤニヤしているかもしれませんが、kubectl はそこそこタイプ数が多いです。このコストを最小化することで日々の生産性を向上しましょう。

## kubectl にエイリアスを設定する

エイリアスは `k` に設定します。これで oc に勝てます。

```
alias k="kubectl"
```

これだけなのですが、もちろん補完も設定しなければなりません。補完については [kubectl completion: Bash/Zsh 向けの kubectl のシェル自動補完](https://qiita.com/superbrothers/items/631508630320aa1dbcbc) に詳しく書いたのでそちらを参照してもらうとして、補完が有効にならないととてもじゃないですが快適な Kubernetes 生活は過ごせません。あらゆるところでコピペが必要になります。しかし残念ながらこれまではエイリアスに対して補完を設定しても正常に動作しない問題がありました。

これまでにと書いたように先日リリースされた Kubernetes 1.10 の `kubectl completion` においてついにエイリアスに対して設定した補完が正常に動作するようになりました :tada: 

```
complete -o default -F __start_kubectl k
```

bash, zsh ともにこれで `k` に対して kubectl の補完が有効になります。

最終的には下記を `.bashrc` または `.zshrc` に追記してください。

**bash** (bash の場合は bash-completion が必要です。詳しくは `kubectl completion -h` を参照してください)

```sh:.bashrc
source /path/to/bash_completion
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k
```

**zsh**

```sh:.zshrc
source <(kubectl completion zsh)
alias k=kubectl
complete -o default -F __start_kubectl k
```

## 1.9 以下でもエイリアスを使いたい

エイリアスで補完を使えるのは 1.10 からと言いましたが、実はワークアラウンドで 1.9 以下の kubectl でも使うことができます。

```
source <(kubectl completion bash | sed -e 's/kubectl/k/g')
```

`kubectl completion bash` で出力されるスクリプトの kubectl をエイリアス名に置換することでエイリアスに対して補完を有効にできます。あくまでワークアラウンドなのでどこか補完が壊れるかもしれません。できれば kubectl 1.10 を使ってください。

## まとめ

Kubernetes 1.10 からエイリアスに対して kubectl の補完を使えるようになりました。より快適な Kubernetes 生活を送りましょう。

---

このエントリは [Kubernetes / OpenShift もくもく会　No\. 2](https://openshift-mokumoku.connpass.com/event/76968/) で書きました。
静的解析CIツール SideCI使ってみた

#SideCIとは
各言語の静的解析ツールを用いた、自動コードレビューツール。
GitHubに対応しており、プルリクエストの内容を自動的に解析してくれる。
[SideCI](https://sideci.com/ja)

#準備
SideCIのホームページからGitHubのアカウントでログインし、対象のリポジトリを選択する。

#プルリクエストを作る
以下のような空ブロック（ESLintの「no-empty」でエラー）を含むJavaScriptのコードをプッシュし、プルリクエストを作成する。

```
var num;
num = 100;
{ } //追加
```
プルリクエストを作成すると、早速解析してくれます。SideCIのダッシュボードでプルリクエストごとに解析結果を参照できます。作成後数秒待つと解析が終了し、（エラーがある場合）以下のように対象のプルリクエストが赤く表示されました。
<img width="1201" alt="スクリーンショット 2018-03-29 18.13.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/203706/9c33d8c5-1d20-1943-a379-9c79dec83ad5.png">
ちなみに、GitHub上でも確認できます。
<img width="779" alt="スクリーンショット 2018-03-29 18.12.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/203706/5db8d40b-5835-69bf-7d70-fa52aef7a4b1.png">

詳細を確認すると、エラーの内容を確認できます。
![スクリーンショットfixed 2018-03-29 18.13.10.png](https://qiita-image-store.s3.amazonaws.com/0/203706/79d3d7e3-6ece-252e-e6be-a472f53d3d47.png)
エラーに対してコメントができたり、クローズすることができます。

#感想
コードレビューに関する勉強会に参加した際にSideCIを知り、「使ってみたい」と思ったのが発端でした。面倒な設定もなく、とにかく簡単に導入できました！解析ツールもメジャーな言語に対していくつか選んで設定することができます。
RustでEitherを実装する(している)

# きっかけ
最近、Rustを始めて標準でEitherがないのは不便と思ったので、実装しています。
元々、Scalaをやっていたので実装はScalaに合わせています。

- ソース
  - https://github.com/ryota-sakamoto/scala/blob/master/src/util/mod.rs

# 困っていること

## flatMapの実装
- 今回の実装
  - https://github.com/ryota-sakamoto/scala/blob/master/src/util/mod.rs#L85
- Scalaの実装
  - https://github.com/scala/scala/blob/2.13.x/src/library/scala/util/Either.scala#L337

ScalaだとasInstanceOfを使っていて以下のような型変換が可能ですが、


```scala
import scala.util.Right

val r = Right("right") // scala.util.Right[Nothing,String]
r.asInstanceOf[Either[Nothing, Int]] // Either[Nothing,Int]
```

Rustだとこんな便利関数は見つけられませんでした。
そこで、これを再現する方法を以下の2つ思いつきましたが、結局transmuteを使う事で実現したい事の半分は出来ました。
(ジェネリクス使った際のキャストのベストプラクティスわかる方いたら教えて欲しいです)

- transmute
- libc::mallocで頑張る

transmuteはコンパイル時にサイズがわかっていないといけない(?)のでBoxに包んで誤魔化す事でコンパイルは出来ました。
## 問題発生
コンパイルは通り、実行してみると落ちるという現象が起きました。
落ちる原因は型のサイズ違いによりメモリ違反？かなんかが起きていると考えています。
(バイナリのデバック方法をよくわかっていない)
実行時に落ちるのは使い物にならないので、これを何とかしたいけど現状方法が何も思いついていません。
以下、再現コードです。

```rust
extern crate scala;

use std::num::ParseIntError;
use scala::util::Either;

fn main() {
    let result = f("a1000")
        .flat_map(Box::new(|n|f1(n)));
    println!("{:?}", result); //Left(ParseIntError { kind: InvalidDigit })

    let result = f("a1000")
        .flat_map(Box::new(|n|e1(n)));
    //printlnしたら落ちる
    //println!("{:?}", result);
}

fn f(s: &str) -> Either<ParseIntError, u64> {
    Either::parse_result(s.parse())
}

fn f1(n: u64) -> Either<ParseIntError, u8> {
    Either::parse_result(format!("{}", n).parse())
}

fn e1(n: u64) -> Either<String, String> {
    if n == 1000 {
        Either::Right("n is 1000".to_string())
    } else {
        Either::Left("n is not 1000".to_string())
    }
}
```

```
# cargo run
   Compiling scala v0.1.0 (file:///root/scala)
    Finished dev [unoptimized + debuginfo] target(s) in 1.25 secs
     Running `target/debug/scala`
Left(ParseIntError { kind: InvalidDigit })
Illegal instruction (core dumped)

```

# 今後実装したい事
## for式
簡単にですが、以下のように使えるように実装してみました。
e_forという名前なのはforが使えなかったからです。
変数束縛とかちゃんと実装していきたいです。

```rust
let result = e_for!{
    _ <- f("1100")
    _ <- f1()
    _ <- f2()
};
```

## 他のライブラリ
Scalaの標準ライブラリは書きやすいのが多いので実装していきたい。
concurrent.futuresによる並行処理

サンプルコード

```python
import time
import concurrent.futures

@app.route('/api/aaa', methods=['POST'])
def aaa():
    
    def one(args1, args2):
        #重い処理(省略)
        #処理結果を返す
        return result

    def two(args3, args4, args5, args6):
        return "two"

    executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
    #時間が非常にかかる処理
    worker_one = executor.submit(one,args1, args2)
    #早く終われる処理
    worker_two = executor.submit(two,args3, args4, args5, args6)

    return worker_two

```
/api/aaaをコールすると、関数one,two同時に実行される。
twoは早く終われるから、すぐresponseする。
普通の処理ならここで終わりますが、
concurrent.futuresを使うことで、oneはまだバックグラウンドで実行している。

参照：
https://docs.python.org/3/library/concurrent.futures.html
https://qiita.com/castaneai/items/9cc33817419896667f34