OmniAICreator/Qiita-1.07M huggingface dataset:
PlayのJsonコンビネータでWritesにcontramapを使う

```scala:実装抜粋
package controllers.presenters

import models.domains._
import play.api.libs.json._
import play.api.libs.functional.syntax._

trait JsonPostsPresenterImpl extends PostsPresenter {
  implicit val postWrites = (
    (__ \ "id").write[String].contramap((postId: PostId) => postId.toString) and
      (__ \ "user_id").write[String].contramap((userId: UserId) => userId.toString) and
      (__ \ "text").write[String].contramap((text: Text) => text.toString) and
      (__ \ "posted_at").write[String].contramap((postedAt: PostedAt) => postedAt.toString)
  )(unlift(Post.unapply))

  override def present(input: Seq[Post]) = Json.toJson(input)
}
```
DDD的な実装をしているScalaアプリケーションだとクラスの構成要素がプリミティブ型ということはおそらく少なくて、ほぼほぼ専用の値クラスを用意している場合が多いんではないかと思う。

~~PlayのJsonコンビネータはドキュメントの例を見た感じ、プリミティブ型しか食えないっぽいので `contramap` を使って値クラスからプリミティブ型への変換をしてやる処理が必要のようだ。~~ → コメントに追記があります。
QlikViewのデータ圧縮はファイルの種類によって異なる？

QlikViewのファイル圧縮には謎が多い。
とりあえず、こんなスクリプトでデータファイルを作ってみる。

#データの作成
Customer=1,000,000件,Product=10,000件、Transaction=100,000,000件のデータをテキトーに作ってみる。

```vimscript:QVDファイルの作成
LET vCustomerCnt =1000000;
LET vProductCnt = 10000;
LET vTranCnt = 100000000;

Customer:
LOAD RowNo()			as customer_id,
	 Hash128(RowNo())	as customer_name
AutoGenerate $(vCustomerCnt);

Product:
LOAD RowNo()				as product_id,
	 'Product_' & RowNo()	as product_name
AutoGenerate $(vProductCnt);

Transaction:
LOAD RowNo()										as tran_id,
	 Ceil(Rand()*$(vCustomerCnt))				as customer_id,
	 Ceil(Rand()*$(vProductCnt))					as product_id,
	 Mod(Floor(pow(Rand(),2)),3)+1				as unit,
	 Ceil(Sqrt(Rand()*10000000))					as amount
AutoGenerate $(vTranCnt);

STORE Customer into Customer.qvd(qvd);
STORE Product into product.qvd(qvd);
STORE Transaction into Transaction.qvd(qvd);
```
上の方法でCSVとQVD形式でStoreするとファイルサイズはこんな感じになる。
まずはCSV

![csv.png](https://qiita-image-store.s3.amazonaws.com/0/263849/7994b8ef-2ef8-8b25-7f4c-6eec759aa389.png)

qvdにすると当然圧縮できるわけだけど、重複度にもよるが、上のスクリプトでロードして作成した場合はこれくらいに圧縮できる。

![qvd.png](https://qiita-image-store.s3.amazonaws.com/0/263849/a62af3d0-9885-8cd4-8fc9-5b625a018e8f.png)

Transaction(100,000,000件)で約54%くらいにはなるね。

#データロード実験
QlikViewでのロードがテキストファイルよりQVDからロードしたほうが数倍速いと言われている。
じゃあ、数倍ってどの程度なのか。
以下のロードスクリプトでベンチマークしてみる。
因みにマシンスペックは以下のとおり
- CPU:  i7-3520M (2.9GHz)
- メモリ:12GB


```vimscript:データのロード
Customer:
LOAD *
FROM
Customer.qvd(qvd);

Product:
LOAD *
FROM
Product.qvd(qvd);

LET vRap = Now();

Transaction:
LOAD * FROM
Transaction.qvd(qvd);

LET vRap1 = interval(Now() - '$(vRap)');
```

リロード時間を比較すると
![qvd_load.png](https://qiita-image-store.s3.amazonaws.com/0/263849/f1ff5664-989c-229e-0996-beedb9e9681a.png)

QVDからロードしたほうが、3.57倍速いことになる。

#データソースがCSVとQVDの場合でファイルサイズは異なる？
今回の記事のメインはこれ。
ちょっと意外な結果なのだが、実はCSVからデータロードした場合とQVDからロードした場合でファイルサイズが異なる。

![filesaize.png](https://qiita-image-store.s3.amazonaws.com/0/263849/ce7d89a9-69b7-5c9e-a632-e672162fb33d.png)

ホントかよ。
なぜ違うのかわからないが、QVDからロードするとCSVに比較して77.4%のファイルサイズになる。
何かの間違いではと思って何度もやったのだが、結果は同じ。

で、結論は..

**”QVWのファイルサイズはQVDからロードしたほうが小さくなる。”**

未だに信じられないけどね。
GPSの研究　その14

概要
GPSを理解したかった。
RTK-GPS調べてみた。

#RTK-GPS

RTK測位は、2台の受信機を使用します（1つは固定基準局、もう一つは移動局）。
受信機から衛星までの距離を搬送波の波数と位相差から求める。
それぞれの受信機において観測される搬送波位相を測定します。
位相は受信機内で搬送波のレプリカを発生させ、比較をすることで知ることができます。
しかし、その間にいくつの波数（整数値バイアス）が存在するのかはわかりません。
次の手順として、この整数値バイアスを決定する必要があります。
この整数値バイアスの決定には『推測　-->　収束』の手順で行われます。
始めの推測値は前項で説明した単独測位の受信機を2台使用したディファレンシャル測位より求められます。
その解から候補範囲を推測し、収束させていきます。
収束解を得るまでに若干の時間が掛かりますが、整数値バイアスが決定すると2cm CEPの位置精度を提供します。
また、整数値バイアスが決定した後は常に位相差を積算してきます。
RTK測位の受信機は、およそ0.75mmの分解能で波長（衛星から受信機までの距離）を測定することができるので、位置精度2cmという高精度な測定を維持しています。
なお、単独測位で使用するL1 C/Aコードによる距離の分解能は、6cmが現在のところ限界となっています。
RTK測位では、整数値バイアスが決まるまでの間に30秒程度の時間がかかります。
整数値バイアスが決まるまでの解をフロート解（推測解）呼び、その精度は20cm CEP RMSです。
そこから収束をしていきFIX解が決まると精度は2cm CEP RMSとなります。

#受信機

普及型1周波

u-blox AEK-4T
u-blox EVK-5H
NovAtel SuperStar II
Hemisphere Crescent

測量級2周波
NovAtel OEMV-3


以上。
GoogleAppsScriptをWebAPIとして公開したとき実行制限はあるのか？

# これはなにか
- GoogleAppsScriptはWebAPIとして公開できる便利な機能がある
    - [Web Apps](https://developers.google.com/apps-script/guides/web)
- GoogleAppsScript内で使用するAPIには上限があったりするのだがWeb Appsについての記載は特に見つけられない
    - [Quotas for Google Services](https://developers.google.com/apps-script/guides/services/quotas)
- おそらく上限はないのだが、実際に外部公開用のサイトで利用するにあたって勘で使うのはちょっと怖い
- ということで実験してみた


# 方法
- スプレッドシートの中身をシンプルにJSONで返すAPIを想定
- スプレッドシートの中身はとりあえず30×30くらいにした
- このAPIに0.5秒おきに1000回RequestしてみてResponseをチェックする
    - 合計30分くらいかかる
- コードはこんな感じです

```javascript
function doGet(e){
  const res = getData()
  return ContentService.createTextOutput(JSON.stringify(res));
}

function getData(){
  const id = 'xxxxxxxxxx'
    , sheet = SpreadsheetApp.openById(id).getSheetByName(name)
    , sheet_data = sheet.getDataRange().getValues()
    , keys = sheet_data[0]
    , vals = sheet_data.slice(1)
    ;
  var datas = []
    , data 
    ;
  
  vals.forEach(function(v){
	data = {}
	keys.forEach(function(k, i){
		data[k] = v[i];
	})
	datas.push(data);
  })
  
  return datas;
}
```

# 結果
## まず上限はありそうだったか？
30分間で1000回Request送る程度では問題なし


## 時系列でのResponseTimeの変動

![image.png](https://qiita-image-store.s3.amazonaws.com/0/127651/94767aee-61ad-109a-087c-ad1758b9c0f9.png)

## ResponseTimeのHistgram
![image.png](https://qiita-image-store.s3.amazonaws.com/0/127651/e96c9bd4-1d53-b24c-e68b-3f3a9177e57e.png)

ムラはあるが大体1秒以内でResponseできている

# まとめ
- 大丈夫そう
- もっとRequest回数を増やしてもやってみたい
    - GoogleにIPで制限されるのはちょっと怖いけど
Object.defineProperties非対応環境向け webpack + babel + babel-preset-env トランスパイル設定

## 2019/01/03追記 この記事には改訂版があります

この記事の内容は古くなったため、改訂版を作成しました。

[Babel + rollup.js で ES3環境向けトランスパイル](https://qiita.com/masato_makino/items/8a61e97ea67f101cf1ae)

本記事の手順では、Babel7での正常なトランスパイルができません。改訂版では代替案としてrollup.jsの導入を行なっています。

webpack4 + babel6での組み合わせでトランスパイルを行う際のメモとして、この記事は残しています。
**新規導入の際はこの記事を利用しないでください。**

## 目標

moduleのimportを使用したjavascriptを、現行のwebpackとbabelを使用して、es3相当にトランスパイルします。

## 前提とする環境

本記事で前提とする環境は以下の通りです。バージョンが異なる場合、この記事の内容は適用できない場合があります。記事を読む前にバージョンをご確認ください。

+ macOS : 10.13
+ webpack : 4.10.2
+ babel : 6.23.0
+ babel-preset-env : 1.7.0

## なぜそんな古い規格を？

es3はブラウザ上からはすっかり消滅しましたが、アプリケーションに組み込まれた独自のjavascriptエンジンではまだ存在します。
私の場合、Adobe CCの各アプリのバッチ処理のためjsを使用しています。このjsエンジンが非常に古いため、es3相当のコードしか実行できません。
importを利用できれば、共通処理をくくり出せるため、バッチの生産性が高くなります。
どうにかしてimportを使用できる状況でコードを書き、Adobe CC上で実行できるようにトランスパイルします。

## 構成

使用するパッケージは以下の通りです。
npmからインストールしてください。

*▼package.json*

```json
"devDependencies": {
    "babel": "^6.23.0",
    "babel-cli": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
    "babel-plugin-transform-es3-property-literals": "^6.22.0",
    "babel-preset-env": "^1.7.0",
    "webpack": "^4.10.2",
    "webpack-cli": "^3.0.1"
}
```

## babelの設定

babelの設定は以下の通りです。
`"env", { "loose" : true }`でLoose modeを有効にすると、`Object.defineProperties`を使用しないようにトランスパイルが行われます。
また、transform-es3-*プラグインでオブジェクトのプロパティ名をstringに、呼び出しを連想配列に置き換えます。

*▼.babelrc*

```json
{
    "presets": [
        [ "env", { "loose" : true } ]
    ],
    "plugins": [
        "transform-es3-member-expression-literals",
        "transform-es3-property-literals"
    ]
}
```

この設定では最低限、importと最低限のトランスパイルが実行されるだけとなります。
その他のes2015以降の機能を利用したい場合は、対応するbabel-pluginを追加してください。
例として、Object.assignを使用したい場合は[babel-plugin-transform-object-assign](https://babeljs.io/docs/en/babel-plugin-transform-object-assign/)を追加します。

## webpackの設定

あとはbabel-loaderを使用したwebpackを行えば、import処理を含めたトランスパイルが行われます。

*▼webpack.config.js*

```js

const path = require("path");

module.exports = {
    entry: entryfile,
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name]',
    },

    module: {
        rules: [{
            test: /\.js$/,           
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader'
            }
        }]
    }
}
```
Atomからファイルの作成や保存ができない

MacでAtomからファイルを作成、保存しようとすると、パスワードを聞かれる。
`EACCES, permission denied`
#解決方法
```
sudo chmod -R 777  ~/.atom
```
 でAtom関連のファイルにフルパーミッションを与える。

改善しない場合、Atomから編集しているファイル/ディレクイトリのパーミッションも変更する。

```
sudo chmod -R 777 ワーキングディレクトリ
```
webpackのentryファイルを複数指定、globパッケージの使い方

## 目標

webpackで複数entryを簡単に実現するためのパッケージ[glob](https://github.com/isaacs/node-glob)の使い方をまとめます。
関連するドキュメントはネット上にありますが、必要とする情報が分散していたためまとめて記事とします。

## 前提とする環境

本記事で前提とする環境は以下の通りです。バージョンが異なる場合、この記事の内容は適用できない場合があります。記事を読む前にバージョンをご確認ください。

+ macOS : 10.15.6
+ webpack : 4.44.1
+ glob : 7.1.6

## node-glob

https://github.com/isaacs/node-glob

インストールはnpm上から行えます。

```bash
npm i glob
```

### 基本的な使い方

*▼webpack.config.js*

```js
const glob = require("glob");

const entries = glob.sync("./src/**/*.js");
module.exports = {
    entry: entries,
    ...
}
```

基本的な記法は、.gitignoreで見慣れたminimatchと同じです。
上記の例の場合、srcフォルダー以下のすべてのjsファイルを取り出して、entryに渡しています。
これでディレクトリ構造を保ったまま、複数のentryをwebpackに渡せます。

### 除外

*▼webpack.config.js*

```js
const entries = glob.sync("./src/**/*.js", {
    ignore: './src/**/_*.js'
})
```

第2引数のOptionオブジェクトのignoreに除外パターンを追加することで、検索結果から特定のファイルを除外できます。
上記の例の場合`_`から始まるファイルネームを持つファイルを除外します。
ignoreはstringもしくは配列で指定します。複数のパターンを除外する場合は配列を与えます。

### 検索ディレクトリの変更

*▼webpack.config.js*

```js
const entries = glob.sync("**/*.js", {
  cwd: "./src"
});
```
オプションに``cwd``を設定すると、そのディレクトリをルートとして検索が行われます。

もしも以下のようなファイル群があったとして

```console
./src/script1.js
./src/script2.js
./src/sub/script3.js
./src/sub/script4.js
```

cwdを設定した結果は

```console
[ "script1.js",
  "script2.js",
  "sub/script3.js",
  "sub/script4.js" ]
```

という配列で出力されます。

### 出力フォルダーの調整

*▼webpack.config.js*

```js
const path = require("path");
const glob = require("glob");

const srcDir = "./src";
const entries = glob
  .sync("**/*.js", {
    ignore: "**/_*.js",
    cwd: srcDir,
  })
  .map(function (key) {
    // [ '**/*.js' , './src/**/*.js' ]という形式の配列になる
    return [key, path.resolve(srcDir, key)];
  });

// 配列→{key:value}の連想配列へ変換
const entryObj = Object.fromEntries(entries);

module.exports = {
  entry: entryObj,
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name]",
  },
};
```

glob.sync()の戻り値はstring配列です。出力フォルダーの調整を行う場合、この配列を{key:value}の連想配列に整形する必要があります。
複数エントリー指定の正確な仕様については[公式ドキュメント](https://webpack.js.org/concepts/entry-points/#multi-page-application)を参照してください。
出力ファイル名は'[name]'と指定しておくことで、entryのファイル名を維持したまま出力が可能です。
TextFormFieldにValueをセットする


メモとして残しておく

## TextFormField

Flutterでのフォーム `TextFormField` にValueを設定するオプションはないみたいなので `controller` でテキストを設定するみたい

## 実装

```dart

Widget _formUserName() {
    final userNameInputController = new TextEditingController();
    userNameInputController.text = "flutter君";

    return new Container(
      margin: new EdgeInsets.all(10.0),
      child: new TextFormField(
        controller: userNameInputController,
        decoration: new InputDecoration(
          border: new UnderlineInputBorder(),
          labelText: "UserName",
        ),
      ),
    );
  }

```

<img width="371" alt="スクリーンショット 2018-06-17 14.17.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/139360/c71c8dd9-592d-74ef-4287-0fd477974526.png">
[Rails][RSpec][Capybara][poltergeist] confirm ダイアログでOKを選択する

poltergeist を使用している場合、自動で OK が選択されるため、

```rb
expect { click_link I18n.t('post.edit.destroy') }.to change { Post.count }.by(-1)
```

こんな感じで何もする必要がない。
Python3でMeCabを使う方法

# 概要
Python3でMeCabを使う方法と、それによって発生した問題とTravisCI上で発生した問題を解説します。

# テスト環境
- Ubuntu16.04
- Python 3.6.4
- TravisCI

# 結論
## Install(apt)
- python-tk(python2)
- python3-tk(python3)
- tk-dev
- mecab
- mecab-ipadic
- mecab-utils
- mecab-ipadic-utf8
- libmecab-dev

## Install(pip)
- mecab-python

## 辞書設定
/etc/mecabrcの`dicdir = /var/lib/mecab/dic/debian`を、必要があれば書き換えます。
私は`dicdir = /var/lib/mecab/dic/ipadic-utf8`に書き換えました。
`/var/lib/mecab/dic/`以下を見れば、インストールされてある辞書を見ることができます。

## コード
```
tagger = MeCab.Tagger('-Ochasen')
tagger.parse('')  # mecab-pythonのバグで、事前に空parseを挟まないといけない場合もある
result = tagger.parseToNode(self.text)
while result:
  print("feature: ", result.feature, " surface: ",  result.surface) # パース内容が取得できる
  result = result.next
```


# 発生した問題
上記の回答に至るまでの意発生した問題を順番に解説します。

## TravisCI
**Python:** 動作環境としてPython3系しか設定していない場合でも、Python2系のパッケージなどが使われる場合がある。
そのため`python-tk`など、2系のパッケージも導入している。

**文字コード:** TravisCIでは裏で2系が動くこともあるため、2バイト文字以上を扱う場合codingを設定する必要がある。Python3ではcodingを指定する必要はないが、TravisCIでは指定する必要があるので気をつけてください。
ASCII文字しか使わない場合はcodingの指定は必要ありません。


## mecab
mecabを使用するまでに必要なものは色々あります。
まずaptで通常のmecabや辞書、mecabを扱うためのその他パッケージを導入します。
コマンドで通常使うだけならこれだけでもほぼ問題ないはずです。

辞書を変更したい場合は、結論に書いたように`dicdir`を変更します。
辞書は様々な種類があるので、別途インストールすればそれも設定できます。

## tkinter
`mecab-python`のパッケージ内で`tkinter`というパッケージを使用します。
mecabを通常使用するだけのパッケージ構成だと、pythonの`ImportError`が発生します。
tkinterとは、tkというGUIを扱う物のinterfaceです。
通常のCentOSなどでは、デフォルトでインストールされていたりもします。
これを解消するために`tk-dev`や`python-tk`などをインストールします。

ここが1番の罠なのですが、pythonをインストールした時点でtkがインストールされていないと認識されません。
(パスなどをつなぐ方法があるかもしれませんが、現状把握していません)
tkを後からインストールした場合は、pythonをアンインストールして、インストールし直してください。

pyenvの場合

```
pyenv uninstall 3.6.4
pyenv install 3.6.4
```

## mecab-python
**mecab-pythonのバグ:** mecab-pythonのバグで、事前に空parseを挟まないといけない場合もある。

```
tagger.parse('')
result = tagger.parseToNode(text)
```

**TypeErrorが出る場合:** textが外部から渡される場合、unicode型などで渡される場合などある場合、typeを検査しencodeする。

```
if not isinstance(self.text, str):
    self.text = self.text.encode('utf-8')
```

# まとめ
以上で今回遭遇した問題は解決しました。

# 参考URL
- [python3 + mecabでnode.surfaceが取得できないバグへの対応](https://qiita.com/piruty/items/ce218090eae53b775b79)
- [Ubuntu 16.04 LTSのPythonでMeCabを動かす方法](https://qiita.com/SUZUKI_Masaya/items/685000d569452585210c)
Parse (ParseServer) Twitterログインできなくなった問題の解決方法


先日（2018/6/13）よりGDPRの影響？でツイッターでのログインの設定が変わり突然落ちるようになりました。

この解決にとても工数を使い苦しみましたので、情報共有します。

エラー内容：
<?xml version="1.0" encoding="UTF-8"?><errors><error code="415">Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings</error></errors>

解決方法：
具体的には開発アプリの管理画面である https://apps.twitter.com/ のSettingsタブのCallbackURLsの値を、 http://twitter-oauth.callback に変更します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/14388/28b90c13-ec4a-5f2e-74da-092189059dfa.png)

※これはSDK(ParseTwitterUtils）が更新されるまでの一時措置かもしれません。
もし更新などで変更された場合はSDKソースの中oauth_callbackの値と開発アプリの管理画面のCallbackURLsが同じであれば動作します。

https://github.com/parse-community/ParseTwitterUtils-iOS

（参考までにこちらが公式のアナウンスです）
https://twittercommunity.com/t/action-required-sign-…/105342

同じことで苦しむ方がもしこの情報で解決できれば幸いです。
rebassのComponentをStorybookのStoryに追加する際のひと手間

rebassを使ったreactプロジェクトにstorybookをセットアップした際に行ったことをメモ

rebassのドキュメント [Getting Started](https://github.com/jxnblk/rebass/blob/master/docs/getting-started.md)を見ると、rebassが提供するComponentを利用する場合、ルートのComponentを `<Provider />` というコンポーネントでラップする必要があるとの記述があります。
アプリケーション側では、indexやAppといったルートになるComponent内で`<Provider />`でのラッピングを行えばいいのですが、Storybook側でも同様のことを行う必要があります。

## 前提
`create-react-app` で作成したプロジェクトで `getstorybook` した直後に作成されたconfig.js

```js:config.js
import { configure } from '@storybook/react';

function loadStories() {
  require('../src/stories');
}

configure(loadStories, module);
```


## ひと手間

次のように変更します。

```js:config.js
import React from "react";
import { configure, addDecorator } from "@storybook/react";
import { Provider } from "rebass";

const ThemeDecorator = storyFn => <Provider>{storyFn()}</Provider>;
addDecorator(ThemeDecorator);

function loadStories() {
  require('../src/stories');
}

configure(loadStories, module);
```

Storybookの[ドキュメント](https://storybook.js.org/addons/introduction/)を見ると分かる通り、まさに今回のケースにピッタリのAPI(addDecorator)が用意されていたという感じです。


## 参考

https://github.com/jxnblk/rebasse/issues/354
https://storybook.js.org/addons/introduction/
WSL(Ubuntu 18.04)環境のgitでWinMergeを使う方法

「Windows 10 April 2018 Update」の Ubuntu 18.04 環境対応です。
パス変換のコマンド wslpath が提供されるようになったので簡単になりました。

WinMergeは3wayマージ対応の日本語版を前提にしています。
[WinMerge 日本語版](http://www.geocities.co.jp/SiliconValley-SanJose/8165/winmerge.html)

# 作業パス変更
## リポジトリを /mnt/c 以下に置く
/home/username 以下はWindowsアプリから扱えないので、/mnt/c/Users/username 以下で作業します。

わざわざ cd /mnt/c/Users/username とするのも面倒であれば、シンボリックリンクを作成してもいいです。

```
$ cd ~
$ ln -s "/mnt/c/Users/username" win
$ cd win; mkdir gitwork; cd gitwork
$ git init
$ git ...
```

## テンポラリフォルダのパスを変更する
gitの外部ツール連携の仕組みは、一旦テンポラリフォルダにチェックアウトしてから、そのパスを渡すというものです。

WSLではWindows側から見えないパスがテンポラリフォルダとして設定されていますので、Windows側に変更する必要が有ります。

~/.bashrc に以下をコピペします。

```
export TMPDIR=`cmd.exe /C echo %TEMP% | tr -d '\r' | sed -e 's|\\\\|\\\\\\\\|g' | xargs wslpath -ua`
```

(バックスラッシュが多いですが、sedで1回、シェルスクリプトに記載するのにさらにエスケープ、そしてwslpathにパイプで渡す際にもエスケープが必要な為です。2*2*2=8)

参考) wslpathコマンド
WindowsのパスをWindows表記とWSL(Linux)表記で相互変換する為のツールです。

a. WindowsパスからWSLの絶対パスへの変換

```
$ wslpath -ua 'C:\Users'
/mnt/c/Users
```

b. WSLパスからWindowsの絶対パスに変換

```
$ wslpath -wa '/mnt/c/Users'
C:\Users
```

相対パスのまま変換する場合は、aオプションを外します。

# Gitに WinMerge を設定する
~/.gitconfig に以下を記載します。

```
[diff]
    tool = WinMerge
[difftool]
    prompt = false
[difftool "WinMerge"]
    path = 'WinMergeU.exe'
    cmd = \"WinMergeU.exe\" -e -r -u -wl -dl Local -wr -dr Remote \"`wslpath -wa $LOCAL`\" \"`wslpath -wa $REMOTE`\"
    trustExitCode = false
[merge]
    tool = WinMerge
[mergetool]
    prompt = false
    keepBackup = false
[mergetool "WinMerge"]
    cmd = \"WinMergeU.exe\" -r -e -u -al -dl Local -wm -dm Remote -wr -dr 共通祖先 \"`wslpath -wa $LOCAL`\" \"`wslpath -wa $REMOTE`\" \"`wslpath -wa $BASE`\" -o \"`wslpath -wa $MERGED`\"
    trustExitCode = false
[alias]
    windiff = difftool -y -d --no-symlinks -t WinMerge
    winmerge = mergetool -y -t WinMerge
```

# 使い方

- 比較

git diff と同じです。

```
git windiff [比較元] [比較先]
```

- マージ

git mergeとかpull, rebase, cherry-pick などでコンフリクトしたら、

```
git winmerge
```

と叩いて下さい。
3Wayマージを行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120192/459bd1a9-b882-bee3-fa4b-0e77084e102b.png)

左側がローカルの作業ファイル、中央がマージ対象、右側が両ブランチの共通祖先となるコミットです。
共通祖先に対して修正箇所が被らない所が、左側のローカルにオートマージされた状態です。
両方で修正されていてコンフリクトになっている所(一番下)は、Location Paneで赤くなるようです。

必要な編集を行って保存し、WinMergeを閉じるとファイルがステージングされた状態になります。
あとはコミットするだけです。
AndroidStudio での Tensorflow 導入からエミュレータ（PCカメラ）のデモまで

# 前提
- 開発PCはMacです
- AndroidStudio インストール済であること

# Tensorflow をクローンする
任意の場所にクローンする
`git clone https://github.com/tensorflow/tensorflow`

# ビルド前に設定を変更する
## tensorflow/examples/android/build.gradle の編集

```build.gradle
buildscript {
    repositories {
        google()
        jcenter()
    }
```

```build.gradle
// set to 'bazel', 'cmake', 'makefile', 'none'
def nativeBuildSystem = 'none'
```

## 使用カメラの設定

エミュレータで使用するカメラをPCカメラにする必要があるので、設定をする

AndroidStudio のAVDマネージャーを開く
<img width="789" alt="スクリーンショット 2018-06-17 12.54.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/221399/f9745e51-7873-7a45-a650-01faf37f7362.png">

編集ボタンを押下
<img width="1352" alt="スクリーンショット 2018-06-17 12.59.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/221399/fd5602d1-bf03-595b-7590-0bf06a52f1ab.png">

`Show Advanced Settings` を押下
<img width="1112" alt="スクリーンショット 2018-06-17 13.00.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/221399/8eceaa61-566f-f956-bf0b-ae5871009636.png">

`Camera` を `Webcam0`に変更
<img width="1112" alt="スクリーンショット 2018-06-17 13.02.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/221399/947b4ab2-5ec2-6fe3-b3cc-aed442f9357e.png">

これでエミュレータのカメラがPCカメラで起動するようになります。

# プロジェクトを開く
`tensorflow/examples/android` をAndroidStudioでオープンし、ビルドが終わるのを待ちます。
※ツールのバージョンが古いすぎる等何度か怒られましたが、基本的には指示に従ってアップデートをするだけでビルド成功するようになりました。

エミュレータを起動→エミュレータ内部のカメラを起動します。
しばらくすると、青い部分が出現して、画面に映っているものの名前を表示してくれます。

財布を写してみました。
<img width="411" alt="スクリーンショット 2018-06-17 13.16.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/221399/4ed21afe-1a53-8f5c-5e37-00c7555cc9e4.png">

`wallet: 0.23740001`と表示されています。
数字はリアルタイムでどんどん変化していくので、色々映してみると楽しいです！

今回はとりあえずデモの起動までを行いました。
MacにPython3.6.5をインストールしPATHを設定する

## 概要
MacBook Proを新たに購入したので、諸々環境構築の手順をまとめておきます。
デフォルトではPython2.7系が入っていたので、今回は、Python3.6.5(~~現在の最新バージョン~~)のインストールです。

## 動作環境
- MacOS High Sierra (バージョン10.13.4)
- Homebrew 1.6.8

## インストールの手順
1. pyenvのインストール
2. Python3.6.5のインストール
3. Python3.6.5のGlobal設定
4. PATHの設定

## 1. pyenvのインストール


```shell-session:~
$ brew install pyenv
$ pyenv versions
* system (set by /Users/***/.pyenv/version) # ***にはユーザ名が入ります
```
pyenvがインストールされました。
ホームディレクトリ内に~/.pyenvフォルダが存在します。

## 2. Python3.6.5のインストール

```shell-session:~
$ pyenv install 3.6.5
$ pyenv versions
* system (set by /Users/***/.pyenv/version)
  3.6.5 
```
Python3.6.5がインストールされたことがわかります。

--**2018/9/2追記**--
下記のようなbuildエラーが出た場合、xcodeのコマンドラインツールが入ってない場合があります。

```shell-session
BUILD FAILED (OS X 10.12.6 using python-build 20180424)
```
以下のコマンドでコマンドラインツールをインストールしてから再びpythonのインストールを試して見ましょう。

```shell-session:~
$ xcode-select --install
```


## 3. Python3.6.5のGlobal設定
```shell-session:~
$ pyenv global 3.6.5
$ pyenv versions
  system
* 3.6.5 (set by /Users/***/.pyenv/version)
```
これで、ローカル環境では、先ほどインストールされたPython3.6.5が使えるようになります。
## 4. PATHの設定
```shell-session:~
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
```
ホームディレクトリ下の~/.bash_profileに上記の設定を書き込みます。

```shell-session:~
$ source ~/.bash_profile
$ python --version
Python 3.6.5
```
.bash_profileに書いた設定を読み込み、Python3.6.5へ切り替えが完了しました。
Node.jsでつくるNode.js - もくじ

# はじめに

「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」([ラムダノート](https://www.lambdanote.com/products/ruby-ruby), [Amazon](https://www.amazon.co.jp/dp/4908686017)) という本を手を動かしながら読んで、非常に感銘を受けました。そんなおりに [PythonでつくるPython](http://akimacho.hatenablog.com/entry/2018/05/22/220109)という記事を読み、自分でもNode.jsでミニNode.js作りにチャンレンジすることにしました。
予想以上に手間取り端折った部分もありますが、なんとか最後はブートストラップまで行くことができました。

# 目次

## ミニインタープリター編

* [Step1：ソースのパース](https://qiita.com/massie_g/items/3f604413ca5ea4552b45) ... 初めての esprima
* [Step2：単純化](https://qiita.com/massie_g/items/6c852f96f7271e9e70bf) ... 抽象構文木(AST)を単純化
* [Step 3: +演算子を評価する](https://qiita.com/massie_g/items/ad6ae33ec1e46b67ad57) ... 足し算を実行
* [Step 4: 四則演算で電卓を作る](https://qiita.com/massie_g/items/40591822228d7e166b63) ... 電卓を作るところまでと、比較演算子の実装
* [Step 5: 変数を使う](https://qiita.com/massie_g/items/1e5bf8b3cca0ae08fd1c) ... 変数の宣言、代入、参照
* [Step 6: 条件分岐と繰り返し](https://qiita.com/massie_g/items/f801692fb9b07d007285) ... ifで条件分岐、 whileで繰り返し
* [Step 7: 組み込み関数](https://qiita.com/massie_g/items/22506a9dabbd13cee13f) ... 組み込み関数を呼び出す
* [Step 8: ユーザ定義関数](https://qiita.com/massie_g/items/e537f14300a6113a6237) ... 自分で関数を定義、利用できるように
* [Step 9: 配列とハッシュ](https://qiita.com/massie_g/items/b2a94e98ff80868bedec) ... ブートストラップに備えて配列ハッシュを使えるように
* [Step 10: オブジェクトの利用を回避](https://qiita.com/massie_g/items/1b59efb5f891b3dda05b) ... 知らず知らずにオブジェクトを利用してた処理をモジュールとして分離
* [Step 11: returnを諦めて、無理矢理ブートストラップ](https://qiita.com/massie_g/items/5d8d61cdbf54390d8709) ... return処理を避けて無理矢理ブートストラップを実現
* [Step 12: returnをサポート](https://qiita.com/massie_g/items/35555286594e1cf780e1) ... あらためてreturn処理を実装してブートストラップ達成
* [Extra 1： ミニRubyの単純化Treeを実行する](https://qiita.com/massie_g/items/3a4888168bb288965393) ... ミニRubyの単純化Treeを読み込んで実行する
* [Extra 2： 演算子を追加する](https://qiita.com/massie_g/items/d1ef41bab2f8fd7343b5) ... 否定演算子や論理演算子を追加

## ミニコンパイラ編

* [ミニコンパイラ編 目次](https://qiita.com/massie_g/items/3ba1ba5d55499ee84b0b)

## WASMコンパイラ編

* [Node.jsでつくるNode.js-WASMコンパイラ - もくじ](https://qiita.com/massie_g/items/c663095759a80c53c126)

# 謝辞

「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」([ラムダノート](https://www.lambdanote.com/products/ruby-ruby), [Amazon](https://www.amazon.co.jp/dp/4908686017)) に感銘をうけて自分でもミニNode.jsを作って見ましたが、本を読んでいた時には気がつかなかったことが多々ありました。書籍の構成、ミニRubyの設計がとても優れていて、とても参考になりました。
素晴らしい書籍を作ってくださった作者の遠藤さんとラムダノートさんに改めて感謝します。ありがとうございました。


# ソースコード

今回作ったコードは GitHub で公開しています。

* [mganeko/mininode](https://github.com/mganeko/mininode)
* [mganeko/mininode_compiler](https://github.com/mganeko/mininode_compiler)
* [mganeko/mini_node_wasm](https://github.com/mganeko/mini_node_wasm)

# いつかやりたいこと

* Extra 3: 関数の前方参照、ブロックスコープ、グローバル変数をサポートする
* 済 Extra 4：LLVMを使ってバイナリ生成できるか？ ... [コンパイラ編で実施済](https://qiita.com/massie_g/items/3ba1ba5d55499ee84b0b)
GridLayoutでweightを利用してViewを画面幅いっぱいに表示する

## やりたいこと

`android.support.v7.widget.GridLayout`を用いて、複数の要素を画面サイズに合わせて画面横幅いっぱいに表示したい。
要素ごとのwidthは可変である必要がある。

![スクリーンショット 2018-06-17 12.43.19.png](https://qiita-image-store.s3.amazonaws.com/0/62874/1567eaaf-5017-ec67-cc98-6e8ceda46ade.png)

## コード

サポートライブラリを追加しておく。

```gradle:build.gradle
dependencies {
    ...
    implementation 'com.android.support:gridlayout-v7:26.0.1'
    ...
}
```

レイアウトファイルでは`android.support.v7.widget.GridLayout`を追加。
要素のViewに`layout_columnWeight`を指定してやる。

```xml:grid_sample.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <android.support.v7.widget.GridLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="4dp"

        app:columnCount="3"
        app:rowOrderPreserved="false"
        app:useDefaultMargins="true">

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            app:layout_columnWeight="1"
            android:padding="5dp"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="ABCDEFGHIJKL" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            app:layout_columnWeight="1"
            android:padding="5dp"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="ABCDEFGHIJKL" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            app:layout_columnWeight="1"
            android:padding="5dp"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="ABCDEFGHIJKL" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            app:layout_columnWeight="1"
            android:padding="5dp"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="ABCDEFGHIJKL" />

    </android.support.v7.widget.GridLayout>
</android.support.constraint.ConstraintLayout>
```

## ポイント

### 1. `android.widget.GridLayout`ではなく`android.support.v7.widget.GridLayout`を利用する

前者では`layout_columnWeight`が利用できないので、後者を利用する。

### 2. `layout_width`には`0dp`を指定する

`layout_width:"wrap_content"`でも一見上手く動作するのだが、テキストが一行で収まらない量になると要素がGridLayoutをはみ出してしまう。

![スクリーンショット 2018-06-17 12.41.44.png](https://qiita-image-store.s3.amazonaws.com/0/62874/5e50c441-1b2b-29ed-5293-9bd13950f0e9.png)

## 参考

GridLayoutでweightを使う
https://qiita.com/yysk/items/da65ae4c82c84d0c0449

[Android] GridLayout（GridViewではなく）すべての子を均等に伸ばす方法 android-layout android-gridview | CODE Q&A [日本語]
https://code.i-harness.com/ja/q/98d657
UiPath Academy最大の難所「レッスン１」を乗り越える

※2018/11/3 追記
以下の記事は2018年9月まで提供されていた
　"Level 1 - Foundation Training"
の内容をベースに書いています。現在は
　"Level 1 Foundation（基礎）トレーニング -【改良ベータ版】"
に改定され、構成・内容とも刷新された別物になってます。

# 背景
製品シェアを高める戦略として
「個人利用なら無償で使える＆勉強できるようにして世界中で開発者の裾野を広げる」
というのがあって、ゲームエンジンの[Unity](https://unity3d.com/jp)や[Unreal engine](https://www.unrealengine.com/ja/blog)で有名ですが、
RPAだとまさにUiPathがそれで、私もその戦略に引っかかってしまい今に至ります。

で、UiPath開発者を増やすべく日々"自称エヴァンジェリスト"として周囲にUiPathを推していて
**Q.「UiPathを使いこなせるようになるには何をすればいいの？」**
　という質問には
**A.「UiPath Academyの"Level 1 - Foundation Training"を受ければ十分だよ、タダだよლ(´ڡ`ლ)」**

と触れ回っているのですが、だいたい数日後には

**Q.「レッスン１から難しすぎて進まねーよ、確認テストも全然合格できねーよ、どうすんだコレ」
A.「そんなワケねーだろ、やる気の問題だろ、さてはアンチだなオメー」**

みたいなやり取りになっていて、いよいよ信頼失墜の危機。

何か対策を取らなければまずいと思い、数ヶ月前に受けた「レッスン１ - UiPathの概要」を見返してみる。

# レッスン１の問題点
レッスン１の問題点を列挙すると、
### 聞き慣れない単語がバンバン飛び交い、理解の向こう側を逝く
- アテンディットモードとアンアテンディットモード
- エニーテラーアプリケーション
- タイプイントゥアクティビティ

といった言葉がナレーションに次々出てきて「？？？」となっているうちに先に進んでしまう。
### クイズ（確認テスト）の内容が完全にUiPathを触った事がある人向け
「そもそも**クイズ**って言葉が軽くない？」完全にテストです。
正直難しいです。１つ１つは２章以降で詳細に触れるので、この時点で完全に理解する必要は無いのに70点以上取らないと先に進めないのは厳しい。

※2018/07/21追記 公式の[ビデオチュートリアル](https://www.uipath.com/ja/tutorials)で、ビデオだけなら最初から選んで視聴できます。

### ナレーションと字幕が合っていない
映画でもそうだし、そういうものかも。基本はナレーション側に沿って下さい。
字幕の方は言葉づかいがぶっきらぼうで、慣れてくるとナレーションとのギャップを楽しめます。

# レッスン１を乗り越えるための対策集

ネットでも"レッスン２からでいいんじゃない？"という意見があり、全くその通りですが
Academyでは１つずつクリアしないと先に進めないので、
レッスン１で挫折した／これからレッスン１を受けようとしている人は↓の対策を参考にして下さい。
レッスン１で大事なのは、レッスン１を通過する事です。

### ナレーションで出てくる用語を知っとく
出てくる用語の意味を知っているだけでも動画の理解度が全然違います。

|ナレーション|スペル|意味|
|:-----------------|:------------------|:------------------|
|アテンディットモード|Attended mode|人間がポチッと実行ボタンを押してワークフローを実行する事。フロントオフィスロボット(FOR)とも言う。|
|アンアテンディットモード|Unattended mode|↓のOrchestratorサーバーからの指示で無人でワークフローが実行される事。バックオフィスロボット(BOR)とも言う。|
|オーケストレーター|Orchestrator|無人でワークフローを自動実行するために必要なサーバー集中管理機能。ちなみに何百万円もする。|
|エニーテラーアプリケーション|Any Teller Application|Academy内で、UiPathの操作対象として登場する架空の会計ソフト|
|タイプイントゥアクティビティ|Type Into Activity|操作対象のシステムに文字や数字を入力するためのコマンド|
|ゲットテキストアクティビティ|Get Text Activity|操作対象のシステムに表示されてる文字や数字を取ってくるためのコマンド|

### クイズで70点以上取るためのヒント
あくまで**クイズ**のヒントです。回答そのものではないですよ。

- 画面上[Manage Valuables]か画面下[Variablesパネル]で変数の範囲を変更できる。 
- [Variablesパネル]で新しい変数を追加、変数のデータ型を変更、変数のデフォルト値を設定、ができる。
- 複雑なワークフローの作成が、フローチャート(Flowchartアクティビティ)に最適な用途。
- Type Intoアクティビティが、アプリケーション領域のテキスト入力に使用できる。
- ジェネリック(Generic value)型変数にはString/Integer/Boolean等、どんなデータ型でも格納できる。
- 画面左[Activities Panel]で、ワークフローで使用できるアクティビティの一覧が確認できる。
- ロボットは完全自動モード(=Unattended mode)／アシスタントモード(=Attended mode)で動作する。
- セレクタを使用するのが、一番正確にUI要素にアクセスすることができる方法。
- Trimメソッドで、文字列の（前後の）余分な空白を取り除く事ができる。
- 複数のロボットに処理を分散させるためにQueuesコマンドがある。
- Citrix環境からテキストを取得するには、OCRと組み合わせてScrape Relative機能を使用​​する。	
- Type Intoでは、toStringメソッドでひも付けされた変数や、静的文字列を受け取ることができる。
- UiPath ExplorerはUI要素に関する詳細情報の取得するために使用される。
- Data Scrapingアクティビティが、ウェブページから構造化されたデータを取得するのに最も簡単な方法。
- Read PDF Textを使用するか、PDFを開いて画面スクレイピングを使用すればPDF文章を取得できる。
- ログイン情報の保管は、UiPath Orchestrator内か、Windows Credentials Manager内が安全。
 
挙げると結構あるね。

---
今回はここまで。
Academyは怒涛の勢いでナレーションが進むので圧倒されてしまいますが、
ここで出る話題は後の章で全て詳しく触れられるので、今の時点では流しで見て
「こんな事ができるのか」程度の理解で良いです。
React関連のサイト・記事まとめ〜入門から最新バージョンまで〜

# はじめに

[React](https://github.com/facebook/react/)に関する記事はとても多いので、入門から最新バージョンについての記事のまとめです。
素晴らしい記事をありがとうございます🙌
「この記事いいよ！」などあれば、教えてください。

※ ReduxやNextjsに関する記事は含めていません

# 入門向け

## 仮想DOMについて

- [なぜ仮想DOMという概念が俺達の魂を震えさせるのか](https://qiita.com/mizchi/items/4d25bc26def1719d52e6)

## Reactの概要

- [Reactを使うとなぜjQueryが要らなくなるのか](https://qiita.com/naruto/items/fdb61bc743395f8d8faf)
- [出来る限り短く説明するReact.js入門](https://qiita.com/rgbkids/items/8ec309d1bf5e203d2b19)

## React入門

- [Reactの公式ドキュメント](https://reactjs.org/docs/hello-world.html)
- [Reactの公式チュートリアル](https://reactjs.org/tutorial/tutorial.html)
    - [日本語の解説](https://github.com/10shi10ma/reactTutorial)
    - [Reactチュートリアル: Intro To React【日本語翻訳】](https://mae.chab.in/archives/2943)
- [React基礎](http://basic-react.axlight.com/html/)
- [一人React.js Advent Calendar 2014
](https://qiita.com/advent-calendar/2014/reactjs)
- [ReactJSで作る今時のSPA入門（基本編）](https://qiita.com/teradonburi/items/fb91e5feacab5071cfef)
- [Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する](https://qiita.com/chibicode/items/8533dd72f1ebaeb4b614)
- [30分間React入門「いいねボタン」作成チュートリアル](http://c16e.com/1510161700/)

# 実践向け
## React全般について

- [すべてのReact.js初心者が知っておくべき9つのポイント](
https://qiita.com/ossan-engineer/items/3622e57ceb70c7f12295)
- [React を導入したフロントエンド開発](https://www.slideshare.net/daisuke-a-matsui/react-55890813)

## Componentについて

- [メンテナブルな React Component を目指すための小技](https://qiita.com/terrierscript/items/372727448b58d4738018)
- [俺が考えた最強の Reactのステートレスコンポーネントの書き方](https://qiita.com/mizchi/items/04b245ff80f3d3006190)
- [コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス](https://www.slideshare.net/axross/react-48651340)
- [React Componentのライフサイクルのまとめと利用用途](https://qiita.com/yukika/items/1859743921a10d7e3e6b)
- [React component ライフサイクル図](https://qiita.com/kawachi/items/092bfc281f88e3a6e456)
- [早く・それなりの UI を実現する React コンポーネントセット 16 選](https://qiita.com/kyrieleison/items/39ce30dd2d204791a9ea)

## ルーティング

- [react-router | Examples](https://reacttraining.com/react-router/web/example/basic)
- [react-router@v4を使ってみよう：シンプルなtutorial](https://qiita.com/m4iyama/items/b4ca1773580317e7112e)

## テスト

- [Facebook製のJavaScriptテストツール「Jest」の逆引き使用例](https://qiita.com/chimame/items/e97883fd46b67529d59f)

# React最新バージョン

## version 16.x.xについて
現在、最新のバージョンはv16.4.1です。(2018/6/17時点)


- [React v16 changes](http://blog.koba04.com/post/2017/09/27/react-v16-changes/)
- [React context APIを触ってみた](http://rskull.hateblo.jp/entry/2018/03/02/021753)
- [React v16.3 changes](http://blog.koba04.com/post/2018/04/04/react-v163-changes/)
[Ruby]等差数列を表示させる方法

プログラミングを勉強し始めて３週間です。日々壁にぶち当たっています＞＜

今回は等差数列を求めるコードがわからず解決するまでめっちゃ時間がかかってしまいました！

多分私の書いたコードはめちゃくちゃなのですが、とりあえず期待値になったので忘れないように個人的なメモとして残しておきます！

## 初項３、公差３の時の１０項目を求めて表示させたい

■入力エリア
3　3

■期待値
3 6 9 12 15 18 21 24 27 30

■私の書いたコード

```ruby
num = gets.chomp.split(" ")
num.map!(&:to_i)

x = num[0]
i = 1
array = []
while i <= 10
  array << x
  x = x + num[1]
  i += 1
end
print res.join(" ")
```

とりあえずこれで期待値を出せたのですが、もっとスッキリしたコードはあるのでしょうねぇ。。。

あと、数値と数値の間にスペースがなかなか入れられなくて、ようやく「.join(" ")」と言うので入れられることができました！

プロからみたらこんなコードあかんって言われると思う☆
repeat.sh テンプレートにデータを埋め込んで繰り返す coneta #4

#**repeat.sh**
文字列を置換しながら繰り返すbashのスクリプトです。





#**機能**
- 固定部と可変部からなるテンプレートの可変部をリスト形式のデータで置換する。データが複数ある場合は、区切り文字列を付加しながら置換を繰り返す。結果は`stdout`に出力する。
- ヘッダ文字列とフッタ文字列を結果の前後に出力することも可能。
- テンプレートの固定部、ヘッダ文字列、フッタ文字列および区切り文字列は`printf`コマンドのエスケープシーケンスが使用可能。







#**使用方法**

【呼び出し形式】  

~~~bash:
__HD__="ヘッダ文字列" __FT__="フッタ文字列" repeat.sh 'テンプレート' '区切り文字列' '被置換文字列のリスト' 'データのリスト#1' 'データのリスト#2' ... 'データのリスト#n'
~~~
【パラメータの説明】  

| パラメータ | 内容 | 備考 |
|:--|:--|:--|
| 環境変数`__HD__`  | ヘッダ文字列  | 省略可  |
| 環境変数`__FT__`  | フッタ文字列  | 省略可  |
| 第１引数  | テンプレート文字列  |   |
| 第２引数  | 区切り文字列  |  |
| 第３引数  | 被置換文字列のリスト  | `bash`のリスト形式、`(`と`)`で囲む|
| 以降の引数  | データのリスト | `bash`のリスト形式、`(`と`)`で囲む |








【実行例】

~~~bash:
__HD__="CREATE TABLE tbl001 (\n" __FT__="\n);\n" repeat.sh '    @1@\t   @2@' ",\n" '(@1@ @2@)' '("i1" "int")' '("i2" "int")' '("vc1" "varchar(80)")' '("vc2" "varchar(80)")'
~~~

| パラメータ | 値 |
|:--|:--|
| ヘッダ文字列 | `__HD__="CREATE TABLE tbl001 (\n"` |
| フッタ文字列 | `__FT__="\n);\n"` |
| 本スクリプト | repeat.sh |
| テンプレート文字列 | `'    @1@\t   @2@'` |
| 区切り文字列 | `",\n"` |
| 被置換文字列のリスト | `'(@1@ @2@)'` |
| データのリスト | `'("i1" "int")'` |
| データのリスト | `'("i2" "int")'` |
| データのリスト | `'("vc1" "int")'` |
| データのリスト | `'("vc1" "varchar(80)")'` |
| データのリスト | `'("vc2" "varchar(80)")'` |

【実行結果】

~~~bash:
CREATE TABLE tbl001 (
    i1     int,
    i2     int,
    vc1    varchar(80),
    vc2    varchar(80)
);
~~~



#**実装**

~~~bash:repeat.sh
#/bin/bash
template=$1
delimiter=$2
defs=$3
shift 3
sd=$(echo -n -e '\x04')
eval adefs="${defs}"
for data in "${@}"
do
	adata=("${adata[@]}" "${data}")
done
printf "${__HD__}"
dlmt=""
for a in "${adata[@]}"
do
	line=$({
		printf "sed '"
		eval aa="${a}"
		for ((i=0;i<${#aa[@]};i++))
		do
			printf "s${sd}%s${sd}%s${sd}g\n" "${adefs[i]}" "${aa[i]}"
		done
		printf "' <<< '%s'" "${template}"
	}|bash)
	printf "${dlmt}"
	printf "${line}"
	dlmt=${delimiter}
done
printf "${__FT__}"

~~~

#**環境**


ホスト　Windows10 COREi7 
VM　　　VirtualBox バージョン 5.2.8 r121009 (Qt5.6.2)
　　　　　CentOS Linux release 7.4.1708 (Core)
　　　　　3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
sed (GNU sed) 4.2.2
自分なりにオブジェクト指向を整理してみる

# 始めに
クラス設計の話で色々調べてたら段々遡りオブジェクト指向までたどり着きました。
その時自分の中でオブジェクト指向って何かきちんと形になっていないことに気付きました。
てか、オブジェクト指向って「考え方」なんだから、そもそも正確に定義できるものなのか？
という疑問もありますが、とりあえず自分なりに簡単に整理してみることにしました。

# オブジェクト指向の原則
オブジェクト指向をググると必ずでてくる3第原則があります。
・カプセル化
・継承
・ポリモーフィズム

## カプセル化
カプセル化とは「隠す」ことです。
隠すって言ってもどういうこと?となるので車で例えて考えてみます。

車の内部には様々な部品があります。
運転手はその部品についていちいち知らなくても車を運転することができます。
運転手が知るべくものは
・アクセルを踏む＝速度を上げる
・ブレーキを踏む＝速度を下げる
などの「運転方法」を知ればいいだけです。
つまり中の複雑な動作は隠し、簡単な使い方さえ知れば良いことになるのです。

ここで重要なことは各部品が役割に徹底することです。
アクセルがワイパーを動かしたり、ブレーキに干渉されてアクセルを踏んでも加速しなかったりすると車として成り立たないのです。

これをプログラミングで言うと「クラス(部品)」は一つの独立した役割を持ち、その中身を理解しなくても「簡単に使える」べきだと言えます。
私はArrayList.addがどういう実装になっているのか知らなくても、リストに値を格納することができます。

## 継承
継承は「規格化・抽象化」することです。

また車で例えてみます。
車には軽自動車、セダン、トラックなど色んな種類が存在します。
そして車はみんな「走る」「人を乗せる」などの共通点があります。
つまり車という規格によって共通の性質を持つことができます。

プログラミングで言うとインターフェースやクラスの親子関係に当たります。
javaで継承というと、親クラスのメソッドを引き継ぐためによく使われます。
しかし、これは1つの機能に過ぎず、重要なのは同じ性質をまとめて「規格化・抽象化」する考え方だと思います。
うまく規格化されたソースは機能追加や改修に対して直す箇所も少なく、明確に見えるはずです。

## ポリモーフィズム
ポリモーフィズムは多態性と言い、同じメソッドで異なる動きをするこどです。
これは上の継承で規格化したものを実際にプログラミングすることで実現します。

上で例えたように車には様々な種類が存在します。
その種類によってエンジンのメーカーや種類も変わってくるでしょう。
しかし運転手はそれを意識せず、搭載している様々なエンジンを動かすことができます。
それは「エンジンをかける」という同一メソッドに対して、各エンジンに合う振る舞いを実装しているからです。

つまりCar.startEngineに対して、継承側で様々な実装をすることで多態性を持つようになります。

# まとめ
上記の3代原則を意識した考え方がオブジェクト指向に繋がると思います。
オブジェクト指向を意識することで独立性が高く、柔軟なソースを書けます。
それによって修正しやすく、可読性も高いソースになると思います。

私は自分なりに書きながら整理することで、かなりスッキリしました。
もちろん概念を理解しただけで直ぐに意識したプログラミングができる訳はないと思います。
デザインパターンを勉強し、設計の経験を積み重ねることで身に付けることができるでしょう。
これからも頑張ります！

簡単に書くつもりがかなり長くなりました。
ありがとうございます！

# ちなみに
言葉の生みの親Alan Kay氏はオブジェクト指向という言葉は失敗だと語るそうです。
重視すべきは「オブジェクト」でなく「メッセージング」だとか、、、
[オブジェクト指向 - Wikipedia](https://ja.wikipedia.org/wiki/オブジェクト指向)

# 参考
[オブジェクト指向とは何か？わかりやすい例で説明してみた。](https://www.sejuku.net/blog/5973)
[オブジェクト指向と10年戦ってわかったこと](https://qiita.com/tutinoco/items/6952b01e5fc38914ec4e)
[オブジェクト指向プログラミングとは](https://thinkit.co.jp/article/13058)
WiFiモジュール(ESP8266)で作るワンコイントラッカー(1)

Sigfox社が低消費電力の利点を活かした位置情報サービス[Atlas](https://atlas.sigfox.com/) Wi-Fiが正式リリースされました。このサービスを利用することにより、GPSモジュールを必要としないトラッキングデバイスを開発することができます。また、GPSでは捕捉できない屋内位置推定としても使えますので、GPS+WiFiというハイブリッドなLPWAトラッカーを実現することも可能です。
ここでは、2回に分け、Atlas + WiFiの使い方を説明していきます。
#Altas+WiFiとは
Atlas+WiFiは、Sigfoxゲートウェイで受信したメッセージの受信レベルからIoTデバイスの位置を推定するSigfox Geolocation Atlasに加え、WiFiアクセスポイントの情報から位置を推定するサービスを追加したものです。デバイスは、GPSモジュールを搭載する必要なく、WiFiモジュールでアクセスポイントのMACアドレスをSigfoxメッセージとして送信することにより、推定位置情報をCallbackしてくれるサービスです。
イメージ的には、Google Map Geolocation APIに近いのですが、Googleのサービスより低価格に利用可能です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/c4d8fe73-1383-cf0f-c59b-190e7de9e5cf.png)

#ESP8266とは
ESP8266は、中国の[Espressif社](https://www.espressif.com/)が製造しているマイクロコントローラ付きWiFiモジュールで国内でも技適の問題なく購入可能です。価格も数百円で、Sigfox通信モジュールと合わせても500円程度でトラッカーが完成します。（もちろん、アンテナ、筐体、バッテリーなどは無視していますが。）
![IMG_2280.jpeg](https://qiita-image-store.s3.amazonaws.com/0/172313/f0b97a84-89b6-cd83-cbb0-1d47157a97b2.jpeg)
※写真の製品は、ESP8266を搭載した開発ボードESPr® Developerです。
ESPr Developerは、USB-シリアル変換IC FT231XSを搭載していますので、PCとシリアル接続し、簡単にESP8266のATコマンドを使った動作確認が可能です。
ATコマンドは、[こちら](https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf)のドキュメントで確認できます。
#Atlas+WiFiに必要な情報をESP8266で取得する
Atlas+WiFiサービスを使うためには、無線LANアクセスポイントのMACアドレスをSigfoxメッセージとして送信すれば可能です。たった2つのATコマンドで実現できるでしょう。
##ESP8266でWiFi MACアドレスを取得する
ESP8266でWiFiのMACアドレスを取得するには、下記2つのATコマンドで可能です。
1.Stationモードで起動する
今回は、周辺にある無線LANアクセスポイントのMACアドレスを取得するだけですから、ESP8266は無線クライアントして立ち上げておけば結構です。
`AT+CWMODE=1`
2.周辺アクセスポイントをリストアップする
下記コマンドで可能です。
`AT+CWLAP`
私の自宅で試してみたところ、こんな感じで取得できました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/8cf58d81-8bba-5d7e-9b1e-17be15a47d81.png)
あとは、ここで取得したMACアドレスをSigfoxメッセージで送信（AT$SFコマンド）すればよいのですが、Sigfox上りメッセージのペイロード長は、最大12バイトです。MACアドレスは48ビット長（6バイト）ですので、2つのMACアドレスしか送れません。
つまり、測位に必要のないアクセスポイント情報は送っては大損ですので、テザリング端末の削除などの工夫が必要です。

とにかく、WiFiモジュールとSigfoxモジュールで安価かつ屋内も利用可能なトラッキングツールが開発可能です。是非、お試しください。

[次へ > WiFiモジュール(ESP8266)で作るワンコイントラッカー(2)](https://qiita.com/ghibi/items/949ff48d23501760aadd)

[Sigfox Japan KCCS](https://qiita.com/organizations/sigfox)
PostgreSQLでデータ移行前に整合性チェックを行う

PostgreSQLでデータ移行前に整合性チェックを行います。
-- エラー検出SQL
-- エラーメッセージ、件数(%s)
以下をそれぞれ書き変えてください。

```sql:PL/pgSQL
DROP FUNCTION IF EXISTS check_error();
CREATE FUNCTION check_error() RETURNS void AS $$
  DECLARE
	error_row RECORD;
	error_rows TEXT[];
	error_messages TEXT[];

  BEGIN
	-- table_a チェック
	error_rows := '{}';
	FOR error_row IN (
		-- エラー検出SQL
		SELECT * FROM table_a WHERE true
	) LOOP error_rows := error_rows || error_row::TEXT; END LOOP;
	IF array_length(error_rows, 1) > 0 THEN error_messages := error_messages || format(
		-- エラーメッセージ、件数(%s)
		E'\ntable_a 存在チェックエラー件数：%s'
	, array_length(error_rows, 1)) || error_rows; END IF;

	-- table_b チェック
	error_rows := '{}';
	FOR error_row IN (
		-- エラー検出SQL
		SELECT * FROM table_b WHERE 1 = 1
	) LOOP error_rows := error_rows || error_row::TEXT; END LOOP;
	IF array_length(error_rows, 1) > 0 THEN error_messages := error_messages || format(
		-- エラーメッセージ、件数(%s)
		E'\ntable_b 重複エラー件数は%s件でした'
	, array_length(error_rows, 1)) || error_rows; END IF;

	-- チェック結果
	IF array_length(error_messages, 1) > 0 THEN
		RAISE EXCEPTION E'%\n\nエラーが発生しました。処理を中止します。\n\n', array_to_string(error_messages, E'\n', 'NULL');
	END IF;
  END;
$$ LANGUAGE plpgsql;

SELECT check_error();

-- EXCEPTION 無しなら移行SQLを実行する
```
【解決方法】passenger利用時にRailsのログがコンソールへ出力されない

# はじめに
Ruby 2.5.1 + Rails 5.2 環境で作成したアプリをphusion/passenger-ruby25イメージを利用してコンテナ化した際に何箇所か引っかかったところがあったので備忘録として投稿します。

- [Ruby 2.5.1 を利用できるようにする](https://qiita.com/NaokiIshimura/items/7740baa941b6100d0d48)
- [Rails 5.2 のアプリが起動しない](https://qiita.com/NaokiIshimura/items/bf595e7d2041b1d970d1)
- Railsのログがコンソールへ出力されない　←本投稿

# 問題点

コンテナを起動させているコンソールにRailsのログが出力されない。
（以前までは特別な設定をしなくてもログが出力されていた記憶だが。。。）

```shell-session
$ docker run -p 3000:80  \
rails-image

*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/my_init.d/30_presetup_nginx.sh...
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 9
ok: run: /etc/service/nginx-log-forwarder: (pid 17) 0s
...
```

# 解決方法

環境変数：**RAILS_LOG_TO_STDOUT**を設定して、Railsのログを標準出力へアウトプットさせる。

## Railsのコンフィグ

`config/environment/production.rb`には環境変数：**RAILS_LOG_TO_STDOUT**が存在した場合にログを標準出力へアウトプットする設定がデフォルトで含まれている。

```config/environment/production.rb
  if ENV["RAILS_LOG_TO_STDOUT"].present?
    logger           = ActiveSupport::Logger.new(STDOUT)
    logger.formatter = config.log_formatter
    config.logger    = ActiveSupport::TaggedLogging.new(logger)
  end
```

## Passengerのコンフィグ

passenger上で動かすアプリで利用する環境変数は、事前に定義しておく必要があるので、**RAILS_LOG_TO_STDOUT**を追加しておく。

```config:secret_key.conf
# 省略
env RAILS_LOG_TO_STDOUT;
```

## コンテナ起動

環境変数：**RAILS_LOG_TO_STDOUT**を指定した状態でコンテナを起動する。

```shell-session
$ docker run -p 3000:80  \
-e RAILS_LOG_TO_STDOUT=ON \
rails-image
```

> 補足：
> 環境変数：**RAILS_LOG_TO_STDOUT**に指定する値は何でもよい
【回避方法】passengerでRails5.2アプリが起動しない

# はじめに
Ruby 2.5.1 + Rails 5.2 環境で作成したアプリをphusion/passenger-ruby25イメージを利用してコンテナ化した際に何箇所か引っかかったところがあったので備忘録として投稿します。

- [Ruby 2.5.1 を利用できるようにする](https://qiita.com/NaokiIshimura/items/7740baa941b6100d0d48)
- Rails 5.2 のアプリが起動しない　←本投稿
- [Railsのログがコンソールへ出力されない](https://qiita.com/NaokiIshimura/items/95a034fcbe91ddcdcc3e)

# 問題点

Rails 5.2 のアプリがPassengerで起動しない

# 原因調査

## ログ

ログを確認したところ**bootsnap**が原因と思われるエラーを出力していた。

```shell-session
Error: The application encountered the following error: Permission denied @ rb_sysopen - /home/app/webapp/tmp/cache/bootsnap-load-path-cache.52.85473.tmp (Errno::EACCES)
```

## フォーラム

bootsnapのissueに同じ内容の投稿があり、アクセス権限の変更などが提案されていたが、自分の環境では解決しなかった。

[Errno::EACCES: Permission denied · Issue \#77 · Shopify/bootsnap](https://github.com/Shopify/bootsnap/issues/77)

# 回避方法

**bootsnap**を利用しないように設定する。
（`config/boot.rb`で`require 'bootsnap/setup'`をコメントアウトする）


```ruby:config/boot.rb
# require 'bootsnap/setup'
```

> 補足：
> **bootsnap**はRails 5.2から追加された起動時間を短縮させるgem

# 備考

**回避方法**を実施した後は、`bootsnap`が有効な新規アプリを含んだコンテナイメージを作成しても再発しなくなった🤔
Androidアプリでボタン内に画像とテキストを中央寄せで表示する

## やりたいこと

ボタンの中央に、画像とテキストを並べて表示させたい。
画像が左寄せ・右寄せなら `android:drawableLeft` 等を利用すると良いが、横幅が可変のボタンで画像もテキストも中央寄せで表示したい場合は使えなかった。

成果物はこんな感じ。

<img width="313" alt="スクリーンショット 2018-06-17 11.33.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/62874/04843248-f829-8a56-4040-432efb185c90.png">

## 実現方法

String中に画像を埋め込める`SpannableString`を利用する。

```kotlin:make_button.kt
val button = View.inflate(context, R.layout.sample_button, null) as Button
val imageResourceId = R.drawable.icon

val ss = SpannableString("  サンプル")
val drawable = ContextCompat.getDrawable(context, imageResourceId)
drawable.setBounds(0, 0, 50, 50)
val span = ImageSpan(drawable, DynamicDrawableSpan.ALIGN_BASELINE)
ss.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)

button.text = ss
addView(button)
```

```xml:sample_button.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:text="サンプル"
    android:background="@android:color/holo_blue_dark"
    android:textStyle="bold"
    android:textAllCaps="false" />
```

## ハマりどころ

### 画像が表示されない

Android5.0以上だとButtonに`android:textAllCaps="false"`が設定されてないと不具合で画像が表示されないらしい。
1時間溶かした…。

```xml:sample_button.xml
<Button
    ...
    android:textAllCaps="false" />
```

## 参考

How to center icon and text in a android button with width set to "fill parent" - Stack Overflow
https://stackoverflow.com/a/8386510

android - SpannableString with Image example - Stack Overflow
https://stackoverflow.com/a/3177667

Button setText with Spannable doesn't work for Android 5.0 Lollipop - Stack Overflow
https://stackoverflow.com/questions/29007746/button-settext-with-spannable-doesnt-work-for-android-5-0-lollipop
Jupyter Labが起動できないときの対処 (Please install nodejs and npm ...)

## Jupyter labが下記エラーで起動しなかったときの対処
'Errored, use --debug for full output:
ValueError: Please install nodejs and npm before continuing installation. nodejs may be installed using conda or directly from the nodejs website.'

**環境**
 - Windows 10 64bit 
 - Anacondaでjupyter labインストール済み (`conda install -c conda-forge jupyterlab`)

## 解決策
`> conda install nodejs`
JS基礎ー非同期とコールバック

# 初めに
自分は業務中でよくPromiseで非同期処理を実現しますが、そもそもなぜPromise使うのかをよくわからないので、今回は基礎からJavaScriptの非同期とコールバックについて整理してみます。

# 先ずは定義
**非同期処理**：JSにおける非同期処理は、プログラムコードを上から順に1行ずつ実行していきません
**コールバック**：他のコードの引数として渡されるサブルーチンである
例

```javascript
function A(callback){
    console.log("I am A");
    callback();  //渡されるサブルーチン
}

function B(){
   console.log("I am B");
}

A(B);
```

# 非同期処理とコールバック
コールバックは非同期処理を実現するの手段の一つであり、逆にコールバックで実装したコードは必ず非同期処理とは言えません。
上の例がコールバックで同期処理の例です。
で、次は非同期処理を見にいきましょうか。
また、以下のような関数があります

```
f1() // 時間をかかる
f2() // f1の次の番実行する
f3() // f1,f2と関係ない、できれば早めに実行する
```

f1の実行に時間がかかるのため、f2とf3は待つしかない

コールバックで非同期させます：

```javascript

function f1(callback){
    setTimeout(function () {
        // do some thing
        callback();
    }, 1000);
}

f1(f2);

f3();

```
こういう書き方だと、setTimeoutを使ってf1を非同期処理させ、f3を早めに実行できるようになりました。

# なぜ非同期なのか？
JavaScriptの特徴の一つにシングルスレッドがあります。
であれば、どうやって一つスレッドしかを使わないで非同期を実現する？
答えはEvent Loopとのことです。
![event-loop.png](https://qiita-image-store.s3.amazonaws.com/0/255229/c318e452-e81c-c847-59a4-49c5ea59aac1.png)
（event-loopのインメージ from [「Help, I’m stuck in an event-loop」](https://vimeo.com/96425312)）

要するに、JavaScriptの実行順番は下記となります：
➀：heap、stackを生成する
②：stack中のコードを外部apiを呼び出し、イベント（click，load，done）をcallback queueに追加する
③：stack中のコードの実行が**終わったら**、callback queue内のcallback functionをstackに投げる
④：step➀に戻る

ですので、上記の例で、f1()をsetTimeout経由でcallback queueに追加し、とりあえずf3()を実行します。
要注意：setTimeoutの設定通り、1000ms後、コールバック関数を**実行ではなくて、callback queueに追加するだけ**です。

# まとめ
今回は基礎からJavaScriptの非同期とコールバックについて整理し、非同期処理の流れが明確になりました。