OmniAICreator/Qiita-1.07M huggingface dataset:
python/torchでのデバッグ

## はじめに
私はプログラミング言語ではpythonをよく使用します。
今回はlua (torch) を触ろうとしたときにpythonと同じようなデバッグツールがないかと探して得られた知見を載せます。前半でpythonでの普段のデバッグを説明して、後半でtorchでのデバッグを説明します。

## pythonでのデバッグ
普段デバッグするときはおおよそ以下の2つの手段を取ります。

- `import ipdb; ipdb.set_trace()` をコード中に埋め込む
- `python -m pdb <file name>.py`で実行する

### ipdb
ipdbは**コード内に埋め込んで使用**するものです。
非常に便利なデバッガーでinteractive shell (ipythonのインターフェース）が実行時に起動します。
**補完が効く**ため重宝しています。

```python
# 例
a = 3
import ipdb; ipdb.set_trace()
# ここで、interactive shellが起動
# >> a. と入力し、Tabを押すと補完が効く
```

### pdb
実装した直後に実行しても大体エラーで落ちます。
pdbを用いて実行した場合には、**エラーはデバッガーによってキャッチされます。**
そのため**エラーを具体的に検討しやすくなります。**
実装した直後のコードを実行する際に使用することがあります。

```bash
$ python -m pdb <file name>.py
-> <file name>.pyの一行目
(pdb) 
```
という画面が得られるため、`c`と入力しEnterを押します。
するとそのままコードを実行し続け、**バグが生じて落ちたときにエラー落ちせずにそこで止まってくれます**。

## torchでのデバッグ
結論から言うといいものが見つかりませんでした。
あれば教えてください。

### debug
これはipdbのようにコード内に埋め込んで使用するものです。
`require 'debug'`を最初に実行してライブラリをimportします。
その後、`debug.debug()`を止めたい所に入力すると、そこで止まります。
しかしながら、ipdbのように**補完が効きません。**

## 補足
探している最中にitorchというものを見つけました。
**pythonにおけるjupyterのtorch版です。**

installに向けたsetup
https://github.com/facebookarchive/iTorch#requirements

install
https://github.com/facebookarchive/iTorch#installing-itorch

実行方法
https://github.com/facebookarchive/iTorch#how-itorch-works

ipythonのバージョンが新しすぎて`itorch notebook`自体は使えませんでしたが、
`jupyter notebook`としたときに、kernelとしてpython3以外にitorchが選択できるようになっていました。便利。
テキストがおしゃれスライドになるTalkie.jsを超簡単に使う方法 ＆ Jupyterにスライドを埋め込む方法

# 背景
Talkie.jsとは、マークダウンやhtmlで書いたちょっとしたテキストが、
簡単におしゃれなスライドになるツールです。

以下のURLを見ていただくと良いと思います。
 * [Talkie.jsの製作者さまの紹介スライド](http://s.aho.mu/161203-wcan_winter/)
 * [Qiita上で紹介されていた先輩記事](https://qiita.com/supermanner/items/b134aa519eb434e69cdc)

社内のちょっとした勉強会や、コードハイライトしたスライドをすぐ作りたい時、
Web上にスライドを公開したい場合などに最適だと思われます。

# 本投稿の内容

## 1. Talkie.jsを簡単に利用できるテンプレートセットの紹介
Talkie.js を使うことで、スライド作成の生産性/見栄えを大幅に向上出来るのですが、
活用までに若干敷居が高いところがあります。
そこでまず、本投稿では、その敷居を大きく下げる以下のテンプレートセットを紹介します。

[html2png2pdf&Talkieテンプレートセット](https://www.vector.co.jp/soft/winnt/writing/se517303.html)
（ https://www.vector.co.jp/soft/winnt/writing/se517303.html ）

 * npmや、コマンドラインを一切触らずに、ダウンロードだけで初心者でも容易に使える
 * PDF化ツールや、良く使うTipsや画像がセットでパッケージされている

これは上記サイトからダウンロードすれば終わり、という話です。
ぜひ一度ダウンロードしてTalkie.jsの、簡単さ、便利さ、綺麗さをご確認ください。

## 2. 応用例： Jupyter Notebook にスライドを埋め込む方法の紹介
Jupyter Notebookは、pythonや機械学習のコードを作成/共有するために良く使われています。
Jupyter Notebook上で、デモを行いながらそのままプレゼンすることも多々見かけます。
しかし、プレゼンツールとしては、Webページを読んでいるような印象があり、
少々不格好な印象を受けることもあります。
そこで、このTalkie.jsを、htmlとしてJupyter内に組み込めることにより、
スマートに、プレゼンとデモコードの行き来が出来る方法を紹介します。

 
#  Jupyter Notebook にHTMLやyoutube動画を埋め込む方法

## まずは、JpyterNotebookに通常のHTMLを埋め込む方法

```python:html表現をJupyterに埋め込む
#以下の記法により、HTMLタグを表示することができる
from IPython.display import HTML
HTML(r'<h1>Hello HTML</h1>')
```

※ なお、jupyternotebookのセルの形式をMarkdownにすれば直接HTMLも書けますが、
　その方法だとiframeタグは上手く動作せず、以降のyoutubeやTalkie.jsの埋め込みには不適切です。
 
## 次に、Youtubeの動画を埋め込む方法

再生ボタンで直接再生できます。

```python:YoutubeをJupyterに埋め込む
#youtube で埋め込みたい動画を表示することもできる。
#youtube側で「共有」⇒「埋め込む」で表示されるURLを事前にコピーしておく。
HTML(r'<iframe width="560" height="315" src="https://www.youtube.com/embed/0E00Zuayv9Q" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>')
```

## Jupyter上で見ると、以下のような形で表示されます。

![JupyterHtml.PNG](https://qiita-image-store.s3.amazonaws.com/0/193512/6c35d21c-7eaa-ce8b-96d1-7c761035b0c9.png)

#  [応用例] Jupyter Notebook にTalkie.jsスライドを埋め込む方法

テンプレートでは、「F」ボタンを押すと全画面切り替えができますが、
この埋め込みにおいても「F」ボタンを押すと、全画面スライドとJupyterを行き来できます。

以下はJupyterのipynbファイルと同じ階層にテンプレートのフォルダを配置した例：

```python:Talkie.jsのスライドををJupyterに埋め込む
# Talkieテンプレートセットと組み合わせる
# https://www.vector.co.jp/soft/winnt/writing/se517303.html
HTML(r'<iframe width="800" height="500" src="./TalkieJsTemplate_YW/index_template.html" frameborder="0"  allowfullscreen></iframe>')
```

## Jupyter上で見ると、以下のような形で表示されます。

右下の ＜ ＞ でスライドをめくれます！

![JupyterHtml_Slide.PNG](https://qiita-image-store.s3.amazonaws.com/0/193512/189c1850-9262-6a2a-627b-1dbb74e84f7d.png)

# Talkie.js も Jupyter Notebookも便利！ 組み合わせでさらに楽しく！

Talkie.jsのテンプレートにも、コードのハイライト機能があり、
社内の勉強会や、ちょっとしたライトニングトークなどには大変便利です。
とはいえ、やはりコードを動かして見せたいこともあり、Jupyterとの組み合わせは有効です。

Jupyter Notebookは、作業や開発を進めるには大変便利です。
一方で、その内容を人に発表するにはちょっと表現力が不足しています。
パワーポイントなどと行ったり来たりするか、
Jupyter上のマークダウンだけでは見た目がイマイチになりがちです。
スクロールが縦に長く長くなっていくのもイマイチでしょう。

今回の手法によって、Jupyterとスライドをシームレスに繋ぐことができます。

改めての紹介になります。まずは、Talkie.jsのテンプレートを入手し、試してみてください。
[html2png2pdf&Talkieテンプレートセット](https://www.vector.co.jp/soft/winnt/writing/se517303.html)
（ https://www.vector.co.jp/soft/winnt/writing/se517303.html ）
そして、それをJupyterにも組み込んでみると、活用の幅がさらに広がるでしょう！


以上。
アルゴリズム入門②実用的なソート

# はじめに
[アルゴリズム入門①計算量とソートの基本](https://qiita.com/kamezaki/items/8f04771b1babd616a3f0)で計算量と基本的なソートに関してまとめたので、この記事では効率がよく、実用的なソートアルゴリズムに関してまとめます。

# 実用的なソートとは
[アルゴリズム入門①計算量とソートの基本](https://qiita.com/kamezaki/items/8f04771b1babd616a3f0)で紹介したソートアルゴリズムは$O(n^2)$で、効率が悪く、実用的ではありませんでした。

再帰・分割統治法などのテクニックを用いた、より高速で実用的なアルゴリズムを紹介します。

この記事で紹介するのは

- 常に$ O(n\log n) $の高速なアルゴリズム → マージソート
- 条件付きで$ O(n\log n)$で動くソートアルゴリズム → クイックソート

になります。

# マージソート
以下のような手順でソートを行います。

1. 配列を2つに分割する。
2. 分割したそれぞれの配列をマージソートする。
3. 二つのソートされた配列をマージする。

入力データを保持する配列以外に一時的なメモリ領域が必要になるという特徴を持ちます。
計算量が必ず$ O(n\log n)$になるという特徴がある。

# クイックソート
以下のような手順でソートを行います。

1. データの要素から任意の数を選ぶ(pivot)
2. pivotより小さい数を配列left, pivotより大きい数を配列rightに入れる
3. それぞれの配列に対して、再びクイックソートを行う。
4. 要素数が1以下の領域ができた場合、その領域を確定とする。
4. ソートされた配列left, pivot, ソートされた配列rightを結合する。

不安定なソート。
また入力値とpivotの選び方によっては、$O(n^2)$になるケースがある。

注意: 領域の左端の値が領域内で最小かつ、同じ値が他の位置にない場合、ピボットとしてその値を選ぶと無限ループとなってしまいます。

# まとめ

| ソート名 | 最良 | 最悪 | 安定|
|:-:|:-:|:-:|:-:|
| マージソート  | $ O(n\log n)$  |$ O(n\log n)$  | ○ |
| クイックソート  | $ O(n\log n)$  | $O(n^2)$  | × |

- クイックソートはピボットの選び方によっては$O(n^2)$になる。
- マージソートは必ず$ O(n\log n)$になる。
マインクラフトのスキンを取得する

## 0. まえがき

以前は以下のようなURLにアクセスすると自動でリダイレクトし、スキンが表示されたのですが、

```
http://skins.minecraft.net/MinecraftSkins/yuta0801.png
```

いつからか、使用できなくなりました。

なので、そのリダイレクト先でもあるURLを取得する方法を残して置こうかと思います

__この記事での、URLや返ってくるデータは全て、僕が所有するマインクラフトアカウント(id:yuta0801, uuid:bc7fd64b669e45d48667b77142557036)を対象に実行したものです。使用する場合は適宜読み替えてください。__

## 1. ユーザー名からUUIDを取得する

現段階で使用できる公式のAPIをくまなく調べたのですが、ユーザー名から直接スキンを取得する方法がなかったので、まずはUUIDを取得しなければいけません。

UUIDを取得すると言ってもそんなに難しいことではなく以下のURLにアクセスすると、

```
https://api.mojang.com/users/profiles/minecraft/yuta0801
```

IDを含んだJSONを得ることができます。

```json
{
    "id": "bc7fd64b669e45d48667b77142557036",
    "name": "yuta0801"
}
```

## 2. ユーザーデータを取得する

次に、先程得たUUIDを使用してユーザーのデータを取得していきます。

これも先程と同じようにUUIDを含めたURLにアクセスするとユーザーデータがbase64エンコードされた値が入ったJSONが帰ってきます。~~なぜbase64エンコードした値を返すか謎~~

```
https://sessionserver.mojang.com/session/minecraft/profile/bc7fd64b669e45d48667b77142557036
```

このJSONの.properties[0].valueに入ってるのが**base64エンコードされたJSON**です。

てっきり画像データかと思って何十分も画像にデコードしようと頑張ってましたorg

~~なんでJSONの中にbase64エンコードしたJSONを入れるんだよ💢~~

```json
{
    "id": "bc7fd64b669e45d48667b77142557036",
    "name": "yuta0801",
    "properties": [
        {
            "name": "textures",
            "value": "eyJ0aW1lc3RhbXAiOjE1MjA2NzE0MzQ3MDMsInByb2ZpbGVJZCI6ImJjN2ZkNjRiNjY5ZTQ1ZDQ4NjY3Yjc3MTQyNTU3MDM2IiwicHJvZmlsZU5hbWUiOiJ5dXRhMDgwMSIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kNTljNWNlZDYwNGY2Y2Y3NzE1ZGEzNDI5M2M4NWM4ZDlmYjY0NDRlZjFlM2JmNWY5Y2I0Zjk2ZWNkNDk1In19fQ=="
        }
    ]
}
```

ちなみにbase64をデコードすると以下のようなJSONになります

```json
{
    "timestamp": 1520669872059,
    "profileId": "bc7fd64b669e45d48667b77142557036",
    "profileName": "yuta0801",
    "textures": {
        "SKIN": {
            "url": "http://textures.minecraft.net/texture/d59c5ced604f6cf7715da34293c85c8d9fb6444ef1e3bf5f9cb4f96ecd495"
        }
    }
}
```

.textures.SKIN.urlが一番最初のURL(現在は使用不可)にアクセスしたときのリダイレクト先のURLを取得できるようになりました。めでたしめでたし。~~なんであれを削除したんだよ~~

## 5. 最後に

ぶっちゃけ、こんな面倒なことをしなくてもサードパーティのAPIを使えば一発で顔部分を切り抜いた画像や、全身の立体画像などを取得できるので、わざわざこんな面倒なことをする必要はないです、はい。

## 4. 参考資料

Mojang API - wiki.vg - <http://wiki.vg/Mojang_API>

crafatar/crafatar: A blazing fast API for Minecraft faces - <https://github.com/crafatar/crafatar>
[備忘録] Pythonでファイルがあるディレクトリを取得する

自分はプログラムを書く中で, よく参照するファイルを絶対パス形式で直打ちすることが多い (相対パスだとcronとかで動かす時にたまにエラーを吐かれて面倒だから)
が, 案の定面倒くさい
なので, プログラム中からディレクトリ名を取得する方法がないか調査したら, os.pathの関数を使えばいけるらしかったので, 備忘録も兼ねて紹介しておく

# dirnameとabspath
まず, 使用する関数はdirnameとabspathの2つ
この2つを組み合わせることで取得可能となる.

os.path.dirnameは, 引数で渡したパス名からディレクトリ名の部分だけ抜き出す関数
例はこんな感じ

```
>>> import os
>>> os.path.dirname("test.py")
''

>>> os.path.dirname("/User/Program/test.py")
'/User/Program'

>>> os.path.dirname("/User/Program")
'/User'
```

os.path.abspathは引数で与えたパス名の絶対パスを取得する関数
例はこんな感じ

```
>>> os.path.abspath("test.py")
'/User/Program/test.py'
>>> os.path.abspath("/User/Program/test.py")
'/User/Program/test.py'
>>> os.path.abspath("/User/Program/")
'/User/Program'
>>> os.path.abspath(".")
'/User/Program'
```

# ディレクトリ名の獲得
dirnameとabspathを使い, 実行中のスクリプトのディレクトリ名を取得する書き方はこのようになる

```
print(os.path.dirname(os.path.abspath(__file__)))

/Usr/Program
```

# まとめ
dirnameとabspathを組み合わせることで, ディレクトリ名の獲得をプログラム中で行えるようになった
これで参照するファイル名だけを直打ちあるいは実行時の引数として渡すだけで良くなる

ちなみに, 存在しないファイル名を引数にして試しに実行してみたところ, エラーを吐くことなくカレントデディレクトリの名前が返ってきた
なので, 引数に渡したファイルがどこにあるのかを走査している訳ではないらしい

# 疑問点
この記事を書いてる際に疑問が生じたので書いておく
ディレクトリ名を獲得するあの書き方は, 他の記事でもよく紹介されているため, おそらくメジャーな書き方なのだろう
しかし, os.path.abspath(".")でも同じものが獲得できるので, わざわざ2つを組み合わせたあの書き方をする必要はない(というか, os.path.abspath(".")の方が短いためこっちでいい気がする)

なぜ2つ組み合わせた書き方が多く紹介されてるのだろうか・・・
check-node-versionでengineStrictの代わりにNode.jsのバージョン指定を厳格にする

Node.jsを使用したアプリケーションを開発していると、開発環境によってはNode.jsやnpmのバージョンが明確に固定されている必要があるケースがあります。BundlerなどではRubyのバージョンをGemfileで固定できますが、Node.jsではそれに相当する `engineStrict` が [npm v3 で削除されてしまった](https://github.com/krakenjs/lusca/issues/47#issuecomment-138139471)ため、プロジェクトに応じてなんらかの工夫が必要になります。

# check-node-versionを使う

[check-node-version](https://www.npmjs.com/package/check-node-version)というnpmは、実行時の環境のNode.jsやnpmのバージョンをチェックできます。

以下を実行すると *>=6.0.0 <7.0.0* のバージョンでない場合にエラーを出します。

```bash
$ check-node-version --node 6
node: 8.2.1
Error: Wanted node version 6 (>=6.0.0 <7.0.0)
To install node, run `nvm install 6` or see https://nodejs.org/
```
以下はNode.jsバージョンの範囲指定の例です。 `8.9.0` 以降であることを期待しています。

```
$ check-node-version --node '>= 8.9.0'
```

同様にしてnpmのバージョンや、yarnもチェックできます

```bash
# Node.jsとnpmのバージョンチェック
$ check-node-version --node 4 --npm 2.14

# yarnのバージョンチェック
$ check-node-version --yarn 0.17.1
```


## script実行との併用
実用的な例として、以下のようにコマンドの実行前に `check-node-version` によるバージョンチェックを行って、Node.jsのバージョン差異によって問題が起きるの事前に防ぐことができます。

```json
{
  "name": "my-package",
  "devDependencies": {
    "check-node-version": "^1.0.0"
  },
  "scripts": {
    "test": "check-node-version --node '>= 4.2.3' && node my-tests.js"
  }
}
```
プログラミング言語Goを読みながらメモ(第一章)

[プログラミング言語 Go]( https://www.amazon.co.jp/dp/4621300253 ) を読みながら、気になったことをメモ。

# Hello, 世界

最初に驚いたのは、以下のコードがコンパイルエラーになること：

```go
package main

import "fmt"

func main() 
{
	fmt.Println("Hello, 世界")
}
```

`main()` と `{` の間に改行を入れてはいけないのである。(1.1 / p3)
他にも

* 不要な import 宣言があるとコンパイルエラー( 1.1 / p3 )

なんかも驚いた。

地味に心地よいのは、ビルドした結果のファイル名がソースコードのファイル名から取られるところ。 gcc なんかだと 指定しないと `a.out` になるのがちょっと不便に感じていたので。
私が windows の `cl.exe` に慣れているだけかもしれない。

# コマンドライン引数

```go
// コマンドライン引数をそのまま出す
package main

import (
	"fmt"
	"os"
)

func main() {
	var s, sep string
	for i := 1; i < len(os.Args); ++i {
		s += sep + os.Args[i]
		sep = " "
	}
	fmt.Println(s)
}
```

がエラーになるのも驚いた。C++ 好きなので、 `++` 書くなら前置でしょ、と思ったんだけど、エラーになった。後置しかない。そして、式ではなく文なので値を取れない。( 1.2 / p6 )
なるほど式じゃないなら前置は要らないね。

先程の関数定義の `{` と同様、 `for` 文の `{` の直前には改行を入れてはいけない。( 1.2 p6 )というのも意外。固いね。

もっと意外なのは、「使われないローカル変数を許しません」という点。
未使用のローカル変数は軽い警告として黙らせてしまいがちな感じだけど、むしろエラーなのか。

初期化の「`:=`」と再代入の「`=`」が区別されているのは心地よく感じる。コロン忘れがちだけど。

あと。echo1.go と echo2.go を同じフォルダに作ったら VSCode が文句を言ってきた。ひとつのフォルダに main 関数はひとつだけにしてくれということらしい。そういうものか。

# 重複した行を見つける

ここで一番驚いたのは、map の順序が実行するたびに異なるという点。実際に実行してみたら本当に毎回異なった。びっくり。

あと、`fmt.Printf` の `%g` の説明がやや不十分と思ったので、例を書いておこうと思う。

```go
// コマンドライン引数をそのまま出す
package main

import (
	"fmt"
)

func test(s string) {
	fmt.Printf("%s : "+s+"\n", s, 3.141592653589793238)
	fmt.Printf("%s : "+s+"\n\n", s, 3.141592653589793238e10)
}

func main() {
	test("%f")
	test("%g")
	test("%e")
}
```

を実行すると、

```
%f : 3.141593
%f : 31415926535.897934

%g : 3.141592653589793
%g : 3.1415926535897934e+10

%e : 3.141593e+00
%e : 3.141593e+10
```

が出力される。つまり、`%f` は、XX.XX 形式。 `%e` は、X.XXX+eX 形式。`%g` は、桁数を見て、`%f` か `%e` のどちらかにする。桁数も違うみたいだけど。

ファイルの `Close` が陽に呼ばれているけど、C# の `using` 、Java の try-with-resources、　Python の with 文、C++ の デストラクタ のようなものを使って避ける方法はあるのだろうか。

# goルーチンで fetch

ソースコードを見ても、私の中にメンタルモデルを作れなかった。
第8章をしっかり読まなくてはいけないけど、だいぶ先だね。

# Webサーバ

シンプルな記述で好ましい。
しかし、mutex の lock/unlock を陽に書かなくてはいけないのが残念。
あるいは避ける方法があるのだろうか。

今日のところはこれぐらいで。
と、書いたけど、2章も読んだ。 see https://qiita.com/Nabetani/items/d053304698dfa3601116
Solidity 言語における詰まりどころメモ

Ethereum のスマートコントラクト記述言語 Solidity は、他のプログラミング言語と比べると言語仕様が少し特殊なところがあります。
Solidity を書いていて、詰まったり躓いたりしたポイントをメモしていきたいと思います。

なお、使用しているのは Solidity 0.4.18 です。もし間違っている点がありましたらぜひ教えてください。

## 変数の値が存在しないこと(NULL)を判定したい

https://stackoverflow.com/questions/37852682/are-there-null-like-thing-in-solidity

**Solidity に NULL はありません。**
代替手段として、デフォルトの初期値であるかどうかで判定することができます。

https://ethereum.stackexchange.com/questions/40559/what-are-the-initial-zero-values-for-different-data-types-in-solidity

Solidity で宣言されたすべての変数には、デフォルトの初期値が設定されています。
また、配列の場合は、`length` が0であるかどうかで判定できます。

type      | initial default value
---       | ---
`bool`    | `false`
`uint`    | `0`
`int`     | `0`
`fixed`   | `0.0`
`string`  | `""`
`address` | `0x0`

## Struct を返却したい

https://ethereum.stackexchange.com/questions/36229/invalid-solidity-type-tuple
https://ethereum.stackexchange.com/questions/3609/returning-a-struct-and-reading-via-web3

**Struct は返り値として受け取ることができません。**
代替手段として、Struct をフィールドを別々の戻り値として返却する方法があります。

```
contract Sample {
    struct User {
        uint userId;
        string name;
    }
    User[] public users;

    function addUser(uint _userId, string _name) public returns (uint) {
        return users.push(User(_userId, _name)) - 1;
    }

    function getUser(uint _index) public view returns (uint, string) {
        return (users[_index].userId, users[_index].name);
    }
}
```

なお、内部呼び出しの関数であれば返り値として構造体を受け取ることはできるようです。

## Array から一部削除したい

https://ethereum.stackexchange.com/questions/33543/how-to-delete-array-at-index

**`delete` オペレータを使用して削除できます。**

```
contract Sample {
    uint[] public array = [1, 2, 3, 4, 5];
    function remove(uint _index) public {
        delete array[_index];
    }
}
```

## String の Array を返却したい

https://ethereum.stackexchange.com/questions/37627/unimplementedfeatureerror-nested-dynamic-arrays-not-implemented-here

**String の Array はまだ返却できません。**

Solidity では、多次元配列(厳密には、動的配列の動的配列)が未実装のようです。
String は動的配列そのものなので、返却しようとすると `UnimplementedFeatureError: Nested dynamic arrays not implemented here` エラーが出ます。

## `Attempting to run transaction which calls a contract function, but recipient address is not a contract address` が発生する

https://ethereum.stackexchange.com/questions/41407/what-caused-this-error-attempting-to-run-transaction-which-calls-a-contract-fun

**`./build/contracts` を削除します。**
言語仕様とは少し異なるところですが、このエラーが突然発生すると焦るので書き残しておきます。
JavaのcompareToの結果は、必ず0と比較しよう

## はじめに
Javaの`compareTo`に関する初歩的な小ネタです。
「`compareTo`の結果って、どっちがどっちかすぐわかんなくなっちゃう」という方に読んで欲しいです。

## `compareTo`は常に`0`と比較する
`Comparable#compareTo`の結果は、常に`0`と比較する必要があります。
`-1`や`1`と比較しているコードを見かけることがありますが、これは正しくありません。

以下、[標準APIのJavaDoc](https://docs.oracle.com/javase/jp/9/docs/api/java/lang/Comparable.html#compareTo-T-)から引用(強調は私がしました)

> 戻り値:
> このオブジェクトが指定されたオブジェクトより小さい場合は**負の整数**、等しい場合は**ゼロ**、大きい場合は**正の整数**

上記のとおり、必ずしも`-1`や`1`といった固定値が返ってくる保証はありません。
(`-1`や`1`を返す実装になっていることが多いですが)

## サンプルコード

比較演算子[^1]の左辺に`compareTo`呼び出し、右辺に`0`を記述するようにすれば、素直に読み書きできます。

```java:compareTo
if (obj1.compareTo(obj2) == 0) {
  System.out.println("obj1 ＝ obj2");
}

if (obj1.compareTo(obj2) != 0) {
  System.out.println("obj1 ≠ obj2");
}

if (obj1.compareTo(obj2) < 0) {
  System.out.println("obj1 ＜ obj2");
}

if (obj1.compareTo(obj2) <= 0) {
  System.out.println("obj1 ≦ obj2");
}

if (obj1.compareTo(obj2) > 0) {
  System.out.println("obj1 ＞ obj2");
}

if (obj1.compareTo(obj2) >= 0) {
  System.out.println("obj1 ≧ obj2");
}
```

## さいごに
`0`と比較することを徹底すれば、`compareTo`の結果で迷うことはありません。

[^1]: `==`や`<`など
npm installを無効にする

yarnを使ってるプロジェクトで、開発者がうっかり `npm install` でパッケージのインストールをしてしまうと依存性解決の差異でよくわからない問題がおきることがあります。

こういう場合の対策の仕組みとして、以下のようなスクリプトを用意して `npm install` を無効化し、 `yarn install` を使うよう誘導することができます。

```js:tools/preinstall-script.js
/**
 * Do NOT allow using `npm` as package manager.
 */
if (process.env.npm_execpath.indexOf('yarn') === -1) {
  console.error('You must use Yarn to install dependencies:');
  console.error('  $ yarn install');
  process.exit(1);
}
```
作成したスクリプトは `preinstall` で実行させます。

```json:package.json
  "scripts": {
    "preinstall": "node tools/preinstall-script.js"
  }
```
この仕組みは[AMP HTML](https://github.com/ampproject/amphtml)でも採用されているようです。

参考: https://github.com/yarnpkg/yarn/issues/4895
できるだけ簡単にAzure REST APIを実行する

Azure関連でプレビュー機能が公開されて間もない時など、Azure PowershellやCLIのコマンドがなくてREST APIしかインターフェース提供されてないって場合がたまにある。そういう時、さっくりAzure REST APIたたきたい。[Microsoft Azureのリソース管理方法まとめ](https://qiita.com/gutzeit1106/items/aac835e021b735d288c3)

本来のAzure REST APIの実行手順は、下記のリファレンスの仕様に従ってHTTPリクエストを作成して投げるけど、
Request header の Authorization に Azure サブスクリプションに紐づくAzure ADからOauth 2.0のbearer tokenを取得してセットしないといけないのでちょっと面倒に感じる。

　Azure REST API Reference - Create the request
　https://docs.microsoft.com/ja-jp/rest/api/#create-the-request

そこでもっと簡単にAzure REST API投げる方法ないかなーと試行錯誤したところ、Azure Powershellでログインしたらローカルにbearer token保存されてることが判明。これ使おうってことで、Azure Powersell入ってる環境でPowershellの Invoke-WebRequestコマンドつかってAzure REST APIにリクエストなげるスクリプト作ってみた。(事前にAzure Powershellはインストール必要)

使用するREST APIはなんでもいいけど、まずはシンプルに仮想マシンのリソース情報とってみる(Virtual Machines - Get)[https://docs.microsoft.com/ja-jp/rest/api/compute/virtualmachines/get]

サブスクリプションID、リソースグループ名、仮想マシン名のパラメータを変更してPowershellで実行するとJSON形式で仮想マシンの構成情報が取得できる。

```
#Parameter Setting
$subscriptionId = "xxx" #サブスクリプションID
$resourceGroup = "xxx" #リソースグループ名
$vmName = "xxx" #仮想マシン名


#Login and acquire my access token
Login-AzureRmAccount -SubscriptionId $subscriptionId

$context = Get-AzureRmContext
foreach($token in $context.TokenCache.ReadItems())
{
    if($token.TenantId -eq $context.Tenant.Id){
        $currentToken = $token
        break
    }
}

#Executing Azure REST-API
$method = "GET"
$apiurl = "https://management.azure.com/subscriptions/"+$subscriptionId+"/resourceGroups/"+$resourceGroup+"/providers/Microsoft.Compute/virtualMachines/"+$vmName +"?api-version=2017-12-01"
$authHeader = "Bearer " + $currentToken.AccessToken

$requestHeader = @{
"Authorization" = $authHeader
"Accept" = "application/json"
}
$contentType = "application/json;charset=utf-8"
$apires = Invoke-WebRequest -Uri $apiurl -Method $method -Headers $requestHeader -ContentType $contentType

#Display the responce body
$apires.Content
```
Python3でNEMのAPIを叩く-001-概要

#はじめに
NEMのAPIを勉強するために、Python3を使ってコードを書くことにしました。
（Pythonも初めて触るので、Pythonも勉強していきます）

APIの和訳が以下のサイトにあるため、こちらを読みなが勉強していきます。
New Economy Movement(NEM) APIマニュアル和訳
https://www.pr1sm.com/crypto-coin/nem-nis-api-documentation-in-japanese/

扱いやすいと噂のNEM APIですが、コードを見たことがない人はピンとこないと思います。私が学習した内容をメモする目的もありますが、サンプルコードを掲載していきますので、どれぐらい簡単なのか知ってもらえれば幸いです。
また、私が間違った理解もあると思いますので、見た誰かが指摘してくれたらいいなぁっていう邪な気持ちもあったりします（笑）

ちなみに、実行環境はPAIZAを使う予定です。
https://paiza.io/ja

#NEMって何？って方へ
トレストさん（twitterアカウント:@TrendStream）のサイトが非常にわかりやすいです。
https://www.cryptostream.jp/nem_xem/

以下、概要を引用します。
>NEMはもともとNew Economy Movement（新しい経済運動）の略称でした。現在はその略称ではなくNEMという固有名詞であるとされています。金銭的な自由、分散化、平等、および連帯感の原則に基づき、新しい経済圏の創出を目標としてはじまった仮想通貨（暗号通貨）のプロジェクトです。

>2014年1月19日、bitcointalk.orgのフォーラムにてutopianfutureというハンドルネームの人物により企画が持ち上がり、2015年3月31日に公開されました。

>ちなみに最初のタイムスタンプは2015年3月29日なのでその日が"誕生日"です。
>(引用元)https://www.cryptostream.jp/nem_xem/

#NEM APIを叩く方法
APIを叩くには、NIS（NEMインフラストラクチャーサーバー)へアクセスします。
NISはHTTP GETとPOSTの両方のリクエストを受け付けています。
HTTP GETリクエストはブラウザから実行され次の形式になります。
http://<サーバー名 or IPアドレス>:7890< APIパス >?< APIのパラメータ >

なんだか難しいので、てっとり早く試すために、以下のURLを開いてください。
http://23.228.67.85:7890/heartbeat

|URLの部分|解説|
|---|---|
|23.228.67.85|NISのIPアドレスです。単にノードって呼ばれたりもします。|
|7890|NISへはアクセスへは7890ポートを使います|
|heartbeat|NISに「生きているか？」と問い合わせるAPIです|
NISが生きていれば以下の結果が帰ってきます。

```json:json
{"code":1,"type":2,"message":"ok"}
```
※返ってこなかったら別のノードを試してみよう

JSON形式のデータなんですが、最初はなんのことやらよくわからないと思います。
JSON？？返ってきた値はなんだ？？とかとか。
私も勉強して次回から解説しようと思います。

ノードが分からない人は、NanoWalletで選択できるノードリストのどれかを指定すれば良いでしょう。
以下の画像はテストネットのノード選択画面です。
![スクリーンショット 2018-03-10 15.59.45.png](https://qiita-image-store.s3.amazonaws.com/0/242994/f19f60a0-9e70-b794-f1b5-7b596389f976.png)

これをPython３を使った場合、どういうソースコードになるか以下に掲載します。

```python:Python3

import requests
import json

r = requests.get('http://<サーバー名 or IPアドレス>:7890/heartbeat').json()

print(r)
```
HTTP GETリクエストを使って、APIを叩いています。
URLを開いた場合と同じ結果になると思います。

#NEM APIを叩く流れのまとめ
1.NISへHTTP GET/POSTクエストを使ってNEM APIを叩く
2.NISからJSON形式のデータが返ってくる
3.JSON形式のデータをプログラム内で活用する
この3ステップで可能でした。
次回からはJSON形式のデータの取り出し方も交えてNEM APIを解説してきます。

#次回
[Python3でNEMのAPIを叩く-002-NISが稼動しているかどうかを判断する](
https://qiita.com/oden_umai/items/390395c9ec7594eb709b)
機械学習プロジェクト用リファレンス

#概要
機械学習プロジェクトに関しての自分用の備忘録です。まだ、プロジェクト自体にアサインされたばかりなので、とりあえず調べ物の途中経過的なリストです。
それでも皆さんの学習やプロジェクトの参考になれば幸いです。そのうちそれぞれ文献のまとめ記事も作成しようと考えています。

# KDNuggets（英文）
https://www.kdnuggets.com/

機械学習、ディープラーニングなどデータサイエンスに関する記事がまとめられているサイト。最新のディープラーニングのフレームワークの動向についての記事だったり、IoTイベント情報が載ってたりで情報豊富。毎日チェックしています。

# Advice For New and Junior Data Scientists （英文）
https://www.kdnuggets.com/2017/11/chang-advice-new-junior-data-scientists.html

TwitterからAirbnbへとキャリアチェンジをしたRobert Chang氏の記事。機械学習プロジェクトの難しい点や言語の学習について、現場サイドからアドヴァイスしています。詳しくは後日まとめようと思います。

# 仕事ではじめる機械学習
http://amzn.asia/1q8LSMM

仕事で機械学習をはじめる人の定番、らしいです。機械学習プロジェクトに関して僕が初めて手に取った本です。個人的には第1章でほぼ全体像を述べてる印象を受けました。

# 仮説検証とサンプルサイズ
http://techlife.cookpad.com/entry/2016/09/26/111601

クックパッド開発者のブログです。先に紹介した[仕事ではじめる機械学習](http://amzn.asia/faWZTXu)で紹介されていたので参照したところ、自分は特に仮説検証の部分で非常に役に立つと思います。ちなみに僕はわりとクックパッド閲覧します（とくにお菓子）

# 機械学習プロジェクトの始め方--人材と体制における3つの役割
https://japan.zdnet.com/article/35103641/

「機械学習プロジェクト」とググると一番最初に出てくる記事でした。先に紹介したものでもよいと思いますが、より簡潔に機械学習プロジェクトに関してフォーカスして書かれているので、頭の整理にとても良いです。

# 感想
プロジェクトもアサインされたばかりで、右も左もわからない状態から、とりあえず目指すべきものは何かの方向付けには斜め読みしただけでもしてくれると思います。
個人的に良質の文献であれば、たくさんを参照しなくても十分応用できるんじゃないかと思っているので、まずはこれらのリファレンスを読み込みつつ現場でTry&Errorしながら貢献していきたいです。
Flutter入門1日目

## はじめに

モバイルアプリ作りたいとうだうだいいつつ、ちょっとiOSに手を出してすぐ終わったレベルのエンジニアがFlutterで頑張ってモバイルアプリを作る記録。
毎日何か記事を投稿するのを目指す（緩めに）。
記録と同じような人の参考になればと思いつつ。

## スキル

２０１８年の時点

* 社会人７年目
* Web開発
* PHP/JavaScript/HTML/CSSメイン
* Objective-C/Swift/C#は仕事とかで軽く触る程度はあるがあんまりわかってない

特別すごい事ができるわけでもなく、仕事としてはやっていけるかっていうレベル。

## Flutterの選択の理由

iOSだけでもいいけど、どうせならandroidも作りたいってことで、今話題ということで。情報も少ないけどだからこそってことも思いつつ。
UIがいい感じにできそう。

でもiOSアプリできます！！っていってもSwiftとかではないから、仕事関係の依頼は受けられないがそんなのあるかもわからないので考えないようにする。

## Flutter作業開始

とりあえずってことでドキュメントを流し読みする

https://flutter.io/
https://flutter.io/using-ide/

勿論英語だがドキュメント程度の英語はすごい大雑把ならなんとか読めるが、英語の勉強をしたいわけではないのでgoogle翻訳さんにお願いした。

次は環境を構築しようかな。

そもそも、技術的なことを含まない投稿もありそうで使い方間違ってるとか怒られそうだけど、それはそのときってことで。
Firebase + SPA で SSR なしに OGP 対応


SPA で構築すると気になるのは SEO と OGP です。SEO に関しては Google のクローラは JS を解釈してくれるようになったので fetch as Google で確認する限りインデックスされるようです（順位に影響があるかどうかは不明）。OGP に関しては現状、 facebook / twitter のクローラは JS を解釈してくれないので、サーバから返却される HTML に `<meta property="og:title" content="title">` のようなタグを埋め込んでおく必要があります。

SPA OGP 対策として一番最初に語られるのが SSR (サーバサイドレンダリング) だと思いますが、OGP のためだけに SSR するのは面倒なので、Firebase Hosting + Functions を使ってなんとかして見る方法を試してみました。そのメモです。

## 注意

今回の対応方法は Firebase のみで構築をするパターンです。これには弱点が幾つかあります。

- リダイレクト処理が入るので、最初のレスポンスが微妙
- Google のインデックスがリダイレクトが入るため評価されるか微妙

これを回避するためには CloudFront + Lambda@edge を併用するパターンもあります。こちらも対応方法を書いたので参考にしてみてください。

[Firebase + SPA + CloudFront + Lambda で SSR なしに OGP 対応](https://qiita.com/zaru/items/e7c2c11f8a9267dc8bb7)

## Hosting から Functions へ

Firebase Hosting では `.firebase` ファイルにルールを記載すると、特定 URL 時に Functions へ処理を受け渡すことができます。

```json
{
  "hosting": {
    "rewrites": [
      {
        "source": "/@note/*",
        "function": "note"
      }
    ]
  }
}
```

この例だと `/@note/piyo` のような URL にアクセスすると note Function が起動します。

## Functions で OGP 含む HTML

次にリクエストを受け取った note FUnction で、OGP のタグを含んだ HTML を返却するようにします。

```typescript
import * as functions from 'firebase-functions';
import DocumentSnapshot = FirebaseFirestore.DocumentSnapshot;
import DocumentData = FirebaseFirestore.DocumentData;
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
const db = admin.firestore()

function buildHtmlWithPost (id: string, noteObj:DocumentData) : string {
  return `<!DOCTYPE html><head>
  <title>${noteObj.title}</title>
  <meta property="og:title" content="${noteObj.title}">
  <meta property="og:image" content="${noteObj.image}">
  <meta property="og:image:width" content="600">
  <meta property="og:image:height" content="600">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="${noteObj.title}">
  <meta name="twitter:image" content="${noteObj.image}">
  <link rel="canonical" href="/@note/${id}">
  </head><body>
  <script>window.location="/@note/?noteId=${id}";</script>
  </body></html>`
}

export const note = functions.https.onRequest(function(req, res) {
  const path = req.path.split('/')
  const noteId = path[2]
  db.collection('note').doc(noteId).get().then((doc:DocumentSnapshot) : void => {
    const htmlString = buildHtmlWithPost(noteId, doc.data())
    res.status(200).end(htmlString)
  }).catch(err => {
    res.status(500).end(err)
  })
})
```

この例では、URL に含まれている ID を元に firestore へデータを取得して適宜 HTML に埋め込んでいます。

ポイントは `<meta>` タグのみを記載し、実際のコンテンツは `window.location` でリダイレクトしているところです。こうすると、 facebook / twitter などはリダイレクトされず、通常ユーザは `/@note/?noteID=xxx` へリダイレクトされます。

このままだと正規の URL `/@note/xxx` が `/@note/?noteID=xxx` になってしまうため HTML5 history replace を使って URL を書き換えてあげます。vue-router を使っている例はこちら。 `$route.query` でクエリパラメータがあった場合は正規 URL に変更してあげるような処理です。

```javascript
created () {
  if (this.$route.query.noteId) {
    this.$router.replace('/@note/' + this.$route.query.noteId)
  }
}
```

以上で、 Firebase のみで OGP 対応をすることができました。
ubuntu + rbenvでrubyをインストール

## はじめに
ubuntu14.04、rbenvを使ったrubyのインストール手順を記載。

- ubuntu 14.04
- git
- rbenv
- ruby-build
- ruby

## gitのインストール

```sh
sudo apt-get -y install git
```

gitがインストールされたか確認

```sh
git --version
```

## rbenvのインストール

gitからclone

```sh
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```

.bash_profileに設定を追記

```sh
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
```

上記の設定を反映させるために再読み込み

```sh
exec $SHELL -l
```

rbenvがインストールされたか確認

```sh
rbenv -v
```

## ruby-buildのインストール

ruby-buildとは、rubyをインストールするためのrbenvのプラグイン。
ruby-buildもgitからclone。

```sh
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

## rubyのインストール

インストール可能なrubyのバージョンを確認

```sh
rbenv install --list
```

バージョンを指定してrubyをインストール&設定
（今回はバージョン2.4.0をインストール）

```sh
rbenv install 2.4.0
rbenv rehash
rbenv global 2.4.0
```

インストールされたかの確認は下記コマンド

```sh
rbenv versions
```
singularity-pythonを使ってみた。


[singularity-python](https://github.com/singularityware/singularity-python)は、Singularityコンテナを操作するためのPythonモジュールとコマンドラインツールです。PythonからSingularityを操作してみたかったので、singularity-pythonを使って色々試してみました。また何かやってみたら追記していきます。

>追記：singularity-pythonはdeprecatedになるみたいで、今開発中の[singularity-cli](https://github.com/singularityhub/singularity-cli)が後継になるらしいです。

## インストール

```
pip3 install singularity
```

python3推奨です。

## 環境変数

`SINGULARITY_PULLFOLDER` : [Singularity Hub](https://www.singularity-hub.org/)などから落としてきたコンテナイメージファイルが保存される場所を設定できます。デフォルトだとカレントディレクトリに保存されます。

pythonでやるなら、こんな感じでしょうか。

```python
import os

singularity_env = os.path.expanduser("~/.singularity/images/")
os.environ["SINGULARITY_PULLFOLDER"] = singularity_env
```

これで`~/.singularity/images/`の中にコンテナイメージファイルが保存されるようになります。

## pull

[Singularity Hub](https://www.singularity-hub.org/)などからコンテナイメージを落とします。

```python
from singularity.cli import Singularity

S = Singularity()
container_id = "shub://hogehoge/hogehoge"
image_name = S.pull(container_id)
```
`SINGULARITY_PULLFOLDER`を設定しておくと、指定したディレクトリの中に保存されます。
`S.pull(container_id,image_name="hoge.simg")`のようにすると保存されるコンテナイメージファイルの名前を変更する事ができます。


## run

コンテナの作成時のレシピファイルに書かれている`%runscript`を実行します。

```python
result = S.run(image_name, args="hoge")
print(result)
```

## execute

コンテナ内の環境に存在するコマンドを実行します。


```python
result = S.execute(image_name, "ls")
print(result)
```
[GAS] GoogleDriveにファイルが追加されたら添付してメールする

#概要
メインフォルダ下の各フォルダに追加されたファイルを各setting.txtの内容に従ってファイルをメールに添付して送信するものです。
google謹製の同期ソフトを使用してローカルでファイルを特定のフォルダに追加 → クラウドに同期 → settiing.txtに従い添付してメール送信みたいな動作を想定しています。

#構成
フォルダ構成例

```text:フォルダ
メインフォルダ/
┝ hoge部長/
|   └ setting.txt
└ fuga先生/
    ┝ setting.txt
    ┝ 添付送信されるファイル1
    └ 添付送信されるファイル2
```
setting.txtには上から順にメールアドレス、タイトル、本文テンプレートが書かれてあります。

```text:setting.txt
example@hoge.com
メールのタイトル
メール本文。<br>で改行。
```
フォルダとsetting.txtを追加すれば増やせます。添付ファイルは複数okです。

#結果
![タイトルなし.jpg](https://qiita-image-store.s3.amazonaws.com/0/242971/bf8ced2d-1325-b7e1-460e-a4c6ef339408.jpeg)

#コード
```js:autoMail.gs
function autoMail() {
  var folderId = 'メインフォルダid';
  
  folders2Arr(DriveApp.getFolderById(folderId).getFolders()) //メインフォルダ下のフォルダをすべて取得                                                                             
  .filter(function (folder) { 
    return files2Arr(folder.getFiles()).length >= 2; //setting.txtしかないものはフィルタ
  }) 
  .map(function(folder) {                              
    return folder.getFilesByName('setting.txt').next() //setting.txtの取得
    .getBlob().getDataAsString("sjis").split(/[\s]+/)  //shiftjisで読み込み、改行部分で分けて配列に
    .concat([files2Arr(folder.getFiles())              //添付ファイルの配列を末尾に追加
            .filter(function(file) { 
              return file.getName() != 'setting.txt'; 
            })]
    )
    .concat(folder);                                   
  })
  .map(function([to, sub, body, files, folder]) {
    
    MailApp.sendEmail({ //メールの送信
      to: to,
      subject: sub,
      htmlBody: body,
      attachments: files
    });
    
    files.map(function(x){ //送信したファイルを削除
      folder.removeFile(x); 
    })
  });
}
 
function files2Arr(files) { //配列に変換
  var arr = [];
  
  while(files.hasNext()) {
    arr.push(files.next());
  }
  
  return arr; 
}

function folders2Arr(folder) {
  return files2Arr(folder); 
}
```
DartでmapIndexedなど

DartでmapIndexedなど作ってみた。
generatorは便利だね。TypeScriptにもあればいいのに

```map_indexed.dart
Iterable<R> mapIndexed<T,R>(Iterable<T> list, R f(int index, T val)) sync*{
  int i = 0;
  for(T val in list){
    yield f(i++, val);
  }
}
```

```map_notnull.dart
Iterable<R> mapNotNull<T,R>(Iterable<T> list, R f(T val)) sync*{
  for(T val in list){
    R result = f(val);
    if(result != null){
      yield result;
    }
  }
}
```

```range.dart
Iterable<int> range(int size) sync* {
  for(int i = 0; i < size; i++){
    yield i;
  }
}
```
グーグルマップの履歴(timeline)をダウンロード

#経緯
グーグルマップのtimeline機能で、過去のある1日の移動経路がわかります。

が

**一回に1日分しか表示できないけど、これまでの履歴全部を一発で見たい...**

#APIないの？
google map timelineに関するAPIがないかを少し調べましたが、どうやら存在しないようです。
愚直にデータをダウンロードして表示する方針にしました。



#グーグルマップの履歴をダウンロードする手順
https://takeout.google.com/settings/takeout/custom/location_history
に行き、次へ。
<img width="699" alt="スクリーンショット 2018-03-10 15.47.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/32b2bb03-7425-9588-905a-310a8f2e846d.png">

アーカイブの形式設定はデフォルトのままで特に問題ないと思います。

ぽちぽち進んでいくと、jsonのダウンロードができます。

<img width="715" alt="スクリーンショット 2018-03-10 15.07.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/5015f6e1-4002-0e1d-6529-80f6b7f3b3cb.png">


ダウンロード後、jsonファイルの中身をみてみると、以下のような感じでした。
時折`activity`の属性が入っていて、状態が"STILL"なのか"IN_VEHICLE"なのか等の推定がなされているようですね。
<img width="305" alt="スクリーンショット 2018-03-10 16.01.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/eeb3ad94-8a20-e9c0-271d-f12065651d75.png">
(一部数値を`***`で置き換えてます)

#これから
自分が過去に通った道を全て重ね合わせて一つのMapにしたいので、このJsonファイルを投げると全ての経路が重ね合わされて表示されるようなページを作りたいと思います。

#追記
とりあえず動くもの？ができました。**色が怖い。**

https://maatumo.github.io/gmaptl/index.html
処理が重すぎて一回PC落ちたので、万が一ご利用になる際はご注意ください。(jsonを少しづつ読み込むような設計に変えたい
<img width="1430" alt="スクリーンショット 2018-03-10 17.45.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/14671e9b-d6bd-3ec2-9073-80f453737f51.png">
fastlaneの`upload_to_app_store`コマンド実行中に`We’re temporarily unable to save your changes.`と出てアップロード出来ない時の対処法

## 概要

fastlaneでアプリのバイナリをiTunesConnectにあげようとした時に、下記のようなエラーが出て止まることがある。
不思議なことに手動でアップロードする分には正常にアップロードできる。
なので、エラー文にあるように時間を置いてやり直しても直らない。
それに対する対処法を見つけたのでそれを記す。

```
[⠸] Uploading metadata to iTunes Connect iTunes Connect temporary error received: 'We’re temporarily unable to save your changes. Please try again later.'. Retrying after 60 seconds (remaining: 4)
```

## 解決法

`fastlane/metadata/review_information`ディレクトリ内の情報が足りていないためにエラーが生じている可能性がある。
なので`first_name.txt`や`last_name.txt`,`email_address.txt`,`phone_number.txt`などの内容をきちんと入力してから同様のコマンドを再実行する。

するとエラーが別のものに変わって対処しやすくなるはずだ。
【ASP.NET_MVC,IIS】windowsUpdateをしたらデバッグができなくなった件の解決方法

Cドライブの容量がパンパンだったため、WindowsUpdateを２ヶ月ぐらい見送りにしていましたが、さすがにやらないといけないよなと思い、つい先日(2018/03/09)にアップデートをしました。<br>

長かったアップデートを乗り越えた後に、VisualStudio2018を立ち上げ今勉強中のASP.NET_MVCのソリューションをデバッグしたところ以下のエラーメッセージが出力され画面が表示されませんでした。<br>

エラーメッセージ：<b>「指定された引数は、有効な値の範囲内にありません。 パラメーター名:site」</b><br>
色々調べた結果解決しましたので備忘録として載せておきます。<br>

#１.IISの確認
とりあえず、WindowsUpdateでIISの設定が変わったのかなと思いブラウザ(Google Chrome)のURLに「http:/localhost」と入れ更新。<br>
しかし、NotFoundとなりページが見つからないのでIISが起動していないことがわかります。<br>

#２．インターネットインフォメーションサービス（IIS）マネージャーを起動
「コントロールパネル＞管理ツール＞インターネットインフォメーションサービス（IIS）マネージャー」から「インターネットインフォメーションサービス（IIS）マネージャー」を開くことができます。<br>

しかし、自分の管理ツールには「インターネットインフォメーションサービス（IIS）マネージャー」がありませんでした。<br>
そこで、「コントロール パネル＜プログラム＜プログラムと機能＜Windowsの機能の有効かまたは無効化」を開き、「インターネットインフォメーションサービス」確認します。<br>
![1.png](https://qiita-image-store.s3.amazonaws.com/0/60753/d0e50190-62b3-339d-0f77-71d8b14b056f.png)<br>
なんと、<b>「インターネットインフォメーションサービス」にチェックが入っていないではありませんか！</b>
即座に、チェックをいれOKボタンを押します。

そしてそのあと、「コントロールパネル＞管理ツール」を開き新たに表示された「インターネットインフォメーションサービス（IIS）マネージャー」をクリックしてIISマネージャーを開きます。


#３．Default Web Siteを起動する
IISマネージャーを開いたところ、左側の接続欄（ツリー）に表示してあるDefaultWebSiteに停止マークがついていました。（□みたいなやつ）
DefaultWebSiteを選択し、開始をしても「プロセスが使用中なため起動できません」みたいなよくわからないエラーが出力されてしまい<b>DefaultWebSiteが起動できません。</b>

そこで、<b>一旦PCを再起動し再びIISマネージャーを開いた</b>ところDefaulWebSiteについてた停止マークはなくなっており、すでに起動されていました。謎ですね。

この状態で、VisualStudioを開きソリューションをデバッグしたところ問題なく画面が表示されデバッグができました。

#最後に
まさか、WindowsUpdateをするだけでIISマネージャーを削除するとは思いませんでした。
挙句の果てにはよくわからないエラーの塊。
負けずに開発をしていきたいですね。
【備忘録】RubyMineでLiveEditを利用する

# 1. RubyMineにPluginをインストールする

RubyMineの`Preferences > Plugins`から**LiveEdit**をインストールする

![liveedit01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/a26c5be6-2e16-9257-8fae-67706a315e41.png)

![liveedit02.png](https://qiita-image-store.s3.amazonaws.com/0/141934/4d153dd7-12e7-6a1e-0112-d381895d3972.png)

![liveedit03.png](https://qiita-image-store.s3.amazonaws.com/0/141934/c9aaf051-3007-5121-c578-e144ef32864f.png)

![liveedit04.png](https://qiita-image-store.s3.amazonaws.com/0/141934/f958e458-09f4-c1cb-883d-536709cf3eb8.png)

# 2. Chrome拡張機能をインストールする

Chromeウェブストアから[JetBrains IDE Support](https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji)をインストールする

![liveedit05.png](https://qiita-image-store.s3.amazonaws.com/0/141934/b2f8bcb9-35ed-5c80-e2ef-54cf8c8f70ea.png)

![liveedit06.png](https://qiita-image-store.s3.amazonaws.com/0/141934/ced08d01-19ae-d75c-a18a-a9d16e6a975d.png)

![liveedit07.png](https://qiita-image-store.s3.amazonaws.com/0/141934/2bc64d26-293b-6413-1fd5-747c4897ff61.png)

# 3. LiveEditを利用する

html.erbの編集タブで`右クリック > Debug 'xxx'`を選択すると、Chromeで新しいタブが開いてhtml.erbの編集がリアルタイムに反映される

![liveedit08.png](https://qiita-image-store.s3.amazonaws.com/0/141934/8076ffa1-4929-fb18-3cb0-f0718aea3a41.png)

![liveedit09.png](https://qiita-image-store.s3.amazonaws.com/0/141934/acac92e6-3ed5-9dec-596b-795eefed55bd.png)
2018/02/10 名古屋PowerBI勉強会にいってきた

##セミナーで得た事実

###BIツール の動向
　実質３強。PowerBI,Tableau,Qlick
　　あと勉強会のLTでは Domoを紹介していた

###PowerBI Pro（有料）と Desktopの違い
　レポートの共有ができる
　クエリの共有ができる
　（おそらく99%）データも共有できる

Office365 E5のライセンスがあるなら、PowerBI Proがつかえる
　activateするだけ
オンプレミス環境にこだわるなら
　PowerBI Report Serverがある
Office365グループのアクセス権で開示できる範囲を設定できる

PowerApps ビジネスをしっている人がアプリをつくれる
　https://powerapps.microsoft.com/ja-jp/

Microsoft Flow　MSアカウントをもっている人なら誰でもつくれる
　Workflow、今風にいうと、RPAみたいなやつ

PoweBI Service
　https://powerapps.microsoft.com/ja-jp/
　ストリーミングデータセット（JSON形式）で、データリンクしたりダッシュボード（レポート）をつくることができる

PowerApps, MicrosoftFlow, PowerBI Serviceの３つでお店予約システムを２時間でつくれる（ノンプログラミング）
　つまり light solution

###わかったこと

ぶっちゃけ 製品仕様DBっぽいものはPowerBIでできるんじゃないか。
　それができて共有すれば、あとはどうでもなる気がしてきた。

####参考URL

　Power BI 勉強会＠名古屋支部 #01 を終えて
　#PBIJP Power BI勉強会
　https://qiita.com/PowerBIxyz

　Qiita PowerBIメモ
　https://qiita.com/search?q=PowerBI%E3%83%A1%E3%83%A2

　Microsoft Power BIブログ
　https://powerbi.microsoft.com/ja-jp/blog/
ActiveModel::AttrbiuteMethodsが機能しない原因


AttributeMethodsが正しく機能するためには、

attribute_method_prefix, attribute_method_suffixは
define_attribute_method 'age' の手前に書いておく必要があります。

```ruby:公式チュートリアルのコード

class Person
  include ActiveModel::AttributeMethods
 
  attribute_method_prefix 'reset_'
  attribute_method_suffix '_highest?'
  define_attribute_methods 'age'
 
  attr_accessor :age
 
  private
    def reset_attribute(attribute)
      send("#{attribute}=", 0)
    end
 
    def attribute_highest?(attribute)
      send(attribute) > 100
    end
end

```

以下のようにちゃんと機能して動きます。

```
person = Person.new
person.age = 110
person.age_highest?
=> true
```


```ruby:機能しないコード

class Person
  include ActiveModel::AttributeMethods

  define_attribute_methods 'age' #←  attribute_method_prefixの手前にに定義してしまっている
  attribute_method_prefix 'reset_'
  attribute_method_suffix '_highest?'

 
  attr_accessor :age
 
  private
    def reset_attribute(attribute)
      send("#{attribute}=", 0)
    end
 
    def attribute_highest?(attribute)
      send(attribute) > 100
    end
end

```

```
person = Person.new
person.age = 110
person.age_highest?
=> NoMethodError undefined_method 'age_highest?'
```

順番で影響をうけるので、公式コードの書き方は素直に真似した方がよさそうです。
ContOS7にyumでjenkinsを入れるDockerfile [追記：privileged無し]

###■環境
----

Windows10 Pro 1709
Docker-toolbox 18.02.0-ce
VirtualBox 5.2.8

----
###■イメージ作成
----

必要最低限の物だけ記載してます。

```docker:Dockerfile
FROM centos:7.4.1708

RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime && \
    yum -y install wget && \
    wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo && \
    rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key && \
    yum -y install jenkins java-1.8.0-openjdk initscripts && \
    systemctl enable jenkins
CMD /sbin/init

```

**ビルド**

```
$ build -t jenkins .
```
----
###■コンテナ起動
----
```
$ docker run -itd --privileged -p 8080:8080 --name my-jenkins jenkins
```

この画面みるまで遠かった "Orz

![jenkins.jpg](https://qiita-image-store.s3.amazonaws.com/0/71525/c12a679b-623b-e7fa-7df3-ffa665674c30.jpeg)

----

###■ 追記：2018.05.23 (privileged 無し版)

```docker:Dockerfile
FROM centos:7.4.1708

RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime && \
    yum -y install wget && \
    wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo && \
    rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key && \
    yum -y install jenkins java-1.8.0-openjdk initscripts

CMD ["/usr/bin/java","-jar","/usr/lib/jenkins/jenkins.war"]

```

```
$ docker run -itd -p 8080:8080 --name my-jenkins jenkins
```

感謝記事:[お前らのdocker記事はもう古い！](https://qiita.com/akashima/items/6b0679b95db170f94f22)
メモリストリーム

プログラミング言語 C における文字列というのはメモリの塊そのものです。 見えているままのデータがメモリ上のどこかに配置されています。 余計なことをしない単純さは機械の性能を引き出しやすい一方で、ちょっとしたことでもプログラマが手間をかけなければいけません。

もちろん、文字列を扱うライブラリを導入したり作ったりすればいくらでも複雑なことは出来るのですが、凝ったデータ構造は標準ライブラリとの組合せがやり難くなります。 そのあたりを考慮して使い勝手がよく汎用性が高い仕組みが作れないものかと私は考えていました。

そして先日、 Qiita に投稿されたある記事の文字列生成関数に対して[「出力先として `FILE*` を指定できるバージョンもあればよいのではないか」という旨](https://qiita.com/smicle/items/e195ce546fb2cf628088#comment-600a3a231f67fd32449a)のコメントがついているのを見て、文字列 (メモリブロック) にストリームとしてのインターフェイスがあればよいのだと思いつきました。

ファイルと文字列が共通のインターフェイスで扱える仕組みを私は知っています。 Scheme の文字列ポートです。 C のファイルの読書きをするときにはストリームという抽象化された層が用意されていますが、 Scheme にも同様にポートという概念が用意されており、ポートは文字列に対しても使えます。 考え方を真似て C でもやれば良いのです。

結果として出来たライブラリに memstream と名付けて Github に置きました。

https://github.com/SaitoAtsushi/memstream

例えば数をストリームに出力する関数があったとして、関数 `open_output_memstream` がオープンしたストリームを出力先にすればそのまま文字列を構築することが出来ます。 以下のように使えます。

```c
#include <stdio.h>
#include <stdlib.h>
#include "memstream.h"

int count_three(FILE* fp) {
  int total=0;
  for(int i=3; i>0; i--)
    total += fprintf(fp, "%d\n", i);
  return total;
}

char* count_three_string(void) {
  FILE* fp=open_output_memstream();
  count_three(fp);
  fputc('\0', fp);
  size_t len;
  char* str = mclose(fp, &len);
  return str;
}

int main(void) {
  count_three(stdout);
  char* str=count_three_string();
  printf("%s\n", str);
  free(str);
  return 0;
}
```

ライブラリ memstream は Windows のパイプの機能を利用しています。 パイプの読書きのハンドルに対しては、シークを除いてはファイルに対しての読書きとほぼ同じ操作が可能なので、パイプのもう一旦で受取った情報を文字列として構築するという考え方です。 私自身のプログラミング環境の都合で Windows のみを想定していますが、 Unix 等でも実現可能な方法だと思うので、興味があれば移植してみても面白いかもしれません。
関数の overloading の曖昧さからの template

初投稿です。

# はじめに

UTF-8 なバイト配列にバイトだけでなく直接 Unicode のコードポイントを追加・削除できたり、iterator　を`std::regex`とか`<algorithm>`にそのまま使えたりしたらいいな、と思ったので、`std::basic_string`に倣って rope を書いています。ソースは [GitHub](https://github.com/niefla/utf8_saker) で保管してます。もうちょっと書いたら push します。

色々今までよく分からなかった C++ のことが、これを書いてるのをきっかけに少し分かるようになった（つもりな）ので、何枚か記事を書いてまとめたいと思います。誰かの役に立てば嬉しいですね。

# 何をしたかったか

`std::basic_string<CharT>`のメソッドの例をいくつか挙げます。

```cpp
basic_string(
    size_type count,
    CharT ch,
    const Allocator& alloc = Allocator()
);

basic_string& operator=(
    CharT ch
);

basic_string& assign(
    size_type count,
    CharT ch
);
```

当たり前のことですが、`std::basic_string<CharT>`のメソッドの引数は、`CharT`がベースです。しかし、バイトもコードポイントも書き込める rope を実装するには、引数をバイトとするメソッドと、引数をコードポイントとするメソッドの両方が欲しいですね。これを実装するには色んな方法があるのですが、そのうち筆者が思いついたものを挙げていきます。

1.  違う関数名で、引数をバイトとする関数と引数をコードポイントとする関数を書く
2.  template で全部拾って、引数としてバイトを渡しているのか、コードポイントとして渡しているのかを伝える「モード」的な引数を設ける
3.  同じ関数名でバイトの型とコードポイントの型のオーバーロードを書く
4.  template で全部拾って、ある型に特化したコードポイント版を書き、汎用はバイト版として書く

それぞれの書き方と、良い点と悪い点を考えていきます。

# 別々の関数を書く

`std::basic_string::assign`に倣って、`rope::assign`をこの方法で書いてみるとしましょう。実装はこんな感じになります。

```cpp
rope& rope::assign(
    size_type count,
    OctetT ch // OctetT はバイトを表す型
) {
    // chをバイトとして何らかの処理を行う
}

rope& rope::assign_cp(
    size_type count,
    CodepointT ch // CodepointT はコードポイントを表す型
) {
    // chをコードポイントとして何らかの処理を行う
}
```
ユーザからしても、関数名からこの関数がバイトなのかコードポイントなのかが分かるので、筆者はこの方法を使っています。

しかし、コンストラクタのようなメソッドは、関数名を指定できないので、この方法は使えません。別の方法を考えましょう。

# template と「モード」引数

rope のコンストラクタを実装すると、こんな感じになります。

```cpp
enum struct mode {
    octet, cp
};

template <typename GeneralT>
rope(
    size_type count,
    GeneralT ch,
    const mode& m = mode::octet, // デフォルトはバイト
    const Allocator& alloc = Allocator()
) : /* 初期化 */ {
    if (m == mode::octet) {
        // chをバイトとして何らかの処理を行う
    }
    else {
        // chをコードポイントとして何らかの処理を行う
    }
}
```

template を使っているので、色々な型を受け付けながらも、引数がバイトを表しているのか、コードポイントを表しているのかを指定できるというのは便利ですね。引数が`const T*`だったり、`std::initializer_list<T>`だったりすると、キャストがややこしくなるので、template を使うのは適策だと思います。

しかし、operator をオーバーロードする場合は、引数の量を増やすことはできません。operator は、標準ライブラリの`<algorithm>`とかに対応するためには不可欠なので、別の方法を考えないといけません。

# 同じ関数名で overload する

`operator=`を実装してみましょう。

```cpp
rope& operator=(OctetT ch) {
    // chをバイトとして何らかの処理を行う
}

rope& operator=(CodepointT ch) {
    // chをコードポイントとして何らかの処理を行う
}
```

しかし、これだと、`OctetT`でも`CodepointT`でもない型の引数を通したい場合、ユーザ側が引数をどちらかにキャストをしないと、曖昧なオーバーロードとしてエラーが出ます。いちいちキャストを書くのは面倒くさいので、何かいい方法はないでしょうか。

# template と特化

`operator=` を実装してみましょう。

```cpp
template <typename GeneralT>
rope& operator=(GeneralT ch) {
    // chをバイトとして何らかの処理を行う
}

template <>
rope& operator=(CodepointT ch) {
    // chをコードポイントとして何らかの処理を行う
}
```

引数の型が`CodepointT`ならば、コードポイント版が呼び出されます。そうでない場合は、バイト版が呼び出されます。template の典型的な用例だと思います。
SQLServerの変数のちょっと変わった挙動(Select編)

##概要
oracleのストアドを手動でsqlserver用に変換しているのだけれど、
元のソースが冗長な書き方をしていて無駄な発行を抑えられないかなと思って
いろいろ試してたら予想外な挙動をしたので備忘録。

##その1

```
declare @Quantity int;

SELECT	@Quantity = ISNULL(Quantity, 0)
  FROM	t_XXX
where Quantity = -1;--レコード条件が0になる

select @Quantity;

```

結果はnull。わかりみが深い。

##その2

```
declare @Quantity int;
Set @Quantity = 0　--★追加したよ

SELECT	@Quantity = ISNULL(Quantity, 0)
  FROM	t_XXX
where Quantity = -1;--レコード条件が0になる

select @Quantity;

```
結果は**0**。わかりみが浅い。しかし予想以上に星の存在感すごい。

##どういうこと？
Select文の結果行が0件なので、そもそも代入が行われない模様。

つまり「前もって変数に初期値を設定していないと痛い目を見るかもしれないよ」って
ことですね。
Unity2017.3をMacにインストールする

# Unity2017.3をMacにインストール

Leap Motionを使って3Dお絵かきをしてみたかったので人生初のUnityに挑戦

1. Unityのインストーラーをダウンロード<br>
公式サイトからUnityのインストーラーをまずダウンロード<br>
今回は「Personal」の無料版を使います
https://store.unity.com/ja
![スクリーンショット 2018-03-10 10.35.56.png](https://qiita-image-store.s3.amazonaws.com/0/208719/15840164-80e1-afbd-8392-e8dce60f210a.png)  
<br>
2. 条件に同意してダウンロード
![スクリーンショット 2018-03-10 10.39.10.png](https://qiita-image-store.s3.amazonaws.com/0/208719/d5bd9dd3-7bbe-08c8-3a21-b76704d555b1.png)
<br>

3. UnityDownloadAssistant-2017.3.1f1.dmgがダウンロードされるので実行
Unity Download Assitant.appを選択
![スクリーンショット 2018-03-10 10.52.52.png](https://qiita-image-store.s3.amazonaws.com/0/208719/d17025d4-83fe-65d0-78d2-408ecee73618.png)
<br>

4. Continueをクリック
![スクリーンショット 2018-03-10 10.54.42.png](https://qiita-image-store.s3.amazonaws.com/0/208719/27e5e4e1-0a35-6bb1-6ab8-9b1aabfc9049.png)
<br>

5. ライセンスに同意してContinueをクリック
![スクリーンショット 2018-03-10 10.57.14.png](https://qiita-image-store.s3.amazonaws.com/0/208719/4d36d3b8-e1a6-480a-d40a-6735356b6946.png)
<br>

6. インストールするコンポーネントを選択してContinueをクリック
今後もしかしたらiOSやAndroidも使うカモなのでチェック
![スクリーンショット 2018-03-10 13.11.38.png](https://qiita-image-store.s3.amazonaws.com/0/208719/2a32edf7-e54d-f93f-e9ad-937eaa4d4fdc.png)
<br>

7. インストール先を選択してContinueをクリック
今回はMachintosh HDを選択します
![スクリーンショット 2018-03-10 13.14.40.png](https://qiita-image-store.s3.amazonaws.com/0/208719/23b490f3-ada4-3b2a-6a92-ac477371939e.png)
<br>

8. インストール完了
![スクリーンショット 2018-03-10 13.47.33.png](https://qiita-image-store.s3.amazonaws.com/0/208719/0528d276-7798-1eb4-aa00-a562b6456e8b.png)
<br>

9. アカウント作成
公式サイトでアカウントを作成
![スクリーンショット 2018-03-10 13.53.00.png](https://qiita-image-store.s3.amazonaws.com/0/208719/7eeeb061-a034-7942-5312-42d1247b7672.png)
<br>

10. ログイン
作成したアカウント情報を入力してログイン
![スクリーンショット 2018-03-10 13.49.29.png](https://qiita-image-store.s3.amazonaws.com/0/208719/2b88a9e3-7b6b-0ca2-344b-d60b67de31b8.png)
<br>

11. ライセンスを選択してNEXTをクリック
![スクリーンショット 2018-03-10 14.00.29.png](https://qiita-image-store.s3.amazonaws.com/0/208719/6e15efed-9da6-cb11-3e2d-c6af8ccf60c3.png)
<br>

12. 必要情報を入力してOKをクリック
![スクリーンショット 2018-03-10 14.04.43.png](https://qiita-image-store.s3.amazonaws.com/0/208719/ec261b4e-caa5-1adc-7af3-040c1da699a8.png)
<br>

13. 完了！
![スクリーンショット 2018-03-10 14.06.35.png](https://qiita-image-store.s3.amazonaws.com/0/208719/2ef9be5b-03e1-81ff-8530-f00c11df02be.png)

これでUnity2017.3をMacにインストールする事が出来ました！
バレンタインデーにもらったチョコが義理か本命か判定するAIを実際に作って公開した 


## 1. 概要
[AIが義理チョコを判別](https://valentine.boomin.yokohama/)するシステムを開発してみました。その挙動について、[ここ](https://boomin.yokohama/archives/990)で解説をしていきたいと思います。ホワイトデー前にサービスインすることも大事と考えて、記事は後追いでアップしていきます。

<a href="https://boomin.yokohama/wp-content/uploads/2018/03/giri_result.png"><img src="https://boomin.yokohama/wp-content/uploads/2018/03/giri_result-300x290.png" alt="" width="300" height="290" class="aligncenter size-medium wp-image-1005" /></a>

なお、[こちらが元ネタ](https://qiita.com/hiyoko9t/items/089c3c828b2d3b04f756)です。

> 「なぜ先に思いつかなかったんだ・・・・」

と地団太を踏まずにはいられずに、自分でも開発しました。
GASでテキストファイルの内容を読み取る

#なんでやろうと思ったか
Google Diveの同期を使ってローカル環境から細かな設定ができないかなと思ったから。

プレーンテキストファイルに設定を書き込む
↓
Goole謹製ソフトによる同期
↓
GoogleAppsScript (GAS)に設定の反映

みたいなことを想定しています。
#GASでの読み込みコード
ルートフォルダ上にある'test.txt'の内容を読み取ります。
.getRootFolder()の部分は読み取りたいテキストファイルのあるフォルダを指定してください。
例えば 

```
getFolderById('test.txtのあるフォルダid')
```
Windowsを想定しているためsjisで読み取ってますが、環境によって調整してください。あと.getFilesByName()を使っているため同じ名前のファイルがあるとうまく動きません。

```js
function test () {
  var contents = DriveApp.getRootFolder()
.getFilesByName('test.txt')
.next()
.getBlob()
.getDataAsString("sjis");
  Logger.log(contents);
}
```
以下を末尾に加えると改行ごとに分けて配列にすることができます。

```js
.split(/[\s]+/)
```
##追記 2019-11-04
JSON版を載せておきます。変数に名前をつけれるので扱いやすいと思います。

```js
function getDataFromMyTextFile() {
  const contents = DriveApp.getRootFolder()
  .getFilesByName('test.txt')
  .next()
  .getBlob()
  .getDataAsString("utf-8")
  .replace(/\r?\n/g, ''); //改行削除

  return JSON.parse(contents);
}
  
/*text.txt
{ 
"num" : 1,
"test": "hoge",
"arr" : [1,3,4],
"script1" : {"a":1, "b":2, "c":3},
"script2" : {"a":6, "b":7, "c":9}
}
*/
function test3() {
  const data = getDataFromMyTextFile();

  Logger.log(data.num)        // 1
  Logger.log(typeof data.num) // number
  Logger.log(data.test)       // hoge
  Logger.log(data.arr[2])     // 4.0
  Logger.log(data.script1.a + data.script2.a) // 7.0
}
```

#参考資料
第36回．フォルダとファイルを扱う（DriveApp）
https://excel-ubara.com/apps_script1/GAS036.html

Google Apps Script
https://developers.google.com/apps-script/reference/drive/drive-app