OmniAICreator/Qiita-1.07M huggingface dataset:
日経平均株価を深層学習で予測してみたい（下調べ編）

## とりあえずググってみた

http://anopara.net/2016/06/21/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%A7%E6%97%A5%E7%B5%8C%E5%B9%B3%E5%9D%87%E3%81%AE%E5%A4%89%E5%8B%95%E3%82%92%E4%BA%88%E6%B8%AC%E3%81%99%E3%82%8B1/
https://anopara.net/2016/06/27/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%A7%E6%97%A5%E7%B5%8C%E5%B9%B3%E5%9D%87%E3%81%AE%E5%A4%89%E5%8B%95%E3%82%92%E4%BA%88%E6%B8%AC%E3%81%99%E3%82%8B2/
https://www.buildinsider.net/small/deeplearningnext/stockprediction
http://www.madopro.net/entry/2016/07/16/221041
https://kaigi.org/jsai/webprogram/2017/pdf/1112.pdf
https://qiita.com/wbh/items/efbf71c5c89a9b52640f
https://qiita.com/verizi/items/a3642b44f0ef5ad299f5
http://blog.takuya-andou.com/entry/deeplearning_kabu
https://www.slideshare.net/ssuser4b29b7/ss-66793390
http://cedro3.com/ai/nikkei-stock-dl/#comment-600
https://qiita.com/torus117/items/fe92b46fe8fb83699505
https://www.ecomott.co.jp/tech_blog/?p=2424
https://qiita.com/AfricaUmare/items/4317fb88299995e54e5f
http://www.rccm.co.jp/icem/pukiwiki/index.php?LSTMによる時系列データ予測
http://www.ieice.org/~iss/jpn/Publications/issposter_2018/data/pdf/ISS-P-040.pdf

LSTMが多いようだ。
Hugo で AsciiDoc しようとしてハマった話

## 環境

* OS: Ubuntu 16.04
* Hugo: v0.37

Hugo は ``snap install hugo`` でインストールした．

## 事象

``.adoc`` ファイルを含むサイトをビルドしようとすると，``asciidoctor`` と ``asciidoc`` が見つからないと怒られる．

```
% hugo
Building sites … ERROR 2018/03/31 17:21:14 asciidoctor / asciidoc not found in $PATH: Please install.
                  Leaving AsciiDoc content unrendered.
```

ところが，両方とも PATH 上には存在する．

```
% which asciidoctor
/usr/bin/asciidoctor

% which asciidoc
/usr/bin/asciidoc
```

## 原因

Hugo のインストールに Snappy を使っていた (``snap install hugo`` でインストールしていた) のが原因．
Snappy 環境から外部のプログラムを呼び出すことができないらしい．

## 解決法

おとなしく APT からインストールするか，deb ファイルをダウンロードしてきてインストールする．

### Snappy 環境の Hugo の削除

まず，Snappy 環境の Hugo をアンインストールする．

```
% sudo snap remove hugo
```

### Hugo の入れなおし

楽にインストールしたいなら，APT でインストール:

```
% sudo apt install hugo
```

新版を使いたいなら，deb ファイルをダウンロードしてきてインストール:

```
% wget https://github.com/gohugoio/hugo/releases/download/v0.37.1/hugo_0.37.1_Linux-64bit.deb
% sudo dpkg -i hugo_0.37.1_Linux-64bit.deb
```

## 参考文献

* https://discourse.gohugo.io/t/solved-asciidoctor-asciidoc-not-found-in-path/10017/9
gradle tasks 日本語訳

gradle tasks 実行時に出力されるヘルプメッセージの日本語訳。


#root プロジェクトから実行可能な全タスク


##ビルド設定タスク

###gradle init
新しい Gradle プロジェクトを初期化する。

###gradle wrapper
Gradle ラッパーファイルを生成する。


##ヘルプタスク

###gradle buildEnvironment
root プロジェクトの ``source`` に宣言されている依存情報を全て表示する。

###gradle components
root プロジェクトの ``source`` によって生成される構成要素を表示する。 [開発中]

###gradle dependencies
root プロジェクト内に宣言された依存情報を全て表示する 。

###gradle dependencyInsight
root プロジェクトの ``source`` 内の特定の依存情報に対する洞察を表示する。

###gradle dependentCompononts
root プロジェクトの ``source`` 内の構成要素の依存構成要素を表示する。 [開発中]

###gradle help
ヘルプメッセージを表示する。

###gradle model
root プロジェクトの ``source`` の設定体系を表示する。 [開発中]

###gradle projects
root プロジェクトの ``source`` のサブプロジェクトを表示する 。

###gradle properties
プロジェクトの ``source`` のプロパティを表示する。

###gradle tasks
root プロジェクトの ``source`` から実行できるタスクを表示する 。

###gradle tasks --all
全タスクを表示し、より詳細な情報を表示する。

###gradle help --task task
タスクについての詳細を表示する。
【python3】配列の要素を文字列に変換して一行表示

<h1>for文をつかう方法</h1>
```python
#入力
array=["a","b","c"]
oneLinerString=""
for x in array:
    oneLinerString += x
print(oneLinerString)

#出力
abc
```
<h1>for文をつかわない方法（joinをつかう）</h1>
```python
#入力
array=["a","b","c"]
oneLinerString="".join(array)
print(oneLinerString)

#出力
abc
```
【GoogleChrome】localStorageを使って表示状態を保存可能にした

# 概要
GoogleChromeの拡張機能を作る企画第2.5弾です。前回は[こちら](https://qiita.com/mkt120/items/419efa254e7c6d4cba16)。
以前実装したブックマーク一覧表示のアコーディオン表示の開閉状態を保存して、
次回表示時に復元できるようにしました。

# コード
githubにコードを上げています。
https://github.com/mkt120/BookmarkListNewTab

## LocalStorage
以下を参考に実装しました。
[WebStorage API(LocalStorage)を使ってみた](https://qiita.com/masamitsu-konya/items/c69515604570150d3ab9)

key&value(String限定)形式で持てる設定ファイルってイメージです。
追加したのは大きく二か所

### アコーディオン開閉時

クリックによるアコーディオンの開閉時に、localStorageに開閉状態を保持させるようにしました。

```newtab.js
parentDiv.addEventListener("click", function(){
  var element = parentDiv.getElementsByClassName(CLASS_BOOKMARK_TITLE_ICON_VIEW)[0];
  var isOpen;
  if (childViews.style.display != "none") {
    // 開いている状態 クローズする  
    isOpen = 'false';
    element.innerHTML = TITLE_VIEW_ICON_OPEN;
    childViews.style.display = "none";
  } else {
    // 閉じている状態 オープンする
    isOpen = 'true';
    element.innerHTML = TITLE_VIEW_ICON_CLOSE;
    childViews.style.display = "";
 }
 var id = parentDiv.getAttribute('id');
 localStorage[id] = isOpen;
);
```

### View生成時
View生成時にローカルストレージを参照して開閉状態を取得、表示状態に反映させるようにしました。

```newtab.js
// localStorageから開閉状態を取得し、表示に反映
var isOpen = localStorage[id];
if (isOpen == 'true') {
  childViews.style.display = "";
} else {
  childViews.style.display = "none";
}
```

これで画面再表示時に、前回の表示状態が復元されるようになりました。

# 最後に
Android Javaしか書けない私なので、HTMLとかCSSとかJavascriptの勉強も兼ねてですが、
将来的にはiGoogleの機能を独自実装できるようになることを目指しています。
Node.jsでGoogle AnalyticsのPV数を取得

#準備

1. [Google Developer Console](https://console.developers.google.com)にアクセス。
2. 左部の「ライブラリ」から、「Google Analytics Reporting API」を選択し有効化。
2. 左部の「認証情報」>「認証情報を作成」>「サービスアカウントキー」を選択。
3. サービスアカウント名、サービスアカウントIDを適当に入力、キーのタイプはJSONを選択、役割は「Project」>「閲覧者」を選択し、「作成」を押すとJSONファイルが生成される。
4. [Google Analytics](https://analytics.google.com)にアクセスし、JSON内にある「client_email」を表示・分析権限を付与して登録。


#コードを作成
適当にNodeのプロジェクトを作成し、```npm install --save googleapis```を実行。
googleapisのリファレンスを参考にしながら、下記のコードを作成。メトリクスにはga:pageviewsを指定。

```javascript:app.js
const {GoogleApis} = require('googleapis');
const google = new GoogleApis();
var analytics = google.analyticsreporting('v4');
var credential = require('./XXXXXXXX.json');        //準備時に生成したJSONファイルを指定
var viewId = 'XXXXXXXXX';                           //GoogleAnalyticsのビューidを指定
var startDate = "2018-01-01";                       
var endDate = "2018-04-01";

var jwtClient = new google.auth.JWT(credential.client_email, null, credential.private_key, ["https://www.googleapis.com/auth/analytics.readonly"], null);

jwtClient.authorize((error, tokens) => {
    if (error) {
        console.log(error);
        return;
    }
    analytics.reports.batchGet({
        resource: {
            "reportRequests": [
                {
                    "dateRanges": [
                        {
                            "startDate": startDate,
                            "endDate": endDate
                        }
                    ],
                    "viewId": viewId,
                    "dimensions": [
                        {
                            "name": "ga:pagePath"
                        }
                    ],
                    "metrics": [
                        {
                            "expression": "ga:pageviews"
                        }
                    ],
                }
            ]
        },
        auth: jwtClient
    }, (error, response) => {
        if (error) {
            console.log(error);
        }
        const pv = response.data.reports[0].data.rows[0].metrics;
        console.log('pv');
        console.log(pv);
    });
});
```

#実行
```node app.js```で実行すると下記のようなログが出力される。
<img width="187" alt="スクリーンショット 2018-03-31 16.24.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/203706/c71bed35-a819-898e-924c-26e9ff022728.png">

GoogleAnalyticsでも一応確認。
<img width="608" alt="スクリーンショット 2018-03-31 16.23.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/203706/0f432662-b898-3877-15f9-ab0464266e79.png">
ログの値と、ページビュー数が一致していることから、正しく値を取得できていることを確認。

#参考
https://github.com/google/google-api-nodejs-client
http://beyondjapan.com/blog/2017/04/get-google-analytics-data-by-nodejs
FlutterでAWSを使いたい！

# はじめに
FlutterでAmazon Web Serviceを使いたかったのですが、

<img width="1199" alt="スクリーンショット 2018-03-24 9.46.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/71342/e466b5b5-1818-e161-8f18-2e3375961bc4.png">

現時点でDart用のSDKは用意されていません。
そこで何とか使う方法を探ってみてうまくいったので、この記事ではその導入手順について解説します。
`dart:js`を使ってAWSのfor JS SDKを叩くやり口もあるかもしれませんが、ここで紹介するのは各プラットフォーム毎にパッケージを導入してそれぞれのネイティブコードを書く戦術です。
### 環境
- macOS High Sierra 10.13.3
- Xcode 9.2
- Android Studio 3.0.1

# 手順
[公式サイト](https://flutter.io/platform-channels/)を参考にしつつ、プラットフォームと連携したプロジェクトを作っていきます。
## プロジェクトの作成
デフォルトではAndroidはJAVA、iOSはobjective-Cのコードが生成されます。もしKotlinとSwiftに変えたい場合には以下のようにします。

```
$ flutter create -I swift -a kotlin {project_name}
```


## iOSプラットフォームサイドにAWS SDKを導入
今回はCarthageを使っていきます。
[AWS公式Github](https://github.com/aws/aws-sdk-ios)
### Carthageのセットアップ
Carthageをインストールします。

```
$ brew install carthage
```

`{Flutterプロジェクトディレクトリ}/ios/` にCartfileを作成します。

```
$ vi Cartfile
```

Cartfileの中身は以下のようにします。

```:Cartfile
 github "aws/aws-sdk-ios"
```

ライブラリをインストールするために、以下のコマンドを走らせます。

```
$ carthage update
```

### Xcodeでの設定
1. `{Flutterプロジェクトディレクトリ}/ios/Runner.xcworkspace`をXcodeで開きます。
2. **Target** > **General** > **Embedded Binaries**にある**+ボタン**をクリックします。
3. 出てきたウィンドウで**Add Other...**をクリック。
4. `{Flutterプロジェクトディレクトリ}/ios/Carthage/Build/iOS/`にframeworkファイルがあるので、使いたいものを選択します。~~面倒なので*.frameworkを全て選択しました。~~
5. **Destination: Copy items if needed**はチェックを入れずに**Finish**をクリック。
<img width="766" alt="スクリーンショット 2018-03-24 11.24.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/71342/c7ce4100-60ea-59b0-0df5-0f781c8fc4bd.png">
6. **Target** > **Build Phrases** > **Run Script**に下の１行を追記します。

```
/usr/local/bin/carthage copy-frameworks
```
このステップを飛ばしてもアプリは動くには動きます。
ここまででiOSでの導入は完了となります。


## AndroidプラットフォームサイドにAWS SDKを導入
作業としてはiOSより楽です。
### セットアップ
- AWS Android SDKを[ダウンロード](https://aws.amazon.com/jp/sdkforandroid/)します
- ダウンロードしたフォルダの中から必要なライブラリとなるjarファイルを選び、Flutterプロジェクトの `app/libs` 下にコピー。
- `app/build.gradle` ファイルの `dependencies` 欄に 前手順で移動したファイルの分だけ `compile files` 行を追加します。
<img width="604" alt="スクリーンショット 2018-03-31 16.40.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/71342/3e2ed0e8-e1d4-2341-6821-13bc8fcd6d29.png">
- Android Studioで作業していれば `Sync now` のボタンが出てくるのでクリック。

ここまででAndroidでの導入は完了です。
Mathematica でグラフを描く

#使用したもの
Mathematica 11


#目標
目標はMathematica を使って意図した通りにグラフを描くことです。自分用の備忘録のつもりなので、ヘルプドキュメント内を探し回ってもなかなか見つからなかったものについてだけ書きます。


#2次元のグラフを描く
##Plot

###例題
自由落下する物体の時間*t* に対する変位*x* のグラフを描きます。

###出力
画像のように出力します。
![Plot.png](https://qiita-image-store.s3.amazonaws.com/0/246571/696df334-a3c9-905d-5c63-c644216ea822.png)


###入力
先の図を出力するための入力内容です。

```
f[t_] = (9.8/2)*t^2;(*Free fall on the Earth*)
g[t_] = (1.6/2)*t^2;(*Free fall on the Moon*)

Plot[{f[t], g[t]}, {t, 0, 2},
 PlotLegends -> 
  Placed[{Style["On the Earth", FontSize -> 18, Black, 
     FontFamily -> "Times New Roman"], 
    Style["On the Moon", FontSize -> 18, Black, 
     FontFamily -> "Times New Roman"]}, Right],
 PlotStyle -> {Directive[Blue, Thickness[0.01]], {Green, 
    Thickness[0.01], Dashed}},
 PlotRange -> {{0, 2}, {f[0], f[2]}},
 PlotLabel -> 
  Style["Free fall", Bold, FontSize -> 20, Black, 
   FontFamily -> "Times New Roman"],
 AspectRatio -> 1,
 Frame -> True,
 FrameStyle -> Directive[Black],
 FrameLabel -> {Row[{Style["t", Italic, FontSize -> 20, Black, 
      FontFamily -> "Times New Roman"], 
     Style[" [s]", FontSize -> 20, Black, 
      FontFamily -> "Times New Roman"]}], 
   Row[{Style["x", Italic, FontSize -> 20, Black, 
      FontFamily -> "Times New Roman"], 
     Style[" [m]", FontSize -> 20, Black, 
      FontFamily -> "Times New Roman"]}]},
 FrameTicksStyle -> 
  Directive[Black, FontSize -> 20,  FontFamily -> "Times New Roman"],
 ImageSize -> Medium]
```

###入力の説明
####`Row` 関数
リストを渡すと、それを横に並べてくれる関数のようです。`FrameLabel` の部分で使用しています。この関数を使わずに`Style[]` を並べるだけだと[m]*x* のように単位と変数が逆転してしまったので、それを回避するために使用しました。
####その他に気を付けたこと
`Plot` のデフォルトのままだとラベル等の文字色がグレーになっていたので、各所で`Black` の指定を入れています。
Linux のデスクトップ環境とテーマ について

Linux初心者の質問、ご了承ください。

LinuxのopenSUSE Leap, Tumbleweedともにインストールしました。しかし、テーマ（ログイン画面、背景）を添付画像のものに変更したいと思っていますが、

1. これは何というテーマでしょうか？(GNOMEを使用する予定です)

2. このテーマのデザインはどこにあるのでしょうか？

3. openSUSE Leap, Tumbleweedでも設定できますか？

4. /usr/shareの中にはbackgroundsは存在していないようすです。

5. 簡単でも結構ですので、存在する場所と手順を教えていただければ幸いです。


![maxresdefault.jpg](https://qiita-image-store.s3.amazonaws.com/0/192533/24d19299-f602-147e-0765-86c8ff36e35f.jpeg)
iOS11.3 ServiceWorkerのファーストインプレッション

iOS11.3とMacOS10.13.4アップデートを実施したメモです。
なお、筆者はiPhone歴9年目で、Androidは個人購入したことありません。

# 動作確認

アップデートが終わると、iPhoneの設定のsafariからいける実験的な機能一覧でServiceWorkerのトグルがデフォルトでONになっています。
![サファリ.jpeg](https://qiita-image-store.s3.amazonaws.com/0/194428/496f7c48-42b2-a8b6-b58c-f25b4f43c662.jpeg)


Mac上から確認すると、確かにServiceWorkerから供給されていることが確認できます。Cool!
![コンソール.jpeg](https://qiita-image-store.s3.amazonaws.com/0/194428/ba53cd8d-6a84-ddaf-072a-5c52abbc7e81.jpeg)

# 開発ツール

上記の動作確認で気づいた方がいらっしゃるかもしれませんが、serviceworker.js（workerスクリプト）やmanifest.jsonが一覧に出てきていません。
通常なら、iPhoneをMacに繋いでSafariの開発メニューの対象デバイスをクリックすると、iPhoneで動かしているwebサイトのコンソールが見られるわけですが、ServiceWorkerの項目は何もありません。

- iPhoneの場合、標準でServiceWorkerのデバッグする機能が見つからない。

- デスクトップ版では、Safari開発メニューにServiceWorkerという専用項目が増えている。
    - デスクトップ版Safariでアクセスしているページのみが対象。iPhoneアクセスしているページは除外されている。
    - 通常の開発コンソールのリソースタブやネットワークタブからworkerスクリプト部分が切り出されてまとめられている。
    - cacheStorageのビューアーは無い。
    - ChromeでのServiceWorkerの登録・解除やmanifestのレビューやイベントのエミューレートのような開発補助は無い。

# ホームスクリーンアイコン

manifest.jsonのアイコンが反映されません。タブ画面のスクショがアイコン化されます。
もともとMobile Safariには「ホーム画面に追加」というメニュー（Webクリップ）があり、独自タグ`<link rel="apple-touch-icon" href="hoge.png" />`でアイコン指定する形式でしたが、まだ統合されていないようです。

# ホームスクリーンからの起動

MobileSafariのタブが動作制御されて起動するのかと思いきや、別アプリとして起動します（たぶんWebViewなんでしょう）。
MobileSafariの出たり消えたりするヘッダー/フッターは一切出現しなくなります。Cool!

WebViewで起動することで、筆者の試験アプリでは以下の状況が発生しました。

- LocalStorageが別扱いになる
- カメラキャプチャがエラーになる(navigator.mediaDevices.getUserMediaがundefined）

他にもポロポロ出てきそうです。

# ディープリンク/ユニバーサルリンク

iOSはstoreで発行する`app-id`が必要ですが、store登録がサポートされていないのでできません。

# PushAPIは無い

リソースキャッシュとホームスクリーン追加だけです。

# 感想

開発ツールはこれから拡充するものとして待っていれば良さそうなものですが、WebView起動が大きなインパクトありました。PC版ChromeでもPWAのデスクトップ版アプリをインストールできる試験機能がフラグ付きで出ていて、似たように別アプリとして起動します。また、MicroSoftがPWAをStore配布できるようにすると発表しています。よって、WebView起動に合わせた設計の見直しが必要になると覚悟した次第です。
シングルトンクラスのインスタンスは作れない

Rubyならできると思ったんだけど。

```ruby
class Sample; end

class << Sample
  def initialize; end
end

# Sample.singleton_class.new　でも同じ
(class << Sample; self; end).new

# これでももちろんだめ
Sample.singleton_class.class_eval do |obj|
  obj.new
end
```

`can't create instance of singleton class (TypeError)` でエラー。頑張ったら相応のことはいけそうな気がするけど。

Note) ちなみにシングルトンクラスのサブクラスも作れない。仮に、サブクラスを作れるとしたら、そのクラスがシングルトンクラスかどうか見分けがつかず、インスタンスを作成することができてしまい、矛盾を発生してしまうからかも。

```ruby
class Sample; end
Class.new(Sample.singleton_class) # can't make subclass of singleton class (TypeError)
```
[Note] Using Tensorflow API in C++

Before jumping into Tensorflow in C++.

I have summarised about Bazel, which google uses for building the project!
Please kindly take a look if you have interest on it.
https://qiita.com/Rowing0914/items/8e60588fa698693d20a3

[Official Tutorial](https://www.tensorflow.org/api_guides/cc/guide)

```c++
// tensorflow/yourfolder/filename.cc

#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"

int main() {
  using namespace tensorflow;
  using namespace tensorflow::ops;
  Scope root = Scope::NewRootScope();
  // Matrix A = [3 2; -1 0]
  auto A = Const(root, { {3.f, 2.f}, {-1.f, 0.f} });
  // Vector b = [3 5]
  auto b = Const(root, { {3.f, 5.f} });
  // v = Ab^T
  auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
  std::vector<Tensor> outputs;
  ClientSession session(root);
  // Run and fetch v
  TF_CHECK_OK(session.Run({v}, &outputs));
  // Expect outputs[0] == [19; -3]
  LOG(INFO) << outputs[0].matrix<float>();
  return 0;
}
```

Put the application above into the folder you make newly under tensorflow directory.
And please make a BUILD file to notice the bazel dependencies of this application.

```bash
cc_binary(
    name = "project",
    srcs = ["code.cpp"],
    linkopts = 
		["-lopencv_core","-lopencv_imgproc", "-lopencv_highgui", 
		"-Wl,--version-script=tensorflow/tf_version_script.lds"],
    copts = ["-I/usr/local/include/", "-O3"],
    deps = [
        "//tensorflow/core:tensorflow"
    ])
```
![Screen Shot 2018-04-14 at 23.31.32.png](https://qiita-image-store.s3.amazonaws.com/0/240801/15283d2b-ccc3-4efd-ae23-78d9235e7e3e.png)

And then run the bazel!
【Jenkins】Pipelineのパラレルとパラレルでない書き方

### JenkinsのPipeline
- すでにJenkinsで作成済みのジョブを直列・並列処理するジョブを作ることができます

### 直列・並列処理を混ぜたスクリプト

    node {
        stage('app-deploy-stage'){
            echo '直列処理1'
            parallel(
                "stream1":{
                    echo '並列処理1'
                    build( job:'JOB1', parameters:[ [$class: 'StringParameterValue', name:'version' ,value:'1.1.8' ]])
                },
                "stream2":{
                    echo '並列処理2'
                    build( job:'JOB2', parameters:[ [$class: 'StringParameterValue', name:'release' ,value:'3.5' ]])
                }
            )
            echo "App deploy finished!!"
        }
        stage('data-update-stage'){
            echo '直列処理2'
            build('JOB3')
        }
        stage('data-delete-stage'){
            echo '直列処理3'
            build('JOB4')
        }
        echo 'All finished'
    }

#### 処理の順番
- 直列処理1(並列処理1、並列処理2(同じタイミングで実行される))→直列処理2→直列処理3

#### ログの出る順番
- 直列処理1→並列処理1→並列処理2→App deploy finished!!→直列処理2→直列処理3→All finished

#### ジョブにパラメーターがある場合
- 並列処理1のようにパラメーター名と実際の値をビルドファンクションに渡すことで設定できる
Falconで画像アップロードを爆速開発

# クライアントサイド

jQueryを使い`Content-Type: multipart/form-data`で画像を送ります。
アップロードボタンを押せば、canvasに表示されている画像をアップロードできます。

```javascript:client.js
$('#upload').click(function(){
  // アップロードボタンをdisableにする
  $('#upload').prop('disabled', true);
  $('#upload').text('Wait...');

  // canvasからbase64画像データを取得
  var base64 = $('#canvas').get(0).toDataURL('image/jpeg');        
  // base64からBlobデータを作成
  var barr, bin, i, len;
  bin = atob(base64.split('base64,')[1]);
  len = bin.length;
  barr = new Uint8Array(len);
  i = 0;
  while (i < len) {
    barr[i] = bin.charCodeAt(i);
    i++;
  }
  blob = new Blob([barr], {type: 'image/jpeg'});

  // フォームデータの形に整形し画像を添付
  var fd = new FormData();
  fd.append('file', blob);
  $.ajax({
    url: API_ENDPOINT, // http://xxx.xxx.xxx.xxx
    type: 'POST',
    dataType: 'json',
    data: fd,
    processData: false,
    contentType: false
  })
  .done(function( res, textStatus, jqXHR ) {
    console.log(res.result);
  });
});
```



# サーバサイド

必要なものをインストール

```
pip install falcon
pip install falcon-multipart
pip gunicorn

# gunicornは, apt-getでインストールした/usr/bin/gunicornと競合する可能性があります. 
# その場合,　sudo apt-get remove gunicornで消し、シンボリックリンクを張って解決します.
# sudo ln -nsf /home/hogehoge/.pyenv/shims/gunicorn /usr/bin/gunicorn
```

FalconでPOSTを受け取り画像をサーバに保存します。

```python:server.py
# -*- coding: utf-8 -*-
import falcon
from falcon_multipart.middleware import MultipartMiddleware
import json
from datetime import datetime

class CORSMiddleware:
    def process_request(self, req, resp):
        resp.set_header('Access-Control-Allow-Origin', '*')

class Upload:
  def on_post(self, req, res):

    image = req.get_param('file')
    raw = image.file.read()
    filepath = './' + datetime.now().strftime('%Y%m%d%H%M%S') + '.jpg'
    with open(filepath, 'wb') as f:
      f.write(raw)

    resp = {
      'result': filepath + ' uploaded',
    }
    res.body = json.dumps(resp)

api = falcon.API(middleware=[CORSMiddleware(), MultipartMiddleware()])
api.add_route('/', Upload())
```

falconの動かし方

```
gunicorn server:api -b 192.168.xxx.xxx  # IPを指定してください.
```

以上でブラウザから画像をサーバにアップロードできます!!!!!!
Laradock + nginx + MySQL + phpMyAdmin on Ubuntu16.04

# はじめに
※この手順ではlaradockをプロジェクト毎にダウンロードしないとならず、手間もディスクスペースももったいないです。git cloneしたlaradockを使い回すやり方を思いついたので、手順がまとまったら別記事に残します。

Docker for Macで環境構築した時と少しだけ勝手が違ったので記事に残します。
(複数プロジェクトを管理しやすいように更新。2017/4/1)
(Laravel Mixを利用しやすいように更新。2017/4/1)

- Docker version 18.03.0-ce, build 0520e24
- docker-compose version 1.20.1, build 5d8c71b

# 作業
### Laradock配置

``` 
mkdir 任意のプロジェクト名 && cd 任意のプロジェクト名
mkdir src
git clone https://github.com/Laradock/laradock.git
mv laradock laradock-任意のプロジェクト名 (一意であればなんでも可)
cd laradock-任意のプロジェクト名
cp env-example .env
```

### Laradockの.env編集

```laradock/.env
APPLICATION=../src/

DATA_SAVE_PATH=~/.laradock/data/任意のプロジェクト名

WORKSPACE_INSTALL_NODE=true

WORKSPACE_INSTALL_PYTHON=true

NGINX_HOST_HTTP_PORT=8880

MYSQL_PORT=33066:3306
```
- もしくは下記コマンドを実行

```
find . -name ".env" | xargs sed -i "s/APPLICATION=..\//APPLICATION=..\/src\//g"
find . -name ".env" | xargs sed -i "s/DATA_SAVE_PATH=~\/.laradock\/data/DATA_SAVE_PATH=~\/.laradock\/data\/任意のプロジェクト名/g"
find . -name ".env" | xargs sed -i "s/WORKSPACE_INSTALL_NODE=false/WORKSPACE_INSTALL_NODE=true/g"
find . -name ".env" | xargs sed -i "s/WORKSPACE_INSTALL_PYTHON=false/WORKSPACE_INSTALL_PYTHON=true/g"
find . -name ".env" | xargs sed -i "s/NGINX_HOST_HTTP_PORT=80/NGINX_HOST_HTTP_PORT=8880/g"
find . -name ".env" | xargs sed -i "s/MYSQL_PORT=3306/MYSQL_PORT=33066:3306/g"
```

### コンテナのビルドと起動

```
docker-compose up --build -d nginx mysql phpmyadmin
#--buildオプションはlaradockの設定を変更した時のみ
```
### コンテナに接続、Laravelプロジェクト作成
```
docker-compose exec --user=laradock workspace bash
composer create-project --prefer-dist laravel/laravel .
chmod -R 777 storage
```
### Laravelの.env編集

```var/www/.envもしくはsrc/.env
#中略　9行目
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
```

コンテナ内にて下記コマンドでマイグレーションができればMySQLの設定は成功です。

```
php artisan migrate
```

ブラウザでlocalhost:8880にアクセスした際にLaravelのデフォルトWelcomeページが表示され、
localhost:8080ではphpMyAdminにアクセスできるかと思います。

# 最後に
複数プロジェクトを管理する場合はdocker-compose stopでコンテナを止めてから他のプロジェクトのコンテナを起動する必要があります。
たくさんのサイトや記事を参考にさせていただきました。ありがとうございます。
Apache Sparkでdebug機能を試してみた

Apache SparkでIntelliJのdebug機能を試してみた

```scala:spark-submitコマンド

hisashinoMacBook-Pro:apache-spark-csv-sample hisashi$ sudo $SPARK_HOME/bin/spark-submit --class com.sample.csv.spark.SparkCSVSample --master "local[2]" --driver-java-options "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" target/scala-2.11/spark_csv_sample_2.11-1.0.0.jar logs/ tmp/spark_csv_sample.csv /hoge,/piyo

↓コンソール上にこんなメッセージがでてきた
Listening for transport dt_socket at address: 5005
```

```scala:spark-submitコマンド

$SPARK_HOME/bin/spark-submit 
  --class com.sample.csv.spark.SparkCSVSample 
  --master "local[2]" 
  --driver-java-options "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" ←(ここを　IntelliJのCommand line arguments for running remote JVM の定義に合わせるらしい)
  target/scala-2.11/spark_csv_sample_2.11-1.0.0.jar 
  logs/ tmp/spark_csv_sample.csv /hoge,/piyo

```

予めIntelliJのデバッグモードを設定しておいて。
<img width="1299" alt="スクリーンショット 2018-03-31 15.39.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/241715/43b38d00-bf3e-5180-5064-5b188edcaaf8.png">

虫のマークをオンにして
<img width="186" alt="スクリーンショット 2018-03-31 15.43.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/241715/1e44e62d-328e-737a-5209-ff15cafbf513.png">

おお！。ポインターをおいたところでとまった。
<img width="1066" alt="スクリーンショット 2018-03-31 15.41.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/241715/e551c31f-57fb-5d61-b4cd-94b1d493a8bc.png">

参考サイト：すみません。以下のサイトのプログラムをベースにさせてもらってます。
[Apache Spark を使ってアクセスログを解析して、その結果をCSVファイルに出力してみた。](https://qiita.com/uriborn/items/501aba49dc806996e74f)
Java で TensorFlowをする。メチャクチャ簡単だけれど。。。。

機械学習といえば、Googleの開発した[TensorFlow](https://www.tensorflow.org/)が有名ですよね。

実は、みんな大好きJavaでも、TensorFlowを使えるのです。しかも使い方はとても簡単。buildに１ライブラリを追加するだけです。

```groovy
compile 'org.tensorflow:tensorflow:1.7.0'
```
build.gradleの全体は[こちら](https://github.com/ukiuni/TensorFlowForJavaInspect/blob/master/build.gradle)

これだけでサンプルコードが動きます。

```java:サンプル抜粋
try (Graph g = new Graph(); Session session = new Session(g)) {
	Tensor<?> t = Tensor.create("初めてのTensorFlow".getBytes());
	g.opBuilder("Const", "message").setAttr("dtype", t.dataType()).setAttr("value", t).build();
	Tensor<?> out = session.runner().fetch("message").run().get(0);
	System.out.println(new String(out.bytesValue()));
}
```
↓
初めてのTensorFlow とコンソールに出力されます。

サンプルコード全体は[こちら](https://github.com/ukiuni/TensorFlowForJavaInspect/blob/master/src/test/java/org/ukiuni/inspect/TensorFlowInspect.java)

とても簡単に機械学習の環境が整います。

# ただし。。。
判定はJavaでできるものの、最初の学習はPythonやCなど、他でやる必要があります。
イチからJavaでできるようになるといいですね！
Ionicの開発環境構築してみる

モバイルアプリ作ってみたいなーと思い立ち、Ionic勉強し始めた。
私のWindows10PCで開発環境作ってみた。

#私のPC環境
- OS：Windows10
- Node：v8.9.4
- npm：5.8.0
- git：2.13.2.windows.1
- エディタ：Visual Studio Code


#手順
##Node.jsインストール
[ここ](https://qiita.com/Masayuki-M/items/840a997a824e18f576d8)参考。
Node.js入れれば自動でnpmも入ります。

##gitインストール
インストール手順は[ここ](http://prog-8.com/blogs/git-preparation-windows)参考。

##エディタインストールと拡張機能追加
[ここ](https://code.visualstudio.com/)からインストールできます。この左のメニューアイコンの中から四角形のアイコンクリックして
拡張機能「Angular Language Service」を追加します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/e0b30b96-86d0-2dbd-2ed9-48134348cab4.png)
「Angular Language Service」で検索して「Editor service for Angular templates」と説明文ついてるやつクリックしてインストールします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/0cc975af-2436-6e6e-d99b-ba3c952a281c.png)



##lonic CLIインストール
```:コマンドプロンプト
npm install ionic cordova -g
```

```:出力メッセージ
C:\Users\take\AppData\Roaming\npm\cordova -> C:\Users\take\AppData\Roaming\npm\node_modules\cordova\bin\cordova
C:\Users\take\AppData\Roaming\npm\ionic -> C:\Users\take\AppData\Roaming\npm\node_modules\ionic\bin\ionic
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\ionic\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ cordova@8.0.0
+ ionic@3.20.0
added 658 packages from 462 contributors in 65.612s
```

できたっぽい。バージョン確認してみてバージョンでればおけ。

```:コマンドプロンプト
ionic -v
```

```:出力メッセージ
3.20.0
```

##スマホで動かすツールのインストール
###iOSアプリの場合：Xcodeインストール
[ここ](https://itunes.apple.com/jp/app/xcode/id497799835)からインストールするのですが、macOS向けの統合開発環境なのでWindowsPCの私はインストールできないっす。仮想でmacOS立てたりすればインストールできますが私は自分のMacでやろうかなと思いここはスキップします。

>HDDに5GB以上の空きが必要らしいです。20分以上時間かかるらしいです。

###Androidアプリの場合：Android Studioインストール
[ここ](https://developer.android.com/studio)からインストール。とりあえず私こっちインストールしてみた。
この黄緑のボタン押して
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/a6b10460-62e3-17e1-8c18-a031bb474638.png)
同意してダウンロード
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/2868442e-fe4d-ecc0-6b19-5b63e7402984.png)

exeファイルがダウンロードされるので案内に従って実行してインストール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/a018cefa-e83d-31f2-d49d-b7fe77d87e9a.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/0112321e-d324-051d-b9fc-4996c08cdc1f.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/025bf704-27d9-b839-ec67-7fc4929642e9.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/947d409c-1d6d-a87d-8279-59962989f9d2.png)

>合計3GB以上容量使いました。私は特に何も設定変えずにポチポチ進めて起動してます。20分くらい時間かかった気がします。
BusyBox設定備忘録

## 概要
Windows環境下でUnix系のコマンド使用できるようにするためのBusyBoxの環境設定方法。

## ダウンロード
下記サイトよりexeファイルダウンロードします。


[busybox](https://frippery.org/busybox/)
## 使い方
ダウンロードしたexeを任意のフォルダに配置し、システム環境変数に追加すると<br>
コマンドプロンプト or PowerShellで下記のようにコマンドを組み合わせてUnixコマンドを使用することができます。

```
C:\Users\WorkSpace>busybox ls -la 
```
- busyboxで使用可能なコマンドは、引数なしで実行すると詳細が表示されます。

```
C:\Tool>busybox
BusyBox v1.28.0-FRP-1722-g096aee2bb (2017-12-09 09:30:52 GMT) multi-call binary
(mingw64-gcc 7.2.0-1.fc27; mingw64-crt 5.0.2-2.fc27; safe)

BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list
   or: busybox --install [DIR]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  The shell in this build
        is configured to run built-in utilities without $PATH search.
        You don't need to install a link to busybox for each utility.
        To run external program, use full path (/sbin/ip instead of ip).

Currently defined functions:
        [, [[, ar, arch, ash, awk, base64, basename, bash, bunzip2, busybox, bzcat, bzip2, cal, cat, chmod, cksum,
        clear, cmp, comm, cp, cpio, cut, date, dc, dd, df, diff, dirname, dos2unix, dpkg-deb, du, echo, ed, egrep, env,
        expand, expr, factor, false, fgrep, find, fold, ftpget, ftpput, getopt, grep, groups, gunzip, gzip, hd, head,
        hexdump, id, ipcalc, kill, killall, less, link, ln, logname, ls, lzcat, lzma, lzop, lzopcat, man, md5sum,
        mkdir, mktemp, mv, nc, nl, od, paste, patch, pgrep, pidof, printenv, printf, ps, pwd, rev, rm, rmdir, rpm,
        rpm2cpio, sed, seq, sh, sha1sum, sha256sum, sha3sum, sha512sum, shuf, sleep, sort, split, stat, strings, sum,
        tac, tail, tar, tee, test, timeout, touch, tr, true, truncate, uname, uncompress, unexpand, uniq, unix2dos,
        unlink, unlzma, unlzop, unxz, unzip, usleep, uudecode, uuencode, vi, watch, wc, wget, which, whoami, whois,
        xargs, xxd, xz, xzcat, yes, zcat
```


また、下記のように設定するとbusyboxコマンドなしでそのままUnixのコマンドを使用することができます。
1. コマンドを展開するフォルダを作成する
```
C:\Tool>mkdir busybox
```
2. busyboxで使用できるコマンドを任意のフォルダに展開する
```
C:\Tool>busybox --install ./busybox
```
3. 展開したフォルダPathをシステム環境変数に追加する
```
C:\Users\WorkSpace>ls -la 
```
プログラムからSlackに画像投稿する方法まとめ

# やりたいこと
BotやプログラムからSlackに画像付きのメッセージを送りたい。

<img src="https://qiita-image-store.s3.amazonaws.com/0/83530/dea67abf-2c4d-1fe7-44d9-b055d1d22948.png" width=40%>

やり方としては２通り

* 通常のメッセージにimage_urlを指定する
* file.upload apiを利用して画像を送る

# image_urlを指定する方法

こちら、投稿したい画像がWeb上にあることが前提の方法です。

## 準備
### WebhookのURLを取得
まず、メッセージ送信用にWebhookの設定を行います。
WebHookの設定は[Appディレクトリ](https://mamedeppo.slack.com/apps)で着信Webフックを検索するか[Webhooks](https://api.slack.com/incoming-webhooks)の" incoming webhook integration"のリンクあたりから設定画面に行って行うことができます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/83530/e2326100-3c39-01f9-4ef2-c9cdc971c2ff.png" width=60%>

チャンネルを指定するとURLが発行されるのでこれを使います。

## サンプルソース
```python
import requests
import json

SLACK_POST_URL = #取得したURL

post_json = {
    "text": "テストです",
    "attachments": [{
        "fields": [
            {
                "title": "てすと",
                "value": "てすと",
            }],
        "image_url": "http://hogehoge/fuga.png"
      }]
}
requests.post(SLACK_POST_URL, data = json.dumps(post_json))
```
image_urlに画像のURLを指定することで、slack上では上の図のように画像が自動的に展開されて表示されます。

attachmentsの公式リファレンスはは[こちら](https://api.slack.com/docs/message-attachments)

# file.uploadを利用する方法
こちらは、画像を直接slackにアップロードする方法です。
web上に置いていない場合や、画像を生成して投稿したい場合はこちらになります。

## 準備
### Tokenを取得する

こちらを利用するためにはTokenを取得する必要があります。
トークンは色々種類がありますが、[リファレンス](https://api.slack.com/methods/files.upload)によると"bot"か"workspace"か"user"使ってね、とあるのでどれかにします。
レガシートークンだとこの辺りの指定を考えなくて良いのですが、あんまり使わないでねとあった気がするのでやめましょう。

[Appディレクトリ](https://mamedeppo.slack.com/apps)でBotsを検索するとBotの設定画面にたどり着くのでここで新しく設定を追加してみましょう。

（この辺りの各種設定、いつもどこで設定すればいいのかわからなくなる。）

### Channelを取得する

投稿先のChannelのIDを指定します。
ChannelIDの取得はどうやるのが楽なんでしょうか？
私はWeb版のSlackで該当チャンネルを開いてURLからコピペしてます。

## サンプルソース
```python
import requests
import json
import pandas as pd
import numpy as np
import matplotlib

matplotlib.use('Agg') # CUI環境でmatplotlib使いたい場合、指定する
import matplotlib.pyplot as plt

TOKEN = # 取得したトークン
CHANNEL = # チャンネルID

#####################################
# 画像を生成する例、アップロードするだけなら不要
#####################################

# データ読み込む
data = pd.read_table(
    "/path/to/data/input.tsv", #なんかtsv/csv読み込むサンプル
    header=-1, 
    names=("date","value")
)
# 軸の基準になるとこ
data.index = pd.to_datetime(data.iloc[:,0])
data.plot()
# 保存するよ
plt.savefig('figure.png')

###############
# 画像送信ここから
###############
files = {'file': open("figure.png", 'rb')}
param = {
    'token':TOKEN, 
    'channels':CHANNEL,
    'filename':"filename",
    'initial_comment': "initial_comment",
    'title': "title"
}
requests.post(url="https://slack.com/api/files.upload",params=param, files=files)
```

# 参考

[pythonでslackに画像をアップロードする方法](https://qiita.com/tottu22/items/594e8c506ece0f8cc87c)
[Slack API attachmentsチートシート](https://qiita.com/daikiojm/items/759ea40c00f9b539a4c8)
UbuntuでTesseract 4.0（LSTM）を動かす

# UbuntuでTesseractを動かせるようにします。(所要時間15分程度)

```
# 必要な開発ツールをインストール
# See. https://github.com/tesseract-ocr/tesseract/wiki/Compiling

sudo apt-get install g++ # or clang++ (presumably)
sudo apt-get install autoconf automake libtool
sudo apt-get install autoconf-archive
sudo apt-get install pkg-config
sudo apt-get install libpng-dev
sudo apt-get install libjpeg8-dev
sudo apt-get install libtiff5-dev
sudo apt-get install zlib1g-dev
sudo apt-get install libicu-dev
sudo apt-get install libpango1.0-dev
sudo apt-get install libcairo2-dev

# Leptonicaをソースからコンパイル
# See. http://www.leptonica.org/source/README.html

wget http://www.leptonica.org/source/leptonica-1.74.4.tar.gz
tar xvfz leptonica-1.74.4.tar.gz
rm leptonica-1.74.4.tar.gz
cd leptonica-1.74.4/
./configure
make
sudo make install

# Tesseract LSTMをソースからコンパイル
# See. https://github.com/tesseract-ocr/tesseract/wiki/Compiling-%E2%80%93-GitInstallation

git clone https://github.com/tesseract-ocr/tesseract.git tesseract-ocr
cd tesseract-ocr
./autogen.sh
./configure
make
sudo make install
make training
sudo make training-install
sudo ldconfig

# 学習済み言語データをインストール
# 日本語の場合、jpnとjpn_vertの2つが必要

wget https://github.com/tesseract-ocr/tessdata_best/raw/master/eng.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/master/jpn.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/master/jpn_vert.traineddata
sudo mv *.traineddata /usr/local/share/tessdata/

# 日本語の言語データの33行目が不具合を起こすのでコメントアウトしたい.
# そのまま編集するとデータが壊れるので、編集可能なconfig部分のみを抽出して編集し、その後結合するという方法をとる.

sudo combine_tessdata -e /usr/local/share/tessdata/jpn.traineddata jpn.config
sudo vi jpn.config # comment out line 33
sudo combine_tessdata -o /usr/local/share/tessdata/jpn.traineddata jpn.config
sudo combine_tessdata -e /usr/local/share/tessdata/jpn_vert.traineddata jpn_vert.config
sudo vi jpn_vert.config # comment out line 33
sudo combine_tessdata -o /usr/local/share/tessdata/jpn_vert.traineddata jpn_vert.config

# 動作確認
tesseract test.png out --oem 1 -l jpn
```
Macでlibtool: unrecognized option `-static'といエラーが出たときの対応


### 現象

npm installでモジュール入れようとすると、、ビルドでこける（以下、抜粋）。

>ちなみに、npm install -g remixdでこけた。

```bash
> node-gyp rebuild

  SOLINK_MODULE(target) Release/copied_files.node
  CC(target) Release/obj.target/scrypt_wrapper/src/util/memlimit.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/keyderivation.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/pickparams.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/hash.o
  LIBTOOL-STATIC Release/scrypt_wrapper.a
libtool: unrecognized option `-static'
libtool: Try `libtool --help' for more information.
make: *** [Release/scrypt_wrapper.a] Error 1
gyp ERR! build error
```

node-gypのエラーはpython2.7を入れたら解決！的な記事もあったが、私の環境ではpythonは2.7。。。

### 原因

原因は私の環境に強く依存するものでした。。。
私はMAMPを使っており、MySQLをPATHを通すため、.bash_profileで、

```bash
export PATH=/Applications/MAMP/Library/bin:$PATH
```

として、MAMPが/usr/binよりも優先されるようにしていたのですが、/Applications/MAMP/Library/bin以下にもlibtoolがり、さらにそのlibtoolが/usr/bin/libtool（標準）とは仕様が違うようなのです。


### 対応

方法は２つの方向

* .bash_profileのPATHを変更する（MAMP優先でなくする）
* PATH=/Applications/MAMP/Library/bin/libtoolをリネームする

MAMPのlibtoolを利用することは無いのでとりあえず後者のリネームで対応しました。何か不具合があればまた考えます。

私的環境依存ですが、いちおうメモ。

## 追記

node-gyp rebuildがらみのエラーもこれ。
npm install truffle-hdwallet-provider
でも同じ原因がコケました。。。
Go言語用和暦ライブラリを作りました

Go言語用和暦ライブラリを作りました。
よかったら使ってみてください。

## 使い方

### ライブラリを取得
```bash
$ cd $GOPATH
$ go get github.com/hideshi/go-wareki
```

### サンプル
```go
package main

import (
    "time"
    "fmt"
    "github.com/hideshi/go-wareki"
)

func main() {
    // Go言語バージョン1のリリース日
    firstReleaseDateOfMajorVersionOfGolang := time.Date(2012, 3, 28, 0, 0, 0, 0, time.UTC)

    // 和暦を取得
    wareki := wareki.NewWareki(firstReleaseDateOfMajorVersionOfGolang)

    // 和暦の文字列を取得
    fmt.Println(wareki.String()) // 平成24年3月28日
    fmt.Printf("%s\n", wareki) // 平成24年3月28日

    // 和暦から西暦の日付を取得
    d := wareki.Date // time.Time型
    fmt.Printf("%v\n", d) // 2012-03-28 00:00:00 +0000 UTC 
}
```
samba-client／cifs-utilsを使ってWindowsの共有フォルダをマウントする

# samba-client／cifs-utilsを使ってWindowsの共有フォルダをマウントする

## 環境
|＃|環境|概要|
|:--|:--|:--|
|1|IP|192.168.33.10|
|2|Vagrant|2.0.3|
|3|Oracle VM VirtualBox|5.2.8|
|4|CentOS|6.9|

## Windowsに共有フォルダを作成する

Sambaを使ってWindowsの共有フォルダをマウントし、CentOS環境とWindows環境でファイルを共有する場合でも、
特にWindowsの共有フォルダ作成は、通常と変わりありません。

気を付ける点としては、

* 共有フォルダへのアクセス権設定用のWindowsアカウントを個別に作成する。
* 対象Windowsアカウントに共有フォルダへのアクセス権を設定する。
* 詳細な共有の設定により、対象Windowsアカウントに対して必要に応じてフルコントロールを与える。
* Windows標準のファイアウォールの設定で、  
セキュリティが強化されたWindowsDefenderファイアウォール＞受信の規則＞ファイルとプリンターの共有（SMB受信）  
の規則が有効化されていること。  
*※別のウィルス対策ソフトによってファイアウォールの設定がされている場合、samba-clientを使ってマウントする際に利用されるポート（標準：445）を開放するような設定が必要。*

## samba-client,cifs-utilsのインストール

```shell
yum install -y samba-client cifs-utils
```

## CentOS側にWindowsの共有フォルダをマウントした際の共有用のディレクトリを作成する

```shell
mkdir /usr/local/src/share
```

## mountコマンドを実行してWindowsの共有フォルダをマウント

ここでは以下の条件に対しマウントする

* Windows側環境
 * 共有フォルダは「//192.168.0.95/share」
 * アクセス許可をしているアカウント「share / sharepass」
* CentOS側環境
 * マウントする際のCentOS側のディレクトリ「/usr/local/src/share」

```shell
mount.cifs -o "username=share,password=sharepass" //192.168.0.95/share /usr/local/src/share
```

このコマンドの実行の結果、特にコンソールへ何も表示されなければマウント完了です。
※Windows7環境の共有フォルダで検証した際は、上記手順で問題なくマウントできましたが、
　Windows10環境の共有フォルダで検証すると、上記手順では正常にマウントできず、以下のエラーが発生しました。

```
mount error(112): Host is down
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
```

後続の [Windows10環境へのマウントがうまくいかない件](#Windows10環境へのマウントがうまくいかない件) を参照

## マウントできているか確認

mount コマンドを実行することで、マウントの情報が確認できます。

```shell
mount
～～（省略）～～
//192.168.0.95/share on /usr/local/src/share type cifs (rw)
```

## CentOS側を再起動したあともマウントされるように/etc/fstabを修正

```shell
vim /etc/fstab
```

/etc/fstabの最終行に以下の行を追加する。

```
//192.168.0.95/share /usr/local/src/share cifs username=share,password=sharepass 0 2
```

この状態であれば、CentOS側を再起動してもファイル共有はされた状態となる。

## Windows10環境へのマウントがうまくいかない件

CentOS6.9環境でyum installした状態でmount.cifsのバージョンを確認すると以下の状態だった。

```shell
mount.cifs -V
mount.cifs version: 4.8.1
```

では、CentOS7.4環境ではどうなるか検証してみた。

```shell
mount.cifs -V
mount.cifs version: 6.2
```

だいぶバージョンが違うので、もしかしてと思い、Windows10環境へのマウントを試みたところ、正常にマウントできた。
ちなみに、マウントした時のコマンドは以下の通り。

```shell
mount.cifs -o "username=share,password=sharepass,vers=2.0" //192.168.0.170/share /usr/local/src/share
```

注意点として、他のサイトでも紹介されていた通り、「vers=2.0」というオプションを付けないと、正常にマウントできないようです。
ちなみに「vers=3.0」というオプションにして実行してみたところ、これも正常にマウントできました。

なので、結論として、CentOS6.9の標準リポジトリを利用してyumでセットアップしたsamba-client及びcifs-utilsを利用すると、Windows10環境の共有フォルダはマウントできないということらしいです。
Vue.js で created と watch の両方にあるメソッド呼び出しを一つにする

7 Secret Patterns Vue Consultants Don’t Want You to Know - Chris Fritz - YouTube
https://www.youtube.com/watch?v=7lpemgMhi0k

によると次のコードは、

```js
created() {
  this.fetchUserList()
},
watch: {
  searchText() {
    this.fetchUserList()
  },
},
```

次のように書けるとのことです。

```js
watch: {
  searchText: {
    handler: "fetchUserList",
    immediate: true,
  }
},
```

実際に確認してみたのがこれです。起動時に `fetchUserList` が呼ばれているため最初から `counter` が 1 になっていることがわかります。

<p data-height="256" data-theme-id="0" data-slug-hash="mxxZOa" data-default-tab="js,result" data-user="akicho8" data-embed-version="2" data-pen-title="Vue.js Smarter Watchers " class="codepen">See the Pen <a href="https://codepen.io/akicho8/pen/mxxZOa/">Vue.js Smarter Watchers </a> by Akira Ikeda (<a href="https://codepen.io/akicho8">@akicho8</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

公式ドキュメントの

API — Vue.js
https://jp.vuejs.org/v2/api/index.html#watch

にも似たような例があって b と d の例を組み合わせた形で書ける、ということみたいです。

そんだけです
browser color Names

### list
https://gnjo.github.io/colorNames.js?v=0

```js:colorNames.js
;(function(root){
root.colorNames = {
    aliceblue: "f0f8ff",
    antiquewhite: "faebd7",
    aqua: "0ff",
    ...
   yellowgreen: "9acd32"
}
;
})(this); 
```
```js
console.log(colorNames)
```
CentOS7　vsftpd

CentOS7にvsftpdを導入してftpサーバーを構築したときのメモ。

wordpressを運用していると、プラグインやテーマを更新する際にFTPかFTPSを構築する必要がある。
今時FTPを使う機会は減っているとは思うけれども・・・
そもそもFTPは認証も含め暗号化されないし、FTPSを使うぐらいならSCPかSFTP使った方が楽だけれども・・・

#前提
CentOS7でWEBサーバーを構築し、lets encryptでhttpsを対応していること
※ftpsは証明書が必要なため
　ただのFTPだけならwebサーバーも証明書も不要

WEBサーバーとSSL（lets encryptの証明書）の構築はこちら
https://qiita.com/salt_field/items/31acb1cbb707102e0702

FTPサーバーはマルチドメインではなく、メインのドメインのみで運用することを前提とする。
同一サーバーなので、wordpressで使用する際はユーザー名とパスワードだけ変更すれば問題ない。たぶん

vsftpdの設定項目の意味はこちらを参照しました。
http://www.nina.jp/server/redhat/vsftpd/vsftpd.conf.html#log

##ドメインとかユーザーの情報
|項目|メインドメイン|
|:---|:---|
|ドメイン|main.test.com|
|ユーザー|User1|
|パスワード|User1Pass|

##インストール

```
yum -y install vsftpd
```

##設定変更

```
#vi /etc/vsftpd/vsftpd.conf

anonymous_enable=NO
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=NO
log_ftp_protocol=YES
ascii_upload_enable=YES
ascii_download_enable=YES
ftpd_banner=Welcome to blah FTP service.
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
ls_recurse_enable=YES

###ここから下は最後に追記する。###

local_root=public_html

pam_service_name=vsftpd
userlist_enable=YES
userlist_deny=YES
userlist_file=/etc/vsftpd/user_list
tcp_wrappers=YES
use_localtime=YES
allow_writeable_chroot=YES

pasv_enable=YES
pasv_address=main.test.com
pasv_min_port=60000
pasv_max_port=60030
pasv_addr_resolve=YES
pasv_promiscuous=YES

ssl_enable=YES
rsa_cert_file=/etc/letsencrypt/live/main.test.com/fullchain.pem
rsa_private_key_file=/etc/letsencrypt/live/main.test.com/privkey.pem
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
ssl_ciphers=HIGH
```

public_html以外のディレクトリへのアクセスを許可する場合はchroot_listにユーザー名を追記する。

```
echo User1 >> /ect/vsftpd/chroot_list
```

##ポートを開放する

```
firewall-cmd --add-service=ftp --zone=public --permanent
firewall-cmd --add-port=60000-60030/tcp --zone=public --permanent
firewall-cmd --reload
```

##起動

```
systemctl start vsftpd
systemctl enable vsftpd
```

##あとがき
ffftpでアクセスするとき、ipv4、ipv6いずれかでアクセスできると認証はできるが、その後パッシブモードに（勝手に）切り替わったとき、どちらかのアドレスでしかアクセスできなくなる。（勝手に切り替わるのは設定しているからだけれども）
DNSをきちんと設定してある＆サーバーに適切なIPが設定してある状態でないと、ドはまりする。
私の場合、IPv6のDNSが古いアドレスで設定されている状態だった為、ipv4でログインした後パッシブモード（ipv6）時にファイル一覧が取得できずアップロードもダウンロードもできない状態になった・・・

適切な設定がされているのに上記のような症状に悩まされたらDNS設定を見てみよう。

こんな初歩的な問題＆個別すぎる問題はググっても出てこないから気を付けよう。
Fitbitのアクティビティデータを他サービスへ連携したい！その２

# 前回までのあらすじ
[Fitbitのアクティビティデータを他サービスへ連携したい！](https://qiita.com/ASLA/items/2e93fdae44f3a7619d1c)

* Fitbitのデータを連携したい
* IFTTTのWebhooksでXML連携ができない
* Zapier使ってみたら？でもFitbitのトリガーが無い！　<- いまここ

# IFTTTと合わせ技で何とかしてみる
こんな感じで無理やり連携させる。

![DataFlow](https://qiita-image-store.s3.amazonaws.com/0/233979/c1edcc64-2695-f395-59a2-bd35fd9bbb7b.png)

もっとうまいやり方があるのだろうと思いつつ、送ったデータのログも残るので、Google Sheetsをはさむこととする。

# Zapを作っていく
## トリガーの作成
Google Sheetsを選択し、以下のような流れで作成していく。

1. トリガーの選択
2. Googleアカウントの選択
3. スプレッドシート、ワークシートの選択

「トリガーの選択」では、2種類のトリガーが選択できる。

* New or Updated Spreadsheet Row（行の追加と更新）
* New Spreadsheet Row（行の追加）

## アクションの作成
トリガーに対する処理を追加する。
今回メインの目的であるXMLのPOSTを実現するため、二段階のアクションを設定する。
### Code
![Zapier_Action_Code](https://qiita-image-store.s3.amazonaws.com/0/233979/508241ee-a8d6-584e-108d-34613cf69953.png) 
データとして送信するためのXMLを作成する処理。
JavascriptとPythonが選択できる。
今回は大したことはしないのでどちらでもよいが、Javascriptを選ぼう。

* Input Data
トリガーで取得できるデータをコード内で使用できるよう、名前を付ける。
なお、スプレッドシートの1行目の値が、列名としてリストに表示される。わかりやすい名前を記載しておこう。

* Code
データを作成するためのJavascriptコードを書く。
上記で名前を付けたデータは、inputData.[名前]のように呼び出すことができる。
次のアクションに渡すデータとして「output」という変数が予約されており、この変数にJSONデータとして格納する。

ベタだが以下のような感じで書いていこう。

```javascript
var xml = '<?xml version="1.0" encoding="UTF-8"?>';
xml += '<xml>';
xml += '<data>';
xml += inputData.Steps;
xml += '</data></xml>';

output = {'payload':xml};
```

### Webhooks
![Zapier_Action_Webhooks](https://qiita-image-store.s3.amazonaws.com/0/233979/4272069d-5e84-be03-3771-476598068419.png) 
外部のWebサービスへデータをPOSTするアクション。
上記で作成したデータをそのまま送りたいので、「Custom Request」を選ぼう。

* Method
GET/PUT/POST/PATCH/DELETE/Customから選択できる。
今回はPUT。

* URL
送信先のURLを指定する。

* Data Pass-Through? (optional)
リクエストデータを前のアクションからのデータで上書きするかどうか。
通常、デフォルトのnoでよい。

* Data (optional)
リクエストデータを指定する。
トリガーからのデータと前のステップのデータが指定できる。
今回は前のステップで作成したデータの、「payload」を指定する。
ちなみに、実行時のログやメモリ使用量なども指定できるが、あまり用途が思いつかない。

* Unflatten (optional)
アンダースコア「_」をネストとして扱うかどうか。noでよい。

* Basic Auth (optional)
ベーシック認証のID/パスワードを指定する。

* Headers (optional)
リクエストヘッダを指定する。今回は「Content-Type:application/xml」を指定しよう。

# 今後の課題
以上でめでたくFitbitのデータを他サービスへ連携できるようになった。
ただ、課題というか、ちょっと工夫したい箇所も残った。

* Webhooksで送信したときのレスポンスが取得できない
他サービスに連携できたのかどうか、レスポンスに含まれるエラーコードを取得して失敗したら通知する、といったルールを作りたかったのだが、どうもWebhooksではレスポンスを取得できない仕様のようだ。

```html
Webhook Not Returning Results for next Steps
Unfortunately, not all apps can send back data in a way that our system can interpret in subsequent steps.
If you're familiar with Python or Javascript, a potential workaround is to do this with a Code step. 
Please note that the Code app is an advanced feature and we aren't able to help troubleshoot the code if there are errors.
```

やりたければCodeステップで実装しろ、と書いてある。
Codeステップの中でレスポンス発行もできるようなので、Webhooksステップを使わずコード書けということなのだろう。
面倒くさがりのあなたへ、MFI（モバイルファーストインデックス）の情報まとめ

とっても面倒くさがりな自分のために、まとメモを作りました。

# MFIってそもそもなんなん？

* MFI（モバイルファーストインデックス）は、グーグル検索のランキングに直接的な関係があるわけではなく、「クロールしインデックスして評価の対象となるページ」をモバイルを主とするように切り替えるということです。
* MFIに対応している、していないでランキングの影響が必ずしもあるわけはありません。
* しかし例えばSPとPCで別ディレクトリにページが分けられており、MFIの移行がかかった場合は<br>
SPとPCでコンテンツ量に差があったりUXに制限がかかっていると、ランキングへの影響があります。
* 影響を受けるサイトは、**別URL構成、動的構成、AMP版＋非AMP版**のみです。

* [Google ウェブマスター向け公式ブログ: モバイル ファースト インデックスを開始します](https://webmaster-ja.googleblog.com/2018/03/rolling-out-mobile-first-indexing.html)

## MFIへの移行のタイミング
* 準備が整っているサイトから順次移行されます
* ページ単位ではなく、サイト単位での移行です

### 準備ができているかどうかの判断
* 準備ができているかどうかはgoogleが提唱しているベストプラティクスに準じているかどうかです。<br>
[Best practices for mobile-first indexing  |  Search  |  Google Developers](https://developers.google.com/search/mobile-sites/mobile-first-indexing)
* 特に何か制作側からアクションを起こすわけではなく、googleが判断し自動で対応します。
* 準備ができているかどうかは、google search consoleから通知が来るほか、モバイル向けのGoogleクローラ「Googlebot」のアクセスが大幅に増えるとのことです。


# Web制作者側が気にすべき内容

## ディレクトリ構造やリダイレクト設定が変わる
* MFIに対応しようと思うと、pcをベースにspページはspディレクトリ内に置いて、デバイス毎にリダイレクトをかける。<br>
という手法は、**構成の仕方が逆になります**
* spをベースにpcディレクトリを下層に置いて、デバイス毎にpcディレクトリにリダイレクトをかけます



## URLの正規化について
* PC・SPで別URL構成にしていた場合は、下記のURLの正規化をしていたと思います。<br>
・PCページ：alternate を設定<br>
　内容的にもっとも近いと思われるページを指定<br>
　`rel="alternate"`<br>
・SPページ：canonical を設定<br>
　内容的にもっとも近いと思われるページを指定、あるいは1ページ目を選択<br>
　`rel="canonical"`
* MFIになった場合は、alternateとcanonicalを入れ替えないといけないのか！？というと、そちらは不要です。<br>
Googleは内部処理を行うとのことで、サイト側での対応は必要は不要らしいです。<br>
個人的にはいつやーめた！って言われてもおかしくはないと思いますが、当面は大丈夫そうですね。
* [canonicalタグって意味あるの？／解説とSEOに役立つ設定法](https://seopack.jp/seoblog/20160817-canonical/)



## PC・SPのページ構成やコンテンツについて
* ページ構成はSP・PCで同一のものにしておき、デバイス毎に情報量の差が出ないようにしましょう
* コンテンツの内容についてもPCとSPで同一のものにしておきます
* SPに表示する内容を一部アコーディオンで隠したりする場合は、html内にコンテンツ文章があればOK
* PCとSPの一致度は、完全でなくとも大丈夫。HTMLソースの違いや語順程度であればOK
* 構造化データにする場合は、PC・SPの両方に必要です
* [SEO強化のサポート役「構造化データマークアップ」って何？ そのやり方は？ | それいけ！フロントエンド](https://liginc.co.jp/357759)



## リンクについて
* PCに存在していたサイドメニューなどをSP版では非表示にする場合、おそらく問題はありません（未確定）
* PCのGナビの内容をSPでハンバーガーメニューにする場合、おそらく問題はありません（未確定）
* PCのコンテンツ内にあった重要なリンクをSPで省略するのはNG
* この辺りはまだ名言が避けられているので、引き続きウォッチが必要です。



## その他
* altの内容はPCとSPで統一させましょう
* インタースティシャル広告（コンテンツに被さるスクリーンタイプの広告）をSPページに入れていると、PCサイトの順位に影響するようになります。
* 念には念を入れて、xmlのサイトマップの最新版をgoogle search consoleから送信しておきましょう
* AMPにMFIの影響はありません<br>
※AMP版＋非AMP版の場合は、影響の可能性があります



# まとめると
* 迷った時は、ユーザーが使いやすいかどうか、UXで判断しましょう。MFIの施行の目的もユーザーが使いやすいように、です！
* 移行準備ができていないサイトは、いつMFIの影響を受けるのか不明。いつの日か一斉に切り替えがあるかも…！


## 参考リンク
* [Googleのモバイルファーストインデックス（MFI）導入による影響と対策【2018年2月最新版】 | プロモニスタ](https://promonista.com/mobile-first-indexing/)
* [グーグルがMFIへの切り替えを正式に開始！ 準備ができたサイトから順次。SCへの通知も | 編集長ブログ―安田英久 | Web担当者Forum](https://webtan.impress.co.jp/e/2018/03/27/28811)