OmniAICreator/Qiita-1.07M huggingface dataset:
SudachiをUbuntuにインストールしてみた

研究でSudachiを使うことになり，　Ubuntuにインストールすることになったのでその時のメモ書きです。

# 環境
OS : Ubuntu 16.04.4 LTS
日時 : 2018/05/29

# 手順


## 1. java1.8系のインストールと切り替え

java　のバージョンを確認

```
$ java -version
```

1.7系なら1.8系をインストール後，　以下のコマンドでバージョン切り替え

```
$ sudo update-alternatives --config java
```

***※1.8系にしてなかった場合***
後述の`mvn package`の実行時に以下のような文章を含むエラーがでました。

```
無効なターゲットリリース：1.8 - > [ヘルプ1]
```

## 2. git lfsのインストール
git lfsはGitで大きいサイズのファイルのversion管理を行うための仕組み

公式のDebianの部分を実行していく
sudoなどは適宜つける

```
$ echo 'deb http://http.debian.net/debian wheezy-backports main' > /etc/apt/sources.list.d/wheezy-backports-main.list
$curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
$ sudo apt-get install git-lfs
$ git lfs install
``` 
## 3. Mavenのインストール
java用のプロジェクト管理ツールらしい

```
$sudo apt-get update
$sudo apt-get upgrade
$sudo apt-get maven
```
## 4. Sudachiのクローンとビルド

```
$ git clone https://github.com/WorksApplications/Sudachi.git
$ cd Sudachi/
$ mvn package
```
## 5. Sudachiの実行
***※今後のjarファイルやjsonファイルへのパスは自分のカレントディレクトリからのpathに読み替えてください***
この資料の作業時のディレクトリは`Sudachi/target`

`target/`にある`sudachi-0.1.1-SNAPSHOT.jar`を実行
しかしエラー

```
$java -jar sudachi-0.1.1-SNAPSHOT.jar
Exception in thread "main" java.io.FileNotFoundException: system_core.dic (そのようなファイルやディレクトリはありません)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(FileInputStream.java:195)
	at java.io.FileInputStream.<init>(FileInputStream.java:138)
	at java.io.FileInputStream.<init>(FileInputStream.java:93)
	at com.worksap.nlp.sudachi.JapaneseDictionary.readSystemDictionary(JapaneseDictionary.java:106)
	at com.worksap.nlp.sudachi.JapaneseDictionary.<init>(JapaneseDictionary.java:71)
	at com.worksap.nlp.sudachi.JapaneseDictionary.<init>(JapaneseDictionary.java:56)
	at com.worksap.nlp.sudachi.DictionaryFactory.create(DictionaryFactory.java:44)
	at com.worksap.nlp.sudachi.SudachiCommandLine.main(SudachiCommandLine.java:135)
```

`system_core.dic`、つまりDictionaryファイルがないと言われいるので以下を解凍
(fullも使いたいなら解凍しておいたほうがいいかも)

```
$unzip target/sudachi-0.1.1-SNAPSHOT-dictionary-core.zip(.tar.bz)
```

これで実行可能に
`-m C`のオプションでSudachiの特徴でもある固有表現の抽出も可能に

```
$ java -jar sudachi-0.1.1-SNAPSHOT.jar -m C
機能性食品
機能性食品	名詞,普通名詞,一般,*,*,*	機能性食品
EOS
    
さっぽろテレビ塔
さっぽろ	名詞,固有名詞,地名,一般,*,*	さっぽろ
テレビ塔	名詞,普通名詞,一般,*,*,*	テレビ塔
EOS
```

## 6. フル辞書の選択
上記のようにコア辞書の使用では`さっぽろテレビ塔`のような語を固有表現としてとれません．
このような語を固有表現として抽出するためには以下のようにフル辞書を指定する必要があります．

```
java -jar sudachi-0.1.1-SNAPSHOT.jar -m C -r ../src/main/resources/sudachi_fulldict.json
さっぽろテレビ塔
さっぽろテレビ塔	名詞,固有名詞,一般,*,*,*	さっぽろテレビ塔
EOS
```
***※`-r`で指定するjsonファイルはsudachi.jsonがコア辞書，　sudachi_fulldict.jsonがフル辞書***

## 追記
`system_full.dic`がないと怒られた．

```
Exception in thread "main" java.io.FileNotFoundException: system_full.dic (そのようなファイルやディレクトリはありません)
```

設定を見に行くと`sudachi.json`という設定ファイルあたりで指定してそうだったけどここを変えるのもなんだかなぁ　と思ったのでとりあえず放置
実行場所に`system_full.dic`をおいて暫定解決とした．
解決方法あれば教えてほしい…

# 参考文献
https://qiita.com/ichiren1/items/ed0f72f59adb1cc8f9ae
Nuxt.js の公式 starter が動かなかった件

## [公式のスターター](https://ja.nuxtjs.org/guide/installation/#nuxt-js-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88)を使って Nuxt.js 導入しようとすると……

`npm run dev` 実行したところエラーが発生し、ローカルサーバが起動しない。

※エラーメッセージ抜粋です

```bash
 ERROR  Failed to compile with 5 errors                                                                                                                                                                                                                                   13:03:30
 error  in ./.nuxt/components/nuxt-error.vue

Module build failed: Error: No parser and no file path given, couldn't infer a parser.
    at normalize (<!-- DIRECTORY -->\node_modules\prettier\index.js:7051:13)
    at formatWithCursor (<!-- DIRECTORY -->\node_modules\prettier\index.js:10370:12)
    at <!-- DIRECTORY -->\node_modules\prettier\index.js:31115:15
    at Object.format (<!-- DIRECTORY -->\node_modules\prettier\index.js:31134:12)
    at Object.module.exports (<!-- DIRECTORY -->\node_modules\vue-loader\lib\template-compiler\index.js:80:23)

 @ ./.nuxt/components/nuxt-error.vue 11:0-379
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
```

## 原因

prettierのバージョンが「1.13.0」になっているため
※細かい原因は未確認

```package-lock.json
    "prettier": {
      "version": "1.13.0",
      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.13.0.tgz",
      "integrity": "sha512-ubNahzMwHtdrSVGMMNabOHSeBKvZu+N5Z7Tu2CvbTexffL6aHwwOc7/fvEaWYTtvu4CtXnniHGA2vxV/NIH6KQ=="
    },
```


## 対応
1.12.1にダウングレードすれば動作しました。（以下参考にしました。）

```bash
$ npm i prettier@1.12.1 --save-dev --save-exact
```

https://stackoverflow.com/questions/50561649/module-build-failed-error-no-parser-and-no-file-path-given-couldnt-infer-a-p?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

まさか Nuxt.js 始めた直後に躓くとは思わなかった、、、
nginxunit 触ってみただけ

公式のリファレンス見ながらDockerfile書いた。

## リポジトリ

https://github.com/tsumac/nginxunit

## 設定の反映・変更

curl でローカルホスト（nginxunitソケット）にリクエストを送ると更新される。

```bash
curl \
    -X PUT \
    -d @/etc/unit/config.json \
    --unix-socket /run/control.unit.sock http://localhost/
```

nginxunitソケットが80番をリッスンしてるわけじゃないので外部からは操作できない。で合ってる？

いろいろ追記していきたい。
[C#]Excel カラム名 ↔ 数値 変換

探すと意外となかったので「カラム文字 ⇒ 数値」のコードを書いてみました。
それだけではなんなので「数値 ⇒ カラム文字」もあります

##カラム文字 ⇒ 数値

```c#

using System;
using System.Linq;
using System.Text.RegularExpressions;

public static class StringExtensions
{
    /// <summary>
    /// 文字列をExcelのカラム番号へ変換します
    /// </summary>
    /// <param name="column">a-z/A-Zのみで構成された文字列</param>
    public static int ToColumnNumber(this string source)
    {
            if (string.IsNullOrWhiteSpace(source))
                return 0;

            string buf = source.ToUpper();
            if (Regex.IsMatch(buf, @"^[A-Z]+$") == false)
                throw new FormatException("Argument format is only alphabet");

            // 変換後がint.MaxValueに収まるか?
            if (buf.CompareTo("FXSHRXW") >= 1)
                throw new ArgumentOutOfRangeException("Argument range max \"FXSHRXW\"");

            return buf.ToColumnNumber(0);
    }

    /// <summary>
    /// 文字列→Excelカラム番号変換処理の実体
    /// </summary>
    /// <param name="column">A-Zのみで構成された文字列</param>
    /// <param name="call_num">呼び出し回数</param>
    static int ToColumnNumber(this string source, int call_num)
    {
        if (source == "") return 0;
        int digit = (int)Math.Pow(26, call_num);
        return ((source.Last() - 'A' + 1) * digit) + ToColumnNumber(source.Substring(0, source.Length - 1), ++call_num);
    }
}
```

ひとつのメソッドにまとめてもよかったのですが、再帰するたびにエラーチェックするのも無駄だと思い分けました。

##数値 ⇒ カラム文字

```c#

public static class IntExtensions
{
    /// <summary>
    /// 数値をExcelのカラム文字へ変換します
    /// </summary>
    /// <param name="column"></param>
    /// <returns></returns>
    public static string ToColumnName(this int source)
    {
        if (source< 1) return string.Empty;
        return ToColumnName((source- 1) / 26) + (char)('A' + ((source- 1) % 26));
    }
}
```
Lumenでpasswordの中身をマスクしてログに出力する


# やりたいこと
ログを出すときに、ユーザから送られてきたパスワードや、パスワード確認にセットされているパスワード文字列がログに書かれてしまうのをなんとかする。
個別に処理するのではなく、logを出す方で自動的にマスクして出力するようにする。


# 前提
PHP 7
Lumen 5
ログに monologを使っている



# やりかた


```bootstrap/app.php

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\NativeMailerHandler;
use Monolog\Formatter\JsonFormatter;


   :
   (割愛)
   :

$app->configureMonologUsing(function ($monolog) {
    $monolog->pushHandler((
        new StreamHandler('php://stdout', Logger::DEBUG)
    )->setFormatter(new JsonFormatter()));

    $monolog->pushProcessor(function($record){
        array_walk_recursive($record, function(&$val, $key){
            if (($key === 'password')||($key === 'password_confirmation')) {
                $val = '********';
            }
        });
        return $record;
    });
    return $monolog;
});


   :
   (割愛)
   :


```

\Monolog\Logger::StreamHandler では、
第一引数 : `php://stdout` 標準出力
第二引数 : Logger::DEBUG デバックレベルで出力する
setFormatter(new JsonFormatter())) : JSON形式で出力する

の設定になっている（AWS CloudWatch Logs に出す想定)


ログ出力内容を変更したり追加したりする場合は、\Monolog\Logger::pushProcessorを使う。
ここに、既存の processrを追加したりしてとても便利だったりする。

独自のコールバックを書くこともできる。
引数の `$record` に、ログに書き出す内容の配列が渡されるので、その中の `password`, `password_confirmation` の値を `********` に上書きする処理にする。


[array_walk_recursive](http://php.net/manual/ja/function.array-walk-recursive.php) は、第一引数に指定した配列の全ての要素に、ユーザー関数を再帰的に適用してくれる便利なやつ。


# 感想

でも遅くなりそうな予感。
Xojo教えてもらいました

過日行われた [DTPerのスクリプトもくもく会 #7](https://dtpmkmk.connpass.com/event/83459/) に参加して、 [ものかのさん](https://t.co/WR1RdvQfHT)にXojoについてあれこれご教示いただいたので忘れないようにメモ。


## Properties  
プロジェクトを通して値を保持したい場合に設定する。

![プロパティ](https://qiita-image-store.s3.amazonaws.com/0/7001/08f429d0-5b7c-5e0d-bcaf-b2aa774b819e.png)

## Methods
コードの共有をするためにメソッド化。

![メソッド](https://qiita-image-store.s3.amazonaws.com/0/7001/30dcff14-b68e-aec2-8461-745de62b6059.png)

利用するにはメソッド名を呼ぶだけ。

## Module
メソッドをそれぞれのプロジェクトで利用するだけではなく、各ファイルから参照できるようメソッドのモジュール化。

![モジュール1](https://qiita-image-store.s3.amazonaws.com/0/7001/317f0c8b-f2d7-e470-336b-c26509390913.png)　![モジュール2](https://qiita-image-store.s3.amazonaws.com/0/7001/fb5011f8-73bb-55dc-b427-6ea19ef6bf73.png)

利用するにはプロジェクトに追加する際に**コマンド＋オプションキー**を押しながらドラッグ&ドロップする。

**Module 1**が二つあるが、外部参照をしている上の方はアイコンにエイリアスの**矢印**がついているのとモジュール名が**イタリック**になっているので区別できる。

![モジュール3](https://qiita-image-store.s3.amazonaws.com/0/7001/58307e76-1250-c3bf-2f4b-50f759625070.png)

　　
外部参照したモジュールでメソッド名が競合した場合**ローカル**が優先される。
スコープを**Protected**に変更する事で外部メソッドの値を保護できる。
外部メソッドを利用するには**モジュール名.メソッド名**と書く。

![モジュール4](https://qiita-image-store.s3.amazonaws.com/0/7001/3b88863f-2783-40f2-989b-a8e201e8a186.png)

## Menu  
上部ボタンよりメニューを追加し、**ID**の**Name**を割り当てたい機能の**メソッド名**にする。
ショートカットを設定することもできる。


## Preference

~/Library/Preferencesにplistで保存する方法もあるが、今回は**~/Library/Application Support**に保存する方法を教えていただいた。
下記例では、Application Supportフォルダにtmpフォルダがなければ作成する。
実際の保存まではまだ書いていないがjson形式で書き出すつもり。

```VB:

dim useAppSupFolder as FolderItem = SpecialFolder.UserLibrary.Child("application support")
dim f as FolderItem = useAppSupFolder.child("tmp")

if  f <> nil and f.Exists then
  '設定値保存

else
  f.CreateAsFolder
  
end

if f is nil or not f.Exists then
  MsgBox("作れませんでした")
  Return
end

```

## DropObject  
ファイルをテキストフィールドにドラッグ＆ドロップして登録できるようにする。

![dropObj](https://qiita-image-store.s3.amazonaws.com/0/7001/cf7bc0a0-8d60-4761-6c70-01f0bbac8f07.png)

オブジェクトに**DropObject**と**Open**のイベントハンドラを追加する。  

  
```VB:DropObject


pDropArea = obj.FolderItem

'拡張子がtxtでなければ文字列をクリアする。
if pDropArea.Name.RightB(4) = ".txt" then
  me.Text = pDropArea.NativePath
  
else
  me.Text = ""
  pDropArea = Nil
  
end if


```
  
```VB:Open


me.AcceptFileDrop("txt")

```

## Enabled  
言われてみれば確かにこっちの方がいい！と、思ったのがボタンの**Enabled**を使う方法。
見ていただいたプロジェクトは、いくつかのファイルやフォルダを選択後に実行ボタンを押して処理を実行させるもの。
選択されていない場合はエラーメッセージを表示させていたが、そもそも選択されてなかったら実行ボタンの**Enabled**を**False**にすればボタンが押せない。

###### メソッド**IsButtonEnabled()**
```VB:IsButtonEnabled()


'// fieldListFileの判定
if fieldListFile.Text.LenB=0 then
  ' 空ならFalse
  Return False
  
else
  ' fieldListFileのパスに実際にアイテムがなければFalse
  dim ListFile as FolderItem = New FolderItem(fieldListFile.Text, FolderItem.PathTypeNative)
  if ListFile is nil or not ListFile.Exists then Return false
  
end if

'フィールド分繰り返す

'// 上記条件をクリアしたことになるので、Trueを返す
Return True

```

各フィールドで上記メソッドを実行

```VB:IsButtonEnabled()


' ボタンのEnabledを設定する
PushButton1.Enabled = IsCopyButtonEnabled()

```
Kotlinで始めるAndroidアプリ入門（中編）


* [Kotlinで始めるAndroidアプリ入門（前編）](https://qiita.com/k-ysd/items/4efdecdfd60afe333a3a)
* Kotlinで始めるAndroidアプリ入門（中編）
* [Kotlinで始めるAndroidアプリ入門（後編）](https://qiita.com/k-ysd/items/48aaf6de44e878c87c13)


[前編](https://qiita.com/k-ysd/items/4efdecdfd60afe333a3a)に引き続きKotlinでAndroidアプリを作ってみます。

最初の画面で入力した文字列を、２つ目の画面に渡すアプリになります。まずは最初の画面を作ります。

## レイアウトエディタを開く

左のプロジェクトウィンドウから、app > res > layout > activity_main.xml を選択します。

もし、XMLが表示されていたら、下のタブでデザインを選択します。

青いアイコンをクリックし、「Blueprint」を選択します。

![settingLayout.png](https://qiita-image-store.s3.amazonaws.com/0/113146/4e083837-6670-a17c-5200-f2897eb26e6a.png "settingLayout.png")


## 最初の画面を作る

最初の画面は、テキストボックスとボタンが一つずつある画面です。

デフォルトで設定されている「Hello World!」が表示されているTextViewは削除してください。右クリックして、削除を選択します。

![deleteHelloWorld.png](https://qiita-image-store.s3.amazonaws.com/0/113146/ff570d4f-21d0-1e93-c1ab-2ee2804f58f4.png "deleteHelloWorld.png")

まずは、テキストボックスを追加します。
左のパレットウィンドウで Text > PlaneText を選択し、画面へドラッグ＆ドロップします。
![createTextBox.png](https://qiita-image-store.s3.amazonaws.com/0/113146/908282c2-177c-c817-738f-6fbfbaa4774c.png "createTextBox.png")

次にボタンを追加します。
左のパレットウィンドウで Button > Button を選択し、画面へドラッグ＆ドロップします。
![createButton.png](https://qiita-image-store.s3.amazonaws.com/0/113146/c4d58598-d738-0a25-7d19-8cacccff490a.png "createButton.png")

### UI文字列を変更する

青いアイコンをクリックし、「デザインを」選択します。
テキストボックスには「Name」、ボタンには「BUTTON」という文字列が表示されていることがわかります。これを変更しましょう。
![designMode.png](https://qiita-image-store.s3.amazonaws.com/0/113146/65bb380e-119b-cfd2-8add-62ef65d3cd29.png "designMode.png")

文字列をハードコピーしてもよいのですが、ここではXMLで管理します。XMLで管理すると、ローカライズなどが簡単にできるようになります。

左のProjectウィンドウから、app > res > values > strings.xml を開きます。上部の「エディターを開く」をクリックします。
![openXML.png](https://qiita-image-store.s3.amazonaws.com/0/113146/1a4186f4-2a75-95e4-29e6-c66ac7d17a97.png "openXML.png")

テキストボックスに表示する文字列を設定します。「＋」ボタンをクリックし、
　キー：	edit_message
　値：Enter a message
と入力します。
![textKey.png](https://qiita-image-store.s3.amazonaws.com/0/113146/2f34b745-92aa-07e8-1f6d-54e5009db78f.png "textKey.png")

次に、ボタンに表示する文字列を設定します。同じく「＋」ボタンをクリックし、
　キー：	button_send
　値：Send
と入力します。
![buttonKey.png](https://qiita-image-store.s3.amazonaws.com/0/113146/1501f070-97aa-3d90-fbf7-a0c38c8f69af.png "buttonKey.png")

設定したビューと文字列を紐つけましょう。
まず、上部のタブバーから「activity_main.xml」をクリックします。
テキストボックスをクリックし、右の属性で「テキスト」を空にします。次に「hint」の横の「…」をクリックします。
![setTextMessage.png](https://qiita-image-store.s3.amazonaws.com/0/113146/1d86694e-9cd9-658c-0e80-25c7ec603dd6.png "setTextMessage.png")

ダイアログで「edit_message」をダブルクリックします。
![chooseMessage.png](https://qiita-image-store.s3.amazonaws.com/0/113146/62d720b1-7af2-b158-056a-b45be234c63d.png "chooseMessage.png")


同様に、ボタンをクリックし、「テキスト」の横の「…」をクリックします。
![setButtonMessage.png](https://qiita-image-store.s3.amazonaws.com/0/113146/82bfde8a-4e54-27cf-f6ca-52c057b010fc.png "setButtonMessage.png")

ダイアログで「button_send」をダブルクリックします。
![chooseButtonMessage.png](https://qiita-image-store.s3.amazonaws.com/0/113146/00e78c67-cce4-25c5-f4dd-fedc1ce38203.png "chooseButtonMessage.png")


これで最初の画面の設定はおしまいです。ビューの制約やサイズの設定もできますが、ここでは割愛します。詳しくは[公式ガイド](https://developer.android.com/training/basics/firstapp/building-ui)をご覧ください。
Kotlinで始めるAndroidアプリ入門（前編）


これからAndroidアプリを作って見ようと思います。せっかくなので最近公式開発言語に選ばれたKotlinで作ってみます。

* Kotlinで始めるAndroidアプリ入門（前編）
* [Kotlinで始めるAndroidアプリ入門（中編）](https://qiita.com/k-ysd/items/f428072e9b5db9285cf3)
* [Kotlinで始めるAndroidアプリ入門（後編）](https://qiita.com/k-ysd/items/48aaf6de44e878c87c13)


[デベロッパーガイド](https://developer.android.com/training/basics/firstapp/)の流れにそって、Kotlinでやってみます。画面に入力した文字列が次の画面で表示されるアプリを作りましょう。前編・中編・後編に分かれますが、Kotlinが登場するのは後編からです。

ちなみに、エミュレータの初回起動まではかなり待ち時間があるので、何か他のことをやりながら進めると良いです。

まずは環境の準備からです。

## 事前準備

事前に[Android Studio](https://developer.android.com/studio/)をインストールしておきます。[日本語化](https://fidscreate.com/tool/android-studio#japanese3)はお好みでどうぞ。


## Androidプロジェクトを作成する

新規プロジェクトを作成します。
![chooseProject.png](https://qiita-image-store.s3.amazonaws.com/0/113146/53ed356c-09e6-9348-40f6-c133d8c43510.png "chooseProject.png")


アプリケーション名や会社ドメインは適当につけてください（そのままでもOKです）。「Kotlinサポートを含める」にチェックを入れてください。
![aboutProject.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113146/b527b1b5-bfe8-f4b3-4861-bf35b5d44791.png)


あとは何も変えずに進めてください。プロジェクトが出来上がります。
![projectSetting1.png](https://qiita-image-store.s3.amazonaws.com/0/113146/6a3b5ebd-18f5-c06a-161d-86065e2446a4.png "projectSetting1.png")
![projectSetting2.png](https://qiita-image-store.s3.amazonaws.com/0/113146/3b698288-3fa1-29ab-892c-4e883a74404c.png "projectSetting2.png")
![projectSetting3.png](https://qiita-image-store.s3.amazonaws.com/0/113146/411f9ce4-aea7-e02a-1328-5803e0cc1062.png "projectSetting3.png")

## エミュレータで実行する

Runボタンを押します。
![run.png](https://qiita-image-store.s3.amazonaws.com/0/113146/c3e72ec4-90b1-0cba-a6ae-61f8bb4e2569.png "run.png")


初回のみ必要な作業です。
「新規仮想デバイスの作成」ボタンを押します。
![makeNewVirtualDevice.png](https://qiita-image-store.s3.amazonaws.com/0/113146/e3426c68-0a02-5007-5608-efcde554eb5e.png "makeNewVirtualDevice.png")


ハードウェアは適当なものを選択してください。
![chooseDevice.png](https://qiita-image-store.s3.amazonaws.com/0/113146/46f38b93-2e55-f7ed-8298-cdfc88ab2e6a.png "chooseDevice.png")


最新APIレベルのシステムイメージをダウンロードしてください。数分かかります。
![chooseSystemImage.png](https://qiita-image-store.s3.amazonaws.com/0/113146/b7334b97-dfc8-6333-8150-bf44c48654b0.png "chooseSystemImage.png")


そのままで進めます。これで仮想デバイスが出来ました。
![aboutVirtualDevice.png](https://qiita-image-store.s3.amazonaws.com/0/113146/9bed510f-8bd2-d530-2bad-8ecbb0ca2eea.png "aboutVirtualDevice.png")

作成した仮想デバイスを選択してください。エミュレータが起動します。
![chooseDevice.png](https://qiita-image-store.s3.amazonaws.com/0/113146/f3f9b04d-09b5-e05d-b933-bbf0a12b22f1.png "chooseDevice.png")

エミュレータの起動まで数分かかります。「Hello World!」が表示されれば成功です。
![emulator.png](https://qiita-image-store.s3.amazonaws.com/0/113146/e73a6f47-078f-0c2a-46c6-58a0c23ca43f.png "emulator.png")


## ここまでのまとめ

前編ではKotlinのコードはまったく登場しませんでした…　次の[中編](https://qiita.com/k-ysd/items/f428072e9b5db9285cf3)で最初の画面を作り、最後の[後編](https://qiita.com/k-ysd/items/48aaf6de44e878c87c13)にKotlinが登場するので、お楽しみに。
Macでコマンドラインから画面をロックする便利なエイリアスを登録する

.bashrcなり.zshrcなりconfig.fishなりに、

```sh
# Screen Lock
alias lock='"/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession" -suspend'
```

以上を書き込んで、ターミナルを立ち上げ直して、 `lock` で画面をロックするようにしておくと便利。
C++ Builder 10.2 Tokyo > TOpenDialog | TSaveDialog > FilterとFilterIndex > デザイン定義とコード定義 > ソフト変更時の失敗予防

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
```

## TOpenDialog > FilterとFilterIndex

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/UsingDialogs_(Delphi)
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Dialogs.TOpenDialog.FilterIndex

TOpenDialog (TSaveDialog)には下記のプロパティがある。

- Filter: フィルタ文字列
- FilterIndex: デフォルトフィルタの指定

### プロパティの設定 > デザイン? or コード?

FilterIndexをコードで設定する場合、どこまでをコードで実装するか。

- A. デザイン + コード
    - Filterはデザイン上 (オブジェクトインスペクタでFilterプロパティ指定)
    - FilterIndexはコードで代入
- B. コードのみ
    - Filterをコードで代入
    - FilterIndexをコードで代入

### ソフト変更時の失敗予防

上記Aの場合、ソフト変更時にデザインとコードそれぞれを変更することになる。

デザインだけ変更して、コード変更忘れしないかどうか。

Bの場合、例として、以下のような実装になる。

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
    TOpenDialog *OpenDialog1;
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

// { 画像ファイルフィルタ設定
static const String kFilter_list = L"jpg|*.jpg|png|*.png|bmp|*.bmp";
enum {
    FILTER_IDX_JPG = 1, // [Note] OpenDialogのFilterは1始まり
    FILTER_IDX_PNG,
    FILTER_IDX_BMP,
};
// } 画像ファイルフィルタ設定


__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // ソフト起動時の画像ファイルフィルタ設定
    OpenDialog1->Filter = kFilter_list;
    OpenDialog1->FilterIndex = FILTER_IDX_PNG;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if (OpenDialog1->Execute() == false) {
        return;
    }

    ShowMessage(OpenDialog1->FileName);
}
//---------------------------------------------------------------------------
```

Bでの実装の場合、`kFilter_list`と`FILTER_IDX_`の定義が近い場所にあるため、片方だけの変更忘れを防止しやすいかもしれない。

### 将来変更しそうな処理は一か所にまとめる

「将来変更しそうな処理は一か所にまとめる」という趣旨の記載が過去読んだ本にあったと思う。
どの本であったかは定かではない。

一か所にまとめることで、「変更漏れ」を防ぎ、テストもしやすくなるだろう。
Leaflet Polyline.SnakeAnim



[IvanSanchez/Leaflet\.Polyline\.SnakeAnim: Animates Leaflet polylines so they creep into full length](https://github.com/IvanSanchez/Leaflet.Polyline.SnakeAnim)

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/4fca192e-3200-7c05-2f4a-4d148c4f7737.png)


```js

var latlngs = [];
for (var i = 0; i < route.length; i++) {
    latlngs.push(new L.LatLng(route[i][1], route[i][0]));
}
    
var line = L.polyline(latlngs, {snakingSpeed: 200});
line.addTo(map).snakeIn();


path.snakeIn();
        
```
Ubuntu に Laravel をインストールする

Laravel を始めようと思っが
installに手こずったのでメモ
# まず、php をインストール
```
sudo apt install php
```
# Composer インストールする
```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```
# Composer path
```
sudo mv composer.phar /usr/local/bin/composer
```
# Laravel インストール
```
composer global require "laravel/installer"
```
# Laravel にpathをとおす
```
export PATH="$PATH:/.config/composer/vendor/bin"

```
をhomeにある.bashrcに追加し

```
source ~/.bashrc 
```
Ubuntuのバージョンによってはこっちかもしれません

```
export PATH="$PATH:/.composer/vendor/bin"
```
# 走らせる
```
php artisan serve
```
![Screenshot from 2018-05-29 18-17-09.png](https://qiita-image-store.s3.amazonaws.com/0/243131/7af6c355-08a9-43d5-44d5-d48501716246.png)
おぉ！！カッコイイ

#参考リンク
https://getcomposer.org/
https://getcomposer.org/doc/00-intro.md#globally
http://laravel.jp/
https://laravel.com/docs/4.2/quick
https://stackoverflow.com/questions/25373188/laravel-installation-how-to-place-the-composer-vendor-bin-directory-in-your
もっと自由にドローン(Ryze Tello)をProcessingのみで飛ばしてみた

# 追記
SDKバージョン1.3.0.0がでました
そこには今回の内容がカヴァーされている形になっています
SDKを利用して自由に飛ばすには「rc」コマンドを利用するとよいかと思います．
以下SDKのドキュメントから引用

>command : rc a b c d
Discription : Send RC control via four channels
a: left/right (-100~100)
b: forward/backward (-100~100)
c: up/down (-100~100)
d: yaw (-100~100)


# 前回
https://qiita.com/tkyko13/items/a873ef8a34dc3f6dc67d

前回では，Telloのページで公式に公開されているSDKからProcessingで飛ばしてみました
ですが，このSDKだとコマンドを実行した後，そのコマンドが実行中は別のコマンドを受け付けてくれませんでした．
なので斜め移動ができない！
今回のテーマは「空を自由に飛びたいな！」です．

# 環境
- Processing 3.3.7
- udp(Processingライブラリ) 1.0

# サンプルコード
今回もとりあえずいきなりサンプルコード
と言いたいところですが，作ったクラス内のコードが長かったのでgithubにもあげました
https://github.com/tkyko13/TelloP5

メインのクラスだけここでは表記します
（若干githubとは差がありますが，基本同じです）

``` java:TelloP5.pde

import hypermedia.net.*;

Tello tello;

void setup() {
  tello = new Tello(this);
}

void draw() {
  tello.update();
}

void keyPressed() {
  if (key == 'a') {
    tello.takeoff();
  } else if (key == 's') {
    tello.land();
  } else if (key == 'w') {
    tello.forward(10);
    tello.left(10);
  }
}

```

## ちょい解説
Telloの飛ばし方は前回を参照してください
コードを実行した後，このコードではaキーを押したら飛び始めると思います
sキーで着陸ですが，wキーだとなんと左前に斜めに移動します！

# 参考サイト
https://gobot.io/blog/2018/04/20/hello-tello-hacking-drones-with-go/
実は上記のgo言語でのライブラリgobotだと斜め移動が可能になっています
実は，今回のgithubに上がっているクラスはそちらを見ながらProcessingに書き直したものになっています

Processingで書き直す前に，node.js用に書き直したほうが汎用性あったかなぁと思っています．．．（前回からの勢いです．．．）
後，クラスでの配布ではなくて，java書いてライブラリで配布できるとよりいいですね．ほしい．．．

言語を変えてライブラリを書き直すっていう，こんにゃくみたいな不思議道具ないかなぁ．．．
文字コードと照合順序について

文字コードについて調べる機会があったので、自分なりに参考にさせていただいた記事を備忘録も兼ねまとめたいと思います。

#調べるきっかけ
今まで開発する中で、文字コードについて曖昧な理解だったのもあり、文字コードの設定やMySQLの照合順序で違いがあることに気づきました。

#文字コードについて
文字コードとは、コンピュータ上で文字を扱うために個々の文字、記号に割り当てられた固有の番号のことです。コンピューターはデータを数値でしか扱えないため、文字も数値で扱わなければならなく、そのため、文字を表示するには文字コードが必要となります。
文字コードは、２つの要素で構成されています。それが、`文字集合`と`符号化方式`です。
##（符号化）文字集合、（文字）符号化方式
- 文字集合  
文字をその要素（元）とする集合体のことである。文字セットという場合もある。

- 符号化方式
文字集合で文字に対応付けた非負整数値を実際にコンピュータで利用できるデータ列に変換する符号化方式のことをいう。
###**参考記事**
※下記リンクの図がイメージしやすいです
・[文字コードとは？~UTF-8はパソコンの世界共通語~｜データ分析用語を解説](https://www.graffe.jp/blog/1278/)

## 文字コードの種類
- **ASCIIコード**
最も基礎となる文字コード。下記の表のようにキーボード上にある「数字」、「アルファベット」、「記号」を1バイトで表現します。これらの文字の他に、赤字で記載している改行コード(LF、CR)やタブ文字(HT)、制御コードのNULLやBSなどもあります。 

- **Unicodeの文字符号化形式**
Windows、Java、XMLなどで用いられている文字コード。以下、Unicodeの文字符号化方式。
 - UTF-8  
ISO/IEC 10646 (UCS) とUnicodeで使える8ビット符号単位の文字符号化形式及び文字符号化スキーム。UTF-8は、データ交換方式・ファイル形式として一般的に使われる傾向にある。ASCIIコードとの互換性が高い。（ASCIIで定義している文字を、Unicodeでそのまま使用することを目的として制定している。）
 - UTF-16  
UnicodeおよびISO/IEC 10646の、符号化形式および符号化スキーム（文字符号化方式を参照）のひとつである。Windows XPなど多くのOSで、内部表現に使われている。
 - UTF-32  
Unicodeの各符号位置に32ビット符号単位一つだけを使う、固定長のUnicodeの符号化形式及び符号化スキーム（文字符号化方式#文字符号化形式と文字符号化スキーム）である。UTF-32は、テキストファイルで使用されることは少なく、主にシステムのメモリ上での管理や、符号位置の数で管理するデータベースなどで使用される。

- **JISの文字符号化形式**
日本語を表現する文字コードのひとつ。パソコンで日本語を扱うための文字コードの一種です。電子メールで日本語を表記する際の標準的な文字コードです。
 - Shift-JIS  
ASCIIコードの文字に加え、日本語の文字を加えたのが、Shift-JISです。ASCIIコードの文字に日本語の文字を加えた物です。Windows、Macでも採用しており、PC上のファイルで広く用いられています。ASCIIコードとの互換性が高い。

- **EUC** 
UNIX上で日本語の文字を扱う場合にもっとも多く利用されている文字コード（符号化方式）のひとつである。UNIX以外のOS上で使われることもある。

#MySQLの照合順序について
MySQLは文字コードとソート順を持っていて、ソート順の部分がCollationとよばれている。(文字コードの部分はCharacter Set)文字コードだけでなくてCollationが一致するかどうかを比較する。
###**Collationとは**
Collationの命名規則は、`文字コード_言語名_比較法`となる。
例）utf-8_general_ciの場合
文字コード：utf-8
言語名：general
比較法：ci
となる。
###**比較法について**
_ci:大文字と小文字が区別されない
_cs:大文字と小文字が区別される
_bin:バイナリ

###**参考記事**
・[【MySQL】照合順序とは？](https://qiita.com/kazu56/items/6af85ffcf8d3954455ad)
・[MySQLのCollationを理解するためにまとめてみた。](http://blog.6vox.com/2014/05/mysqlcollatoin.html)

##utf-8_general_ciとutf-8_unicode_ciの違い
- **utf-8_general_ci**
mysqlのデフォルトはgeneral_ciになる。
アルファベットの大文字小文字は区別しない。全角半角は区別する。

- **utf-8_unicode_ci**
アルファベットの大文字小文字は区別しない。全角半角も区別しない。
さらに濁音、半濁音、ひらがな、カタカナも区別しない。

#Mysqlでの文字コード設定
MySQLには文字列の照合順序(collation)というのがあって、MySQL側でのcharset utf8のときのデフォルトの照合順序はutf8_general_ciになる。

#Railsでの文字コード設定
ActiveRecord::Migrationでは明示的に照合順序を指定しない場合、charset utf8で照合順序utf8_unicode_ciのデータベースを作成になる。
utf-8_unicode_ciからutf-8_genral_ciに変更したい場合は、`config/databese.yml`に`charset`と`collation`を指定すればよいとのこと。

```ruby:config/databese.yml
development:
  adapter: mysql2
  encoding: utf8
  charset: utf8
  collation: utf8_general_ci
  database: mojicode_development
```

#まとめ
`utf-8_unicode_ci`は、「ひらがな」「カタカナ」が混在したりと検索が曖昧になってしまうことがあるため、日本語を使用するwebサイトは基本的に`utf-8_general_ci`を使用した方が良いとのこと。
読む記事によっては、unicode_ci推奨といったものもあり、少し混乱する部分があると思いますが、どちらを使用するかは用途に応じてといったところでしょうか。
文字コードや照合順序などあまり意識することは、普段少ないかもしれませんが、同じように気になった方の少しでも参考になればと思います。

###あわせて読みたい参考になる記事
・[MySQLのencodingをutf8からutfmb4に変更して寿司ビール問題に対応する](https://techracho.bpsinc.jp/hachi8833/2016_08_25/25044)
・[新人さんに知ってほしい「文字コードのお話」](https://qiita.com/yuji38kwmt/items/b3a7820b4d3b544da4ff)
vimgrep & 検索と置換

vim上でディレクトリ内一括検索・置換。
`Sublime Text 3` でいう `Cmd+Shift+f` みたいな。

## Usage

```vim
:vim [pattern] [targets]
```

もしくは

```vim
:vimgrep [pattern] [targets]
```

## Patterns & Targets

### unko という文字列を \*.go のみに限定して検索したい場合

```vim
:vim /unko/ **/*.go
```

### src ディレクトリ以下にある unko を検索したい場合

```vim
:vim /unko/ src/**/*
```

## Quickfix

`.vimrc` に以下を記述すると、検索後に自動で `Quickfix` が起動する。

```vim
autocmd QuickFixCmdPost *grep* cwindow$
```

## 検索→置換

`Quickfix` を起動後、検索語句を一括置換したい。

```vim
:cdo %s/unko/UNKO/gc
```

で各ファイルの検索語句を置換できる。

```vim
:cdo %s/unko/UNKO/gc | update
```

なら置換後保存してくれる。
Processingで常に動き続ける別のスレッドを作る方法

Processingにも実はマルチスレッドを扱う機能がある、というのはすでにいくつか記事がありますよね。RunnableインターフェイスをimplementしたクラスをThreadコンストラクタの引数にしてインスタンス化して`start()`を呼び出す...というやつです。言葉にするとわかりづらいですね。それなら関数作って`thread("funcName")`ってやった方が楽ですね。

なぜこれがダメなのかというと、今回は"常に"動き続けるスレッドがほしかったのです。上の方法で呼び出されたものは与えた処理を実行するとスレッドが終了してしまうので、常に別スレッドで計算したいなどとなると別の方法が必要でした。(Threadクラスを用いる方法があればぜひ教えてください)

ここからが今回の内容になります。

```Processing
boolean isCollided;

void setup(){
  size(400,400);

  new Thread(new Calculator());
}

void draw(){
  background(255);

  if(isCollided){
    fill(255,0,0);
  } else {
    fill(0,0,255);
  }
  ellipse(200,200,100,100);
}

class Calculator{
  void run(){
    if(dist(mouseX,mouseY,200,200)<50){
      isCollided = true;
    } else {
      isCollided = false;
    }
  }
}

class Thread extends PApplet{
  Calculator c;
  
  Thread(Calculator c) {
    this.c = c;

    PSurface surface = super.initSurface();

    surface.startThread(); // これか
    this.startSurface(); // これのどっちか
    // this.startSurface()を使用した場合は上のsurfaceがnever usedと警告出ますが気にしなくていいです。
  }

  void draw(){
    r.run();
  }
}
```

このプログラムでは、カーソルが直径100の円の中にあれば円が赤色に、外なら円が青色になります。
本来であれば`dist()`を用いた内外判定は`draw()`の中に書きますが、Calculatorクラスを用意し、その`run()`内の処理として実装します。

```Processing
new Thread(new Calculator());
```
いきなり見づらい書き方ですみません。丁寧に書くと下のようになります

```Processing
Calculator c = new Calculator();
Thread thread = new Thread(c);
```
ではなんで先のような書き方をしていたのかというと、CalculatorクラスにせよThreadクラスにせよオブジェクトに触れる必要がないからです。(インスタンス化した時点でメモリ上に用意され、使っているうちは存在し続けます。使われなくなったらいつかメモリが解放されます(このことをガベージコレクタとかなんとか...))

Calculatorクラスについては大丈夫ですね。クラス名も適当です。この中に用意した関数をのちに呼び出します。

次はThreadクラスについてです。(Threadクラスというのがもともと用意されていて文字に色が付きますが問題ないです)
PAppletというのはおそらくウィンドウの作成・描画に関するクラスで、複数のウィンドウを作ったりできます。その作られたウィンドウ達はそれぞれ別に処理されることを利用したのが今回の記事です。
※複数ウィンドウについては[3846masaさんのサイト](http://3846masa.blog.jp/archives/1038375725.html)をどうぞ
クラス内部の記述はほとんどコピペで構いません。先ほどの3846masaさんのサイトで紹介されていたものから必要なものだけを書きだしました。
あとは通常のメインループと同じようにdraw()が呼び出されるので、用意したクラスの関数を呼び出してください。
作られるウィンドウはデフォルトでは非表示なので何もしていませんが、ちゃんと動いているかを確認する場合は、コンストラクタの内部の`initSurface()`が呼び出された後で

```Processing
surface.setVisible(true);
```
もしくは

```Processing
this.showSurface();
```
と記述してください。

###経緯
東方Projectという有名な弾幕シューティングゲームに魅了されて、当時勉強していたProcessingの練習もかねて弾幕シューティングゲームを作っていたのですが、大量の弾幕を描画すると重いんですよねやっぱり。だから当たり判定を別スレッドに渡したりと、少しでも処理が軽くできないかなと思い今回の方法を調べるに至りました。
まあ元がJavaの言語でやるものじゃないと思いますけど()
PHP:  clone $this が書かれた親クラスを継承したとき、小クラスの振る舞いはどうなるのか？

「`clone $this`が書かれた親クラスを継承したとき、小クラスの振る舞いはどうなるのか？」 疑問だったので調べた。

このような継承関係のあるクラスで、

```php
class ParentClass {}

class ChildClass extends ParentClass {}
```

親クラスに`clone $this`を書いたとき、

```php
class ParentClass
{
    public function copy(): self
    {
        return clone $this;
    }
}
```

次のコードで、`$obj`は`ParentClass`になるのか、それとも`ChildClass`になるのか？

```php
$child = new ChildClass(); // 小クラス
$obj = $child->copy(); // 親クラスの実装 clone $this が呼ばれる
// $objはParentClass？ ChildClass?
```

正解は、`ChildClass`。


```php
assert(get_class($obj) === 'ChildClass');
```
VCCW上のWordPressにインターネット経由でアクセス可能にしてスマホで確認

`vccw-share` というコマンドを作りました。

https://github.com/vccw-team/vccw-share

これを使用すると、コマンド一発で VCCW 上の WordPress サイトをインターネット経由で確認できるようになり、スマホで確認したり、クライアントに進捗状況を見せたりすることが簡単になります。

## インストール方法

VCCW で構築したマシンに SSH で入ってください。

```
$ vagrant ssh
```

次に、以下のコマンドを実行して必要なパッケージ等をインストールしてください。

```
$ curl https://raw.githubusercontent.com/vccw-team/vccw-share/master/setup.sh | bash
```

セットアップは以上で完了です。

`$HOME/.vccw/provision-post.sh` に上のコマンドを以下のように記述すれば、`vagrant up` のたびに実行されるようになります。

```
#!/usr/bin/env bash

set -ex

curl https://raw.githubusercontent.com/vccw-team/vccw-share/master/setup.sh | bash
```

http://vccw.cc/#h2-5

## VCCW 上の WordPress をインターネット経由で共有する

セットアップが完了すると `vccw-share` というコマンドがインストールされますので、それを VCCW マシン上で実行してください。

```
$ vccw-share
```

このコマンドは VCCW 上の WordPress をインターネット経由で閲覧可能にするためのリバースプロキシ及び `ngrok` を起動します。

```
ngrok by @inconshreveable                                                 (Ctrl+C to quit)

Session Status                online                                                      
Session Expires               7 hours, 59 minutes                                         
Version                       2.2.8                                                       
Region                        United States (us)                                          
Web Interface                 http://xxx.xxx.xxx.xxx:4040                   
Forwarding                    http://xxxx.ngrok.io -> localhost:5000                  
Forwarding                    https://xxxx.ngrok.io -> localhost:5000                 

Connections                   ttl     opn     rt1     rt5     p50     p90                 
                              0       0       0.00    0.00    0.00    0.00
```

上のような出力がでれば成功です。表示されている `https://xxxx.ngrok.io` のような URL にブラウザでアクセスすると WordPress サイトが表示されます。

インターネット経由でのアクセスを止めたい場合は、`Ctrl+C` で `ngrok` を停止することができます。

## 仕組み

`vccw-share` は Vagrant 上の VCCW マシンに Node で開発したリバースプロキシと `ngrok` をインストールし、それらを組み合わせてインターネット経由で WordPress にアクセスすることを可能にしています。

このリバースプロキシは、WordPress のコンテンツに含まれる URL から `WP_HOME` の値、つまりホスト名を削除するために使用しており、これによってインターネット経由で閲覧してもテーマの CSS 等がリンク切れしないで表示されるようになります。

リバースプロキシのソースコードも同じリポジトリにありますので、なにか改善できることがあればプルリクをお待ちしています。

## カスタマイズ

`$HOME/.ngrok2/ngrok.yml` は `ngrok` の設定ファイルです。

ここに例えば以下のようにリージョンに`ap`と指定するとレイテンシーが改善されて若干早くなります。

```
region: ap
tunnels:
  wp:
    addr: 5000
    proto: http
```

https://ngrok.com/docs#config-location

## 既知の問題点

* `wp-admin` にはアクセスできません。できるけどいろいろ不具合があるという感じ。
* `ngrok` は無料アカウントではリクエスト数の制限が40回/分と厳しいため、頻繁にエラーが出てしまいます。

`ngrok` の有料アカウントでは、これらの制限が解除されることに加えて、サブドメインを指定できるようになります。

サブドメインを指定すると、常に同じ URL でアクセスできるようになるので、スマホ等のブラウザでブックマークに入れておくと便利です。
Laravelでscope内にサブクエリを使いたい、且つサブクエリ内に変数を渡したい場合

# やりたいこと
・fugafuga2というタグを持っているpostを取得したい
・これを取るだけだと[hasManyとか](https://readouble.com/laravel/5.5/ja/eloquent-relationships.html)を適当に使うといいが、他のscopeと組み合わせたい
・fugafuga2を$request等から取得したい

# 前提

データモデルは以下のような構造とする（更新日時等は割愛）

posts

|id|title|content|
|---|---|---|
|1|タイトル1|タイトル1\nタイトル1\nタイトル1|
|2|タイトル2|タイトル2\nタイトル2\nタイトル2|
|3|タイトル3|タイトル3\nタイトル3\nタイトル3|

tags

|id|quote|
|---|---|
|1|hogehoge1|
|2|fugafuga1|
|3|hogehoge2|
|4|fugafuga2|
|5|hogehoge3|
|6|fugafuga3|

relation_posts_to_tags

|id|post_id|tag_id|
|---|---|---|
|1|1|2|
|2|1|4|
|3|2|1|
|4|2|3|
|5|3|4|

# 実装

クロージャのあとにuse ([引数])をすればOK

```php:Model
    public function scopeHasTagName($query, $tag_name)
    {
        // tag_nameを持っていない場合は処理せずreturn
        if (empty($tag_name)) return $query;
        return $query->whereIn('id', function ($query) use ($tag_name) {
            return $query->select('post_id')
                         ->from('relation_posts_to_tags')
                         ->join('tags', 'relation_posts_to_tags.tag_id', '=', 'tags.id')
                         ->where('tags.quote', '=', $tag_name);
        });
    }
```

```php:Controller
$posts = Post::hasTagName('fugafuga2')
```
Terraform Bootcamp

<p>この投稿は東京渋谷ヒカリエ 8 階にある <a href="http://aka.ms/aajp" target="_blank">Azure Antenna</a> で実施された「Azure Infrastructure as Code 隊 Terraform Bootcamp 」で使われた資料のご案内です。</p>

- <strong>Terraform Bootcamp</strong><br />
https://www.slideshare.net/ToruMakabe/terraform-bootcamp-azure-infrastructure-as-code

<p>:satellite:&nbsp;&nbsp;新しいイベントの情報は、Connpass の <a href="http://aka.ms/aajp" target="_blank">Azure Antenna サイト</a>よりご確認いただけます。</p>

<p>:arrow_backward:&nbsp;<a href="https://qiita.com/AzureAntenna/items/71f394c100fbfa8ddcc8">「Azure Antenna 実施イベント資料（カテゴリ別）」に戻る</a></p>
【Ruby】methodの小さなサンプルメモ

# メモ

```ruby:test.rb
def test1
  p "test1"
end

def test2
  p "test2"
end

mymethod = method(:test1)
p mymethod
mymethod.call

mymethod = method(:test2)
p mymethod
mymethod.call
```

```console:結果
#<Method: main.test1>
"test1"
#<Method: main.test2>
"test2"
```

# 参考

method (Object) - Rubyリファレンス https://ref.xaio.jp/ruby/classes/object/method
GitLabにバンドルされているnginxからリバースプロキシでJupyterを使う

# はじめに
Omnibus版のGitLabを稼働させているサーバから，LAN内の別のマシンで稼働しているJupyterに接続したかったので，その時の記録です．

# 環境
+ ルータ  
IP:192.168.0.1
+ サーバ1（GitLab用）  
OS: CentOS 7.5  
IP: 192.168.0.2
+ サーバ2（Jupyter用）  
OS: Ubuntu 18.04 LTS  
IP: 192.168.0.3  
JupyterはLAN内からパスワード認証で接続できるようになっています  
（ https://qiita.com/tdrk/items/e6c293021cbcb0e96cd2 ）

## Jupyterの設定の変更（サーバ2）
`~/.jupyter/jupyter_notebook_config.py`の各項目を以下のように編集します．

```jupyter_notebook_config.py
c.NotebookApp.port = 8888
c.NotebookApp.open_browser = False
c.NotebookApp.base_url = '/jupyter/'
c.NotebookApp.base_project_url = '/jupyter/'
c.NotebookApp.webapp_settings = {'static_url_prefix':'/jupyter/static/'}
```

jupyter notebookをバックグラウンドで起動させておきます．
```
$ jupyter notebook &
```

## nginxの設定の変更（サーバ1）

`/var/opt/gitlab/nginx/conf`に設定ファイル`jupyter.conf`を作成します．

```jupyter.conf
location /jupyter {
    proxy_pass http://192.168.0.3:8888;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
}
```

GitLabのnginxは，`/etc/gitlab/gitlab.rb`の内容から設定ファイルを自動生成するので，先程作成した設定ファイルを読み込むよう次の1行を追加します．

```gitlab.rb
nginx['custom_gitlab_server_config'] = "include /var/opt/gitlab/nginx/conf/jupyter.conf;"
```

これで，LAN内から`http://192.168.0.2:8888/jupyter`に接続すると，jupyter notebookが操作できると思います．

# 参考URL
http://fijixfiji.hatenablog.com/entry/2016/02/11/221253
http://www.albertauyeung.com/post/setup-jupyter-nginx-supervisor/
Uncaught ReferenceError: $ is not defined【rails】

### jqueryはrequire_treeより前で読み込む

railsへjQueryを導入しようとしたところ、最初の`$(function()`でエラーが起きる。

```js
$(function(){
//省略
})
```


`//= require_tree .`を最後に読み込むようにして解決👌

```app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require rails-ujs
//= require_tree .
```
【Bigquery】Token must be a short-lived token (60 minutes) and in a reasonable timeframeとかでたときの処方箋

ETLツールの改修をしていてふとこんなメッセージがでたのです。

多分Bigqueryからのエラーメッセージなんだと思う。

エラーの全文

```
Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and ex
p values and use a clock with skew to account for clock differences between systems.
```

まさに、
「あのぉ、さっきまでは動いていたんですけどぉ・・・なにもしてないのに壊れちゃいましたぁ・・・」
状態です。あるあるです。部下がこう言ってきても怒らないと誓っています。

結論からいうと仮想マシンをずっと動かしているとたまに時空がずれるときがあるのです。

なので、

`sudo date -s "2016/12/24 11:45:14"`

といった形で仮想マシンの時間を直してあげると解決するはずです。
ターゲットホストまでのネットワークを探索する（tracert コマンド）

# ネットワークトポロジー
- ネットワーク上で端末がどうのように接続されているか、接続形態のこと。
- スター、バス、リング型などがある。

# tracert

```bash
tracert -d {ターゲットの IP アドレス}
```
※ -d： 	結果に表示するIPアドレスからホスト名への名前解決を行わない。
※ ICMP（ping）で探索する。

# 例）www.yahoo.co.jp までの経路を調査

「www.yahoo.co.jp」の IP アドレスは？

```bash
nslookup -d www.yahoo.co.jp
```
```bash
権限のない回答:
名前:    edge.g.yimg.jp
Address:  182.22.31.124　← これ
Aliases:  www.yahoo.co.jp
```

「www.yahoo.co.jp」までの経路は？

```bash
tracert -d 182.22.31.124
```
```bash
182.22.31.124 へのルートをトレースしています。経由するホップ数は最大 30 です

  1     5 ms     1 ms     2 ms  {自分の IP アドレス}
　…
  8    22 ms    20 ms    19 ms  182.22.31.124

トレースを完了しました。
```
[初心者向け]htmlについて知ろう！

# はじめに


＜対象とする人＞
・プログラミングを勉強していきたい
・プログラミングが全くの未経験
・パソコンが好きだし、プログラミングやってみよかな〜

そんな方のための記事。（ちなみに、筆者自身も今年の2月ごろからプログラミングを始めた初心者です）

そんなのを書いていきますね〜。

この記事ではHTMLの基本的なことを記事に書き、
webページに自分が書いたものを表示できるようにしたいと思います。


## HTMLってなんなの？？？？

一言で言うと・・・・
「ホームページを作るときに使う言語」

です。

めっちゃざっくりとした説明ですので、詳しく知りたい方は、googleで「htmlとは」とググれば詳しくでてきます。

htmlとは、「Hyper Text Markup Language（ハイパーテキスト・マークアップ・ランゲージ）」の略で・・・・
みたいなのでてくるのでそちらをみてみてください。
（この記事では、簡単なことだけ説明をしていきます。）


## 習うより慣れろ

実際にhtmlを書いていったほうが頭に入りやすいと思うので、早速書いていきましょう。

「sublimeText」
を使って進めていきますので、ダウンロードしましょう。

[sublimeTextのダウンロードページ](http://www.sublimetext.com/3)

〜ダウンロード後〜
その１
Sublime textを起動してください。

その２
ファイルを新規作成
ctrlキー + n を押すと、ファイルを新規作成できます。

その３
・beginner.htmlという名前でファイルを保存します。デスクトップに保存しましょう。
ctrlキー + sを使えば保存ができます。

そして、beginner.htmlに

```beginner.html
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8" />
  <title></title>
</head>
  <body>
    プログラミングの勉強頑張ろう！
  </body>
</html>
```

をコピペしちゃってください。
そして、また保存してください。

最後にデスクトップにある、beginner.htmlをダブルクリックします。
すると、
![スクリーンショット 2018-05-29 16.38.08.png](https://qiita-image-store.s3.amazonaws.com/0/255085/9014b195-c566-9b9e-e56d-d7fc05b0d639.png)

こんなWebページを表示することができました！！！！
やったね。

無事、「プログラミングの勉強頑張ろう！」が表示できたかと思います。

##違う言葉を表示させよう
先ほどコピペしたものの中に
＜body＞
と
＜/body＞
というのがあったと思うですが、htmlではその＜body＞と＜/body＞の中に色々と書くことでWebページに表示させるものを変えることができます。
ここでは、例として「プログラミングの勉強頑張ろう！」を「プログラミングって楽しい！」に変えてみようと思います。

```beginner.html
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8" />
  <title></title>
</head>
  <body>
    プログラミングって楽しい！
  </body>
</html>
```

と書いて、
ctrl + s で編集した内容を保存。
そして、beginner.htmlのページで、「F5」を押してwebページの更新。
そうすると、
プログラミングって楽しい！
がページに表示されたかと思います。
## まとめ
細かい説明は飛ばしたのですが、これで、Webページに自分が書いたものが反映されたかと思います。
基本的にプログラミングは、
Webページに表示したいことを「sublimeText3」のようなテキストエディタに書く。コードを書いていく。
↓
Webページに表示できているか確認
↓
よっしゃ表示できてるやん！嬉しい！！

こんな流れになります。
今回は、その「よっしゃできてるやん！嬉しい！！」
の部分を知ってもらえたらなーと思い、この記事を書きました。
お疲れ様でした。


## 補足
細かい説明をすっとばしちゃったんで、一応、少し書いておきますね。

＜!DOCTYPE HTML＞
この文章はHTMLの文章ですよ！
っていう宣言の文です。記述がないと、文字が表示されなかったりします。

＜head＞
サイト自体に関する情報を定義する部分。
webページの見た目にはあんまり関係がないです。

＜meta charset="UTF-8" /＞
文章に関する情報を指定しています。
記述しない場合、文字化けをしてしまうことがあります。

＜body＞
ここに記述されたものがwebページに表示されます。


### というわけで・・・
お読みいただきありがとうございました。
間違い等ございましたら、ご指摘いただけると嬉しいです！
jquery.pep.jsでコールバックが受け取れない

スムーズなドラッグ＆ドロップを実現してくれる便利なjqueryプラグイン、
<a href="http://pep.briangonzalez.org" target="_blank">「Pep」</a>を使っていて気がついたことがあったのでメモ。

このプラグインは指定した要素をドラック＆ドロップなどのマウス操作に対応させ、
さらにキネティックに動かすことができるようになります。

ただし、問題点がひとつ。
指定した要素をJavacriptなどで制御したときにコールバックが受け取れない問題がありました。

たとえば、

```coffeescript
    $(@el).pep({
      cssEaseDuration: 500
      rest: =>
        console.log 'rest!'
```

とすると、マウス操作した際は操作完了後に’rest!’とでてきますが、
下記のようにマウス操作以外のなんらかのタイミングでjavascriptなどで移動させるとコールバックが機能しません。

```coffeescript

    $(@el).css({
      left: 100
      height: 100
    })
```

色々調べてみると、マウス操作などではanimateメソッドで動かしているが、
CSSメソッドで動作させるとCSS3のアニメーション機能で動かしていることがわかりました。

CSS3アニメーションの完了イベントはwebkitTransitionEndなので、
下記のようにイベントを監視します。

```coffeescript
    $(@el).on(
      'webkitTransitionEnd'
      (e)=>
        console.log 'rest!'
    )
```
無事コンソールに'rest!'が表示されました。

ただ複数回コールバックが呼ばれてしまうので、
完了後に適宜offするなどしてください。
Ae コンストラクタによるファンクションの書き方 + アンカーポイントを真ん中へ

#目標のOpenWeatherMap APIで作るアニメーション

プログラムを始める時に「OpenWeatherMapのAPIを活用してお天気ニュース的なものを作る」という事を目標にしていたのですが、もう少しで完成しそうです！！
あとはUIを考えてって感じで、進み具合は60％ぐらいでしょうか。。。

その作業の中でjsonからテキストデータを大量に引っ張ってそれぞれ設定してたら大変なのでコンストラクタによるファンクションで設定しようと思っています。
コンストラクタ内でアンカーポイントの設定を行ってます。

OpenWeatherMapからのjsonから大量に配列であるのであとはfor文で一気にテキスト出力しようと思っています。
とりあえずメモまで

addText("〇〇〇〇")ココにテキストを入れたら
テキストレイヤーが作成され、アンカーポイントも真ん中に設定されます。

```jsx

//アンカーを真ん中に
function addText(Layertext,fs){
    app.beginUndoGroup("moving anchor");
        function roundFloat(number) {
        var _pow = Math.pow( 10 , 4 );
        return Math.round( number * _pow ) / _pow;
        }
        var myComp = app.project.activeItem;
        var curTime = app.project.activeItem.time;
        
        cNText = myComp.layers.addText(Layertext);
        var cNTextTd = cNText.property("ADBE Text Properties").property("ADBE Text Document").value; //テキストドキュメント
        cNTextTd.fontSize = fs;
        cNText.property("ADBE Text Properties").property("ADBE Text Document").setValue(cNTextTd);
    
        var myAnchor = cNText.property("ADBE Transform Group").property("ADBE Anchor Point");
        var tl = cNText.sourceRectAtTime(curTime, false).left; //テキストの左側の座標 l
        var tw =cNText.sourceRectAtTime(curTime, false).width; //テキストの全体の幅 b
        var tt = cNText.sourceRectAtTime(curTime, false).top;//テキスト上の座標 c
        var th = cNText.sourceRectAtTime(curTime, false).height; //テキスト全体の高さ d
        var lv=myAnchor.value;
        var setX=roundFloat((tw/2)+tl);
        var setY=roundFloat((th/2)+tt);
        var setA = myAnchor.setValue([setX,setY]);  
    app.endUndoGroup();
}

addText("ここにテキストを入力する",100)
```
サーバーの動作を確認する（nmap コマンド）

# Ping Sweep
- 複数の IP アドレスに対して ping コマンドを実行して、ネットワークで稼働しているホストを発見・偵察すること。
- Ping Sweep の 1 つとして nmap がある。 

# nmap
``` bash
nmap -sn -PE {IPアドレス}
```
※ -sn：ホストを発見した後にポートスキャンを行わない（No Port Scan）
※ -PE：echo リクエストを送信する

IP アドレスの指定方法はいくつかある。

- Xxx.Xxx.Xxx.0/24
- Xxx.Xxx.Xxx.0-255
- Xxx.Xxx.Xxx.*

# 注意
- ping を送っても返事をしない（echo リクエストを送信しない）設定をしているホストもある。
watch中に変更したファイルのみeslintをかける(grunt, gulp)

eslintのconfigファイルを変更した時など、一旦、変更のあったjsファイルのみにeslintをかけたい時もあると思います。意外と投稿されていなかったので、投稿いたします。

## grunt
grunt-contrib-watchのみで可能です。

```javascript:Gruntfile.js
 module.exports = function(grunt) {
  grunt.initConfig({

    watch: {
     scripts: {
      files: '**/*.js',
      tasks: ['eslint'],
      options: {
        spawn: false, <- *1
      },
     },
   },

   eslint: {
        target: ['**/**.js']
   }
  });

  grunt.event.on('watch', function(action, filepath, target){ <- *2
    if (target == js) {
     grunt.config(['eslint', 'target']);
    }
  });

  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Tasks
  grunt.registerTask('default', ['watch']);
};
```

### 1 watchタスクにspawnオプション追加
一時的な設定の変更を許可する。
 `nospawn: true` でも可能ですがv0.5.0からspawnが導入されているので、spawnの方が良いかと。


### 2 イベントリスナーを設定 grunt.event.on('watch', function())
grunt.configにて一時的にeslintタスクの設定を変更
grunt.config.setと同様

## gulp
gulp-cachedが必要になります。
※あくまでキャッシュなので、初期実行時は全てのファイルのエラーが出ます。その後に変更したjsファイルのみエラーが出力されます。よって、gulp-plumber等は必須になります。

```javascript:gulp.js
// gulp-cached
var cached = require('gulp-cached');

// eslint
var eslint = require('gulp-eslint');

gulp.task('eslint', function () {
  return gulp.src(path.js_src)
    .pipe(cached('eslint')) <- *1
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(eslint())
    .pipe(eslint.format());
});

// task
gulp.task('default', function () {
  gulpSequence('build', 'eslint', 'watch')(); <- *2
});
```

### 2 watchの前に初期実行しておく
この対応によって、変更したタイミングでそのjsファイルのみeslintがかかります。

### gulp-changedが推奨される場合も
ビルド後のファイル群に対するタスクであれば、gulp-changedで行えます。
時系列データの外れ値検出

トレンドを持った時系列データに対して外れ値の検出を行うために指数加重移動平均を使ったらけっこういい感じだったのでまとめる。

注意点として、今回の手法は「理論的に裏付けられている手法」でも「時系列解析で一般的に用いられる手法」でもない (と思う) ので、真似する際は自己責任で。

他にも、「外れ値検出 ⊂ 異常検知」と考えると以下のような手法もあるので参考までに。
[Pythonによる時系列データの異常検知 \- Technology Topics by Brains](http://blog.brains-tech.co.jp/entry/2017/10/17/170140)

## 環境
今回は Python 3.6 環境で、以下のモジュールを利用する。

``` python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```

また、Jupyter Notebook 上でグラフを表示させるために以下の設定をしている。

``` python
%matplotlib inline
```

## データ
今回はテキトーな時系列データを生成してそれを使うことにする。

``` python
# 乱数を固定
rand = np.random.RandomState(seed=20)

# データを生成
idx = pd.date_range(start='2018-01-01', end='2020-12-31', freq='D')
x = np.arange(len(idx))
y = 500000 \
    + x ** 2 \
    + np.sin(x/4) * 100000 \
    + rand.randn(len(x)) * 100000 \
    + rand.gamma(0.01, 1000000, len(x))

# Series に変換
ts = pd.Series(y, index=idx)

# 描画
ts.plot()
```

![](https://qiita-image-store.s3.amazonaws.com/0/16369/9e8d10b6-ac81-da7c-88be-f2ed8225f8ba.png)

トレンド + 周期 + ノイズ の中に外れ値のようなものがいくつか見受けられると思う。

この外れ値を検出したい。

## 指数加重移動平均
[指数加重移動平均 (Exponential Weighted Moving Average)](https://ja.wikipedia.org/wiki/%E7%A7%BB%E5%8B%95%E5%B9%B3%E5%9D%87#%E6%8C%87%E6%95%B0%E7%A7%BB%E5%8B%95%E5%B9%B3%E5%9D%87) は、直近のデータを重視し古いデータになるほど指数関数的に重みが減少する移動平均の一種。

単純移動平均と比べると古いデータに影響されにくいので、急激にトレンドが変化する時系列データでも適用しやすい。

Pandas では `ewm` メソッドを使うことで簡単に指数加重移動平均を計算できる。

``` python
ewm_mean = ts.ewm(span=90).mean()  # 指数加重移動平均

fig, ax = plt.subplots()
ax.plot(ts, label='original')
ax.plot(ewm_mean, label='ewma')
ax.legend()
```

![](https://qiita-image-store.s3.amazonaws.com/0/16369/46cfa2f5-ad0d-3423-7714-fea301d1e6cc.png)

おおまかなトレンドが掴めていることがわかると思う。

この移動平均から大きく外れたデータを外れ値として扱いたい。

## 偏差から外れ値を検出する
移動平均と同様に `ewm` メソッドを用いて移動標準偏差を求め、「その時点でのデータのバラつき具合」の指標として利用する。

``` python
def plot_outlier(ts, ewm_span=90, threshold=3.0):
    assert type(ts) == pd.Series
    fig, ax = plt.subplots()

    ewm_mean = ts.ewm(span=ewm_span).mean()  # 指数加重移動平均
    ewm_std = ts.ewm(span=ewm_span).std()  # 指数加重移動標準偏差
    ax.plot(ts, label='original')
    ax.plot(ewm_mean, label='ewma')

    # 標準偏差から 3.0 倍以上外れているデータを外れ値としてプロットする
    ax.fill_between(ts.index,
                    ewm_mean - ewm_std * threshold,
                    ewm_mean + ewm_std * threshold,
                    alpha=0.2)
    outlier = ts[(ts - ewm_mean).abs() > ewm_std * threshold]
    ax.scatter(outlier.index, outlier, label='outlier')

    ax.legend()
    return fig


plot_outlier(ts)
```

![](https://qiita-image-store.s3.amazonaws.com/0/16369/64cbd5a7-b1b1-04da-02f0-9ccecf58f2fa.png)

オレンジの ◯ が外れ値として検出されたデータで、直感的にもそれほど間違ってはいないと思う。

最初 (2018-01 あたり) にある外れ値が検出できていないが、これは移動標準偏差を計算するための過去のデータが足りないためで、過去のデータのみからこれを検出するのは難しい・・・。

また今回「移動平均が移動標準偏差から 3.0 倍以上離れていたら外れ値」と定義したが、この 3.0 という数字に明確な根拠はない。ただ「ある時点でのデータの生起確率が正規分布に従う」と仮定すると、[標準正規分布表](http://www.koka.ac.jp/morigiwa/sjs/standard_normal_distribution.htm) より 3.0 は .4987  なので、「標準偏差の 3.0 倍以上」は「全体の約 0.13% 以下の外れ値」とみなすことができる。