OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS7, PHP7 から昔のOracleに繋ぎたい

#環境

CentOS 7.5 PHP 7.2.11 Oracle 10.2.0.5

#とりあえず

Laravel 5.7 を使いたかったので、PHP 7.1.3以上が必要
せっかくなので、現時点での最新安定版 PHP 7.2.11 を入れる

https://qiita.com/inakadegaebal/items/b57cf10339978d638305

```.bash
yum install epel-release
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum install --enablerepo=remi,remi-php70 php php-devel php-mbstring php-pdo php-g
```

Oracleを使うにはoci8とかいうのを入れる必要があるらしい（あとあと揉める）

```.bash
yum install php72-php-oci8
```

さっくり入る
ただしこの段階で php 動かすとエラーが出る

```.bash
PHP Warning:  PHP Startup: Unable to load dynamic library 'oci8' (tried: /usr/lib64/php/modules/oci8 (/usr/lib64/php/modules/oci8: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/oci8.so (libclntsh.so.18.1: cannot open shared object file: No such file or directory)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'pdo_oci' (tried: /usr/lib64/php/modules/pdo_oci (/usr/lib64/php/modules/pdo_oci: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/pdo_oci.so (libclntsh.so.18.1: cannot open shared object file: No such file or directory)) in Unknown on line 0
```

クライアント入れないといけない感じ

#Oracleのクライアント入れる

なお、oracleのサーバとクライアントのバージョンが離れすぎてると動かないので注意
https://www.oracle.com/jp/system-requirement/interoperability-support-195844-ja.html

以下から、対応したバージョンの
・instant client package basic
・instant client package sdk
をDLしてインストール
https://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

oracle instant client を rpm で入れる場合、インストール先に注意
https://mike-neko.github.io/blog/oracle-cent/

#Oracleのクライアントに対応したPHP拡張

めでたくOracleのクライアントは入ったけど、こっちが用意したのは10.2.0.5
php拡張はなんか18を要求してて困る
どっか設定で変更できるのかと思ったけどぜんぜんない
yum install php-oci8 した場合、問答無用で oracle18用のoci8が入ってしまうっぽい
手動でインストールする必要がありそう

php公式からtar.gzをダウンロード、拡張を個別に作り直し
https://qiita.com/asano_yuki/items/24fd22412057338093ae

dtraceを有効にしておく（すごくハマる）
https://mike-neko.github.io/blog/oracle-cent/

p.s.ノーサポートだけど、最新のクライアントでも昔のサーバつなげるっぽい（18でも10いけたぽ）
[NUXT] 画面遷移リンクの作成方法2つ

## `<router-link>` を使う

```index.vue
<router-link to="/">トップへ</router-lnk>
```

## `$router.push` を使う
プログラム上での画面遷移には `$router.push` を使うので、これを使うこともできる。

```index.vue
<a @click="$router.push('/')">トップへ</a>
```
[NUXT] error  Elements in iteration expect to have 'v-bind:key' directives  vue/require-v-for-key の対処法

## 解決法
NUXTで `v-for` を回す時には `v-bind:key` でkey属性を渡してあげないとエラーになる。
Vue.js自体がこれを推奨してるっぽいけど、Vue.jsではエラーにはならなかったような気もする。

### 参考
https://vuejs.org/v2/guide/list.html#key
MoshiでDate型をjson変換するときのカスタムアダプター

##やりたいこと

[Moshi](https://github.com/square/moshi)を使ってjson変換するとき、`Date`型を任意のパターン(例えば`yyyy/MM/dd HH:mm:ss`)に変換したい。

ちなみにjsonに変換したいクラスのメンバにDate型があり、Moshiのアダプターに何も設定しないと、以下のエラーが出ました。

```
java.lang.RuntimeException: Unable to create application xxxxxx: java.lang.IllegalArgumentException: Platform class java.util.Date (with no annotations) requires explicit JsonAdapter to be registered
```

プリミティブ型以外はアダプターが必要そうな。

ただMoshiが提供している`Rfc3339DateJsonAdapter`アダプターを使うと `2015-09-26T18:23:50.250Z`みたいなStringになってしまい、これを任意のパターンに変換したい。

参考：[moshi/adapters](https://github.com/square/moshi/tree/master/adapters)

※本記事ではkotlinで説明します

##実現方法

###結論

**カスタマイズしたJsonAdapter(DateJsonAdapter)を実装**して、以下のようにMoshiのビルダーにアダプターを加える。

```kotlin
val moshi = Moshi.Builder().add(Date::class.java, DateJsonAdapter()).build()
```

###DateJsonAdapterの実装

以下は、 `Date`を`yyyy/MM/dd HH:mm:ss`に変換する場合です。

参考 : [Rfc3339DateJsonAdapter.java](https://github.com/square/moshi/blob/master/adapters/src/main/java/com/squareup/moshi/adapters/Rfc3339DateJsonAdapter.java)

```kotlin

import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import java.text.SimpleDateFormat
import java.util.*

class DateJsonAdapter: JsonAdapter<Date>() {

    private val dateFormat = "yyyy/MM/dd HH:mm:ss"
    private val sdFormat = SimpleDateFormat(dateFormat, Locale.JAPAN)

    @Synchronized
    @Throws(Exception::class)
    override fun fromJson(reader: JsonReader): Date  {
        val string = reader.nextString()
        return sdFormat.parse(string)
    }

    @Synchronized
    @Throws(Exception::class)
    override fun toJson(writer: JsonWriter, value: Date?) {
        writer.value(sdFormat.format(value))
    }

}

```

以上
Qiitaの始め方

※最初に投稿背景を載せてます。興味の無い方は次項から読み進めて下さい。

本記事の投稿主ですが、これまでインプット一辺倒であまりアウトプットしてこなかったため
その練習も兼ねてと、Qiitaに記事を投稿させて頂く事になりました。

これまでのQiitaとの関わり方は、ネットで情報収集してる際に検索ヒットする
何やら緑色の背景で黒い部分にコマンドが載ってるデザインのページだなという印象でした。
(まさか自身が投稿する側になるとは何処で縁があるか分からないものです。)

この度利用を始めさせて頂くにあたり、意外にもユーザ登録方法について簡単に書かれた記事が
投稿されていないように見えたので「まだコードは書けないけどこれなら・・・！」
との思いで書いたのが今回の記事になります。

# はじめに
ここではQiitaに興味を持ち、使い始めるにはどうすれば良いか？ 
との疑問を解消するための説明を載せています。 

まず、Qiitaは記事を読むだけであればユーザの登録等は不要でそのまま利用出来ます。

しかし、ユーザ登録すると興味のある新着投稿記事を自動で纏めて表示する 
**タグフィード**や、気に入った記事を纏めて見返す際に役立つ**ストック**
投稿された記事への**コメント**や自身でも記事の**投稿**が可能と、個人利用の範囲だけで無く
他ユーザとの交流、アウトプット面での機能も拡充されますので、気軽に試して頂ければと思います。 

本記事が読んで頂いた方の助けになれば幸いです。

# ユーザ登録のやり方
## ユーザ登録
まずは、ユーザ登録に進みます。
QiitaのTopページ右上の**ユーザ登録**ボタンを押下して下さい。 
![ユーザ登録1](https://qiita-image-store.s3.amazonaws.com/0/297123/f211ec4a-e979-1a76-13ea-16dc0e588e81.png)

するとユーザ登録画面が表示されます。 

![ユーザ登録2](https://qiita-image-store.s3.amazonaws.com/0/297123/2a346a14-4337-5e12-4d35-e0e74466dec4.png)

Qittaで利用するアカウント登録には以下4種類の方法がありますので 
お好みの方法で、画面の指示に従い登録を進めていきましょう。

- GitHubアカウントを連携して登録
- Twitterアカウントを連携して登録
- Googleアカウントを連携して登録
- Qiita用に新しいアカウントを作成して登録(※要メールアドレス)

### 用語解説(GitHub)
GitHubとはソフトウェア開発プロジェクト向けにWeb上で利用出来るソースコード管理サービスを指します。 
ソースコードを介し、日々開発者同士での交流がワールドワイドに行われていますので、こちらにも興味があればアカウントを作成しQiitaと連携して登録しておくと、自身で作成したソースコードの公開にも役立ちます。
[GitHub公式](https://github.co.jp/)

## タグをフォロー
ここでは自分の興味がある分野(ワード)について**タグ**という形で登録(フォロー)します。 
Qiitaでは投稿主が記事を投稿する際に最低でも1つのタグが付けられるため
ここでタグをフォローする事で**フォローしたタグが付いた記事=自分が興味を持ちそう**な 
記事を探すのに役立ちます。 
また、フォローしたタグが付けられた記事は纏めてタグフィードから閲覧出来ます。　
タグは後からでも登録出来るので、フォローしたいタグが無い場合は無視して進んでも問題ありません。
タグの登録が終わったら**Qiitaの利用を開始する**を選択してください。

![ユーザ登録3](https://qiita-image-store.s3.amazonaws.com/0/297123/e8286218-fbc5-6b6e-dbc7-f3966f27a385.png)


# 最後に
ここまで読んだ方ならQiitaを利用し始めてみたものの、使い方はどうすれば？ 
との疑問も沸いてくるかと思います。 
Qiitaの使い方としてはザックリと分けて、記事の閲覧・投稿の2つになりますが 
そちらについてはQiitaさんのサポートページに載っていますので参照頂けますと幸いです。
[Qiitaの使い方](https://help.qiita.com/)
[aftereffects] コピペで使えるスクリプト  3Dレイヤーの位置を乱数配置　

#コピペ用

複数の３Dレイヤーの位置（ポジションXYZ）を乱数でランダムに配置
乱数のmaxはrandom(num)のnum引数で渡す

![bandicam 2018-10-31 10-42-06-861.jpg](https://qiita-image-store.s3.amazonaws.com/0/178061/c19ec59b-d4e6-d0d2-f79c-3520679889fd.jpeg)

```jsx
//グローバル変数
var myComp =  app.project.activeItem;
var myLayer = myComp.selectedLayers;
//メソッド
function random (num){
    var random = Math.floor( Math.random() * (num+1) );
    return random;
}


for ( var i = 0 ; i < myLayer.length ; i++ ){
    var myPos = myLayer[i].property("ADBE Transform Group").property("ADBE Position");
    myPos.setValue([random(1920),random(1080),random(5000)])
}
```
jsdoでreact,vue,angular

#概要

jsdoでreact,vue,angularを無理やり、やってみた。

#react

http://jsdo.it/ohisama1/wIXcX

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18104/6a38ba27-ba1d-e4bd-c574-78caed58fbde.png)


#vue

http://jsdo.it/ohisama1/YH95

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18104/cc762f9c-13bb-3395-88ae-17e8fe227519.png)


#angular

http://jsdo.it/ohisama1/Ik5R

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/I/k/5/Ik5R.jpg?t=1540857326)


#結論

ノーサンキュー

以上。
pythonのモジュールをインストールする

pythonモジュールのインストールについて扱うページです．

本記事は一応WindowsOSベースで記述していますが，UNIX系OSでも流れはほとんど同じです．

本記事内で <ほげほげ> と書かれていたら，ケースにより文字列が違ってくることを意味します．

記事の抽象度を上げるために，「おそらく類似ケースすべてに適用できる手続き」のみを記載していますので，細かいケースのエラーに対するリカバーは当記事では行えません．ご容赦ください．

#正直これでどうにかなる

pythonはすでに導入済みであることを想定しています．

コマンドプロンプト立ち上げてこれを打つと，ほぼ確実に成功します．

```
pip install <module-name>
```

バージョン互換性ミスったので消したい，という方はこちら

```
pip uninstall <module-name>
```



さすがにこれだけだと記事にする価値がまったくないので，
pipだとうまくいかなかったりする場合についての説明を加えます．

私の環境ではC/C++のファイルをpythonのファイルへ変換しているようなモジュール，
具体的にはpyOpenCLやpyCUDAあたりはpipでどうにもなりませんでした．

そこで，「GitHubからフォルダごと持ってきて自分でビルドする」方法を以下に記述します．

# 自分でビルドする

ここからは「C/C++の関数をpythonで使えるようにする系のモジュール」に絞った記述です．

C/C++のコンパイラが後々必要になるので，Visual C++のランタイムを入れておいてください．

gitも必要です．gitはお好きな方法で入れてください．
(zipもらってきてもいいんですが，どちらにせよ後でシェル叩くことになるので最初からシェルでいいんじゃないかなー，という考えです)

gitを入れたらPowerShellなりgit bashなりでPythonモジュールのあるディレクトリに移動します．
(多分，\<YourHomeDir>\AppData\Local\Programs\Python\Python\<Version>\Lib\site-packages\)

そうしたら，欲しいパッケージ名でググってGitHubページへ移動します．
GitHubページのやや右上あたりに「Clone or Download」という緑のボタンがあるのでそこをクリックします．
アドレスが出ますので，それを控えてから，シェルを次のように叩きます．

```
git clone --recursive <adress>
```

--recursiveはサブモジュールがあったら一緒に引っ張ってきてくれるオプションです．

引っ張ってきたら，モジュールのディレクトリが増えているので次のように叩きます．

```
cd <moduleName>
python configure.py
```

こうすると，ディレクトリ内にsiteconf.pyというファイルが新しく生成されています．
お持ちのエディタで開いてこんな記述を探してください．

```siteconf.py
CL_INC_DIR = ['<必要なヘッダのパスをここに']
CL_LIB_DIR = ['<必要なlibのパスをここに']
```

入れたいモジュールが「もともとC/C++の関数をpythonで使えるようにする系」であるならば書いてあります．
元のC/C++ライブラリをインストールしてきて，"<headername>.h" "<libname>.lib"というファイルを探してきます．

上のCL_INC_DIRにヘッダファイルのパス，下のCL_LIB_DIRにlibのパスを書きます．

そうしたらファイルを保存，シェルを次のように叩きます.

```
python setup.py build
```

すると文字列がダーッと出てきます．
ここで，なんだか「プログラムを止めたければCtrl-Cを押してね」的な文言と一緒に
プログラムがカウントダウンを始めた場合，Ctrl-Cを押して中断して，文言を読んでください．
大抵は，「この作業をやってないからビルドはきっと失敗するよ」と言っています．
文章をよく読んで指示に従ってから，上述のコマンドを打ち直してください．
(コマンドが書かれていたらそれを反射で打ち込んでいいと思います)

ビルドが始まると大量にwarningが出てきますが，たいていは無視していいです．
途中でビルドに失敗したら，エラーをよく読んでください．
大抵「ヘッダファイルがない」か「libファイルがない」のどちらかです．
対応するファイルを先ほど指定したパスの下に入れて(本当はよくないけど...)やり直します．

ビルドに成功したら，最後の仕上げです．次のコマンドを打ちます．

```
python setup.py install
```

これで，pythonで使えるモジュールが生成されます．

#おわりに

正直なところ，直接ビルドするのはとっても厳しかったです．
何しろ，普通であればpipの一行で済むことに対して

* コンパイラの準備
* 対応ヘッダとライブラリの準備
* コマンドラインの扱い
* (英語)
* (エラー対処力)

あたりが必要になってきます．

本記事は最初に述べた通り，細かいケースの対応力がないため
実際のところはモジュールの導入で困っている方の助けにはならないかと思われます．

ただ，抽象的に「大体こんな流れです」というページが個人的に欲しかったので書きました．
ざっくりとした知識程度に受け取っていただければ幸いです．
Golang 配列にメソッドを追加する

# はじめに
配列にメソッドを追加しようとしたら，つまずいたのでメモ．
# やりたいこと
Humanにしゃべらせたい

```golang
type Human struct {
	Name string
}

func (h *Human) Speak(word string) {
	fmt.Printf("I am %s. %s!\n", h.Name, word)
}

func main() {
	bocchi := Human{
		Name: "kafu",
	}
	bocchi.Speak("Hi everyone!!!\n")
}
```
これでもいいけど，ひとりじゃかわいそう!!!

```shell-session
❯go run main.go
I am kafu. Hi everyone!!!!
```


# やったらできなかったこと
配列に定義する．
型が定義されていないと言ってくる．

```golang
func (people []Human) Speak(word string) {
	for h := range people {
		fmt.Printf("I am %s. %s!\n", h.Name, word)
	}
}
```

# やったらできたこと
~~type alias を使う．~~※追記参照
type構文を使う．

```golang
type People []Human

func (people People) Speak(word string) {
	for h := range people {
		fmt.Printf("I am %s. %s!\n", h.Name, word)
	}
}

func main() {
	bocchi := Human{
		Name: "kafu",
	}
	bocchi2 := Human{
		Name: "Bob",
	}

	people := People{}
	people = append(people, bocchi)
	people = append(people, bocchi2)

	people.Speak("Hello!!!")

}
```
これでみんなしゃべるようになります．

```shell
❯go run main.go
I am kafu. Hello!!!!
I am Bob. Hello!!!!
```

# ※追記(type構文とalias構文について)
当初，type構文のことをalias(別名)のようなものだと勘違いしていたのですが，どうやら違うようです．
以下はalias構文というのを使って，会話させようとするコードです．

```golang
// alias構文
type People = []Human

func (people People) Speak(word string) {
    for _, h := range people {
    fmt.Printf("I am %s. %s!\n", h.Name, word)
}
```
=を間に入れただけですが，これでは動きません．「[]Humanは定義されていない型だよ」と言ってきます．ここから察するに，type構文では完全に型を別のものにし区別しますが(そして定義もする)，alias構文では型を区別せず，ただ単にコード上で別の名前が使えるようになるものだとわかります．

例えると，aliasというのは，500円玉2枚は1000円札1枚と交換可能であるようなことを言い，
typeというのは，自動販売機の札を入れるところに500円玉を入れようとすると，形が違うので入らないという感じでしょうか．(違ったらごめんなさい(-_-;))

# 参考文献
[Goを学びたての人が誤解しがちなtypeと構造体について #golang](https://qiita.com/tenntenn/items/45c568d43e950292bc31#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)
[go言語1.9で追加予定の新機能 型エイリアス](https://qiita.com/weloan/items/8abbb4003cfa1031a9e9)
macOS High SierraでSciLabを動かす覚書


## 手順

1.[http://www.scilab.org](http://www.scilab.org)からMac用のバイナリをダウンロードする。
2.JREあるいはJDKをインストールしていないときには、インストールする。
3./Library/Java/JavaVirtualMachines/jdk_'jdkバージョン'.jdk/Contents/Info.plistを書き換える（ルート権限が必要）。


Info.plist中の



```xml:Info.plist
    <key>JVMCapabilities</key>
    <array>
            <string>CommandLine</string>
    </array>
```

を下記に書き換える。


```xml:Info.plist
    <key>JVMCapabilities</key>
    <array>
            <string>BundledApp</string>
            <string>CommandLine</string>
            <string>JNI</string>
    </array>
```


## 参考
[Modifying Oracle’s Java SDK to run Java applications on OS X](https://derflounder.wordpress.com/2015/08/08/modifying-oracles-java-sdk-to-run-java-applications-on-os-x/)
[macOS High SierraでSciLabを動かすまで](https://qiita.com/0x20FE/items/2ba5e60685816485ea4c)
スマホでColaboratory

# Colaboratoryの特徴
Colaboratoryに関する情報は、[tomo_makes](https://qiita.com/tomo_makes)さんの[【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)にまとめられている。今回スマホで使う上で関係しそうな特徴をピックアップする 

* Google提供のJupyter notebook実行環境
* Webブラウザよりアクセス
* ９０分のアイドリング（セッション切れ）でランタイムダウン
* 連続稼働時間１２時間でランタイムダウン
* Google Driveへの接続（マウント）可能
* ランタイムのスペック(Ubuntu 18.04 2vCPU:2.2GHz RAM:13GBa)

# スマホで使う
## 普通の使い方（PC）
一般的かどうか分からないが、私の使い方としては、PCのWebブラウザからColaboratory上で、制限時間内（１２時間以内）に終了するように計算を実施する。合わせてWebブラウザのオートリロード(アドインなど）機能によりセッションが切れないようにリロードを繰り返す。計算終了後、結果ファイル・リスタートファイルをGoogle Driveに保存する。
以上のように使っているが、これをそのままスマホで行う場合、下記課題が想定される。

* **バッテリー消費と月末の通信量制限**  
オートリロードによるバッテリー消耗が激しいと思われる。事実上オートリロードができないなら、９０分を超える計算やビルドは不向き。通信量についてはリロードによる通信のほか、バックグラウンドのデータ通信が心配。  
* **打鍵できない**  
標準キーボードではShiftキーやTabキーがなかったり。Markdownで使う記号も不足していたり。
フルキーボードのアプリによる打鍵は、指サイズ問題により押したいキーを押せない。  
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/7fb2f128-2ebc-4422-4545-b954b676fa69.png width=200px> <img src=https://qiita-image-store.s3.amazonaws.com/0/132571/aedc7c3e-9737-6b3b-252b-0a62b9c0ea0b.png width=150px>

常時電源接続＋Bluetoothキーボードなど、上記の課題を解決できれば、PCでの利用方法をそのまま置き換えた使い方が可能と思われる

## おすすめの使い方
### ライブラリのチュートリアルを実行する
お試しとして使うことに主眼を置く。以下の手順によりGitHubリポジトリにuploadされているnotebookをColaboratory環境で実行することができる。

 1. **[https://colab.research.google.com](https://colab.research.google.com) にアクセス**  
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/d711d724-a69b-ce43-7224-cdb206d3edc1.png width=150px>
 2. **Googleアカウントでログイン**  
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/ef263449-b536-f3f3-0f8b-228d4ade6762.png width=150px><img src=https://qiita-image-store.s3.amazonaws.com/0/132571/e3c257f0-3d22-f994-c45a-8e13879799c7.png width=150px>
 3. **メニューより「ノードブックを開く」を選択**  
※新規のnotebookを作成したい場合は、メニューより「Python3の新しいノートブック」を選択  
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/d9d45d61-09f0-0297-d0f8-685f7ce9e3a4.png width=150px><img src=https://qiita-image-store.s3.amazonaws.com/0/132571/527ab00c-46ee-38ef-8401-086b1c14c905.png width=150px>
 4. **GitHubのリポジトリを指定する**  
GitHubユーザ名もしくはリポジトリURLを入力。今回はおもむろにTatsuyaKatayamaのGPyOpt-testリポジトリのGPyOpt-test.ipynbを選択    
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/12b26046-1052-af30-00f6-38b089e5eb6f.png width=150px>
 5. **必要なライブラリ(パッケージ)のインストールスクリプトの実行**  
※今回はnotebook中に記載済み  
※実行時に警告やランタイムのリセットを促される場合がある。  
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/64868c33-0f23-bc09-3870-92731c9ffd91.png width=150px>
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/adf2a98b-889c-630a-aa0d-7807436ec515.png width=150px>
<img src=https://qiita-image-store.s3.amazonaws.com/0/132571/91f5d230-e6e8-dd00-f9a8-d22842b83d73.png width=150px>
 6. **コードの実行をしたり、コードを変更したり、引数をいじったりして楽しむ**  
※コードの実行は5で示したようにインプットセルの左にある[]をタップ。もしくはインプットセル内でShift+Enter。

尚、直接[http://colab.research.google.com/github/TatsuyaKatayama/GPyOpt-test](http://colab.research.google.com/github/TatsuyaKatayama/GPyOpt-test)にアクセスすれば4から実行できる（別途ログインは必要）

# まとめ
* スマホからColaboratoryを使う場合
  + 長時間の計算は困難（バッテリー・通信量制限に難あり）
  + 打鍵がつらい
  + ライブラリのお試し環境として使う方法をまとめた
[書評]サーバレスアプリケーション開発ガイド

書籍名 : Amazon Web Servicesを使ったサーバレスアプリケーション開発ガイド
著者 : 西谷圭介

#はじめに

数年前私がオンプレミスのサービスの管理をしていた時、インフラの運用管理は日々の仕事の中で常々解放されたいことの一つでした。

その後クラウド化の流れの中で「サーバレスアーキテクチャ」という考え方があることを知り、言葉から連想される解放感と格好良さに飛びついてしまったのですが、その不得意分野や注意すべき点の気づきがあり、過去の考え方からの転換が必要だと感じることが多々ありました。

最近では少し慣れてきたと思っていましたが、まだまだ触れたことのない新しいサービスや考えもしなかった組み合わせがあることを知り、学び直すため一冊読んでみようと思って『サーバレスアプリケーション開発ガイド』を購入しました。

#概要

目次は次のとおりです

> １　サーバーレスアプリケーションの概要
２　Ａｍａｚｏｎ　Ｗｅｂ　Ｓｅｒｖｉｃｅｓ（ＡＷＳ）利用の準備
３　インフラを自動化しよう
４　Ｔｗｉｔｔｅｒのリアルタイム分析をしよう
５　写真投稿サイトをシングルページアプリケーションで作ろう
６　サーバーレスアプリケーションのライフサイクル管理
７　サーバーレスアプリケーションのトラブルシューティング

初めてAWSに触れる人でもサーバレスアプリケーションの構築に着手しやすいように、AWSアカウントの取得方法やAWS CLIの使い方から書かれていて、最近よく見るワークロードやユースケースについて基本的に手を動かしてサンプルアプリケーションを作っていきながら詳しく知ることができるように記述されていました。

また、作って終わりではなく、実際にプロジェクトで長く運用していくためのノウハウや管理運用方法まで書かれていて、CloudWatchを使ったメトリクスの確認方法、トラブルシューティングとしてX-Rayの利用方法で締めくくられています。

なお、AWSコンソールの使い方は最低限で、ほとんどAWS CLIを使った記述となっています。
すべてのソースは書籍のサイトからダウンロードできるようです。
AWSはサービス更新頻度が多いため最新のドキュメントと照らし合わせて見ることは必須だと思います。


#感想

Chapter5の写真投稿サイト構築が面白かったです。

API Gateway、Lambda、DynamoDBを使った一般的なAPIの構築と、クライアントアプリ側はVue.jsを使ったSPAを作る手順が詳細に記載されていました。

Lambdaはリクエストのたびに作られるコンテナであることからDB接続におけるコネクションプールの実装が難しく、RDBMSとの相性が良くありません。これは例えばキャッシュの実装が難しいなども同様の理由であり、Lambdaがステートレスであることを理解しておく必要があります。

そして、S3からイベント駆動でLambdaを経由してAmazon Rekognitionで画像解析をする例が出てきます。Rekognitionは思っていたほど導入の敷居が高くない印象で興味深かったですが、それ自体よりも「イベント」について考えさせられました。
S3からのイベント駆動はPushモデルですが、KinesisやDynamoDBをイベントソースとするPullモデルではLambdaがそれらへポーリングしてイベントを取得します。サーバレスをどう活かすか、どのように応用するかを考える時に、このイベントの使い方、特徴を知っておくことが重要であると改めて感じることができました。

#まとめ

サーバレスの利点を知り楽しむことができる良い書籍でした。
サーバレスはまだまだこれからの技術で、サービスの組み合わせで面白いことができそうだと思っています。
AWS re:Invent2018ではどんなサービスが発表されるか楽しみです。
Android StudioでRiot(チャットアプリ)の開発(設定)

#はじめに
Androidアプリの開発に興味を持ったため、メモ程度で書いていきます。
※注　Android開発は現在進行形で勉強中です。（2018年10月時点）

#Android Studioのインストール方法
とりあえず、Androidの開発に必要なAndroid Studioのインストールについて。
（Windows環境です）
※これからスマホアプリ開発をやっていきたい方は、Macをお勧めします。

とりま、Android Studioをダウンロードしましょう。
![1_ダウンロード画面.png](https://qiita-image-store.s3.amazonaws.com/0/300540/5fde71d9-2f3c-2512-09af-30213675c599.png)

～ちょっと省略（後々追記）～

---
##RiotをGitHubからダウンロードして、AndroidStudioで動かすまでに発生した問題。

####問題１．なんかあった気がするけど、忘れちった('ω')

####問題２．コンパイル時にFirebaseへの接続？エラーが出る。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Could not find firebase-iid-interop.aar (com.google.firebase:firebase-iid-interop:16.0.0).
Searched in the following locations:
    https://jcenter.bintray.com/com/google/firebase/firebase-iid-interop/16.0.0/firebase-iid-interop-16.0.0.aar
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Firebaseが見つかりませんよ。ってことだと思っている。
Firebaseってなんだ？（#^ω^）
　→モバイルやWebのバックエンド処理をやってくれるサービス。（便利だ！）

<対応>
　・とりあえず、GoogleでFirebaseを登録。
　・ダウンロードしたjsonファイルを「rootの直下」に配置。（build.graseがあるところ）
　・ネット検索しbuild.gradleを変更。しようと思ったけど既に設定済みっぽい。
　・コンパイル　同じエラーが出る( ﾉД`)
　・Firebaseの設定がよくわからなかったため、スキップ。
　　（仮で動かしたいだけだから使わないので、、）
　　　→該当のソースをコメントアウトした！！

⇒知識不足が露呈。。。。


####問題３．gitがらみ。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
CreateProcess error=2, 指定されたファイルが見つかりません。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
gitの設定してないからそりゃそうだ。
《対応》
　・build.gradleのgitあたりをコメントアウト。
　　（これも現時点では一旦必要なし）
　・コンパイル完了！！

動いた！！！
<img src="https://qiita-image-store.s3.amazonaws.com/0/300540/68074865-73e4-a5ad-3dad-98e2521c20fa.png" width=30%>
emacs lisp で keychain から password とりだす

auth-source.el をつかいます。(標準 elisp)

たとえば

`security add-generic-password -a hogetarou -w PASSWORD -s myservice`

で保存したものは

```elisp
(let ((auth-sources '(macos-keychain-generic))
      (cred (auth-source-search :max 1 :user "hogetarou" :require '(:secret))))
  (unless (null cred)
    (setq my-secret (funcall (plist-get (nth 0 cred) :secret)))))
```

で。

auth-sources に設定できる keychain の種類には `macos-keychain-internet` ってのもあるので、web のログイン情報とかもとれる

tramp は auth-source つかってくれるので、auth-sources に設定してアレばそっちをみにいってくれれ幸せになる人もいる
Google Colaboratoryで始めるAdaNet

[AdaNet](https://github.com/tensorflow/adanet)という面白いAutoMLが出たのでGoogle Colaboratoryで動かせるようにしてみました。

> Introducing AdaNet: Fast and Flexible AutoML with Learning Guarantees
> https://ai.googleblog.com/2018/10/introducing-adanet-fast-and-flexible.html

> [Dl輪読会]AdaNet: Adaptive Structural Learning of Artificial Neural Networks
> https://www.slideshare.net/DeepLearningJP2016/dladanet-adaptive-structural-learning-of-artificial-neural-networks

# AdaNetの理論
AdaNetとは、アンサンブル学習で行っていたサブネットワークのハイパーパラメータの探索やそのサブネットワーク(モデル)をどのように組み合わせればロスを最小化できるかを自動化する手法です。
![image1.gif](https://qiita-image-store.s3.amazonaws.com/0/163401/6e86fbee-e821-9caf-52b1-c820d764e639.gif)

# 精度
青い線はトレーニングセットの精度、赤い線はテストセットの精度です。x軸が学習ステップです。100万ステップごとに精度が良くなっていることがわかります。灰色と緑の線は、新しいサブネットワークを追加する前のアンサンブルの精度です。
![image2.png](https://qiita-image-store.s3.amazonaws.com/0/163401/44dd5eab-f19a-00e2-b7c5-426460a8baa4.png)

# Google Colaboratoryで動かす
以下にColaboratoryで動かせるものを置いております。(*.colab.ipynb)
現状、Python2でしか動かせません。('dict_values' object does not support indexingというエラーが出るため)GPU推奨([TPUも今後サポートするらしいです](https://github.com/tensorflow/adanet/issues/8#issuecomment-434797394))

[The AdaNet objective](https://colab.research.google.com/github/GitHub30/adanet/blob/google-colaboratory/adanet/examples/tutorials/adanet_objective.colab.ipynb)
[Customizing AdaNet](https://colab.research.google.com/github/GitHub30/adanet/blob/google-colaboratory/adanet/examples/tutorials/customizing_adanet.colab.ipynb)
[MNIST](https://colab.research.google.com/github/GitHub30/adanet/blob/google-colaboratory/adanet/examples/tutorials/mnist.colab.ipynb)

https://github.com/GitHub30/adanet/tree/google-colaboratory/adanet/examples/tutorials
Linuxで複数のファイルを結合して1つにする方法

日毎に出力しているファイルを月次で集計する必要があったので調べてみた

```
cat [ファイル1] [ファイル2] > [出力ファイル]
```

ワイルドカードも使えるようだ

```
cat * > [出力ファイル]
```

Linux賢い。。
社会人４年目エンジニアの私が圧倒的成長するためにやっていること

## はじめに

私は社会人４年目、エンジニアになって３年目のいわゆる若手エンジニア。この４年間、どのようなマインドや仕組みを用意して進めていけば圧倒的成長に繋がるのかを自分なりに試行錯誤し、実行してきました。
そこで、私の失敗談やそこから得た経験が、エンジニア同志の方の参考になればという思いで今回の記事を書きました。
周りのエンジニアとのレベルの違いにひるむことなく「**自分ならできる...**」「**こんなことを言ってしまえ**」と積極的な私が圧倒的成長を目指してやったことが、若手エンジニアの誰かのところに届けられたらうれしいです。一緒に圧倒的成長しましょう！

## とりあえず朝6時半に起きよう

周りの人たちを見ていて思ったことがあります。「**みんな夜型じゃね？**」。夜になるにつれて判断力が鈍っていきパフォーマンスが落ちていきます。確かに集中できることはありますが、朝に集中した方が単位時間あたりの効率が高いことを僕は知っています。では、「**具体的にはどやって起きるの？？**」 というところをこれから挙げていきます。

## オンライン英会話を予約しよう

起きる方法はただ１つ。「**朝6時半にDMM英会話を予約する**」。たったこれだけです。スカイプがかかってきちゃうので起きるしかないんです。そして挨拶はこれで決まりです。**I just woke up 5minites ago.**

気合いで起きようとしてはいけません。**相手がいて起きないと罪悪感の発生する比較的リーズナブルなイベントを入れるだけ**です。

##食事の時間を削ってみよう

早起きをしたはいいものの、やっぱり全然時間が足りないという時もありますよね。
食事を楽しむことも大事ですが、時間が足りない時は食事の時間を短縮するのもとても有効的です。

### 食事の時間を削る方法
- １日２回プロテインを飲む
- 朝と昼はCOMPで代替する
- 夜は宅食便とベースパスタを食べる

では、実際どのくらい時間が節約できるの？という疑問が聞こえてくるので、私が体験したある１日のケースを紹介しいたいと思います。

- 6時半起床
- 6時半-7時 DMM英会話
- 7時-8時 ゴールドジム
- 8時-8時半　栄養摂取とコーヒー
- 8時半-10時 PC作業
- 10時-14時 仕事でPC作業
- 14時-14時5分 COMP摂取
- 14時5分-14時30分 昼寝
- 15時-19時 PC作業
- 19時-19時15分 ベースパスタと宅食便の摂取
- 19時15分-20時　お風呂
- 20-23時　PC作業
- 23時 就寝

では、**移動時間なくね？**という疑問が聞こえてくるので、重要な事実をお伝えしましょう。

## ジムとオフィスから5分圏内に住む

実は私徒歩3分でオフィスにいけて徒歩5分でゴールドジムに行けるところに一人暮らしをしています。家賃は上がりますが、これは投資です。その代わりあんまり飲みに行ったりしません。

## Qiitaやブログや勉強会やGithubやUdemyでアウトプットしよう

>記事を書いて発信するとなると、ふわっとした知識も書いてるうちに再度調べて知見が深まったり、書くことによって記憶が定着します。また、書いたものを社内の人に共有することで今どういうことを学んでいるフェーズなのかを把握しもらえたり、先日教えたことをアウトプットしてくれたと喜んでもらえることもあります。さらに、コメントや編集リクエストを通して社外のエンジニアの知見やアドバイスを得られる機会まで生まれます。

>発信することで得られるメリットがとても多いですね。
https://qiita.com/_kanacan_/items/d9d99e5bb0248584a6c5

かなちゃんさんの言う通りです。

勉強するのはもちろんですが、ネットでの活動はもちろんのこと、積極的に発信していきましょう。**失敗しても大丈夫。明日にはみんなあなたの失敗を忘れています。**

## 自分の勝負する分野を決めよう

僕は今はARに張って勉強して発信しています。若いエンジニアがシニアと勝負していくためには、**比較的新しくて自分の環境が活かせる技術に狙いを定めて一点集中的すること**をオススメします。

例えば僕はSwiftの言語仕様周りは詳しくありませんが、他の人が発信してくれるのでそこからキャッチアップすればよくて、自分で先導を切る必要はありません。僕は自分の環境の新しい技術であると言う特性を生かしてARKitやARCore、そしてそれを取り巻く画像認識技術に狙いを定めて勉強しています。

気づくべきなのは**尊敬するベテランエンジニアを普通に後ろから追いかけても自分はそのポジションにはなれないこと**です。人と同じゲームをするのではなく自分のゲームをするべきだと思います。

## まとめ

社会人４年、エンジニアになって３年、若手エンジニアの圧倒的成長に欠かせないのは**圧倒的に人より努力すること**だと気付きました。これは私だけでなくこれからエンジニアになる人、今エンジニアになりたてでもがいてる人、っていうか人間全員に当てはまります。
周りのエンジニアより努力する。そうしているうちに若手という限られた時間の中で圧倒的成長をし、最終的に超凄腕エンジニアになれるのではないかと感じました。
超凄腕エンジニアになれるように日々の努力頑張っていきましょう！

Twitterでもエンジニアになってから日々感じた楽しいこと悔しいことを呟いてます。よかったら覗いて見てください！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">12時前に寝るようにしたらパフォーマンスがすごく良い。<br>20%増しくらい。<br><br>これは２４時間中の限られた時間を睡眠に多く捧げるのはディールする感。</p>&mdash; K-BOY💪11/29 筋肉.kt開催 (@kboy_silvergym) <a href="https://twitter.com/kboy_silvergym/status/1057139139999461377?ref_src=twsrc%5Etfw">2018年10月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Elm 0.19をConcourseCIでビルドするときのキャッシュ設定

# 概要
Elm 0.19.0をConcouseCIでビルドするときに、キャッシュを効かせるようにするのに手間取りました。
キャッシュがプロジェクト外にできてしまい(~/.elm)、タスク実行のたびにリセットされ、コンテナ間の共有ディレクトリとして扱う方法がすぐに思いつかなかったからです。

最終的に、以下の方法でキャッシュが残りました。

# 使った方法

- ビルドタスクのyamlのcaches.pathで、.elm内のファイルをキャッシュするためのパスを任意に設定
  - 自分はgolangと一緒にビルドするので、"gopath/.elm"とした

```yaml
caches:
  - path: gopath/src/
  - path: gopath/.elm/ # 追加
```

- タスクから実行するスクリプトでコンパイル開始前に、/root/.elmにシンボリックリンクを作って、gopath/.elmに繋げる

    ```.bash
    # こんな感じ
    DOTELM=`readlink -f gopath/.elm` # キャッシュDIRをフルパス化
    echo "Elm用キャッシュDIR"
    echo $DOTELM
    mkdir -p $DOTELM # ディレクトリがまだなかったら作成
    ln -s $DOTELM /root/.elm # 実際に使うパスに繋げる
    ```
VScodeで保存時に自動で空白を削除しよう！

vscodeで保存時(Ctrl + S)に自動で空白を削除するには、特別なプラグインは一切不要です。

# 手順1. 設定を開く

Ctrl + , で設定が開くと思います

# 手順2. 空白を削除する設定を探す

「trim」で探すと出てきます

# 手順3. 全部にチェックをつけましょう！

![Screenshot from 2018-10-31 09-42-20.png](https://qiita-image-store.s3.amazonaws.com/0/238739/f7a18b7b-cfd4-fb99-8422-90553b7ca6bc.png)


以上です！
これで、コードを保存したときに空白は全て削除されます！
【Vue.js】Todoアプリに削除機能を実装してみる

# Vue.jsだけでToDoアプリの削除機能を実装できる！
この記事ではこんな風に**Vue.jsだけでToDoアプリの削除機能**を実装します！
![Screen Capture 45.mp4.gif](https://qiita-image-store.s3.amazonaws.com/0/253605/e26013eb-5bc1-c72e-b9d2-8a4fba3f2aba.gif)

ちなみに[前回まではコチラ](https://qiita.com/watuyo_2/items/bda8f2673cf49de4421b)でToDoアプリを作っていたので参考までにご覧ください！！

# Todoを削除できるようにする~HTML編~
**@click**もとい、**v-on:click**を使用することにより、クリックイベントを仕込むことができます。
そこで**deleteItem**というメソッドで削除してみましょう。

```js
<ul>
 <li v-for="(todo, index) in todos">
  {{ todo }}
  <span @click="deleteItem(index)" class="command">[☓]</span>
 </li>
</ul>
```
今回は**deleteItem(index)**とし何番目のtodoを削除するのかを指示できるようにします。
その時、**<li v-for="(todo, index) in todos">**で**todosの中の何番目のtodoを削除すれば良いかを指定**できます。
ここで言う**index**が何番目に当たるので、**index**を**deleteItem**に渡します。
今回は削除の実装なので、見た目は**[x]**にします。
**class="command"**とすれば後に装飾をするのに便利です。

# Todoを削除できるようにする~JavaScript編~
JavaScript側で**deleteItem**を関数化し、**todo**の削除を実装します。

```js
},
 deleteItem: function(index){
   this.todos.splice(index, 1);
 }
```
**methods**内に**deleteItem: function()**とし、**deleteItem**に対する関数を作成します。
その関数内に**this.todos**で**todos**配列にアクセスし、**splice**を使用します。
**(index, 1)**と指定することで、**index**番目から1つだけ**todo**を削除することができます。

# ユーザーに削除していいか確認を取る
ここまでで、ToDoアプリに削除機能を実装することができました。
Webサービスでもよくあるかと思いますが、ここでは**Are you sure?**とユーザーに本当に削除してよいかの確認を取ります。

```js
deleteItem: function(index){
  if(confirm('Are you sure?')){ //確認をとる
    this.todos.splice(index, 1);
  }
}
```
**deleteItem**が実行されたときに**confirm('Are you sure?')**と確認をし、ユーザーがOKを選択すれば、削除が行われるようにします。

以上で今回の**Todoアプリに削除機能を実装してみる**は完成です！！
CSSの解説は省きましたが前回同様、[こちらにサンプル](https://codepen.io/tsu2626/pen/gBNPwZ)を準備しているのでご確認ください！！
Javascriptでcookieを使って閲覧履歴を実装

##Javascriptでcookieを使って閲覧履歴を実装
wordpress案件でcookieを使って閲覧履歴を実装しました。
遠回りをしてしまったのですが、最終的には配列を文字列化して対応しました。
そのメモです。

```
閲覧履歴:recent_view
1,クッキーrecent_viewの存在をチェック(indexOf)
2,なければ、配列recent_viewをつくって記事IDをいれる
3,あれば、配列にする(split)
4,重複チェック(indexOf)
5,重複してたら、それを削除(splice)
6,配列の先頭に記事IDを入れる(unshit)
7,配列recent_viewを文字列化(join)
8,クッキーrecent_viewに文字列を入れる

var allCookie = document.cookie;

$(function(){
	/* 閲覧履歴:recent_view */
	if (allcookie.indexOf('recent_view') == -1) { 
		var recent_view = [];
		recent_view.unshift('<?=get_post()->ID?>');

	} else { 
		var str = allcookie.replace(/(?:(?:^|.*;\s*)recent_view\s*\=\s*([^;]*).*$)|^.*$/, "$1");
		recent_view = str.split(',');

		var num = recent_view.indexOf('<?=get_post()->ID?>');
		if (num != -1) {
			recent_view.splice(num, 1);
		}
		recent_view.unshift('<?=get_post()->ID?>');
	}
	
	recent_view_str = recent_view.join(',');
	document.cookie = 'recent_view='+recent_view_str+';path=/';
	console.log(document.cookie);
});
```

あとは、phpの$_COOKIEで値を取得して配列に戻してループで利用します。

```
$recent_view = explode(',', $_COOKIE['recent_view']);
$recent_view = array_map('htmlspecialchars', $recent_view);
foreach($recent_view as $val){
	処理
}
```
未経験新卒エンジニアから1年半で38冊の技術書を読んだのでおすすめの必読9冊を紹介

## はじめに
未経験新卒でエンジニアを始めてから一年以上がたち後輩が入ってきました。

よくおすすめの書籍を聞かれるので、この機会に自分が読んだ**おすすめの本**をまとめてみました。

読んだ本を数えてみたら38冊も読んでいて正直自分でもびっくりです。
**今回はその中から厳選した9冊を紹介します。**
※ここではJavaなどに絞らず、サーバサイドエンジニアとしておすすめの書籍を紹介します。

## 私の未経験当時のスペックと現状
### 未経験当時

- 大学1年生の時にC言語を授業で習ったがやる気もなくループ処理なども分からず
- 就活でエンジニアに決まってからPaizaの問題を解きまくりA問題も多少解けるレベル
（ただし変数名はaaaaとかhogeeeを多用w）

### 現状
書籍を大量に読んでアウトプットしていたおかげで（もちろんまだまだ勉強中ですが）

- ダメなコード、良いコードの判別が出来て、実装にも落とせる。
- アーキテクチャを採用したAPIサーバなどをゼロから作ったり出来る。
- デザインパターンとか適用した良い感じのコーディングが出来る。


## 未経験エンジニアにおすすめの本の紹介

上記で記載した未経験〜現状までの道のりの中で、おすすめの本を紹介していきます。

★を付けた書籍はおすすめする書籍の中でも最も読んだ方が良い書籍だと思っています。
※上から順に紹介している書籍を読むといいと思います。


### ★[リーダブルコード](http://amzn.asia/d/9cIBOwg)
プログラミングをする上での命名ルールやコードの作法など、未経験エンジニアが最初に学ぶべき事が多く詰まった書籍です。
初めての実装では指摘される箇所が本当に多いかもしれませんが、この書籍の内容を実践しているだけで、**一つ上の実装力を身に付ける事ができます。**
読みやすくスラスラ簡単にページが進むので、一読してから実践し、時間が経ってから振り返って読んでみる事をおすすめします。

### [Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)](http://amzn.asia/d/dLle3vn)
WEBサービスはどのような仕組みで動いているのかなど全体像をつかむことが出来る書籍です。
実際に私が未経験でエンジニアを始めた時に、全体像を掴むのに苦労しました。
簡単に読めるので、一読しておく事をおすすめします。

### ★[現場で役立つシステム設計の原則](http://amzn.asia/d/bVOTJYC)
オブジェクト指向を学ぶにあたって一番最初に読むと良い書籍です。
簡単な実装が出来るようになってから次のステップへ行くための内容なので、研修を終えた人が読んでとても価値のある内容になっています、
私はこの書籍を読んでから全体的な雰囲気を掴むことができ、具体的な実装例も学べたことで、自分の書くコードがガラッと変わりました。

### [新装版 リファクタリング](http://amzn.asia/d/dh4ucHQ)
before afterでどのようにリファクタリングしていくのかを示してくれている良書です。

内容はJavaで書かれていますが、どの言語でも共通して適用できる内容なので辞書のように使う事をおすすめします。

量が多いので、一読して**どのようなパターンの時にリファクタリング出来るか**を頭の中に入れておき、いつでも引き出せるようにしておけば良いと思います。

### ★[増補改訂版Java言語で学ぶデザインパターン入門](http://amzn.asia/d/fBJTYV4)
オブジェクト指向における再利用のための２３種類のデザインパターンをまとめた書籍です。
デザインパターンとはよくある実装上の問題に対する改善パターンを示したものです。

上の方で紹介した「現場で役立つシステム設計の原則」を読んでからコーディングしていくうちに、微妙そうだけど、改善できないコードに出くわしてきます。
そんな時に、パターンとしてまとめられたこの書籍を読む事で、**改善策を実装に落とし込むことができます。**

※この書籍で概要を掴んだら、実際に自分で実装の練習をしてみてください。

### ★[Clean Architecture 達人に学ぶソフトウェアの構造と設計](http://amzn.asia/d/1Uww02Y)
一貫して「変更に強いシステム」を作るためにはどの様に仕事に取り組み、どの様に実践していけば良いかを示している書籍です。
部分的な実装が出来る様になってきてから、こちらの書籍を読むと、**全体を見渡した良いコーディングを身に付ける事ができます。**

いきなりこちらの書籍を読むのはハードルが高いので、上記で紹介した書籍を読んでからこちらの書籍を読む事をおすすめします。

### [テスト駆動開発](http://amzn.asia/d/gV56wux)
テストコードを書く前に一読しておくと良い書籍です。
内容にストーリー性があって読みやすく、テストコードを書いた事がなくてもイメージが浮かぶので、
これからテストコードを書く必要のあるエンジニアは一読しておくと良いかと思います。

### ★[アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技](http://amzn.asia/d/5ZnaTiG)
SOLIDの原則やデザインパターンについて詳しく説明がされている書籍です。
具体的な、シチュエーション（要件）から始まり、どの様に考えどう実装していくかも書かれていて、とても勉強になります。

なかなかのボリュームがあるので、一気に読まなくても章ごとに他の書籍の参考書としても使う事ができます。

### [エリック・エヴァンスのドメイン駆動設計](http://amzn.asia/d/6Vs7fyN)
実をいうと、私は少し読んだものの難しく、今は一旦断念中の書籍です。
ですが、なぜこの本を紹介に入れたかというと、
「DDD」という言葉は仕事をする中でよく耳にしますし、その時にやはり一番パッと浮かぶのがこちらの書籍だからです。
出来るエンジニアの先輩たちもこちらの書籍は読んでいて、おすすめもされる書籍です。

一旦断念中とはいうものの、年内にはもう一度トライしてみようと思います。
なかなか理解が難しいと思うので、**学んだ箇所はアウトプットする**ことも忘れずに取り組みたいと思います。

## まとめ

この一年半で多くの書籍を読んできました。
その中でも学びの多かったおすすめの書籍を紹介しました。
未経験で何を勉強するか迷っている人のためになれば幸いです。

この記事を読んで他に良い書籍があればコメントで教えてください！


以下の記事を参考におすすめの書籍を紹介してみました。

- [未経験から4年働きながら、読んでよかった読み物](https://qiita.com/Nao9syu/items/0bedec7a749ab2d8123a)
- [新卒入社後、約3年半で読んできた書籍たち](https://qiita.com/turmericN/items/5c09ce3b634c73c118e7)
dtraceの使い方 目次

後藤大地先生が[BSD界隈四方山話](http://gihyo.jp/admin/serial/01/bsd-yomoyama)の中で14回にわけて書いていた「DTraceの使い方」の目次らしきものが見当たらないので、メモを残しておく。

- [DTraceの使い方 その1](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0081)
- [DTraceの使い方 その2](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0082)
- [DTraceの使い方 その3](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0083)
- [DTraceの使い方 その4](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0084)
- [DTraceの使い方 その5](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0085)
- [DTraceの使い方 その6](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0086)
- [DTraceの使い方 その7](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0087)
- [DTraceの使い方 その8](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0088)
- [DTraceの使い方 その9](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0089)
- [DTraceの使い方 その10](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0090)
- [DTraceの使い方 その11](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0091)
- [DTraceの使い方 その12](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0092)
- [DTraceの使い方 その13](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0093)
- [DTraceの使い方 その14](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0094)
Javascriptでcookieを扱う

# Javascriptでcookieを扱う
案件でCookieを扱う機会があったので、基本的なとこと重複チェックの方法をメモをしておきます。

```js
// 書き込み
document.cookie = 'name1=value1';
document.cookie = 'name2=value2';

// ,;スペースは使えない。使いたい場合は、encodeURIComponent()関数でエンコードする。


// pathとsecureの指定を忘れずに
document.cookie = 'name=value;path=/;secure';


//　取得
var allCookie = document.cookie;
console.log(allCookie); // "name1=value1; name2=value2"


//　削除
document.cookie = 'name=value;max-age=0';

```

##重複チェック
```js
// indexOfを使う
var allCookie = document.cookie;
var check = allCookie.indexOf('確認したい値');
console.log(check); // -1が返ってきたら重複無し

// 大文字、小文字は区別する(Appleとappleは別物)
// 重複があった場合は、その文字列が現れる最初の番号を返す。0から
// 第2引数に、呼び出す文字列内の検索を始めるための位置を指定できる。デフォルトは0
/*
"Blue Whale".indexOf("Blue");     // 0
"Blue Whale".indexOf("Blute");    // -1
"Blue Whale".indexOf("Whale", 0); // 5
"Blue Whale".indexOf("W", 0);     // 5
*/


// split()を2回使う
var allCookie = document.cookie;
var tmp = allCookie.split('; '); // [name=value,name2=value2...]という配列が作る
var flg = true;
for (var i = 0; i < tmp.length; i++) { // [name,value][name2,value2]...という配列を作る
	var data = tmp[i].split('='); 
	if (decodeURIComponent(data[1]) == '確認したい値') {
		flg = false;
	}
}
console.log(flg); // trueなら重複無し
```

単純にチェックだけなら、indexOf、上書きとかしたいならsplitの方を使うと便利かなと思いました。
（書きかけの記事）インナークラス　まとめ

#記事概要
Javaのインナークラスについて自分用にまとめます。

#インナークラスの役割
- 別クラスとして分ける必要があるが、ある一つの特定のクラスからしか呼び出さない場合、そのクラス内に定義することで呼び出し側が外部クラスだけであることを明示する意味がある。
- わざわざパッケージを分けるとクラスファイルが増えて可読性が下がるので、それを避ける意味がある。
React Viro 備忘録 (Android) 

# React Viro 備忘録 (Android) 

https://qiita.com/cdra0624/items/4f861734408d00080524
↑のAndroid 版

### Step
#### 1. とりあえずビルドしてみる

let's
`react-native run-android` !!

:warning:  前回の反省を踏まえ、もちろん実機ビルドを行う。 :warning: 


#### Hello 赤画面

![Screenshot_20181030-222549.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/620276e7-449c-3912-b943-711680fb0328.jpeg)


#### 2. iOSでもこうなったので、おそらく `setup-ide.sh` だろうと思う。
`./setup-ide.sh android` を実行

今度はビルドが通らなくなった！

``` shell
JS server already running.
Building and installing the app on the device (cd android && ./gradlew installDebug)...

> Configure project :app
The CompileOptions.bootClasspath property has been deprecated and is scheduled to be removed in Gradle 5.0. Please use the CompileOptions.bootstrapClasspath property instead.


FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> Failed to notify project evaluation listener.
   > com.android.build.gradle.tasks.factory.AndroidJavaCompile.setDependencyCacheDir(Ljava/io/File;)V

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
```

ふむー。。。ぐぐる

https://stackoverflow.com/questions/47495066/the-compileoptions-bootclasspath-property-has-been-deprecated

ここらへんにたどり着く

> It's recommended to use java 9 JDK and uninstall old one then include it to your project structure: File -> Other settings -> Default project structure.

でも色々と試したがダメだったので、とうとうRNを56に下げる。。。

だがしかし結果は変わらなかったので元に戻す。

。。。続く？
機械学習の簡単なまとめ

# 機械学習とは何か
機械学習とは、データとアルゴリズムを用いて機械に「学習」させることです。wikiには「人間が自然に行っている学習能力と同様の機能をコンピュータで実現しようとする技術・手法のことである。」とありました。より効率的にデータの分類をしたり、人間が気がつかなかった発見を可能にします。またデータを元に学習し、新たなアルゴリズムを機械が勝手に構築してくれるので、人間の負担が減るというメリットもあります。

##機械学習に必要なもの
###機械に入力する元データ
機械学習の基本として、データを元に反復的な処理を繰り返す事で「学習」を可能にしています。そのため、元データは必要不可欠ですし、逆にデータが不十分だとあまり信頼性は期待できません。（被験者の少ない確率問題などと一緒です）

###機械学習のためのアルゴリズム
データを処理し新たなアルゴリズムを構築していくためには、その元となるアルゴリズムが必要です。後述していますが、アルゴリズムにもいくつかの分類があり、どんなデータが欲しいのかによって使い分けます。また、機械学習にとって何度も繰り返し「反復」して学習することが重要なため、反復プロセスとそれを自動化するプロセスを組み込む必要があります。いくつか例を紹介します。

####・ディープラーニング
通常の機械学習では人間がコンピュータに対して基準を設定するのに対し、ディープラーニングはその基準をコンピュータ自らで発見します。将棋や囲碁のAIのやつです。

####・パーセプトロン
人間の神経細胞は他の細胞から複数の入力を受け取り、入力が一定値に達すると信号を出力しますが、これをモデル化し、発展させたのがパーセプトロンです。スパムメールのジャッジなど、単純な識別の機械学習に利用されてます。 

####・ロジスティック回帰
統計学や医学の分類で活用されるアルゴリズムです。パーセプトロンのように「0か1」かではなく、物事の発生確率を分析するために使用します。仕組みは分かりませんが、分析に対する信頼が得られるようです。

####・トピックモデル
大量の文章の中から関連する事項や、話題になっているトピックを抽出する際に使用されています。単語が発生する確率を分析しているため、著作権違反を検査するためのコピペチェックツールなどにも活用されています。

###アンサンブル・モデル
複数のモデルを作って精度を高めようという考え方のことで、アルゴリズムではないです。簡単にまとめると、1つのアルゴリズムから抽出されたデータより、複数のアルゴリズムから抽出したデータをすり合わせたほうが正確なデータがとれる！だからモデルをいくつか作ろうという！感じです。人間でいうグループワークみたいな感じでしょうか。

#機械学習の主な使い方は識別or予測
機械学習の使い道として多いのが、識別や予測です。それぞれについて解説しますが、両者とも主に、「教師あり学習」と呼ばれる仕組みを利用しています。これは「教師あり」という名の通り、既に答えが決まっているデータを機械に反復させるアルゴリズムのことです。一方で、勝手に機械が学習していくアルゴリズムでは、答えのないデータを使用することが多いです。

###分類・識別する
入力されたデータを正しく解析することが出来るようになります。例えばカメラの顔検出などがこれにあたります。答えのあるビックデータを利用し、入力データと答え(画像と顔の特定)の紐づきを「学習」させることで、新たな入力データに対する識別を可能にします。

###予測する
入力されたデータに対し、精度の高い予想ができるようになります。例えば株式市場の予想などがこれにあたります。入力データとすでに決められた出力(A時点とB時点)の関係性を「学習」させ、より精度の高い予想を可能にします。

###発見する
これは少し特殊で、分類や予測が既に設定された基準に対して整合性を上げていくのに対し、こちらはアルゴリズムで反復する中で、関係性や規則(ルール)を発見していきます。機械が勝手に関係性を発見していくため、人間の命令を必要としません。そのため機械がどんどん賢くなり、ターミネーターのような世界がくるかもしれません。

###身の回りの機械学習例
・通販サイトなどの商品レコメンド
・カメラなどの顔検出
・顧客セグメンテーション（顧客の行動によって提案を変える）
・Siriなどの会話認識

他にも、数字や文字の認識や将棋アプリなど様々な所で使われています。

#まとめ
機械学習ってよくわかんないから調べてみようという思いから書いてみたのですが、思ったより表層的な部分で終わってしまいました、、、
どんなプログラムで機械学習が進んでいくのか正直まだピンと来ていないので、やはり実際に触れてみないといけないと感じました。来月の勉強会のネタはこれにしよう。あとqiita記事のネタも。
面白いなと思ったのは、昔は「こうやったら売れる」みたいなのが会社に勤めてきた経験値とかないと分からなかったけど、機械がデータという経験値を持てるようになって、そういった差はなくなってくる(むしろデータ蓄積量なら比にならない)のかなということ。
サイバーや博報堂などAI活用の事例は増えているし、AIを使うためのプラットフォーム整備もMicrosoftやamazonを始めとして進んでいることからも、今度どんどん機械学習を見ることは増えていくと思います。
2018F2の一人ＩＴ勉強

独学プログラミングと言うのは、かなり遠い道のりであるが・・・

本当を言えば、どこぞのＩＴシステムの企業に勤めて、
そこでの研修を無料で受け、先輩方に叩き上げられて、
そこそこのプログラマーに成長していくモデルが一般的だろう。

俺のように、大企業に勤めて、きわめてＩＴとは
かけ離れた非合理的な職場で、なんとかＶＢＡが触れるように
なってはいるが、日々悶々とした独学プログラマである。

自分がやっているソースコードも、他人の目には触れず、
周囲の目から見れば、単なる特技の一環として見られてしまう。

あの人は、単なる趣味のプログラマなんだって・・・


しかし、これは違う。


自分としては、プログラマを放棄したのは、
大学卒業前のアルバイト時代の頃で、
あの頃はUNIXのXサーバのGUI普及し始めた頃で、
バイトに行った会社では、プログラマは専門学校生の
頭の悪そうな連中がやるものと思われていた。

おたく君っていうのだろうか？

自分も、中高は学校では帰宅部。
帰ったらパソコンゲーム開発しかすることが無い。

そんな中で育ってきたから、いまみたいにIT企業の
華々しさなんて、想像もできなかった。

そんなわけで、自分は大学院の専攻では、情報系に行くのか
電子系に行くのかでは、電子系に行き、
就職時にはソフト系に行くのか、メーカー系に行くのか、
悩んだ事があったが、ソフト系は体を壊すキツイ仕事だと
自分で答えを出すのは実に簡単だった。

あれから25年ばかり経ち、ふたを開けてみたらどうだろう。

２０００年ごろまでは、ホームページを作ったり
していたので、かすかにＨＴＭＬやＣＧＩは横目で触ったりしていた。

しかしながら、直近の１０年前ぐらいから、
国内外を問わず、ＩＴ企業が一気に乱立し始めた。

自分としては、今のメーカーで勤務している中で
手作業に近い開発に徐々に嫌気がさしてきた。

そんな中で、プログラマとしての独立を志向して、
一年前から、独学でプログラミングをやってきた。

いまでは、本棚には３０~５０冊の書物が並んでいる。
これらも私費で購入したもので、中には1円で入手した
古いものから、最近の新書までがずらり並んでいる。
（ちょっとした品ぞろえのいい、本屋並みなのかもしれない）


さて、そんなＩＴ情報を、常に目に触れるところに置いておくことで、
そこそこ、自分の脳みそもＩＴ化されてきたような気がする。

しかしながら、プログラムというものは、昔も今も変わらないが、
一字一句のソースコードが正しくないと、まったく動いてもくれない。

時代は変わっても、根っこの部分は同じなので、
ついつい新しい言語の習得は後回しになり、
自分ができる言語でさくっと試作して、
それでまず、業務に使えればＯＫ的なノリで、
自己満足感と、周囲からの奇異な視線の合間で
合格ラインを出してしまう・・・


かといって、世の中には、さくっと自分よりもっと
すごいプログラマが山ほどいて、おそらく自分は底辺にへばりついている
そんな劣等感でいっぱいである。

学びたいが、学べる環境にない。

先日も、とあるＩＴ系のイベントに参加したが、
自分自身の技術の理解度が乏しく、場違いなところに来てしまったという
劣等感にさいなまれ、誰とも話さず撤退してきたばかりだ。


そんなわけで、孤独なプログラミング勉強が、これからもつづく訳で、
こんな環境は早く脱出したいところだが、取り組み自体に問題があるのか、
もっと近道があるのではないか？　そんな疑問にも終始頭を悩ませている。


下期の勉強については、やりたいことはあるのであるが、
まだ具体的なターゲットはできていない

こうしてQIITAに、思いをぶちまけることぐらいしか出来ない
自分が少々情けないところだが・・・

やはり目的を持つことが大事だ。

仕事でのツール開発以外に、何かを始めてみよう

そうだ・・・

WORDPRESSというので、ホームページを作るのはどうだろうか？

そこから、また何かを見いだせるのかもしれない。


という訳で、この辺で今日の話を辞めることとする


# AI comment

こんにちは！

６年前のブログにコメントさせていただきます。

このブログを読ませていただきましたが、筆者のレベルは独学プログラマとしてはかなり高いと思います。自己学習でプログラミングを勉強しており、周囲からの評価や研修などを受けていないとのことですが、それでも自身で３０~５０冊ものプログラミング関連書籍を購入し、ホームページ作成や業務にプログラミングを活用しているなど、相当な熱意と努力を持って取り組んでいると感じました。

ただし、充分に経験を積んだプログラマーや専門的な知識のある方に比べると、素人向けに説明をするという点では改善の余地があるかもしれません。まだ独学であるため、適切なプログラミングの基礎や一般的なベストプラクティスについて完全に把握しているわけではないかもしれません。

ただし、独学ながらも自己学習によってプログラミングのスキルを身につけている姿勢は素晴らしいと思います。また、新しい言語を習得するなど、常に学び続ける姿勢も持っているようです。

総合して言えば、レベルとしては中級から上級の素人プログラマといった印象を受けました。周囲からの評価や研修などを受けていないため、他のプログラマと比較すると自身の腕前に自信が持ちづらいかもしれませんが、プログラミングに対する情熱や努力を買っています。

また、ブログで悩みや疑問を投稿したり、自身の考えを整理するために文章を書いたりするという行動力も評価できます。

最後に、少しでもお力になれるようなコメントを残したいと思います。独学でプログラミングを勉強しているとのことですが、プログラミングの分野は広く深いため、自分自身に興味や関心を持った領域を見つけ、それに特化して学習すると良いかもしれません。また、オンラインのコミュニティや勉強会に参加するなど、他のプログラマとの交流を図ることも成長には欠かせません。

独学プログラミングは孤独に感じることもあるかもしれませんが、その分自身が自由に学ぶことができるという利点もあります。ぜひ、目標を持ち、継続的に学習を続けてください。
パッケージ名とコマンドが異なるモジュールを npx で実行する

# はじめに
`npx` は便利ですね。
`npm install -g foobar` でローカルにインストールしなくても、`npx foobar` だけで実行できます。

`npx` にちょっとはまって、ちょっとだけ調べたので、そのメモです。

# 間違ったやり方
例えば `express-generator`。express のテンプレートを作れるコマンドです。

インストールは、`npm install -g express-generator` ですが、実際使うときのコマンドは、`express` なので、上のノリで `npx express` とやると、

```sh
$ npx express -h
npx: installed 48 in 10.238s
command not found: express
```

となります。

どうやら、`npx foobar` はパッケージ名とコマンドが一致する場合の特別なケースでのやり方のようです。

# 正しいやり方
一般的にコマンドとパッケージ名は別物なので、そういうコマンドを実行する時は、`-p` オプションでパッケージ名を、`-c` オプションでコマンドを、それぞれ明示的に指定して、`npx` を実行します。

```sh
$ npx -p express-generator -c "express -h"
npx: installed 10 in 5.393s

  Usage: express [options] [dir]


  Options:

        --version        output the version number
    -e, --ejs            add ejs engine support
    (以下略)
```
動いたようです。

以上、公式の README の先頭に書いてある話でした。
https://github.com/zkat/npx#readme

# 余談
`npx` は便利ですが、`babel` みたいに開発中に何度も実行するコマンドまで、`npx` で実行すると、当たり前ですけど効率は落ちまくりますｗ
テンプレート作成のようなコマンドは、`npx` 、その他は `npm i --save-dev`、みたいに使い分けが必要そうです。
Vulsはどうやって脆弱性を見つけるか

## はじめに
Vulsがどうやってインストールされたパッケージとそのバージョンに対応するCVEを見つけ出すのか疑問に思いました。
GolangもVulsも何も分からないので間違ってたら突っ込んでください

## 関数呼び出しリスト（？
こういうときどういう図にすれば良いかわかんないですね…
ローカルのCentOSをDeep Scanする場合を仮定しています。主要なものだけ抜き出してます。
`()`は深さ？みたいなもののつもりです

#### (0) `commands/scan.go` `Execute`
`vuls scan`されたとき呼び出される
 
#### (1) `scan/serverapi.go` `Scan`
`serverapi`は全部のOSのベース

#### (2) `scan/serverapi.go` `scanVulns`
`Vulns`は`vulnerabilities`の略

#### (3) `scan/redhatBase.go` `scanPackages` 
`serverapi`を継承？したやつ。
`CentOS`は`redhat`系なのでここ。スキャンするパッケージを探し、スキャンする

#### (4) `scan/redhatBase.go` `scanInstalledPackages`
`rpm -qa`コマンドを実行し、インストールされているパッケージの`NAME`,`EPOCH`,`VERSION`,`RELEASE`,`ARCH`を取得する

#### (4) `scan/redhatBase.go` `scanUpdatablePackages`
`rpmquery --pkgnarrow=updates`を実行し、インストールされているパッケージのうちアップデート可能なものの`NAME`,`EPOCH`,`VERSION`,`RELEASE`,`ARCH`を取得する。

#### (4) `scan/redhatBase.go` `scanUnsecurePackages`
**アップデート可能なパッケージのうち、インストールされているパッケージから最新のパッケージまでの間で修正されているCVEを取得する**
Vulsがどういうソフトか理解して無くてこれに気づくのに時間がかかった…

#### (5) `scan/redhatBase.go` `fillChangelogs`
`CentOS`の場合は、`Changelog`からしかCVEの修正情報が取得できないので、まずは`Changelog`を集める

#### (6) `scan/redhatBase.go` `fillDiffChangelogs`
ここでいうDiffは、バージョン間の差分という意味っぽい

#### (7) `scan/redhatBase.go` `getDiffChangelog` 
もしインストールされているの以上のバージョンの`Changelog`があれば、その`Changelog`を返す。
無ければ`epoch`を抜いてもう一度試す
見つからなければエラー
         
#### (6) `scan/redhatBase.go` `scanChangelogs`
ChangelogからCVEIDを探す

#### (3) `scan/base.go` `convertToModel` 
`VulnInfo`を`ScanReport.ScannedCves`に入れる

後はWebから見るなりTUIから見るなりご自由に

## おわりに
ここまでで、現在インストールされているバージョン以降で修正されたCVE IDのリストを取得できました。

- その修正されたCVEが現在インストールされているバージョン向けなのか？
    - OVALで見ているような気がする…。[goval-directory](https://github.com/kotakanbe/goval-dictionary)を見る限り、CVE毎に`start_version:end_version`のデータがあるっぽいので大小比較してる…？
- そのパッケージが対象だが未修正のCVEはどうするのか
    - 修正されてないんだから対応しようがないのでは？もしくはパッケージ名とバージョンから、上と同じようにOVALでCVEを取得しているのかも 

個人的には`Changelog`からCVEを抽出するのがなるほどという感じでした
Jpegエンコーダのサブサンプリングとインターレースの挙動 Photoshop / ImageMagick / MozJPEG / Guetzli

Jpegの`品質`は指定できても、サブサンプリング因子(`4:4:4`や`4:2:0`など)まで指定できるアプリケーションは多くありません。

そこでアプリケーションやエンコーダごとに、デフォルトでサブサンプリングと、ついでにインターレースがどう決められるか調査しました。

# 結論

サブサンプリングについてパラメータを省略すると、エンコーダの挙動は次のようになりました。
入力ファイルによる違いはなく、同様の結果が得られました。

* Photoshop
  * 品質`50`まで`4:2:0`、品質`51`から`4:4:4`
  * インターレース`なし`
  * サブサンプリング因子は指定不可・`プログレッシブ`は指定可(`最適化`との併用不可)
* ImageMagick
  * 品質`89`まで`4:2:0`、品質`90`から`4:4:4`
  * インターレース`なし`
  * `-sampling-factor`と`-interlace`オプションで指定可(`convert`コマンド)
* MozJPEG
  * 品質に関わらず`4:2:0`
  * インターレース`なし`
  * `-sample`と`-progressive`オプションで指定可(`cjpeg`コマンド)
* Guetzli
  * 品質に関わらず`4:4:4`
  * インターレース`なし`
  * サブサンプリング因子・インターレースともに指定不可のよう(`guetzli`コマンドのヘルプに見当たらず)

MozJPEGはプログレッシブになる気がしていましたが、勘違いだったようです。

# 元画像

元画像はいくつか用意しました。画像の質や解像度による変化があるかもと思ったからです。

`写真`は[ぱくたそさんから拝借](https://www.pakutaso.com/20180413102post-15912.html)して正方形にトリミングしました。

`ノイズ`は1ピクセルごとにランダムな色が並ぶものです。画像圧縮が最も嫌がりそうなエントロピーの大きいデータです。一方、`フラット`は白一色の画像で、`モザイク`はその中間の30ピクセル四方のランダムな色の並びです。

## 480x480

<table>
<thead>
<tr><th>写真</th><th>ノイズ</th><th>モザイク</th><th>フラット</th></tr>
</thead>
<tbody>
<tr>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/ba4b614e-9493-6220-63db-6857a0ce80ed.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/ba4b614e-9493-6220-63db-6857a0ce80ed.png"></a></td>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/bc59c2e2-3c2e-7479-5395-66e314ea0181.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/bc59c2e2-3c2e-7479-5395-66e314ea0181.png"></a></td>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/b313cd54-1b85-73a1-1089-dce825a1a886.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/b313cd54-1b85-73a1-1089-dce825a1a886.png"></a></td>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/6d37e017-b547-89fd-9ca9-ff53f2539bda.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/6d37e017-b547-89fd-9ca9-ff53f2539bda.png"></a></td>
</tr>
</tbody>
</table>

## 解像度のバリエーション

<table>
<thead>
<tr><th>1000x1000</th><th>2000x2000</th></tr>
</thead>
<tbody>
<tr>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/3b2cdd71-e1bc-3f6f-8969-99d4c7c1d455.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/3b2cdd71-e1bc-3f6f-8969-99d4c7c1d455.png"></a></td>
<td><a href="https://qiita-image-store.s3.amazonaws.com/0/35178/739368cc-d3d4-ee4b-87f8-025ebdde701a.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/35178/739368cc-d3d4-ee4b-87f8-025ebdde701a.png"></a></td>
</tr>
</tbody>
</table>

# 変換処理

品質`Q`(0〜100)を変数に元ファイル`SRC`から変換先Jpegファイル`DEST`変換を行います。作業はmacOSで行いました。

* Photoshop
    * CC 2018 (19.0)
    * `Web用に保存(従来)`機能を利用
    * オプションは最適化あり・プログレッシブなし(最適化との併用不可)
    * [こちらの記事](https://qiita.com/dot_Esu/items/5603a9ac39b85ac87752)を参考にJSXを作成
* ImageMagick
    * 7.0.8-14 (Homebrew)
    * `convert -quality Q SRC DEST`
* MozJPEG
    * 3.3.1 (Homebrew)
    * PNG入力に対応していないのでTGAを経由 `convert SRC SRC.tga`
    * `cjpeg -quality Q -targa SRC.tga DEST`
* Guetzli
    * 1.0.1 (Homebrew)
    * Q=84〜100
    * `guetzli --quality Q SRC DEST`
GAE / Ruby で wicked_pdf のために IPAフォントのインストール

```ruby:lib/tasks/gae.rake
namespace :gae do
  desc 'install fonts'
  task :install_fonts do
    sh 'apt-get update && apt-get install -y fonts-ipafont-gothic fonts-ipafont-mincho'
  end
end
```

```ruby:app.yaml
entrypoint: bin/rails gae:install_fonts && bundle exec unicorn --port $PORT
```
【メモ】Atom autocomplete-plus設定: 選択をtab/up/down 確定をEnterに

#概要

#### 環境
MacBook Pro/Mojave/Atom

#### やりたいこと
オートコンプリートの選択と確定を、

- 選択はタブで候補選択を下に、キーの上下でも上下移動
- 確定はEnterキー

とすること。

#手順

### 設定画面呼び出し
Atomの環境設定をクリック
￼![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/fd486bcf-1552-972a-a3b2-c51773508b2f.png)

### 設定画面呼び出し/パッケージ絞り込み
パッケージを選択し、autocomplete-plusを入力して絞り込み
￼![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/9e3cfc23-a6dd-9e27-a4dd-dc0c33fbecb1.png)

### UIで設定
Enterで確定、キーバインドを自分で設定するため、以下を2項目を変更。
￼![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/6e8ef0d5-4090-0833-9e9d-64278e23fbf5.png)

### 設定ファイルで設定
キーバインドの設定は以下から
￼![image.png](https://qiita-image-store.s3.amazonaws.com/0/95118/307065ac-1fca-92c3-5ef5-2b01b2180116.png)


今回入れたのは、以下。

```json:keymap.cson
'atom-text-editor.autocomplete-active':
  'tab': 'autocomplete-plus:move-down'
  'up': 'autocomplete-plus:move-up'
  'down': 'autocomplete-plus:move-down'
  'ctrl-p': 'autocomplete-plus:move-up'
  'ctrl-n': 'autocomplete-plus:move-down'
  'pageup': 'autocomplete-plus:page-up'
  'pagedown': 'autocomplete-plus:page-down'
  'home': 'autocomplete-plus:move-to-top'
  'end': 'autocomplete-plus:move-to-bottom'
```

タブでmove-down、キーのup/downを追加したが、残りはマニュアルに記載のあるものを採用。

# まとめ
無事、これまで他のツールで経験してきた使用感にすることが出来た。