OmniAICreator/Qiita-1.07M huggingface dataset:
補完候補の既入力部分の文字列をハイライト

途中まで名前が同じで長い名前のファイルを扱う機会があり、
「どこまで入力してて、次は何の文字を入力すればファイル名全部補完してくれるんだ～」
「どこまで入力したかハイライトできない？」
と思って調べたら
`nyagos.completion_hook`に`shownlist`ってのが追加されていたので使ってみました。

```lua:.nyagos
------------------------------------------------
-- 補完:入力部分のハイライト
nyagos.completion_hook = function(c)
    for index, item in ipairs(c.list) do
        c.shownlist[index] = '\027[31;;1m' .. c.word .. '\027[;;0m' .. item:sub(string.len(c.word) + 1)
    end
    return c.list, c.shownlist
end
```

#### before

![before.png](https://qiita-image-store.s3.amazonaws.com/0/52493/b0468d5c-fc6d-32be-109b-ec0cbbc2f074.png)

#### after

![after.png](https://qiita-image-store.s3.amazonaws.com/0/52493/91609a24-7147-cd59-2edc-dd7deee05f2a.png)

これで良い！
Tracを導入する

# 前置き
タスク整理のためにチケット管理システムを利用してみることに。ただ、他の人と共有する予定はなく、個人で使えれば良いくらいの用途を想定しているので、スタンドアローンで使える環境を構築していきます。DBやサーバ関連はからっきしな状態で始めているので、都度グーグル先生に聞きながら更新しています。間違いがあればご指摘ください。

そもそもチケット管理システムと聞いて、パッと思い浮かんだのはRedmineでした。ただ、今後Pythonを使うことを考慮して、Tracを導入することにしました。基本的に[TracInstall](https://trac.edgewall.org/wiki/TracInstall)に沿って作業を進めます。

# インストール
## 依存するプログラム
今回導入したのはこちら。依存するプログラムは[TracInstallのDependencies](https://trac.edgewall.org/wiki/TracInstall#Dependencies)に列挙されています。DBはSQLiteがデフォルトのようです。

- [setuptools](https://packaging.python.org/tutorials/installing-packages/)
- SQLite `$sudo apt install sqlite3`
- [apache](https://trac.edgewall.org/wiki/TracModPython)
- [Babel](http://babel.pocoo.org/en/latest/installation.html)
- [docutil ファイル](https://sourceforge.net/projects/docutils/files/)
- [docutil インストール方法](http://docutils.sourceforge.net/README.html#gnu-linux-bsds-unix-mac-os-x-etc)
- htdigest `$sudo apt install apache2-utils`

## インストール
Tracのインストールにはいくつか方法があるようです。詳細は[Installing Trac](https://trac.edgewall.org/wiki/TracInstall#InstallingTrac)をご覧ください。今回はeasy_installでインストールしました。下記のコマンドです。
`$sudo easy_install Trac` 
特に問題なくインストールは完了。

# プロジェクトを構築する
DB初心者にはここからがキツかった。。。
Tracのプロジェクトの環境構築には `trac-admin` コマンドを使用します。コマンドは下記の通り。
`$trac-admin <プロジェクト環境を構築する場所へのパス> initenv`
このコマンドを実行すると、プロジェクト名の入力を促されます。ここは適当に。全角文字もイケるみたい。
プロジェクト名の次は、データベースへの接続文字列を指定します。ローカルにSQLiteのDBを立てる場合は、何も入力せずにエンターを押せばプロジェクトの構築は完了します。既存のDB等を使用する場合は[TracEnvironmentのDatabase Connection Strings](https://trac.edgewall.org/wiki/TracEnvironment#DatabaseConnectionStrings)を参照してください。
サーバ上で運用する場合はディレクトリの権限に気を付けてね、という注意書きがありますが、今回はスルー。

# TracのWelcome画面を表示する
今回はスタンドアローンな環境を構築するので、[Running the Standalone Server](https://trac.edgewall.org/wiki/TracInstall#RunningtheStandaloneServer)に沿って進めます。
まず下記のコマンドを入力。
`$tracd -s --port 8000 <プロジェクト環境を構築する場所へのパス>`
その後、ブラウザを立ち上げて下記のアドレスへアクセス。
`http://localhost:8000`
するとTracのWelcome画面が表示されます。

# ユーザを登録する
このままではログインしようとしても、
`認証情報が利用できません。インストールドキュメントを参照してください。`
というエラーが出てログインできません。

現時点ではここで作業が止まっています。
tracdだけでは認証情報が利用できないようで、Apacheでの設定が必要そう…というところまでしかわかっていません。どこに何を置くんだ??というところも含めて、うまくいったら改めて更新したいと思います。

To Be Continued...
KerasのSequentialモデルでSwishを使う

## やりたいこと

[[1710.05941] Swish: a Self-Gated Activation Function](https://arxiv.org/abs/1710.05941)

の論文で提案されている活性化関数

```math
f(x) = x\cdot\sigma(x)
```

をKerasでも使いたい

## やりかた

### モデルの定義

式が単純なのでやりかたも簡単

```python
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras import backend as K

# Swishの定義
def swish(x):
    return x * K.sigmoid(x)

# モデルの定義
model = Sequential()
model.add(Conv2D(
    32,
    (3, 3),
    strides=(1, 1),
    padding='same',
    data_format=d_format,
    activation=swish,  # <- ここ
    input_shape=input_shape,
    name='conv1'
    ))
# 以下略
```

### 学習済みモデルのロード

学習済みモデルを推論用にロードするときは、`load_model()` に `custom_objects` の情報を与える必要がある。

```python
model = models.load_model(
    model_path,
    custom_objects=
    {
        'swish': swish
    })
```


そのまま学習済みモデルをロードしようとすると、下記のようなエラーが発生する。

```
ValueError: Unknown activation function:swish
```


ベンチマーク結果とかはそのうち気が向いたら書く

## 参考資料

ほぼ公式リファレンス通り
https://keras.io/ja/activations/
iframe内のclickイベントを超簡単に無効にする方法

# はじめに
iframe内のクリックを無効にしようとjavascriptを色々いじっていましたが、結局できませんでした。cssをいじるだけでクリックイベントを簡単に無効にでき、拍子抜けしたので、メモ。

## コード

```html:test.html
<iframe id="iframe_calender" SRC="" scrolling="no"  width="1000px" height="1000px" frameborder="0" ></iframe>

```

```css:test.css
iframe{
  pointer-events:none;
}
```

## 参考

[https://techblog.yahoo.co.jp/advent-calendar-2016/css_pointer_events/](https://techblog.yahoo.co.jp/advent-calendar-2016/css_pointer_events/)
エクセルでＪＳＯＮをパースする

いつ誰が使うんだかわからないが、備忘録代わりに。

# 手順
JSをVBAで起動するライブラリを参照設定から追加してJSでパースできれば一番ラクではあるが、
ところがどっこい、64bit版だとこいつが言う事をきかないのだ。

なので、[こちらのリンク先](https://code.google.com/archive/p/vba-json/)のコードをありがたく利用させてもらおう。[^1]

リンク先のデータを落として解答したら、「json.xls」というファイルを開く。
こいつのVBE画面を開くとクラスモジュールに「jsonlib」というのがあり、これを右クリック→「クラスのエクスポート」の順に実行してすると「jsonlib.cls」というファイルが作成される。
使用する際は、VBE画面内の「ファイル」→「ファイルのインポート」を実行して、上記のファイルをインポートして準備完了。

parse関数を使えばJSON形式の文字列をDictionaryもしくはCollection形式の配列に変換してくれるので、この先は自分の目で確かめてくれ！！


[^1]: オープンソースのライブラリなので、使用は自己責任でお願いします。
ActiveRecord では STI をどう実装しているかを調べたメモ

コード読むときのメモです。すみません

# 仕組み
## モデルのインスタンスを new するところ

メソッド: [ActiveRecord::Inheritance#new](https://github.com/rails/rails/blob/633e9745f8eafb0d1d5523ec761fdee420bcbc91/activerecord/lib/active_record/inheritance.rb#L64-L69)

ActiveRecord::Inheritance モジュールにて、レコードに対応するクラス名を取得していて subclass があれば subclass として new を、それ以外だったら普通に ActiveRecord::Base の new をしている

```rb:lib/active_record/inheritance.rb#L64-L69
        if subclass && subclass != self
          subclass.new(*args, &block)
        else
          super
        end
```

## クラス名の決定
`subclass_from_attributes` メソッド内で、レコードの `inheritance_column` で指定される attributes の値を `find_sti_class` に渡している

メソッド: [ActiveRecord::Inheritance#subclass_from_attributes](https://github.com/rails/rails/blob/633e9745f8eafb0d1d5523ec761fdee420bcbc91/activerecord/lib/active_record/inheritance.rb#L221-L225)

```rb:lib/active_record/inheritance.rb#L221-L225
            subclass_name = attrs[inheritance_column] || attrs[inheritance_column.to_sym]

            if subclass_name.present?
              find_sti_class(subclass_name)
            end
```

`inheritance_column` は ModelSchema で定義していて ([ActiveRecord::Base が include している](https://github.com/rails/rails/blob/633e9745f8eafb0d1d5523ec761fdee420bcbc91/activerecord/lib/active_record/base.rb#L296))、 [デフォルトでは "type"](https://github.com/rails/rails/blob/633e9745f8eafb0d1d5523ec761fdee420bcbc91/activerecord/lib/active_record/model_schema.rb#L143) である

`find_sti_class` メソッドでは、所謂 type を使って constantize までする。
メソッド: [ActiveRecord::Inheritance](https://github.com/rails/rails/blob/633e9745f8eafb0d1d5523ec761fdee420bcbc91/activerecord/lib/active_record/inheritance.rb#L188-L194)

```rb:lib/active_record/inheritance.rb#L188-L194
        def find_sti_class(type_name)
          type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
          subclass = begin
            if store_full_sti_class
              ActiveSupport::Dependencies.constantize(type_name)
            else
              compute_type(type_name)
```

type_name を type_for_attribute で構築し直しているが、type_for_attribute が string じゃないことも一応あるのだろうか...

# 改造したいときは
## カラムを変える
inheritance_column メソッドをオーバーライドすればよいはず

## マッピングルールを変える
たとえば一般的なクラス名を string で入れておく使い方じゃなく、何か別の文字列を入れてクラス名にマッピングさせたいときは、 `find_sti_class` をオーバーライドすることで実現できるらしいです 
https://qiita.com/suusan2go/items/6da23826523744a74ba3
[Ionic]タブバーのアイコンを変更する

# 2018/04/29追記
もっと素晴らしい方法がありました。以下のリンクで紹介されています。
https://golb.hplar.ch/2018/01/Custom-SVG-icons-in-Ionic.html


## 以下、別の方法
Ionicでタブバーで独自のアイコンを利用したい時、CSSに記述すればよいと思います。


````css
.ion-ios-custom,
.ion-md-custom{
  content: url(../assets/icons/custom.svg);
  padding: 2px 0px 3px;
}

.ion-ios-custom-outline,
.ion-md-custom-outline{
  content: url(../assets/icons/custom.svg);
  padding: 2px 0px 3px;
}

````


上記で用意したCSSをtabIconで読み込みます。上記の場合は、customになります。
また、タブバーは選択時とそうじゃないときで表示が切り替わるのでoutlineも用意する必要があります。

````html
<ion-tabs>
  <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="custom"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>
````

以上です。

## タブバーのアイコンを動的に変更させる

tabIconの指定は唯の文字列であるため、プログラム側で変更するのが容易です。

````html
<ion-tabs>
  <ion-tab [root]="tab1Root" tabTitle="Home" [tabIcon]="custom"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>
````

````ts
@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {

  tab1Root = HomePage;
  tab2Root = AboutPage;
  tab3Root = ContactPage;

  custom:string = "custom";

  constructor() {

  }
  change(){
     this.custom = "home";
  }
}

````

上記のソースコードでは、customという変数に最初"custom"という文字列を格納しています。change()メソッドが呼ばれると"home"のアイコンに切り替わります。
HTMLの方は、tabIconを[tabIcon]にすることでcustomを変数として扱うようになります。


## アイコンのサイズについて

cssで直接指定することが可能です。

````css
.ion-ios-custom-outline,
.ion-md-custom-outline{
  content: url(../assets/icons/custom.svg);
  padding: 2px 0px 3px;
  width: 24px;
  height: 32px;
}
````


## ion-iconについて

カスタムアイコンはion-iconでも呼び出し可能です。

````html
<ion-icon name="custom"></ion-icon>
````
Unity2017で、Android(gradleビルド)で、起動後にある処理の部分でいきなりアプリが進まなくなった。。時の対処

```

//各アイテムのレコードUIを読み込み
GameObject prefab = (GameObject)Resources.Load("Prefabs/UI/Menus/Item_1");


Debug.Log("_____D_D17_4_2");
prefab.name = "Item_" + i.ToString();
Debug.Log("_____D_D17_5");


NGUITools.AddChild(scrollViewGridObj, prefab);// NGUIに追加
UiItemUpdate(prefab, category, i, true); // アイテム１個分のメニュー情報更新

```


_____D_D17_4_2　というログまでいかずにAndroid（gradleビルド）で、
アプリの進行が止まる。。（落ちはしない）


ただし、３分ぐらいした後、
起動する。

デフォルトのinternalビルドだと、普通に起動するのですが、、SDKの関係上gradleでやらなくてはいけず。。

また、同じシーンをsingletonで値をかえて画面を切り替えるようにしているのも、
ちょっと気になっていたが、そこも関係あるのか特定できず。。

原因が特定できず路頭に迷い。

NGUIアセットをアップデート、、 それでも駄目。


そして、**Unity2017 1.ｘ**　から　**Unity2017 2.x**にアップデート。。。！

すると、いままで起動時にとまっていたらアプリが無事動いた。。！！
３分→1秒にぐらいになった。。。！
なんだこれ。。

他にも多数SDKや、VR機能等いれていたので
そこらへんも影響していたのか不明ですが、、
これで無事解決！！！
自分のための備忘録。
pandasでjsonlを扱いたい時

## jsonlとは
jsonlとは、1レコードがjsonになっているファイルです。

フォーマットの例

```json
 {"title": "學問のすゝめ", "author": "福澤諭吉", "content": "天は人の上に人を造らず人の下に人を造らずと云へり。"}
 {"title": "人間失格", "author": "太宰治", "content": "私は、その男の写真を三葉、見たことがある。"}
 {"title": "銀河鉄道の夜", "author": "宮沢賢治", "content":"ではみなさんは、そういうふうに川だと言われたり、乳の流れたあとだと言われたりしていた、このぼんやりと白いものがほんとうは何かご承知ですか"}
```

## jsonlでの読み込み方法
pandasを使用して、jsonlを読み込みたい時は以下のようにします。

```python
df = pd.read_json('hogehoge.jsonl', orient='records', lines=True)
```

## jsonlでの出力方法
DataFrameから、jsonlで出力する時は、以下のようにします。

```python
df.to_json('hogehoge.jsonl', orient='records', force_ascii=False, lines=True)
```
Python3の環境をささっと整える(Mac版)

#概要
Qiita初投稿です。
私自身Python初心者なので、メモを兼ねて環境構築から丁寧に書いていきます。

#環境
- macOS High Sierra バージョン10.13

#環境構築
## Homebrewのインストール
様々なソフトウェアをMacにインストールするために使います。
[公式HP](https://brew.sh/)にかかれているコマンドを実行してインストールします。
`$ /usr/bin/ruby -e "$(curl -fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/insta``ll)"`

インストールが成功したかバージョンとともに確認
`$ brew -v`
`Homebrew 1.3.6`

## pyenvのインストール
Pythonのインストールとバージョン管理を行うソフトウェアです。
前述のHomebrewを使ってインストールします。
`$ brew install pyenv`

インストールが成功したかバージョンとともに確認
`$ pyenv -v`
`pyenv 1.1.5`


## Python 3.6.3のインストール
### pyenvを使ってPython 3.6.3をインストールします。
`$ pyenv install 3.6.3`

### 使用するPythonのバージョンを先程インストールした3.6.3にします。
`$ pyenv global 3.6.3`

### 現在インストールされているパイソンのバージョン一覧を確認します。
`$ pyenv versions`
```system
* 3.6.3 (set by /Users/あなたのユーザー名/.pyenv/version)
```
前述のコマンドで3.6.3を選択したので、3.6.3の前に*マークがついています。

# Hello world
**helloworld.py**を作成し、実行してみます。

```py3:helloworld.py
print("Hello world!")
```

```$ python helloworld.py
Hello world!
```

これで終わりです。お疲れ様でした。

# 感想
pyenvの他にrbenv(Ruby)も使っていますが、上記とほぼ同じフローで簡単にHello world!までたどり着けます。バージョン切り替えも楽です。

Python書きやすそうです。
Unity2017 2x でandroid端末だけメモリーエラーで落ちた際のメモ


## Androidのlogcatで、こんなエラーで、落ちる。

```
0-31 10:18:19.391 25006 25023 I Unity   : Firebase Analytics API Initializing
10-31 10:18:19.391 25006 25023 I Unity   :  
10-31 10:18:19.391 25006 25023 I Unity   : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
10-31 10:18:19.391 25006 25023 I Unity   : 
10-31 10:18:19.391 25006 25023 I Unity   : Firebase Analytics API Initialized
10-31 10:18:19.391 25006 25023 I Unity   :  
10-31 10:18:19.391 25006 25023 I Unity   : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
10-31 10:18:19.391 25006 25023 I Unity   : 
10-31 10:18:19.402 25006 25023 I Unity   : Firebase Cloud Messaging API Initialized
10-31 10:18:19.402 25006 25023 I Unity   :  
10-31 10:18:19.402 25006 25023 I Unity   : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
10-31 10:18:19.402 25006 25023 I Unity   : 
10-31 10:18:21.473 25006 25023 I Unity   : GameManager.GameInit
10-31 10:18:21.473 25006 25023 I Unity   :  
10-31 10:18:21.473 25006 25023 I Unity   : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
10-31 10:18:21.473 25006 25023 I Unity   : 
10-31 10:18:23.862 25006 25023 E Unity   : Unable to find kernel32.dll
10-31 10:18:23.957 25006 25023 I Unity   : tutorialSelectPageNum::::: start13
10-31 10:18:23.957 25006 25023 I Unity   :  
10-31 10:18:23.957 25006 25023 I Unity   : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
10-31 10:18:23.957 25006 25023 I Unity   : 
10-31 10:18:26.006 25006 25023 E Unity   : Could not allocate memory: System out of memory!
10-31 10:18:26.006 25006 25023 E Unity   : Trying to allocate: 872415232B with 16 alignment. MemoryLabel: DynamicArray
10-31 10:18:26.006 25006 25023 E Unity   : Allocation happend at: Line:524 in 
10-31 10:18:26.006 25006 25023 E Unity   : Memory overview
10-31 10:18:26.006 25006 25023 E Unity   : 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_DEFAULT ] used: 66115265B | peak: 66116289B | reserved: 67176054B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_TEMP_JOB ] used: 15521B | peak: 0B | reserved: 262144B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_TEMP_BACKGROUND_JOB ] used: 0B | peak: 0B | reserved: 1048576B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_GAMEOBJECT ] used: 465322B | peak: 465329B | reserved: 546661B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_GFX ] used: 3409023B | peak: 16160964B | reserved: 3414704B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_PROFILER ] used: 0B | peak: 0B | reserved: 0B 
10-31 10:18:26.006 25006 25023 E Unity   : [ ALLOC_TEMP_THREAD ] used: 32972B | peak: 0B | reserved: 3440640B 
10-31 10:18:26.006 25006 25023 E Unity   : 
10-31 10:18:26.006 25006 25023 E Unity   :  

```




## 原因が、何故か３DのAnimator＆Animationが原因で修正したら治った。
たった１つのオブジェクトで歩くだけのアニメーションなのに、、！汗

NGUIのアトラス画像や、テクスチャやリソースを断捨離してもだめだったのに、、


### 環境
> * max OSX sierra 
> * Unity2017 2.x 
> * grandleビルド
Xorshift のJuliaでの実装 (３２ビット版だけ）

#本日は

XorshiftのJulia版をやってみましょう．
前々からJuliaをやろうと思いながら重い腰を動かすのに時間がかかります．
グーグル先生にお尋ねしながらJuliaを書いていきました．
もう書き方の方針がわかっているので基本的な文法を抑えるだけで記述できてしまいます．

# 実装例

手元の環境はMacのSierra，Juliaはv0.5.1です．

```Julia
function xorshift32(seed=UInt32(2463534242))
    y = seed
    inner=function counter() 
    	y = y $ (y << 13) 
    	y = y $ (y >> 17)
    	y = y $ (y << 5)
    	return y
    end
    return inner
end

function uniform(generator,b=0.0,e=1.0)
	inner=function inner()
		value=b+generator()/typemax(UInt32)/(e-b)
		return value
	end
	return inner
end

function main()
	xor32=xorshift32()
	uniform01=uniform(xorshift32())
	N=10000000
	count=0
	for i = 1:N
		x=uniform01()
		y=uniform01()
		if x*x+y*y<1.0
			count+=1
		end
	end
	println("Pi=",4.0*count/N)
end

main()
```

良いJuliaの練習になりました．　

$でXORだそうです．　（追記：Juliaのバージョンが0.5.1の場合です．　コメント欄にも指摘されていますように将来的には使えなくなるようです．）

　結構素直にかけます．　Fortranを書いているんだと念じるとendの存在が自然に感じますが，Pythonに戻ると必要なのかこの子は・・・と感じるこの頃です． `uniform`　関数の中で引数がデフォルトだと自明な割り算 `/(e-b)` を行うことになりますが，デフォルトでしか用いない場合はこの割り算はしないほうが速度パフォーマンスが上がります．　

# 追記（パフォーマンス　2017/12/3）

上記の実装では私のMacBook１２inchでは１０秒ほどかかってしまいます．
遅い．遅すぎる．　Pythonに比べると速いのは間違い無いのですが・・・・．
と悶々していた時

@antimon2 さんの記事
[Julia Advent Calendar 2017 3日目　Julia で Closure のパフォーマンスを気にしてみる](https://qiita.com/antimon2/items/8d464d54cf2da6239635#comment-15d81289ee359ecc5c47)

にてパフォーマンスを改善するヒントを提示してくださいました．
最終的にはCでの実装に匹敵するスピードを出してくれたのでとても勉強になりました．
クライアントOS・サーバーOS・ホストOS・ゲストOS

「クライアントOS」「サーバーOS」「ホストOS」「ゲストOS」この4つの言葉を聞いた時は、頭のなかでごちゃごちゃになっていたが理解できたので記しておきます。

<h1>ホストOS</h1>
仮想機械ソフトウェア(VirtualBoxなど)を直接動かしているOSのことを「ホストOS」と呼ぶ。

<h1>ゲストOS</h1>
ホストOSの元で動かしている仮想機械ソフトウェアが「あたかもそこに実在するかのようにみせてくれる仮想機械」の上で動かすのが「ゲストOS」

<h1>クライアントOS</h1>
ゲストOSとしてUbuntuを動かしたとして、そこでブラウザーを起動すればそのブラウザーはWebアプリケーションのクライアントとして動かせます。そのときはそのUbuntuはクライアントとして位置づけられるので「クライアントOS」とも呼べる。

<h1>サーバーOS</h1>
一方、Ubuntuの上でTomcatなどのWebアプリケーションサーバーを動かしたとしたら、そのアプリケーションへ接続するクライアントブラウザーからみてこのUbuntuはサーバーということになるので「サーバーOS」とも言える。

<h2>文脈による</h2>
「サーバー」という言葉は、Tomcatのようなサーバーアプリケーションを指す場合や、そのサーバーアプリケーションを動かしているサーバーOSや、さらにサーバーOSを動かしているサーバー計算機を指すことがあります。
MySQLで品番や郵便番号などの文字列をハイフン区切にする関数「INSERT」

数字などだけで構成された値をハイフン区切にする方法を紹介する。

## INSERT関数の使用例

7桁の郵便番号にハイフンを入れる例。

```sql
SELECT INSERT('0001111', 4, 0, '-')
```

```実行結果
+------------------------------+
| INSERT('0001111', 4, 0, '-') |
+------------------------------+
| 000-1111                     |
+------------------------------+
1 row in set (0.00 sec)
```

これは`INSERT()`という関数で`INSERT`文とは異なる。(Googleで検索しずらい)

## 一般化

最初に紹介したユースケースでの`INSERT()`関数の用法を一般化すると次のようになる。

```sql
SELECT INSERT(ハイフン区切にしたいカラム名, 何文字目の手前に入れるか, 0, '-')
```

## 参考

* [MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.5 文字列関数](https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html#function_insert)
秘密鍵を WIF 形式に変換する処理を Python で実装する

# はじめに

巷でビットコインやブロックチェーンというものが流行っているみたいですね。流行に乗り遅れないように (今さらとか言わないでね :joy:)、最近 [ビットコインとブロックチェーン](http://amzn.asia/gu8mU1V) という本を読み始めました。

この本の中で WIF 形式 (Wallet Import Format) というフォーマットが登場しました。ビットコインのウォレットでは秘密鍵をこの形式で扱います。今回、復習を兼ねて秘密鍵を WIF 形式に変換する処理を Python で実装してみました。

# 実装

具体的には Bitcoin Wiki の [Wallet import format](https://en.bitcoin.it/wiki/Wallet_import_format) というページに書かれている内容をコードに起こしました。

```python
from base58 import b58encode, b58decode
from binascii import hexlify, unhexlify
from hashlib import sha256
import unittest


def encode_private_key_as_wif(private_key):
  """
  秘密鍵 (16 進数文字列) を WIF 形式に変換する。
  """

  # 先頭の 0x80 は秘密鍵をエンコードする際の version byte を表す。
  key = '80' + private_key
  tmp = key
  
  # SHA-256 関数を 2 回適用する。
  tmp = sha256(unhexlify(tmp)).hexdigest()
  tmp = sha256(unhexlify(tmp)).hexdigest()

  # 末尾の 8 バイトをチェックサムとする。
  checksum = tmp[0:8]

  wif_private_key = b58encode(unhexlify(key + checksum))

  return wif_private_key


def decode_wif_private_key(wif_private_key):
  """
  秘密鍵 (WIF 形式) を 16 進数文字列に変換する。
  """
  tmp = hexlify(b58decode(wif_private_key)).decode('utf-8')
  # version byte とチェックサムを取り除く。
  private_key = tmp[2:-8]

  # b58decode の代わりに b58decode_check を使う場合
  # tmp = hexlify(b58decode_check(wif_private_key)).decode('utf-8')
  # private_key = tmp[2:]

  return private_key


def verify_checksum(wif_private_key):
  """
  秘密鍵のチェックサムを検証する。
  """
  b58decoded = hexlify(b58decode(wif_private_key)).decode('utf-8')
  tmp = b58decoded[:-8]
  tmp = sha256(unhexlify(tmp)).hexdigest()
  tmp = sha256(unhexlify(tmp)).hexdigest()

  return b58decoded[-8:] == tmp[:8]


class WIFTest(unittest.TestCase):
  """
  WIF 形式に関する関数の動作を検証するための単体テスト。
  検証のための値は https://en.bitcoin.it/wiki/Wallet_import_format から借用している。
  """

  def test_encode_private_key_as_wif(self):
    private_key = '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d'
    wif_private_key = encode_private_key_as_wif(private_key)

    self.assertEqual('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', wif_private_key)

  def test_decode_wif_private_key(self):
    wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
    private_key = decode_wif_private_key(wif_private_key)

    self.assertEqual('0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d', private_key)

  def test_verify_checksum(self):
    valid_wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
    invalid_wif_private_key = 'SHueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'

    self.assertTrue(verify_checksum(valid_wif_private_key))
    self.assertFalse(verify_checksum(invalid_wif_private_key))


if __name__ == '__main__':
  unittest.main()
```

この Python スクリプトを実行するには `base58` というライブラリが必要です。

```
$ pip install base58
```

なお、スクリプトを実行すると [unittest](https://docs.python.jp/3/library/unittest.html) による単体テストが動きます。

```
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK
```

# 参考

* [Bitcoin Wiki » Wallet import format](https://en.bitcoin.it/wiki/Wallet_import_format)
Jenkins CLIを利用してビルドの表示名、説明を設定する

# はじめに
Jenkins CLIを利用してビルド表示名、説明を設定する方法について調べたので備忘録として投稿させていただきます。

# やりたかったこと
- Jenkinsのビルド中に表示名、説明を更新する
- POST(curlコマンドなど)を利用せずに実現する

# Jenkins CLIの配置場所

POST(curlコマンドなど)を利用せずにビルド表示名、説明を更新するためにJenkins CLIを利用しました。

Jenkins CLIはJENKINS_HOME配下の`war/WEB-INF/jenkins-cli.jar`に配置されてます。
`http://<Jenkinsのアドレス：ポート>/cli`にアクセスして、Jenkins CLIページからDLすることも可能です。

Jenkins CLIページでは利用可能なコマンドのヘルプを閲覧することも可能です。

![jenkins01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/99b2b6f7-ded7-e9cc-1c1a-6aa2e13f366f.png)

# -sオプションについて

ヘルプなどでは`-s`オプションでJenkinsのURLを指定してますが、`Jenkinsの管理 > システムの設定 > Jenkinの位置 > Jenkins URL`が設定済みであれば省略可能です。

![jenkins02.png](https://qiita-image-store.s3.amazonaws.com/0/141934/c9f5c131-6f08-c63a-199b-320dcfa7b403.png)

```shell-session:JenkinsURL未設定
$ java -jar jenkins-cli.jar -s http://<Jenkinsのアドレス：ポート> help
```

```shell-session:JenkinsURL設定済み
$ java -jar jenkins-cli.jar help
```

# コマンド

Jenkins CLIページにビルド表示名、説明の設定方法が記載されているので、これを参考にシェルスクリプトを設定します。

```shell-session:ビルド表示名(set-build-display-name)
java -jar jenkins-cli.jar -s http://xxx.xxx.xxx.xxx/ set-build-display-name JOB BUILD# DISPLAYNAME
ビルドの名称を設定します。

 JOB         : Name of the job to build
 BUILD#      : Number of the build
 DISPLAYNAME : DisplayName to be set. '-' to read from stdin.
```

```shell-session:ビルド説明(set-build-description)
java -jar jenkins-cli.jar -s http://xxx.xxx.xxx.xxx/ set-build-description JOB BUILD# DESCRIPTION
ビルドの説明を設定します。

 JOB         : Name of the job to build
 BUILD#      : Number of the build
 DESCRIPTION : Description to be set. '=' to read from stdin.
```

## シェルスクリプト

今回はビルドしているジョブ自身の表示名、説明を更新するので、`ビルドから利用可能な環境変数`を利用して以下のようなシェルスクリプトを設定しました。

```shell-session
JENKINS_CLI=$JENKINS_HOME/war/WEB-INF/jenkins-cli.jar

java -jar $JENKINS_CLI set-build-display-name $JOB_NAME $BUILD_NUMBER "設定したいビルド表示名"
java -jar $JENKINS_CLI set-build-description $JOB_NAME $BUILD_NUMBER "設定したいビルド説明"
```
![jenkins04.png](https://qiita-image-store.s3.amazonaws.com/0/141934/51e54376-505d-391c-2b53-4da95bd3d41e.png)

ビルドを実行すると`ビルド履歴`にシェルスクリプトで設定した表示名、説明が表示されるようになりました。

![Jenkins03.png](https://qiita-image-store.s3.amazonaws.com/0/141934/d615bd7a-097a-d1e5-3f7b-a7e5ab36ceb5.png)
アプリアイコンを実機で確認する

アプリのアイコンデザインを実機で確認する方法が探してもあまり見つからず，これまではIkonicaというアプリがあったのですが何故かなくなっていたので，備忘録として残します．

##用意するもの

* サーバー
* iPhoneやAndroidなどの端末

##準備
サイズは大きいほどいいですが今回は180*180pxでアイコンを用意します．
![スクリーンショット 2017-10-31 18.34.48.png](https://qiita-image-store.s3.amazonaws.com/0/210654/a4cf1b01-d00e-d867-18d3-a65d6fdd8437.png)

##サーバにアップロード
アイコンを書き出し，サーバーにアップしてください．
![スクリーンショット 2017-10-31 18.38.36.png](https://qiita-image-store.s3.amazonaws.com/0/210654/69cd35d7-7e15-91b0-d0d4-92770a288ba3.png)

##htmlを記述する
同じ階層にhtmlファイルを作成し，以下のように記述してください．

```html:index.html
<html>
　<head>
　　<link rel="apple-touch-icon" href="icon.png" sizes="180x180">
　</head>
</html>
```

細かい設定はこちらのサイト様を参考してください．
https://mamewaza.com/support/blog/favicon2017.html


##実機でアクセスし，ホーム画面に追加する
![IMG_2087.PNG](https://qiita-image-store.s3.amazonaws.com/0/210654/f4f53816-9823-f423-b817-6b3d3ac290b0.png)

![IMG_2088.PNG](https://qiita-image-store.s3.amazonaws.com/0/210654/e3acb2cb-9e1c-3342-758a-1fe8f5622a91.png)


##成功
![IMG_2089.PNG](https://qiita-image-store.s3.amazonaws.com/0/210654/92aae580-af58-bd29-3e1b-549d8d3c28fa.png)
PKCS12から証明書・秘密鍵をGet

# はじめに
グローバルサイン社をはじめ、サーバ証明書取得の際にPKCS12ファイルでサーバ証明書が提供される場面があります。
証明書と秘密鍵をセットにしてくれていますが、どうもコマンドを覚えてられないので備忘録です。


# 秘密鍵
１．openssl コマンドがインストールされているサーバ上にPKCS12ファイルをアップします。
２．まずは秘密鍵から取り出します。

```
# openssl pkcs12 -in <PKCS12ファイル> -nocerts -nodes -out <任意の秘密鍵ファイル名>
Enter Import Password: <パスワード>
MAC verified OK

<sample>
# openssl pkcs12 -in CEDS123456789012.pfx -nocerts -nodes -out ssl.key
Enter import Password: *********
MAC verified OK
```

上記取り出したファイルのヘッダー部分は、削除しましょ。

```
Bag Attributes
    localKeyID: AA BB CC DD EE FF GG HH II JJ KK LL MM NN OO PP QQ RR SS TT
Key Attributes: <No Attributes>
```



# 証明書

```
# openssl pkcs12 -in <PKCS12ファイル> -clcerts -nokeys -out <任意の証明書ファイル名>
Enter Import Password:<パスワード>
MAC verified OK

<sample>
openssl pkcs12 -in CEDS123456789012.pfx -clcerts -nokeys -out ssl.crt
Enter Import Password:*********
MAC verified OK

```

上記取り出したファイルのヘッダー部分は、削除しましょ。

```
Bag Attributes
    localKeyID: AA AA AA AA 11 11 11 11 11 AA AA AA AA AA AA AA AA AA AA AA
subject=/OU=Domain Control Validated/CN=****.abc.com
issuer=/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA - SHA256 - G2
```


# 中間証明書
```
# openssl pkcs12 -in <PKCS12ファイル> -cacerts -nokeys -out <任意の証明書ファイル名>
Enter Import Password:<パスワード>
MAC verified OK

<sample>
openssl pkcs12 -in CEDS123456789012.pfx -cacerts -nokeys -out ca_root.crt
Enter Import Password:*********
MAC verified OK

```

秘密鍵、証明書同様にヘッダー情報を削除しましょ。
※ 中間証明書は、2つ続けて記載があるため、ヘッダー情報は頭と真ん中の2か所にあります。



あとは、適用するだけ！！
MariaDBへ接続する時にPerl or PHPからアクセスできなかった事の解決

Debian9などはMariaDBがインストールされるので、これを機にまじめに設定してみたらPerl or PHPでアクセスできないので調べてみました。
結果的には**「UNIX_SOCKET Authentication Plugin」**がデフォルトで有効になっているため、rootではもちろん、他のアカウントでも手順を踏まないとアクセスできないってことでしたねー。

参考）https://jyn.jp/ubuntu-16-04-mariadb-password-bug/#MariaDB

今回は**UNIX_SOCKET**を使用せずに通常のパスワード認証でアカウントを作成したので、コンソールよりmariadbにログインし、おもむろに下記を実行します。
**ユーザー名は揃える必要がある**ので、Apacheの実行権限が「*hogehoge*」とした場合、下記のコマンドになります。

```mysql
CREATE USER hogehoge@localhost IDENTIFIED BY 'passwd';
```
作成したアカウントに対して、unix_socketが付与されていないことを確認します。

```mysql
select user,host,password,plugin from mysql.user; 
+------------+-----------+-------------------------------------------+-------------+
| user       | host      | password                                  | plugin      |
+------------+-----------+-------------------------------------------+-------------+
| root       | localhost | *FDLK+LSDKFLD+FDMFDSFDSFKDSLFKDLSFKDL+FKD | unix_socket |
| hogehoge   | localhost | *dsadsdsdsdsdsadsadKSDJSIDASDLSDLSDSDSADJ |             |
+------------+-----------+-------------------------------------------+-------------+
```
この状態だとデータベースの作成権限がないため、データベースが無いと相変わらず**access denied**なので、データベースを作成する権限を付与します。

```mysql
grant all on *.* to 'hogehoge'@'localhost';
```

セキュリティー上、より強固になったような気がします！（all on \*.\* ですけど）
node.js 環境を構築する際のコマンド

https://qiita.com/seibe/items/36cef7df85fe2cefa3ea を見ながらWSL上にNode.js環境を作った際のメモ。

# インストール
# node.js のインストール
n package を使って node.js をインストール後、古い node.js を削除。

```bash
sudo apt -y nodejs npm
sudo npm cache clean
sudo npm install n -g
sudo n stable
sudo apt purge -y nodejs npm
```

残しておきたい依存関係だけ、手動でインストールしたとマーク。

```bash
sudo apt-mark manual libfreetype6 gyp libssl-dev libssl-doc python-pkg-resources zlib1g-dev
```

いらない依存関係を削除。

```bash
sudo apt -y autoremove
```

## yarn のインストール
https://yarnpkg.com/en/docs/install#linux-tab の指示に従ってインストール。

```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install -y yarn
```

無理やり古い node.js が入れられるので削除。

```bash
sudo apt purge -f libuv1 nodejs
```


# n コマンド
```bash
sudo n        # インストールされているバージョンを表示
sudo n stable # 安定版をインストールし有効化
sudo n latest # 最新版をインストールし有効化
sudo n lts    # LTS版をインストールし有効化
sudo n 8.8.0  # 指定したバージョンをインストールし有効化
sudo n rm lts # 指定したバージョンを削除
sudo n prune  # 今使っているバージョン以外を削除
```
create-react-appをインターネット非接続の環境にインストール

1. インターネットに接続しているマシンで、node-v8.8.1-linux-x64.tar.gz を展開
 
2. 以下のような設定ファイルを作成して source env.sh

```bash:env.sh
export NODE_HOME=/data/hoge/node-v8.8.1-linux-x64
export PATH=$NODE_HOME/bin:$PATH
export NODE_PATH=$NODE_HOME/lib/node_modules/npm/node_modules
```
3. npm init
4. npm install react-scripts
5. npm install create-react-app
6. その他のパッケージをインストール

----
7. インストール先のマシンで同様にnode-v8.8.1-linux-x64.tar.gz を展開
8. env.shをインストール先の環境に合わせてパスを設定
9. npm init
10. インターネットに接続しているマシンでインストールしたパッケージ群が3-6の操作を行ったディレクトリのnode_modules以下に入っているので丸ごとインストール先にコピー
11. npm listで確認
Project Euler Q17 【数字の文字数】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
1 から 5 までの数字を英単語で書けば one, two, three, four, five であり, 全部で 3 + 3 + 5 + 4 + 4 = 19 の文字が使われている.

では 1 から 1000 (one thousand) までの数字をすべて英単語で書けば, 全部で何文字になるか.

注: 空白文字やハイフンを数えないこと. 例えば, 342 (three hundred and forty-two) は 23 文字, 115 (one hundred and fifteen) は20文字と数える. なお, "and" を使用するのは英国の慣習.

## 解答

```bash
seq -w 1000 |
sed 's/10$/ ten/' |
sed 's/11$/ eleven/' |
sed 's/12$/ twelve/' |
sed 's/13$/ thirteen/' |
sed 's/14$/ fourteen/' |
sed 's/15$/ fifteen/' |
sed 's/16$/ sixteen/' |
sed 's/17$/ seventeen/' |
sed 's/18$/ eighteen/' |
sed 's/19$/ nineteen/' |
sed 's/1/ one /g' |
sed 's/2/ two /g' |
sed 's/3/ three /g' |
sed 's/4/ four /g' |
sed 's/5/ five /g' |
sed 's/6/ six /g' |
sed 's/7/ seven /g' |
sed 's/8/ eight /g' |
sed 's/9/ nine /g' |
sed 's/0/ zero /g' |
sed -r 's/ zero  ([^ ]*)  (.*)/\1 hundred and \2/' |
sed 's/ two  / twenty /' |
sed 's/ three  / thirty /' |
sed 's/ four  / forty /' |
sed 's/ five  / fifty /' |
sed 's/ six  / sixty /' |
sed 's/ seven  / seventy /' |
sed 's/ eight  / eighty /' |
sed 's/ nine  / ninety /' |
sed '1000s/.*/one thousand/' |
sed 's/ and zero  zero//' |
sed 's/ zero  / /' |
sed 's/ zero $//' |
sed 's/zero hundred and//' |
tr -d ' ' |
awk '{s+=length}END{print s}'
21124
```

英語にするまでがクッソ大変。
英語にしてしまえば一瞬。

※英語にせずに桁数でやるやり方も考えたが、数値なのか桁数なのかごっちゃになるし、自分で書いていてよく分からなくなるのでやめた。

## 答え合わせ
こちらのサイト様と一致していればOKとした。
http://kingyojima.net/pje/017.html
Chrome でアクセスしたページをコンソールで取得する

Google Chrome でアクセスしたページをPC上に HTML ファイルで保存したい時のやり方のメモ書き。

Extension不要パターンです。

## 1. URLを普通に curl で叩く

よくやる方法。ログインした後のページとかでは取ってこれない。

```
> curl https://qiita.com/a_yasui/items/825bb769e07f6e8d21cf > test.html
```

## 2. Copy as cURL

見たいページを開く前に、右クリック→`検証`で開発者パネル？を開きます。そこにある `Network` タブを開いてから、見たいページを開きます。

`Name`欄に読み込んでいくのがわかるかと思いますので、見たいページを選んで右クリック→`Copy`→`Copy as cURL` を選べば、クリップボードに全ての情報が付いた`curl`コマンドが入ります。

![out.gif](https://qiita-image-store.s3.amazonaws.com/0/1054/4760079f-c2d2-b140-dd29-7bf47ff63879.gif)
Ubuntu の ufw で NAT サーバを作る

Ubuntu では ufw という「簡単に iptables を扱えるようにラップしたツール」が入っていて、iptables を使ってよくやることはおよそ ufw で設定することができる。

今回は ufw を使って Ubuntu が NAT[^nat] サーバとして動くように設定したのでその手順をメモしておく。

[^nat]: 正確には NAPT (IP マスカレード)

## NAT の設定
OS は Ubuntu 18.04 でやった。

### SSH を許可する
ufw を有効にした際に SSH が拒否されるとログインできなくなってしまうので許可しておく。

``` console
# ufw allow ssh
```

### フォワーディングを許可する
``` :/etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
```

``` :/etc/ufw/sysctl.conf
net/ipv4/ip_forward=1
```

### ルーティングの方法を定義する
``` :/etc/ufw/before.rules
*nat
-F
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/16 -j MASQUERADE
COMMIT
```

`-F` があると `ufw reload` を複数回やっても NAT 設定が重複しなくなる。

NIC が複数ある場合は `-o eth0` のように指定する。

### ufw を有効にする
``` console
# ufw enable
```

### ちゃんと設定されているか確認する
``` console
# iptables -t nat -nL
```

## AWS の場合
- NAT 用の EC2 インスタンスを作る
    - パブリックサブネットに作る (= グローバル IPv4 アドレスを割り当てる)
    - インスタンスサイズは t2.nano でも動くっちゃ動く
    - ネットワーク設定で「送信元/送信先の変更チェック」を無効にする
- 送信元となるリソースが所属するプライベートサブネットのルートテーブルを設定する
    - デフォルトルート `0.0.0.0/0` を NAT 用 EC2 インスタンス (の NIC) 宛に飛ばす

## Azure の場合
- NAT 用の VM を作る
    - VM は NAT 用のサブネット内に作る (少なくとも NAT のアクセス元となるリソースとは別のサブネットにする必要がある)
    - グローバル IPv4 アドレスを割り当てる
    - NIC の設定で IP 転送を有効にする
    - NIC の NSG (ネットワークセキュリティグループ) で以下の2つの通信を許可する
        - 受信: VirtualNetwork → Internet
        - 送信: Internet → VirtualNetwork
- アクセス元となるリソースが所属するサブネットのルートテーブルを設定する
    - デフォルトルート `0.0.0.0/0` を NAT 用 VM (プライベート IPv4 アドレス) 宛に飛ばす
既存のRails & Vue.js (Webpacker) アプリをDockerで動かす

[個人ブログ](http://tackeyy.com/)をRailsとWebpackerを使ってVue.jsで運用しています。
最近メインマシンをMackBookProからThinkPadT470sに移したのはいいですが、
環境構築だるいなーということでDockerで動かすようにしました。

こちらのプルリクを見てもらうとだいたいわかると思います。
https://github.com/tackeyy/blog/pull/200/files


# 前提

- 既存のアプリをDockerで動かせるようにします
- Railsの起動はforemanを使っており、foreman startでRailsが起動するようになっています

# 環境

```
$ docker-compose version
docker-compose version 1.16.1, build 6d1ac21
docker-py version: 2.5.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016
```

# 1. Dockerファイル作成

```diff
+FROM ruby:2.4.1
+LABEL maintainer 'tackeyy'
+
+# Set environment variables
+ENV LANG C.UTF-8
+ENV ROOT_PATH /blog
+
+# Install essential libraries
+RUN apt-get update && apt-get install -y build-essential libpq-dev
+
+# Install node.js
+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
+    apt-get install nodejs
+
+# Install yarn
+RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
+    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
+    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
+    apt-get update && apt-get install -y yarn
+
+# Fix: 'Cannot find module 'node-sass'
+RUN yarn add node-sass
+
+# Move to root
+RUN mkdir $ROOT_PATH
+WORKDIR $ROOT_PATH
+
+# Bundle install
+ADD Gemfile $ROOT_PATH/Gemfile
+ADD Gemfile.lock $ROOT_PATH/Gemfile.lock
+RUN bundle install
+
+# Install foreman
+RUN gem install foreman
+
+ADD . $ROOT_PATH
```

# 2. docker-compose.yml作成

```diff
+services:+version: '2'
+services:
+  db:
+    image: mysql:5.7
+    ports:
+      - "4306:3306"
+    environment:
+      MYSQL_USER: "root"
+      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
+  web:
+    build: .
+    command: foreman start
+    volumes:
+      - .:/blog
+    ports:
+      - "5000:5000"
+      - "8080:8080"
+    depends_on:
+      - db
 ```

# 3. docker-compose.ymlに記載したサービスのビルド

` $ docker-compose build `

# 4. DB/テーブル/初期データ作成

` $ docker-compose run web rake db:create db:migrate db:seed_fu `

# 5. コンテナとサービスの起動

` $ docker-compose up `

これで ` localhost:5000 ` にアクセスすればOKです。
mysqlコマンドのSELECTで枠線を非表示するsilentオプション

MySQLでは`mysql`コマンドで`SELECT`文を発行すると枠線をつけて結果を出力してくれる。このように:

```bash
❯ mysql -uroot mydb -e 'SELECT id FROM mytable'
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
```

出力を眺めるだけならこれで問題ない。しかし、出力結果をシェルスクリプトで処理するような場合はもっとシンプルな出力が理想的。

出力から枠線を消すオプションに`--silent`がある。

```bash
❯ mysql -uroot mydb -e 'SELECT id FROM mytable' --silent
id
1
2
3
```

更にヘッダ行も不要な場合は`--skip-column-names`オプションをつけると良い。

```bash
❯ mysql -uroot mydb -e 'SELECT id FROM mytable' --silent --skip-column-names
1
2
3
```

どちらのオプションも短縮形で指定することもできる。`--silent`は`-s`、`--skip-column-names`は`-N`になる。

```bash
❯ mysql -uroot mydb -e 'SELECT id FROM mytable' -sN
1
2
3
```

ちなみにSELECT文をシェルの`for`で回すときは次のように書ける。

```bash
for ID in $(mysql -uroot mydb -e 'SELECT id FROM mytable' -sN)
do
 echo "id ... $ID"
done
```

```txt:出力結果
id ... 1
id ... 2
id ... 3
```
Unity2017からProfilerのTCPポートが34999に変わった件

UnityEditorから"Build & Run"している場合は関係ないんですが、コマンドラインビルドで生成したapkをAndroid実機で実行してPC直結でプロファイリングするには、ひと手間かかります。

…が、なんと、その手順がUnity2017からこっそり変わっています。

```Unity5.6
adb forward tcp:54999 localabstract:Unity-{insert bundle identifier here}
```
https://docs.unity3d.com/560/Documentation/Manual/ProfilerWindow.html

```Unity2017.1
adb forward tcp:34999 localabstract:Unity-{insert bundle identifier here}
```
https://docs.unity3d.com/ja/current/Manual/ProfilerWindow.html

※{insert bundle identifier here}はPlayer Settingsで設定したPackage Name(旧Bundle Identifier)で置き換え。
※Unity起動前に実行しないと反映されないので注意。

分かります？ adb.exeでトンネリングするTCPポート番号が54999から34999に変わっています。最初は誤記かと思ったんですが、確かに変更しないと繋がりませんでした。んなもん分かるかー！！

コネタでした。
BigQueryで継続率を計算する


ある日に来た人のデータがあれば、継続率を計算できます。
BigQueryなので富豪的になってます。
適当に編集して使ってね。



```sql:継続率の計算

#standardSQL
WITH 
-- 日毎のユーザーアクセス
DUU_HISTORY AS (  
  SELECT 
  USER_ID, -- 数値型 
  DATE       -- 日付型
  FROM --  ユーザーIDとアクセス日が記録されたテーブルを書いてね
),
-- 継続日の定義
CONTINUATION_DAYS AS (
  SELECT 
    DAY -- 継続日  
  FROM  UNNEST(
  ARRAY[1,3,7,14,30] --　継続率を出したい継続日を書いてね
  ) DAY 
),
--初回訪問
FIRST_VISIT AS (
  SELECT 
    USER_ID,  --ユーザーID 
    MIN(DATE) DATE    -- 初回訪問日
  FROM DUU_HISTORY GROUP BY USER_ID 
),
-- 初回訪問日と継続日の表現
DATE_PIVOTS AS (
  SELECT 
    DATE FIRST_VISIT_DATE, --初回訪問日  
    CONTINUATION_DAYS,      --継続日数
    DATE_ADD(DATE, INTERVAL CONTINUATION_DAYS DAY) VISIT_DATE   --訪問日 
  FROM (
    SELECT DAYS.DATE DATE, CONTINUATION_DAYS.DAY CONTINUATION_DAYS FROM ( SELECT DATE FROM DUU_HISTORY GROUP BY DATE ) DAYS
    CROSS JOIN CONTINUATION_DAYS )
  WHERE DATE_DIFF(CURRENT_DATE(), DATE_ADD(DATE, INTERVAL CAST(CONTINUATION_DAYS AS INT64) DAY), DAY ) > 0 
),
--初回訪問したユーザーがある日に来訪したかの表現
CONTINUATION_HISTORY AS(
  SELECT
    DATE_PIVOTS.FIRST_VISIT_DATE FIRST_VISIT_DATE,   --初回訪問日  
    DATE_PIVOTS.CONTINUATION_DAYS CONTINUATION_DAYS,   --継続日数
    CASE
      WHEN FIRST_VISIT.USER_ID = DUU_HISTORY.USER_ID THEN FIRST_VISIT.USER_ID
      ELSE NULL
    END CONTINUATION_USER_ID,  --　継続ユーザーのID
    FIRST_VISIT.USER_ID FIRST_VISIT_USER_ID   -- 初回訪問ユーザーのID
  FROM
    DATE_PIVOTS
  LEFT OUTER JOIN
    FIRST_VISIT
  ON
    DATE_PIVOTS.FIRST_VISIT_DATE = FIRST_VISIT.DATE
  LEFT OUTER JOIN
    DUU_HISTORY
  ON
    DATE_PIVOTS.VISIT_DATE = DUU_HISTORY.DATE
  GROUP BY
    FIRST_VISIT_DATE,
    CONTINUATION_DAYS,
    FIRST_VISIT_USER_ID,
    CONTINUATION_USER_ID 
), 
-- 継続率
RETENSION AS (
SELECT
  FIRST_VISIT_DATE,   --初回訪問日  
  CONTINUATION_DAYS,  --継続日数
  COUNT(DISTINCT FIRST_VISIT_USER_ID) FIRST_VISIT_USERS,  --初回訪問日のユーザー数
  COUNT(DISTINCT CONTINUATION_USER_ID) CONTINUATION_USERS,  --継続日のユーザー数
  100 * COUNT(DISTINCT CONTINUATION_USER_ID) / COUNT(DISTINCT FIRST_VISIT_USER_ID) RETENSION  --継続率
FROM
  CONTINUATION_HISTORY
GROUP BY
  FIRST_VISIT_DATE,
  CONTINUATION_DAYS
)

SELECT * FROM RETENSION



```

こんなかんじで出ます。

- 初回来訪日
- 経過日数
- 初回来訪日のUU数
- 経過日の再来訪UU数
- 継続率

| Row | FIRST_VISIT_DATE | CONTINUATION_DAYS | FIRST_VISIT_USERS | CONTINUATION_USERS | RETENSION |
|:-:|:-:|:-:|:-:|:-:|:-:|
| 1 | 2017-09-21 | 1 | 100 | 50 | 50.0 |
| 2 | 2017-09-21 | 3 | 100 | 30  | 30.0 |
| 3 | 2017-09-22 | 1 | 100 | 40  | 40.0 |
Google Cloud Speech APIを使って音声をテキストへ変換する

iMacの内蔵マイクから入力した声を、Google Cloud Speech APIを使ってテキストに変換する例です。
日本語に対応しています。

参考にしたページ（ありがとうございます）
http://blog.fun-multicores.tokyo/p/blog-page_12.html

# 検証した環境
* PC:iMac (21.5-inch, Late 2013)
* OS:macOS High Sierra

# インストールするもの
* Node  
https://nodejs.org からダウンロード
* Sox  
`brew install sox`

# その他
GoogleアカウントをGoogle Cloud Platformに登録する（上記URLを参考に設定し、jsonファイルをダウンロードする）
環境変数を作っておく

```
export GCLOUD_PROJECT=プロジェクト名
export GOOGLE_APPLICATION_CREDENTIALS="jsonファイル名"
```

# 実行に必要なファイル
* package.json
* ***.json（上記の環境変数で設定したファイル）
* test.js

package.jsonのあるディレクトリで`npm install`すること。

# 実行方法

`node test.js`

マイクに向かって喋るとテキスト化されて表示される。

# コード

```package.json
{
  "name": "test",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "scripts": {
    "test": "cd ..; npm run st -- --verbose speech/system-test/*.test.js"
  },
  "dependencies": {
    "@google-cloud/speech": "0.9.0",
    "@google-cloud/storage": "1.0.0",
    "node-record-lpcm16": "0.3.0"
  },
  "engines": {
    "node": ">=4.3.2"
  }
}
```

```test.js
const record = require('node-record-lpcm16');
const speech = require('@google-cloud/speech');
const speechClient = speech();
const SAMPLE_RATE = 16000

const request = {
  config: {
    encoding: 'LINEAR16',
    sampleRateHertz: SAMPLE_RATE,
    languageCode: 'ja-jp'
  }
};

const recognizeStream = speechClient.createRecognizeStream(request)
  .on('error', console.error)
  .on('data', (data) => {
    console.log(data.results);
  });

record.start({
  sampleRate: SAMPLE_RATE,
  thresholdStart: 0.2, // silence threshold to start recording, overrides threshold
  thresholdEnd: 0.1, // silence threshold to end recording, overrides threshold
  silence: '0.1' // seconds of silence before ending
}).pipe(recognizeStream);
```
crowi ファイルアップロード機能追加時にファイル名文字化け edge

### crowiにファイルアップロード機能追加時にファイル名文字化け

chromeだと文字化けしない。
Microsoft edgeだと文字化けする
phpに以下を追記することによりファイル名の文字化けを回避できる

header('Content-Disposition: attachment; filename*=UTF-8\'\''.rawurlencode("管理表_$_GET[y]_$_GET[m].csv"));

headerメソッドとresponseメソッドとで記載が異なる
responseメソッド
$app->response->headers->set('Content-Disposition', 'attachment; filename='.$filename);

参考にしたサイト
headerメソッド
https://github.com/netcommons/NetCommons2/issues/126
responseメソッド
https://qiita.com/takehironet/items/79c025e4140e29c57abe
Xcode9でリモートリポジトリをBitbucketに指定する。

## リモートリポジトリ作成
Bitbucketでリポジトリ名「sample」を作成

## Xcode

<img width="270" alt="Sample.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/99731/dc46c348-95c6-319d-c47d-208c85d30b7d.jpeg">

<img width="307" alt="スクリーンショット_2017-10-31_16_54_54.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/99731/fdef190d-5781-63ff-e88e-63b9cc789d4a.jpeg">

https://ユーザー名@bitbucket.org/ユーザー名/リポジトリ名.gitを入力

<img width="479" alt="スクリーンショット_2017_10_31_17_00.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/99731/1668b491-509c-5e44-89e8-1a81d29538f9.jpeg">

## プッシュ

### Passwordはログイン時に使うパスワード

<img width="531" alt="スクリーンショット_2017_10_31_17_01 2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/99731/d1b17d98-789e-bc60-e416-c6aee84005f6.jpeg">
5分でasync/awaitを使ったナウい書き方を覚える


# 概要

nodejsのasync/awaitについてサンプル付きで簡単にまとめました。
'こまけぇこたぁとりあえず良いんだよ' の精神。

# 環境

```:version
v8.2.0
```

# 超 雑感
先ずは雑に、なんとなく。動かしてみる。

### async
- 関数の前に `async` と付けて関数を定義できる。
- `async` と付けて定義すると中で `await` を使うことが出来る。
		
```js:promiseで包む
function sample() {
    return new Promise((resolve, reject) => {
    	// 超絶怒涛の処理
    		resolve();
    });
}
```

```js:async
async function asyncSample(){
	// 空前絶後の処理
    return;
}
```

### await
- `async` を付けた関数の中で生きられる
- promiseで包んだ関数に `await` を付けて宣言できる
- 関数が `resolve ` か `reject` するまで待つ

```js:await
async function asyncSample(){
	let await promisedFnction();
    return;
}
```

promisedFnction()の中で __resolve/reject__ するまで待ちます。

## sample

DynamoDBおじさんなのでAWS-SDKを使ったDynamoDBへのQueryをサンプルにします。

### スクリプトの説明
１回のqueryでは全件出力できない時、DynamoDBは `LastEvaluatedKey` という項目を返します。
次のリクエストの際に `ExclusiveStartKey` に先程入手した `LastEvaluatedKey` をセットすると前回の続きからデータを取得することが出来ます。
これをasync/awaitを使って記述します。

```javascript:index.js
'use strict';

const aws = require('aws-sdk');
const dy = new aws.DynamoDB.DocumentClient({
    region: 'ap-northeast-1'
});

const hashKeyId = '123456789012';



main(hashKeyId)
    .then(v => {
        console.log('[END] main function response data: ', v);
    })
    .catch(e => {
        console.log('[END] main function response error data: ', e);
    });


async function main(hashKeyId) {
    let params = {
        TableName: 'dynamodb_table_name',
        KeyConditionExpression: "#hash = :val",
        ExpressionAttributeNames: {
            "#hash": "hash_key_name"
        },
        ExpressionAttributeValues: {
            ":val": hashKeyId
        }
    };

    try {
        let response = await doQuery(params);
        let results = response.data;

        while (response.LastEvaluatedKey) {
            results.concat(response.data);
            params.ExclusiveStartKey = response.LastEvaluatedKey;
            response = await doQuery(params);
        }
        results.concat(response.data);
        return results.length;
        
    } catch (e) {
        //console.log('[ERROR] catch error object: ', e);
        throw new Error(e);
    }
}

function doQuery(parameter) {
    return new Promise((resolve, reject) => {
        dy.query(parameter, (err, data) => {
            if (err) {
                //console.log('[ERROR] DynamoDB Query Error: ', err);
                reject(err);
            } else {
                //console.log('[INFO] DynamoDB Query data: ', data);
                if (data.LastEvaluatedKey) {
                    resolve({data: data.Items, LastEvaluatedKey: data.LastEvaluatedKey});
                } else {
                    resolve({data: data.Items});
                }
            }
        });
    });
}
```


#### 再帰処理書くのくっそ楽


# 参考
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

- https://qiita.com/soarflat/items/1a9613e023200bbebcb3
naming > 画像(とUIを)二倍に拡大 > zoom | enlarge | resize | expand

```txt:動作環境
C++ Builder XE4
```

表示(とクリック入力UI)部分を二倍に拡大する処理を実装完了した。

「二倍に拡大する」という機能の変数名や関数名が気になった。

## zoom

### X2 ZOOM


@ Radar Navigation and Maneuvering Board Manual
> X2 ZOOM key

### zoom in

[C-765 Ultra Zoom; QuickStart Guide](http://cs.olympus-imaging.jp/en/support/imsg/digicamera/download/manual/zoom/qsg_c765uz_e.pdf)
4b. zooming
画像の説明

> Push to Zoom out
> Pull to Zoom in
...
Pull the zoom lever toward T to choose telephoto shooting and get closer to the action.

### enlarge

https://www.merriam-webster.com/dictionary/enlarge

http://answers.unity3d.com/questions/581917/zoom-enlarge-gameobject-.html

### resize

https://www.merriam-webster.com/dictionary/resize

[OPenCV 3.0.0-dev documentation](https://docs.opencv.org/3.0-beta/modules/imgproc/doc/geometric_transformations.html?highlight=enlarge#resize)

### expand

https://processing.org/reference/expand_.html
> Description: 	Increases the size of an array. By default, this function doubles the size of the array, but the optional newSize parameter provides precise control over the increase in size.
構造化データ

# 構造化データ
AMP(accelerated mobile pages)をリッチカードとして表示するためには、構造化データが必要なので投稿いたします。

## 構造化データとは
サイト内の情報を、クローラが収集・解釈できるように、htmlに追記する補足情報

昨今、AMPの登場とSEOの観点から、重要視されている。

## ボキャブラリ
構造化データの規格のこと

- [schema.org](http://schema.org/docs/schemas.html)（Google推奨）
- [openGraph](http://ogp.me/)（SNSで多用）

この二つが代表的。 

## シンタックス
構造化データの記述方法のこと

ツールなら

- データハイライター
- 構造化データマークアップ

自分で書くなら

- microData
- JSON-LD
- RDFa
- Microformats
- OGP(facebook, lineなど)
- Twitterカード(twitter)

## 記述例

### microData

```html
<div>
        <div>
          <ol itemscope itemtype="http://">
            <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
              <a itemprop="item" href="">リスト１</a>
              <meta itemprop="position" content="1">
            </li>
            <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
              <a itemprop="item" href="">リスト２</a>
              <meta itemprop="position" content="２">
            </li>
            <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
              <a itemprop="item" href="">リスト３</a>
              <meta itemprop="position" content="３">
            </li>
          </ol>
        </div>
      </div>
```

（これは、パンくずリスト）
### JSON-LD

```html
<script type="application/ld+json">
{
  "@context":"http://schema.org",
  "@type":"BreadcrumbList",
  "itemListElement":[
    {
      "@type":"ListItem",
      "position":1,
      "url":""
    },
    {
      "@type":"ListItem",
      "position":2,
      "url":""
    },
    {
      "@type":"ListItem",
      "position":3,
      "url":""
    }
 ]
}
</script>
```

（これもパンくずリスト）
### OGP（openGraphProtocolの略、プロトコルなのでシンタックスではないのかも）

```html
<meta property="og:title" content="" />
<meta property="og:type" content="" />
<meta property="og:url" content="ページURL" />
<meta property="og:image" content="サムネイル画像URL" />
<meta property="og:site_name" content="webサイト名" />
<meta property="og:description" content="ページのディスクリプション" />
 ```

### Twitter Cards（OGPの記述も必要）

```html
<meta name="twitter:card" content="カードの種類">
<meta name="twitter:site" content="@[Twitter ID]">
```
 
ちなみに
facebookページ内だけだが、instant articleがあり、１０倍の速さでWebページを表示する。
Practice Recursive function

再帰関数を利用した出力問題

ex) Recursive(5);

5 4 3 2 1 
4 3 2 1 
3 2 1 
2 1 
1

[answer]

void Recursive(int n)
{
  if (n < 1) return;
  for(int i = 0; i < n; i++) {
     printf("%d ", n - i);
  }
  printf("\n");
  Recursive(--n);
}
NSURLのクエリー情報をNSDictionaryに変換する

```:objective-c
@interface NSURL (nsUrlWithQuery)
-(NSDictionary *)queryAsDictionary;
@end

@implementation NSURL (nsUrlWithQuery)

- (NSDictionary *)queryAsDictionary {
    NSLog(@"in queryAsDictionary");
    NSArray *components = [[self query] componentsSeparatedByString:@"&"];
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    for ( NSString *component in components ) {
        NSArray *keyAndValues = [component componentsSeparatedByString:@"="];
        [parameters setObject:[keyAndValues objectAtIndex:1] forKey:[keyAndValues objectAtIndex:0]];
    }
    return parameters;
}

@end
```

```:objective-c
NSDictionary *query = [[NSURL URLWithString:urlString] queryAsDictionary];
NSLog(@"query: %@", query);
```