OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10にWSL+fish環境を入れてみる

#### WSLのインストール

- 「アプリと機能」から「関連設定」の「プログラムと機能」リンクを選択
- 「Windowsの機能の有効化または無効化」リンクを選択
- 「Windows Subsystem for Linux」のチェックボックスをONにして「OK」ボタンを押下
- 再起動が必要になるので「今すぐ再起動」ボタンを押下

#### Linux(Debian)のインストール

- 「Microsoft Store」を起動して"Debian"で検索
- 「Debian GNU/Linux」を選択してインストール

#### fishのインストール

下記コマンドでインストール。
公式の手順に従ってみたけど最初のlistファイルの生成がパーミッションエラーになった(sudoでもダメだった)ので明示的にrootユーザーになってから実行している。

```bash
$ sudo su
# echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/2/Debian_9.0/ /' > /etc/apt/sources.list.d/shells:fish:release:2.list
# exit
$ sudo apt-get update
$ sudo apt-get install fish
```

#### ログインシェルの変更

```bash
$ chsh -s /usr/bin/fish
```

#### 問題点とか

- ログインシェルをfishにすると何故か1つ目に起動したウィンドウでプロンプトが出てくれない。
  - 追加で直接debian.exeを起動 or タスクバーのアイコンを右クリックして起動すれば動く模様。
- fish_configが動かない
  - 403エラーになる。CentOS7にfish入れた時と同じような感じなのかな?
ShellScriptでよく使う表現

ShellScriptでよく使う表現を一般化したものをとりあえず置いておく場所

無限ループ

```bash:loop.sh
    while :
    do
	echo "コンパイルを開始します"
    echo "処理を実行"
	read -p "終了する場合はqを入力してください" res
	if [ $res = q ];then
	    break
	fi
    done
```


規則に従ったファイル名の決定

```bash:FileNameDecide_skip.sh
#!/bin/bash
statement=""
message="同名ファイルが存在します"
fileName ="newFile"
if ls | grep -w $fileName >/dev/null;then
  echo $message
else
  echo $statement > $fileName
fi

#####################################
<<readme
変数の説明
  massage   : 同名ファイルが存在した時のメッセージ
  statement : 入力内容
  filename  : 作成したいファイル名
readme
#####################################
```


指定時間毎に処理を行うスクリプト

```bash:repeater.sh
#!/bin/bash
secInterval=3
shFile="sample.sh"
message1="\n\n\n"
message2="\n\n\n"
while true;do
    printf $message1
    sh $shFile
    printf $message2
    sleep $secInterval
done

#############################
<<readme
変数の説明
  secInterval : 実行間隔(秒)
  shFile      : 実行ファイルのpath
  message1    : 実行前に表示する文字(\nは改行)
  message2    : 実行後に表示する文字(\nは改行)
readme
############################
```

shellscript実行中に任意のコマンドを読み込むスクリプト

```bash:UserCommand.sh
#!/bin/bash
echo "終了時は'quit'と入力"
nowAd=`pwd`
read -p "${nowAd}$ " UserCom
until [ $UserCom = "quit" ];do
  $UserCom
  nowAd=`pwd`
  read -p "${nowAd}$ " UserCom
done
```

javaの`do while文`のように一度処理を行う繰り返しを表現したスクリプト

```bash:DoWhile.sh
#!/bin/bash
read -p "数字を入力: " num
while $num==0 -o $num!=0 ;do
  read -p "数字を入力: " num
done
```

スクリプト中にディレクトリの移動を行わせるスクリプト

```bash:MoveDirectory.sh
#!/bin/bash
ad=`pwd`
cd; cd desktop
# 処理
cd; cd $ad
```
JavaScriptで手軽にシングルトンをつくる【ES2015】

JavaScriptのclassにはprivateがない。そのためJavaのようなシングルトンは作れないと思っていたが、実は簡単にシングルトンを作れることを知ったので共有。

# オブジェクトをexportする

下のコードのようなSingletonクラスがあったとする。Singletonクラスは内部にメンバ変数xを持っており、メソッドgetX()が呼ばれるたびにインクリメントされる。

Singleton.jsではSingletonクラスのインスタンスをexportしている。これによりimportした場合、一つのインスタンスが共有されるようになる。

```js:Singleton.js
class Singleton {
  constructor() {
    this.x = 0;
  }

  getX() {
    this.x++;
    console.log(this.x);
  }
}

export default new Singleton();
```

下のbridge.jsとmain.jsではSingleton.jsをimportしている。

bridge.jsはSingleton.getX()を呼ぶ関数をexportする。main.jsではSingleton.getX()とbridge.jsでexportされた関数をそれぞれ実行する。

```js:bridge.js
import Singleton from './Singleton';

export default function() {
  Singleton.getX();
}
```

```js:main.js
import Singleton from './Singleton';
import bridge from './bridge';

Singleton.getX();
bridge();
```

実行結果は以下の通り。1,2が出力され実行したどちらの関数も同じインスタンスを指していることがわかる。便利便利。

```sh
% ./node_modules/.bin/babel-node main.js
1
2
```
VagrantのVirtualBox用イメージをダウンロードする

# 内容

VagrantのBoxイメージをダウンロードしたいですよね
参考にしていた記事からURLも変わっているので改めて記録しておきます

# 参考記事

[直接Vagrant用のBoxをatlasからダウンロードする](https://qiita.com/liubin/items/a0765fc36bd87dcb4a5e)

# 手順

## 1. Discover Vagrant Boxesのページへ

https://app.vagrantup.com/boxes/search

## 2. 欲しいBoxイメージを選択

今回はCentOS7を選びます

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/179791/51e3fb0f-9bd2-e7cf-0f9c-13e332c679a7.png)

## 3. Boxのバージョンを選択

最新バージョンを選びます

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/179791/c6408ef2-59b2-c1b4-27bb-68e113044792.png)

## 4. URLを確認

遷移した先のURLはこんな感じになります
https://app.vagrantup.com/centos/boxes/7/versions/1801.02

## 5. ダウンロード

末尾に`/providers/virtualbox.box`を追加してEnter！
https://app.vagrantup.com/centos/boxes/7/versions/1801.02/providers/virtualbox.box

# Vagrantfile

ちなみに`Vagrantfile`にはこんな感じで記入します

```ruby
Vagrant.configure(2) do |config|
  config.vm.box = "centos/7"
  config.vm.box_url = "../boxes/CentOS-7-x86_64-Vagrant-1801_02.VirtualBox.box
```

# まとめ

これでうっかり`vagrant box remove centos/7`をやっても安心して`vagrant up`できますね！
golang で実際にメール送信せず smtp.SendMail を試すためのモック作り

["net/smtp" パッケージ](https://golang.org/pkg/net/smtp/) の smtp.SendMail[^1]を使ったプログラムで、そのまま動作確認しようとすると、メールサーバーを正しく指定する必要があったり、実際にメールが送信されちゃったりと面倒この上ないと思ってます。

関数の引数などに、同じ func 型で中身は []byte 型の変数に書き込むだけのモックを用意する方法もありますが、実際に送信しないのが気になったり、モックを用意する前提で関数を設定するから規模によってはちょっと冗長に感じたりしました。

なので smtp.SendMail のテストコード[^2]を参考にして、コード上からローカルにダミーの SMTP サーバーを立ててみました。

## 環境

* golang:1.9.2

## 実装

* https://play.golang.org/p/8mfrqNVWTPK

## やってること

1. `127.0.0.1:%d` で待ち受け
1. 以下を goroutine で実施
    1. 接続要求が着たら繋いで、予め用意しておいたメッセージを送りつける
    1. メッセージを送った後はクライアントからメッセージが届くので受け取る
        * 受け取ったら予め用意しておいたバッファーに格納
    1. `354` を送った後はクライアントからのメール本文が一行ごとに届くので受け取り続けて
    1. `.` だけが着たらメール本文終了でメール送信の終了処理
1. 上記の goroutine が終わったら受け取ったメールデータを返却してくれる関数を戻り値として返却
    * ただし goroutine 内でエラーが発生したらそっちを返却する

* 第1引数以降は可変引数で、指定するとSMTPサーバーレスポンスを変更できるようにしてます
    * デフォルトでは認証付きのメール送信
    * 第2引数で `550` を指定すると接続段階でエラー
    * それ以降は SMTP の仕様を調べてください

* 言い訳だけど、テストコード用の適当実装なので `getReceivedData()` を呼ばなかったりそもそも接続要求しないと多分メモリリークする (`getReceivedData()` 呼んでもするかな..?)

[^1]: https://golang.org/pkg/net/smtp/#SendMail
[^2]: https://golang.org/src/net/smtp/smtp_test.go
Netlityを用いた静的サイトのホスティング

##Netlityとは？

静的コンテンツをベースにしたWebサイトのホスティングに特化したサービス。
現在、便利なホスティングサービスが増えており、簡単に静的サイトを公開できるようになってきました。
[Hexo](https://hexo.io/)などの静的サイトジェネレーターで静的サイトを作り、ホスティング先として利用する。
その中でもNetlifyは高機能ホスティングサービスです。
類似のサービスとしては[GitHub Pages](https://pages.github.com/)があります。
こちらはGitHubのアカウントがあればすぐに静的サイトが公開できるので、そちらもお手軽です。


##Netlifyの特徴
- ビルド、デプロイ、ホスティングの全てを自動で行ってくれる

Netlifyではリポジトリからwebhookを受け取ると自動でリポジトリをpullしてビルドとデプロイを行います。
また、コマンドラインからも静的サイトをアップロードしてくれます。
単純な静的サイトのデプロイであれば下記のコマンドを打つだけです。とても簡単。

```console

npm install netlify-cli -g
cd ~/my-static-website
netlify deploy

```

- 連携できるサービスが豊富

GitHubはもちろん、GitLab、Bitbucketにも対応しています。
また、zipファイルで静的サイトを丸ごとアップロードすれば公開してくれるので、
簡易なものであれば、GitHubとの連携も必要ありません。

- 完全無料のSSL/HTTPS

SSL/HTTPSに対応しており、独自ドメインの設定も可能です。


- アクセス制限

Netlifyではアクセス用のパスワードを設定することで、サイトを非公開にすることができます。（有料）

##無料プランについて

無料プランでは以下の機能が使えます。（※2018/06 現在）

- カスタムドメイン(独自ドメイン)設定
- 無料SSL証明書 (カスタムドメイン利用時のみ)
- OAuthを利用した閲覧ユーザー認証機能


やはり無料とは言っても、以下の制限が設けられています。

- ネットワーク転送量：100GB/月
- 容量：100GB
- デプロイ時のAPIリクエスト：500リクエスト/分

※なおチーム向け、法人向けの有料プランが存在し、有料プランにアップグレードすると複数人での管理機能の強化など便利な機能が開放されるみたいです。

##使ってみる

###STEP1　サインアップ

まずはアカウントを登録します。
アカウントの作成には「Github」「GitLab」「Bitbucket」のアカウント、メールアドレスでサインアップが可能です。
今回はBitbucketのアカウントでサインアップします。

<img width="910" alt="スクリーンショット 2018-03-09 9.34.50.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/140727/07e87cb4-21d9-8932-6fa1-a51d2a1ef257.jpeg">



###STEP2　プロジェクト作成
アカウントの作成が終わったらプロジェクトの作成を行います。
「New Site from Git」を選択して GitリポジトリからWebサイトを作ります。

<img width="1226" alt="スクリーンショット 2018-03-08 22.23.15.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/140727/74ea4d0a-afd4-6cdf-55bb-f32697198a17.jpeg">


<img width="849" alt="スクリーンショット 2018-03-09 9.53.52.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/140727/494128f3-33f4-9749-1b90-34acaf524055.jpeg">

まずはWebサイトのソースコードを管理しているサービスを選択します。
今回はBitbucketを選択。


<img width="NaN" alt="スクリーンショット 2018-03-09 10.02.17.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/140727/6051daa2-e738-ad0e-6375-e4cbcc314be1.jpeg">


サービスを選択すると、サービスに格納されているリポジトリの一覧が出るので、
作成するサイトのリポジトリを選択します。



![スクリーンショット 2018-03-09 10.27.42.jpg](https://qiita-image-store.s3.amazonaws.com/0/140727/af4deab8-5a4e-77c2-9a3a-8e1fa848594f.jpeg)


最後にブランチとビルド設定を行います。
NetlifyではCIのようなビルドタスクを実行する仕組みがあります。
ここで静的サイトジェネレータでページを生成するコマンドを設定すればサーバー側でコマンドを実行してくれるというわけです。

今回はwebpackを使用しているので、「npm run build」を設定します。
公開ディレクトリは「dist」を設定。
ビルド対象にするブランチは「master」を選択しておきます。
サイト公開後はリポジトリ側で、指定したブランチに変更があれば自動でビルドタスクが実行され、サイトが更新されます。



###STEP3 デプロイ
「Deploy site」をクリックすれば、初回のビルドが走ります。
正常に完了したときは、公開URLが表示され、トップページのサムネイルが表示されます。

デフォルトだと、自動生成された文字列がサブドメインとしてNetlify提供のドメインに割り当てられますが、
設定画面でドメイン名を変更できます。


![スクリーンショット 2018-03-09 10.43.48.jpg](https://qiita-image-store.s3.amazonaws.com/0/140727/8917817a-f4fa-c358-5e3d-e8e1cd3ce26a.jpeg)


公開URLを開いて、無事に静的サイトが公開されていれば完成です。
細かい設定などは[公式ドキュメント](https://www.netlify.com/docs/)を参照してください。


###参考
[高機能ホスティングサービスNetlifyについて調べて使ってみた](https://qiita.com/TakahiRoyte/items/b7c4d1581df1a17a93fb)
[netlify をお試ししてみた](http://dojineko.hateblo.jp/entry/2017/09/17/205259)
vim-plug導入

#vim-plugとは?
vimのプラグインマネージャー。つまり、vimのプラグインを導入しやすくしてくれるプラグイン、っといったところでしょうか

#導入方法
やり方は[こちら](https://github.com/junegunn/vim-plug)に書いてありますが、英語なのでかいつまんで説明したいと思います。
環境はmacでの導入を想定しています。windowsについてはいずれ、、、

##plug.vimをダウンロードする
plug.vimをダウンロードしてautoloadディレクトリに配置します。っていうコマンドがあるのでこれを叩きます。

```terminal:terminal

curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```

##.vimrcへの記述
.vimrcへ追記する必要があるのですが
`call plug#begin()`
と
`call plug#end()`
の間に
`Plug ~`のようにプラグインを追加していくシステムのようです。
例えばこんな感じ

```vim:.vimrc
call plug#begin()
Plug 'tpope/vim-sensible'
call plug#end()
```
.vimrcを保存して終了

##PlugInstall
.vimrcに記述しただけではプラグインが反映されないので、Installする必要があります。
どうするかというと、、、

vimを起動しコマンドで
`:PlugInstall`
と叩くと各プラグインのインストールが開始します。

これで正常終了した感じで表示されればプラグインの機能が使えるようになります。
rake taskで可変長引数を扱う

`to_a`メソッドを使えば良い。

```ruby
namespace :hoge do
  desc 'Sample'
  task :fuga, ['piyo'] => :environment do |task, args|
    p args.to_a
    p args
  end
end
```

```
$ bundle exec rake 'hoge:fuga[1,2,3,4]'
["1", "2", "3", "4"]
{:piyo=>"1"}
```

rake taskの引数はHashと説明されることがあるけど、実際はTaskArgumentsでこいつのto_aメソッドで引数の値をすべて取得できる。

* http://www.rubydoc.info/gems/rake/12.0.0/Rake/TaskArguments#to_a-instance_method

ググっていいやり方見つからなかったからリファレンス眺めてたら普通にあった。

# 追記 2020-06-01
`.extras` メソッドの方が適切な場合が多そう。名前付きパラメータにアサインされなかった分の引数を配列が返る（つまり上記の例だと `["2", "3", "4"]` が返る）

* https://www.rubydoc.info/gems/rake/Rake/TaskArguments#extras-instance_method

本当に今更だけど公式ドキュメント読んでたら書いてあった...

* https://ruby.github.io/rake/doc/rakefile_rdoc.html#label-Tasks+that+take+Variable-length+Parameters
素数大富豪の初手に関する考察

素数大富豪というトランプゲームが流行っているらしい。
[公式ルール](http://integers.hatenablog.com/entry/2017/06/28/020242)

## 主なルール
- n枚の手札(ルールにより異なるが7や11などの素数枚が多いらしい)を先に無くした人が勝ち
- 場に素数を出していく
- 10と3で103というように2枚出し、3枚出し……と任意の枚数を出すことが可能


従って、初手ですべてのカードを出して勝つことも可能らしい。
(なお、私は実際にプレイしたことがほとんどないためルールの認識が間違っているかもしれない……)

ということで確認する。

## 素数を作れない自明なパターン
- 全てのカードが偶数または5
  - どのように並べ替えても2の倍数または5の倍数となる 
- 全てのカードの和が3の倍数
  - どのように並べ替えても3の倍数となる 

## 検証ソース
```python
def is_prime(n):
    """試し割りによる素数判定"""
    assert(isinstance(n, int))
    assert(n > 0)
    if n == 1:
        return False
    if n == 2:
        return True
    divisor = 2
    while divisor ** 2 <= n:
        if n % divisor == 0:
            return False
        divisor += 1
    return True
```
```python
def is_all_even_or_five(tefuda):
    return all([x % 2 == 0 or x == 5 for x in tefuda])
```
```python
def is_three_multiple(tefuda):
    return sum(tefuda) % 3 == 0
```
```python
import random
from collections import defaultdict

result_dict = defaultdict(int)

def can_zendashi(tefuda, precision=10000):
    if is_all_even_or_five(tefuda):
        result_dict['全部偶数か5'] += 1
        return False
    if is_three_multiple(tefuda):
        result_dict['3の倍数'] += 1
        return False
    for _ in range(precision):
        # 適当に並べ替えて素数かどうか判定する
        random.shuffle(tefuda)
        num = int(''.join(list(map(str, tefuda))))
        if is_prime(num):
            result_dict['素数'] += 1
            return True
    result_dict['たぶん無理'] += 1
    return False
```

適当に1000回ほど回してみた。

```
{'素数': 678, '全部偶数か5': 8, '3の倍数': 314}
```

## 結論
かなり雑に検証したが、およそ2/3の確率で(理論上)ワンターンキルできてしまう。
ジョーカーや山札から手札に加える行為を考慮していないため、上記の確率はさらに上がりそう。
エンジニアとして成功するための大事なことトップ3


# エンジニアとして成功するための大事なことトップ3
Youtubeの要約です。
先日すごく感銘を受けた動画を見ましたので、シェアさせてください。
もっと短く要約しようと思ったのですが、ほとんど和訳になってました。ところどころ省略しているところもありますので、全文訳で無いことは注意です。


### 3 top qualities for a Software Engineer to be successful
Techlead Google Youtube 
Patrick Shyu

## 【導入部分】
手を早く動かす事はとても大事。何も意味がなくても、キーボードを早く叩いたり、マウスを動かしたり、「早く動く真似事」をするだけでも体が早く動く事に慣れるので、普段からやっておくと良い。



## 1 【インパクト】
エンジニアにとって重要なのは、単にとても多くのバグを無くすだけでも、リファクタリングするだけでも、フレームワークを作るだけではないです。
重要なのはポジティブなインパクトを会社に与える事です。インパクトは計測可能でなければならなくて、例えば、Webサイトへの流入を◯％向上したとか、リファクタリングによってパフォーマンスが◯％向上したなどです。
つまり言いたいのはバグの改修やリファクタリングを行ったのであれば、その効果が明示出来なければ会社からあなたの功績は見えないのです。

どうするか？
もしバグがあれば、バグをリストアップしてまとめてみましょう。まとめたタスクに、パフォーマンスに関係するバグを解決するというストーリーを付けて、パフォーマンスを計測してみます。そしてもしそれが20％のパフォーマンスを向上させたとなると、それはあなたが会社にあたえたインパクトになります。　チームを結成して取り組む事も出来ます。

リファクタリングについて。
リファクタリングに取り掛かる前にあなたは、知っておくべき事があります。それは、会社がどんな方向にリファクタリングしていきたいかです。　もし会社がオブジェクト指向プログラミングから関数型プログラミングに移行したい意思があるのに、オブジェクト指向のままリファクタリングすべきではありません。その行為のインパクトは無いものになってしまいます。


## 2【難しさの解決 (技術的・組織的・不明確なこと)】
難しさには、技術的、組織的、不明確な事の難しさがあります。
技術的な難しさは、すごく難解なアルゴリズムを構築したり、機械学習を駆使したりする事です。
組織的な難しさとは、大きな会社は既にもっているシステムがお互いに複雑に絡み合っていて、その事に対する対応や、複数のチームとコミュニケーションを行う事です。
不明確な事（アンビギュイティー）への難しさとは、誰も分からない事への取り組みです。誰も何を選択して良いのかわからないことです、例えば、どのフレームワークを使えば良いのかさっぱりな状態とか。もしその状態であなたが、ドキュメントを読んでメリットデメリットなどを提示すればプロジェクトは前に進むことができ、不明確な事へ対応するスキルがあると会社は認識します。
大事なことは、上記のように、もしあなたが何か難しい事に対面したら、その重要な瞬間から避ける事をせず果敢にチャレンジしてみてください。


## 3【イニシアチブ・リーダーシップ】
イニシアチブ・リーダーシップは軍隊的なものではなくて、
メンタリングをしたり、他人を手助けしたりする事で、自然に育まれていくものです。技術的なバックグランドや組織的なバックグランドはとても良いアドバイスをするのに役立つでしょう。
リーダーシップは役職に付くものではなく、役職があるから尊敬されるわけではありません。もしリーダー・マネージャーという役職を持っていても上記のように他人を助けたりする事をしなければ、もうリーダー・マネージャーではありません。
それらの事であなたが、会社から信用を得ることが出来ると自分のプロジェクトをする事が出来ます。同じ量の仕事でも誰かのアイディアの仕事をするよりか、自分のアイディアの仕事を進める方が、あなたのキャリアに良い影響を及ぼします。


## 【さいごに】
会社の中だけではなくて人生でも、それらの事は実践可能です。
例えば、家族旅行をプランニングすることは、不明確だし、複雑な事ですが、家族にとってとても良いインパクトを与えて、みなが喜びます。

プロダクトを作っているのであれば、最適化を進めるよりも、より早くマーケットに出してみます。そのことはマーケットにインパクトを与えますし、多くの学びがあります。

多くのエンジニアがクオリティの高いエンジニアとは、多くのGitHubプロダクトを行ったり、クラスのプロジェクト（大学生は）を行ったり、VimやEmacsなどのエディターを使いこなしたり、Macが良いかWindowsが良いかなどを考えたりすることを言います。
それらの事は、3つの重要な事のレンズを通して見ると良いです。
例えば、クラスプロジェクトはインパクトはゼロです。なぜなら、大学の中でのプロジェクトなのでリリースされる事はありません。技術的な難しさはあるでしょう。リーダーシップはゼロです。なぜなら教授があなたをアサインするからです。VimとEmacsどちらを選ぶかには、インパクトも複雑さもイニシアチブもありません。

オープンソースプロジェクトを通して3つの事が学べます。オープンソースプロジェクトはいくらかのインパクトを与える事が出来ます。技術的な複雑さもあります。まちがいなくイニシアチブがあります。


---

個人的な感想としては、会社を社会という風に置き換えて理解することも出来るなと思いました。
今回、動画の内容を詳細に理解するために手伝ってくれた同僚や、内部用にシェアしたものを読んでくれて面白いからシェアしてみたらと言ってくれた仲間に感謝します。
Mac環境のAndroidStudioでエミュレーターを使ったデバッグができないときの対処法

MacでAndroidアプリを作りたいと思い、AndroidStudioを導入しました。

https://techacademy.jp/magazine/1531

このサイトを参考に環境構築していったのですが、エミュレーターでのデバッグが実行できなくて困ってしまいました。
エミュレーターは起動するものの、以下のようなダイアログが出てきてデバッグが実行できませんでした。

![スクリーンショット 2018-03-08 10.24.46.png](https://qiita-image-store.s3.amazonaws.com/0/154305/30c3040c-5d27-f984-cbbe-d59919f5e24e.png)

また、

```
java.io.IOException: Unable to open sync connection!
Error while Installing APK
```

というエラーも発生しました。

ですがなんとか対処してデバッグを実行できたので、その方法を書いていきます。

# 環境

- MacOS 10.13.3
- Android Studio 3.0.1

# 1.AndroidStudioの設定変更

上メニューの「AndroidStudio」から「Preferences」を選択します。
ウィンドウの左メニューの「Build,Execution,Deployment」から「Instant Run」を選択します。
そこにある、「Enable Instant Run to hot swap code/resource changes on deploy (default enabled)」のチェックを外します。

![スクリーンショット 2018-03-08 20.33.27.png](https://qiita-image-store.s3.amazonaws.com/0/154305/8c5dd287-756d-5970-2863-c9c737bc35b0.png)

# 2. adbコマンドを使えるようにする

>Android Debug Bridge（adb）は、エミュレータ インスタンスや接続された Android 端末と通信できる用途の広いコマンドライン ツールです。また、アプリのインストールやデバッグなどのさまざまな端末アクションを支援し、エミュレータや接続された端末でさまざまなコマンドを実行するときに使用できる Unix シェルへのアクセスを提供します。 https://developer.android.com/studio/command-line/adb.html?hl=ja

ターミナルで```adb```したときに、```adb: command not found```が出た場合は、adbコマンドを使えるようにしなければなりません。

adbコマンドを使えるようにするには、シェルの設定ファイルに環境変数を設定します。
その前に、AndroidSDKの場所を確認します。

AndroidStudioで、上メニューの「File」から「Other Settings」>「Default Project Structure」を選択します。
出てきたウィンドウの「Android SDK location」にあるパスがAndroidSDKの場所です。
![スクリーンショット 2018-03-08 22.12.08.png](https://qiita-image-store.s3.amazonaws.com/0/154305/3f579955-9483-7ec6-2efd-f021ac0e5be5.png)

次に、設定ファイルに環境設定ファイルを設定します。
設定ファイルは使っているターミナルがbashであれば```.bash_profile```、zshであれば```.zprofile```です。その他は検索してください…。

設定ファイルをテキストエディタで開いたら、

```
export PATH=$PATH:/Users/xxx/Library/Android/sdk/platform-tools
```

を追加します。パスに```platform-tools```を追加するのを忘れないように。
また、パスは適宜自分の環境に合わせて変えてください。

その後、

```
source ~/.bash_profile
```

を実行して設定ファイルを更新します。

# 3. platform-tools以下のファイルをroot権限にする

```
sudo chown -R root: /Users/xxx/Library/Android/sdk/platform-tools/*
```

# 4. adbサーバーを再起動

以下のコマンドをMacのターミナル上で実行します。

```
sudo /Users/xxx/Library/Android/sdk/platform-tools/adb kill-server
sudo /Users/xxx/Library/Android/sdk/platform-tools/adb start-server
```

# 5. Macの再起動

Mac自体も再起動します。

これでデバッグが実行できると思います。


# 参考
[adbをMacのターミナルで使えるようにする](https://qiita.com/furusin_oriver/items/f956848788c7a63922bd)
[Must do adb kill-server and start-server everytime to recognize android device in Ubuntu
](https://stackoverflow.com/questions/16364748/must-do-adb-kill-server-and-start-server-everytime-to-recognize-android-device-i)
Linuxのwineで「艦これ一覧めいかー改ニ」を動かす

そのままでも動画キャプチャー機能とtwitter連携以外は問題なく動作するはず。

ここでは動画キャプチャーとその音ずれ対策について行った事を書いていく。前者はdllを置換するだけだが、後者はソースに修正を加えてコンパイルするのでwindows環境が必ず必要になる。

個人の環境に大きく依存しそうなので参考程度に。

* 艦これ一覧めいかー改ニ  
  Ver0.12
* 作業環境  
  Arch Linux 64bit  
  VMWare上の Windows 10 64bit


## 動画キャプチャーを使えるようにする

ffmpeg.exeがエラーを吐くのが問題なのでそれの対応をする。

1. windows環境から下記のdllをコピーしてくる。

    ```
    C:\windows\System32\quartz.dll -> ~/.wine/drive_c/windows/system32/quartz.dll
    C:\windows\System32\qcap.dll -> ~/.wine/drive_c/windows/system32/qcap.dll
    C:\windows\System32\downlevel\api-ms-win-core-privateprofile-l1-1-0.dll -> ~/.wine/drive_c/windows/system32/api-ms-win-core-privateprofile-l1-1-0.dll
    ```

2. winecfgでdllオーバーライドの設定を行う。

    `winecfg`を起動し、ライブラリダブで`quartz.dll`と`qcap.dll`を追加する。


## 音ずれを修正する

[艦これ一覧めいかー改二のソース](https://github.com/kanahiron/KanColleListMakerKaini)を修正して**[Hot Soup Processor](http://hsp.tv/)**でコンパイルする。

1. ソースに差分を適用する

    ```
    --- a/src/sub/VideoCapture.hsp
    +++ b/src/sub/VideoCapture.hsp
    @@ -192,20 +192,12 @@
     		diffTime = 0.0
     
     		if (vStartTime!=0.0 && aStartTime!=0.0){
    -			vStartTime = 11644473600.0+vStartTime
     			dim FILETIME, 2
     			GetSystemTimeAsFileTime varptr(FILETIME)
    -			aStartTime = -0.001*timeGetTime() + aStartTime + (4294967295.0*FILETIME(1) + (FILETIME(0)&0x7FFFFFFF) + -2147483648.0*((d(0)&0x80000000)>>31) )/10000000.0
    -			diffTime = (aStartTime-vStartTime)/1000
    -			//2秒以上ズレずれていたら無かったことにする
    -			if ( absf(diffTime)>2.0 ){
    -				diffTime = diffTime2
    -			}
    -		}
    -
    -		//2秒以上ズレずれていたら無(ry)
    -		if ( absf(diffTime)>2.0 ){
    -			diffTime = 0.0
    +			mtime = double(timeGetTime()) / 1000.0
    +			ftime = double(strf("%u", FILETIME(1))) * 4294967296.0 + double(strf("%u", FILETIME(0)))
    +			utime = ftime / (10000.0 * 1000.0) - 11644473600.0
    +			diffTime = (vStartTime - (aStartTime + (utime - mtime)))
     		}
     		
     		logmes "vStartTime :"+vStartTime
    ```

2. HSPのインストールとエディタのUnicode対策

    HSPをインストールする。

    一覧めいかーのソースはutf-8だが、HSPスクリプトエディタは非対応なので……
    1. あらかじめSJISに変換する。
    2. Unicode対応HSP「hsp3utf」を使う。
    3. 自分が知らないだけで楽な解決策がある。

    今回は2の方法で。

    `hsp3utf_20170824b.zip`をダウンロード・展開。`hsed3utf.exe`を`hsed3.exe`に名前変更してHSPインストール先のファイルを上書きする。

3. コンパイル

    `src/main.hsp`をHSPスクリプトエディタで開いて、`メニュー > HSP > 実行ファイルの自動作成`を実行する。文字化けしたファイル`濶ｦ縺薙ｌ荳隕ｧ繧√＞縺九・謾ｹ莠・.exe`が生成されるので`艦これ一覧めいかー改二.exe`に名前変更する。

4. あとはLinux環境に持っていって実行するだけ
JavascriptとRubyの演算子(== & ===)の違い

# Introduction

僕はJavaScriptからプログラミングの学習をスタートし、2年間フロントエンジニアとして、JavaScriptを書いてきた。その後バックエンドエンジニアに転身し、Rubyのコードをガリガリ書くようになった。
コードレビューを受けているうちに、

>「RubyとJavaScriptの==と===の違いをちゃんと理解して使ってる？」

いう指摘を受けた。

僕はしばらくJavaScriptのノリでRubyを書いていて、同じようなものだろうと思っていた。しかし、調べたら全然違うものだった。
この辺を理解していなかったら、いずれなんらかの罠にハマっただろう。


# Rubyの `==` 

・同じデータ型で、かつ同じ値だったら、trueを返す
・値が同じであっても、データ型が異なればfalseを返す

### Example

```rb

1 == 1
=> true 

1 == "1" # 数値と、文字列を比較
=> false

```

## JavaScriptの `==`

・同じ値だったらtrueを返す
・データ型が異なっても、値が同じであればtrueを返す!

### Example

```js

1 == 1
=> true

1 == "1" // 数値と、文字列を比較してもtrueが返ってくる。
=> true 
```

このように、Rubyの` ==`はちゃんと比較してくれるけれど、JavaScriptの`==`の比較はゆるい。

## Rubyの `===`

・結構ややこしい。
・比較の対象が、どちらもオブジェクトの場合、`==`と同じ挙動
### Example

```rb

1 === 1 # どちらもオブジェクトなので == と同じ挙動。
=> true 
```

・左辺がクラスの場合、右辺のオブジェクトが左辺のクラスのインスタンスかどうかを判定する。
・左辺のクラスが右辺のインスタンスであればtrueを返す。
・この比較は、case式でオブジェクトをテストするときに利用される。
  参照: https://ref.xaio.jp/ruby/classes/module/eqq
### Example

```rb

String === "hello" #"hello"はStringクラスのインスタンスなのでtrue
=> true 

String === [] #[]はArrayクラスのインスタンスなのでfalse
=> false 

Array === [] #[]はArrayクラスのインスタンスなのでtrue
=> true 

```

## JavaScriptの `===`

・同じデータ型で、かつ値が同じであればtrueを返す
・つまりRubyの `==`と同じ

### Example
```js

1 === 1
=> true

1 === "1"  // データ型が異なるので、ちゃんとfalseになる
false

```

・このように、Rubyの`===`は使用ケースがあまり思いつかない。一方、JavaScriptの`===`は、しっかり比較してくれるので積極的に利用すべきだと思う。

# Summary


・JavaScriptの`==`はゆるい比較になるので、基本的には`===`を使用する
・Rubyの`==`はしっかり比較してくれるので、基本的に`==`を利用する
・注意すべきはJavaScriptの `===`を使用するノリで、Rubyで`===`を使うこと。
・同様に、Rubyの`==`を使用するノリで、JavaScriptで`==`を使うこと。
・細かい所だけど、言語間でまったく違った意味になるので、ちゃんと理解してから使う。
エンジニアの二年目病とその予防法③

こんばんは。10分で生産的なミーティングができるWebサービス「[minmeeting](https://minmeeting.jp/)」を開発している伊勢川です。

<a title="minmeeting - 10分で生産的なミーティングができる会議ツール" href="https://minmeeting.jp/" target="_blank"><img width="100px" src="https://qiita-image-store.s3.amazonaws.com/0/199506/32e65577-a5bb-2c3b-4d30-4690c3c5ce0f.png" /></a>

3月に突入し、もうすぐ新人エンジニアの皆さんも二年目の先輩エンジニアになることでしょう。そこで、余計なお世話ですが、<B>二年目エンジニアが陥りがちな症状と予防法</B>を何回かの連載で紹介しています。

昨日は少し意識が高い人の症例を紹介しましたが、本日は<B>気が効く頑張りやさんがなりやすい</B>症状をご紹介します。

# 雑用ホイホイ症候群
二年目ともなるとそれなりに仕事に慣れて、雑用も素早くこなせるようになります。しかし、素早くても雑用ばかりやっていると生産性はあがりません。<B>雑用をホイホイ受けてしまって、自分の生産性も上がらないし、後輩の教育にもならない</B>症状を「雑用ホイホイ症候群」と呼ぶことにします。

## 症例
仕事を頼まれたら、これまでやっていたことを放ったらかして、すぐそちらに着手してしまう。後勝ちで、ところてん式に以前のタスクが遅延していく。

あまり意味はないと思いつつも、先輩から引き継いだ雑用を、そのまま意味も分からずに後輩に引き継いでしまう。

逆に、新人にはもってこいの比較的簡単でちょっと勉強になる雑用も、これまでの流れで自分でこなしてしまう。

## 予防法
「この仕事、オレがやる必要ある？」という視点は大事ですが、だいたい<B>1〜3年目くらいが振られる仕事は先輩たちが</B>若手のためにちょうどいいだろうと思って<B>わざわざ段取りしてくれたような仕事が多い</B>です。そのため、偉そうなことを言って突き返されるとがっかりします。ありがたく頂戴して<B>自動化</B>をしたり、誰でもできるように<B>ドキュメントを整理</B>したりするとよいでしょう。

<B>小さな業務の自動化は勉強になる</B>ので、最初のうちは多少コスパが悪くても積極的に取り組むとよいでしょう。

自動化とドキュメンテーションをきちんとやっておけば、さらに上のレベルの仕事が来た際に、すぐに他の人に引き継ぐことができ、次のステージにスムーズに移行できるでしょう。

そして将来的には、そいういった雑用が<B>本当にやる必要があるのかを判断し、辞める決断が下せる</B>立場になってください。

# バックナンバー
1. [エンジニアの二年目病とその予防法①　Google依存症](https://qiita.com/Akira-Isegawa/items/220dcbd9a1639099a325)
1. [エンジニアの二年目病とその予防法②　すぐできる・なんでもできる病](https://qiita.com/Akira-Isegawa/items/d62eea7a7804ecc5fb2e)
Javaで複数行文字列を実現するライブラリmultiline-string


# はじめに

Javaでコードを書く時の悩みが、「複数行に渡る文字列をどう表現するか」でした。本番環境で動くものならファイルに保存すればいいのですが、単体テストで使う場合、コードとデータはなるべく近い場所に置きたいです。

さすがにこれは無理かなと思ってたのですが、[multiline-string][]というライブラリを見つけました。

# ライセンス

READMEに記載はありませんが、[pom.xml](https://github.com/benelog/multiline/blob/master/multiline-string/pom.xml)によれば、「Common Public License Version 1.0」のようです。

# 前提条件

JDK 6以上です。JDK 8で確認しています。

# 準備

概要だけ書きます。詳しくは、[Maven project with Eclipse · benelog/multiline Wiki](https://github.com/benelog/multiline/wiki/Maven-project-with-Eclipse)を参照してください。

1. 依存関係の定義
   - jcenterで配布されているのだけ注意してください。
2. Annotation Processingの定義
   - IntelliJ IDEAの場合: [Annotation Processors - Help | IntelliJ IDEA](https://www.jetbrains.com/help/idea/annotation-processors.html)

# 使い方

以下のように記載します。

- `@Multiline`アノテーションを付ける
- Javadocコメント中(`/**`〜`*/`)に記載(通常のコメントは不可)
- 先頭の空白は保持されるため、 `@formatter:off`, `@formatter:on` を付けて自動整形をオフ
  - `@formatter` はIDEの機能なので、IDEの設定を確認してください。

```java
    // @formatter:off
    /**
<xml version="1.0" encoding="utf-8" ?>
<root>
</root>
     */
    // @formatter:on
    @Multiline
    public static String XML;
```

この文字列を出力すると、以下のようになります。

```
<xml version="1.0" encoding="utf-8" ?>
<root>
</root>
```

# 仕組み

[multiline-string][]の先頭に記載されていますが、元々はこちらの記事が元になっています。こちらを紹介しても良かったのですが、Mavenリポジトリにある方が使いやすいと思い、[multiline-string][]を紹介しました。

- [adrianwalker.org: Java Multiline String](http://www.adrianwalker.org/2011/12/java-multiline-string.html)

この記事にあるように、Pluggable Annotation Processing APIの[javax.lang.model.util.Elements#getDocComment(Element)][] メソッドでJavadocコメントを取得しています。

# おわりに

[Pluggable Annotation Processing API(JSR269)][JSR269]は難しそうだと思ってまだ手を出してなかったのですが、自分でも作ってみようかなと思いました( ´ω`)

[JSR269]: https://jcp.org/en/jsr/detail?id=269
[multiline-string]: https://github.com/benelog/multiline
[javax.lang.model.util.Elements#getDocComment(Element)]: https://docs.oracle.com/javase/jp/8/docs/api/javax/lang/model/util/Elements.html#getDocComment-javax.lang.model.element.Element-
Vim script で「あとで処理を実行する」ための定型処理を vital の外部モジュール化した

Vim のプラグインを書くときに、後でこの処理を実行したい、ということがしばしばあります。この場合二つの選択肢があり、自動コマンド (`:help :autocmd`) かタイマー (`:help timer`) が使えます。ところがこの二つは全く異なるインターフェースをもっており、似たような目的であっても全く違った記述をしなければなりません。また組み合わせて使う場合にはコードが複雑になりがちです。

また、Vim script あるあるの一つだと思うのですが、一回だけ自動コマンドで処理したい、ということがよくあります。この場合自動コマンドイベントに関数をセットし、その関数自身が自動コマンドを解除することで実現します。

```vim
function! s:main() abort
  " set the autocmd event for s:run_once()
  augroup my-group
    autocmd!
    autocmd WinLeave * call s:run_once()
  augroup END
endfunction

function! s:run_once() abort
  call s:do_something()

  " unset the autocmd events
  augroup my-group
    autocmd! WinLeave
  augroup END
endfunction
```

が、正直毎回これを書くのは面倒くさいです。そもそも実行したいのは `s:do_something()` なのに、`s:run_once()` のような関数でラップする手間がかかります。このような定型作業は繰り返したくありません。

# vital-Schedule をつかう

[vital-Schedule](https://github.com/machakann/vital-Schedule)

`vital-Schedule` は上のような不満を解決するためのモジュールです。上の例を `vital-Schedule` を使って書き直してみます。

```vim
let s:Schedule = vital#{pluginname}#new().import('Schedule')

function! s:main() abort
  " set task
  let task = s:Schedule.Task()
  call task.call(function('s:do_something'), [])
  call task.waitfor(['WinLeave'])
endfunction
```

`task.call()` メソッドは組み込みの `call()` 関数と同じインターフェースを持っています。このメソッドに渡された関数が後で実行されます。これに直接 `s:do_something()` を渡すことにより、 `s:run_once()` が必要なくなりました。自動コマンド周りの諸々の手続きは `vital-Schedule` が代替します。

もっと具体的な例を考えてみましょう。例えば何らかの編集を行い、その行を一定時間ハイライトしたい場合を考えてみましょう。ハイライトはタイマーをつかい時間経過で消すのですが、ユーザーがそれ以前に次の編集を開始した場合にも消したいとします。つまり、タイマーと自動コマンドの組み合わせです。

```vim
let s:Schedule = vital#{pluginname}#new().import('Schedule')

function! s:highlight(lnum, duration) abort
  let id = matchaddpos('MyPluginHigroup', [a:lnum])

  " set task
  let task = s:Schedule.Task()
  call task.call('matchdelete', [id])
  call task.waitfor([a:duration, 'TextChanged', 'TextChangedI'])
endfunction
```

`s:highlight()` 関数に行番号とハイライトの持続時間を渡すと一時ハイライトをしてくれます。(実際にはバッファやウィンドウを移動した場合なども考える必要があるかもしれません)

タイマーと自動コマンドを組み合わせて、「どれか最初に発火したもの」という条件で登録した関数を実行しています。

---

コンストラクタ (のようなもの) に文字列を渡すことで augroup を指定することができます。これは省略可能で、省略した場合は `vital-Schedule` が使われます。 augroup なしではありません。人類は augroup なしの自動コマンドを定義すべきではありません。

```vim
let Schedule = vital#{pluginname}#new().import('Schedule')
let task = Schedule.Task('my-group')
```

あるいは `augroup()` 関数を使うと augroup の固定されたモジュールのコピーが使えます。下の例は上の例と同じ意味になります。

```vim
let Schedule = vital#{pluginname}#new().import('Schedule').augroup('my-group')
let task = Schedule.Task()
```

---

あまり vital.vim のことをよくわからずに書いているので、おかしいところがあったら教えていただけるとありがたいです。 `:help vital.vim` すると、 [How to make a vital module](http://d.hatena.ne.jp/thinca/20110311/1299769233) と [External vital modules](https://github.com/vim-jp/vital.vim/wiki/External-vital-modules) へのリンクがありましたが前者の情報は古いっぽい？ `:help` から読めるとうれしいんだけど翻訳するのは大変そう。

あと今回、辞書関数を積極的に使ってみたらスタックトレースに関数名が出ず、デバッグ作業が地獄と化しました…なにかいい方法はないものか…
ラズパイで花が開花する様子をタイムラプス撮影する

## やったこと

- ラズパイとラズパイ標準カメラを使って10分に一回花の撮影をする
- 撮影した画像をffmpegを使ってmp4（パラパラ漫画風）に変換

（クリックでYoutubeに飛びます）
[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/_XCx7uaWSws/0.jpg)](https://www.youtube.com/watch?v=_XCx7uaWSws)

[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/pPORuDOHNQw/0.jpg)]
(https://www.youtube.com/watch?v=pPORuDOHNQw)

結構お手軽にできます。

## ラズパイとラズパイ標準カメラを使って10分に一回撮影する

やり方は方法などはこちらのブログからまるっと拝借しました

- [Raspberry Piで自動撮影してタイムスタンプ入りタイムラプス動画を生成する方法 - karaage. [からあげ] ](http://karaage.hatenadiary.jp/entry/2016/05/17/073000)

上記ブログで撮影用のコードも公開されているのでcloneしてきます

- [https://github.com/karaage0703/denpa-gardening](https://github.com/karaage0703/denpa-gardening)

基本的には上記のコードを使って

```
$ python shutter.py
```
を実行すれば写真が1回分撮影されるので、cronを使って10分に一回 `shutter.py`が実行されるようにします

crontabでcronのエディターを表示

```
$ sudo crontab -e
```

10分に一回撮影する場合は以下のように記述

```
*/10 * * * * python /home/pi/denpa-gardening/shutter.py
```

ちなみに、もし10秒に一回撮影したい場合はこんなふうに指定するらしい

```
* * * * * for i in `seq 0 10 59`;do (sleep ${i} ; python /home/pi/denpa-gardening/shutter.py) & done;
```

crontabの記述が正しく書けた場合は保存してエディターを閉じると 「新しいラインを記録したよ」みたいな表記がでる

これで撮影された画像は `photo_data`ディレクトリ下に格納されていきます。

トップページに貼ったヒヤシンス動画の場合、約3週間弱の期間を10分間隔で撮影し続け、得られた2000枚ほどの画像から作成しています。

## 撮影した画像をffmpegを使ってmp4に変換

撮影したjpeg画像をパラパラ漫画のように繋げて、（タイムラプス）動画を作成します。linuxのコマンドツールである`ffmpeg`を利用します。

自分の場合は、ラズパイへscpして `photo_data`下の画像を全て母艦のMacに転送しました。`ffmpeg`の処理がそこそこ重いのでMacへ移動させましたが、そこまで多くの画像枚数が無いのであればラズパイ上で画像→動画作成の処理をしても良いかもしれません。その場合は[こちらのブログ](http://karaage.hatenadiary.jp/entry/2016/05/17/073000)を参考にして`avconv`で作成してみてください。

以下は`ffmpeg`を使う場合です。

```
# 例
$ ffmpeg -f image2 -r 30 -i %04d.jpg -r 30 -an -vcodec libx264 -pix_fmt yuv420p video.mp4
```
ここで生成される`video.mp4`が目的のタイムラプス動画となります。

### ffmpegの引数について

それぞれのパラメータの意味は[こちら](https://qiita.com/riocampos/items/2f4fe927b5cf99aff767)を参照

ここで最も重要なパラメータは `-r`と`-i`です。

`-r`は1秒間を何フレームで表現するかという引数です。  
上記例では30としているので30フレームが1秒となる動画が作成される。撮影時は10分で1フレームを撮影していたので、30フレームは300分=5時間、つまり5時間を1秒に圧縮したタイムラプス動画を作成することになる。

`-i`は静止画名を表す表記の仕方で、`%04d`で4桁、`%05d`で5桁の数字を表します。  
上記例では 0000.jpgから9999.jpgまでのファイル名を指定していることになります。最も注意すべき点としては、ffmpegは`-i`で指定するファイル名を0001から始まる連番にしなければいけないです。ただ単に連番にするだけでなく、0001から始めないといけないのがポイント。  
仮に、途中に存在する余計なフレームを削除したりして完全な連番でなくなった場合は新たに全ファイル名をrenameして0001から始まる連番にしないといけません。そんなときはMacであれば homebrewでinstallできる`rename`コマンドなどがオススメ。使い方は簡単です。

```bash
$ brew install rename
# 例
$ rename -N 0001 -X -e '$_ = "$N"' *.jpg
```

`-N`でスタートする番号を指定します。ここでは0001をスタートとして指定したので、0001.jpg~9999.jpgに一括でファイル名をrenameしてくれます。

- renameコマンドの使い方参考: [https://qiita.com/GENYA/items/c3bdd6b187c2a9e40be1](https://qiita.com/GENYA/items/c3bdd6b187c2a9e40be1)
redirect_to で urlを指定する時にハマるところ

#rails リファレンス参照したのにうまくいかないぞ......
詳細:http://railsdoc.com/references/redirect_to
こちらの
<img width="906" alt="スクリーンショット 2018-03-08 21.53.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/236412/9d5fffda-911a-3668-b298-7a5014ccd303.png">

ここをそのまま書いたらエラー画面が....

![image.png](https://qiita-image-store.s3.amazonaws.com/0/236412/3fb5a2e5-7d66-f297-653c-4ed4b22db7f5.png)


#解決策
aタグいらない ！！！
これは完全にリファレンスのミスだと思う
redirect_to "http://www.rubyonrails.org"
で大丈夫
ドットインストールの無料コンテンツから選んだ、Webエンジニアになるなら最低限知っておいてほしい技術知識

経験・知識ゼロのところからWebエンジニアになる人が増えてきていると感じています。

そういう人たちがまずわかるようになっておくべき知識を、ドットインストールの2018年3月8日時点での無料コンテンツからリストアップしました。  (勤務先で使っている言語の関係もあり、一部技術に偏りがあります。) Webのバックエンドエンジニアを想定しています。

会社や仕事内容でそれぞれ事情は違うのかもしれませんが、ひとりで開発していくには最低でも下記コンテンツはすべて理解できるようになっている必要があると思いました。

## Web 基礎

* [HTML入門 (全24回)](https://dotinstall.com/lessons/basic_html_v3)
* [CSS入門 (全23回)](https://dotinstall.com/lessons/basic_css_v3)
* [CSS3入門 (全19回)](https://dotinstall.com/lessons/basic_css3_v2)
* [CSSレイアウト入門 (全15回)](https://dotinstall.com/lessons/basic_css_layout)
* [実践！ウェブサイトを作ろう (全17回)](https://dotinstall.com/lessons/website_html_v2)
* [CSSで吹き出しを作ろう (全8回)](https://dotinstall.com/lessons/balloon_css)
* [レスポンシブウェブデザイン入門 (全14回)](https://dotinstall.com/lessons/basic_responsivewebdesign)

## プログラミング基礎

単純にjavascriptの無料コンテンツが多かったので、javascriptが多くなっています。 あまり偏らず、 Ruby, PHP, javascript のコンテンツがわかるようになれば、まあ安心して開発できるレベルには届くんじゃないかと思いました。

* [JavaScript入門 (全24回)](https://dotinstall.com/lessons/basic_javascript_v2)
* [JavaScriptでおみくじを作ろう (全9回)](https://dotinstall.com/lessons/omikuji_js_v3)
* [JavaScriptで5秒当てゲームを作ろう (全9回)](https://dotinstall.com/lessons/just_five_js_v3)
* [JavaScriptで作る誕生日診断 (全5回)](https://dotinstall.com/lessons/date_js)
* [JavaScriptで割り勘電卓を作ろう (全12回)](https://dotinstall.com/lessons/go_dutch_js_v3)
* [JavaScriptでパスワードジェネレータを作ろう (全8回)](https://dotinstall.com/lessons/pwd_generator_js_v3)
* [JavaScriptで文字数チェッカーを作ろう (全8回)](https://dotinstall.com/lessons/char_checker_js_v3)
* [JavaScriptでストップウォッチを作ろう (全13回)](https://dotinstall.com/lessons/stop_watch_js_v4)
* [JavaScriptでカウントダウンタイマーを作ろう (全12回)](https://dotinstall.com/lessons/countdown_js)
* [HTML5で作るシンプルメモ帳 (全8回)](https://dotinstall.com/lessons/memo_html5)
* [jQuery入門 (全20回)](https://dotinstall.com/lessons/basic_jquery_v2)
* [jQueryで作る先頭へのジャンプ機能 (全4回)](https://dotinstall.com/lessons/scroll_js)
* [PHP入門 (全30回)](https://dotinstall.com/lessons/basic_php_v2)
* [PHPで作る簡単サイコロ (全2回)](https://dotinstall.com/lessons/dice_php_v2)
* [PHPで作る簡易掲示板 (全9回)](https://dotinstall.com/lessons/bbs_php_v2)
* [PHPで作るページング機能 (全10回)](https://dotinstall.com/lessons/paging_php_v2)
* [PHPでビンゴシートを作ろう (全7回)](https://dotinstall.com/lessons/bingo_php_v2)
* [PHPとjQueryで実装する「もっと読む」 (全9回)](https://dotinstall.com/lessons/more_php_v2)
* [Ruby入門 (全26回)](https://dotinstall.com/lessons/basic_ruby_v3)
* [Ruby on Rails 5入門 (全28回)](https://dotinstall.com/lessons/basic_rails_v3)
* [Canvasでお絵かきアプリ (全8回)](https://dotinstall.com/lessons/doodle_canvas)

## Linux

サーバの一通りのコマンドは最低でも知っておいてほしいです。

* [UNIXコマンド入門 \[一般ユーザー編\] (全24回)](https://dotinstall.com/lessons/basic_unix_v2)

## データベース

SQLは理解できるようになっておきましょう。

* [PostgreSQL 入門](https://dotinstall.com/lessons/basic_postgresql)

## Virtual Environment

現場によって使う・使わないあると思いますが、知っておくと吉です。

* [Vagrant](https://dotinstall.com/lessons/basic_vagrant)

## Web ツール

ツールが使えるか使えないかで開発スピードは激変します。 寧ろエンジニアでツール使わない人いないと思いますが。

* [Chrome Developer Tools入門 (全10回)](https://dotinstall.com/lessons/basic_chrome_dev_v2)

## VCS

開発をスタートするには必須の知識です。 (現場によって SVN, Mercurial を使っているところもあるとは思いますが。)

* [git入門 (全22回)](https://dotinstall.com/lessons/basic_git)
重複を避けてファイル名を決定するShellScript

自動的にファイルを生成するようなシステムを作った時に、ファイルを上書きしてしまわないために作った仕組み

追記(2018/03/09)
このプログラムはファイル整理をしやすいように連番で出力します。
ただ重複を避けたいだけなら`mktemp -p ./ 任意の名前.XXXXX`と書くのが速くて楽に綺麗にかけるのでいいと思います。
参考:[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 mktempコマンドとは](http://wa3.i-3-i.info/word12124.html)
また、しっかりと時間で管理したいのなら、タイムスタンプで名前を決定してもいいかもしれません。

プログラム
---


このプログラムを使用すると、ファイル名_番号.拡張子(例 : myfile.txt や myfile_1.txt)のような形式で、カレントディレクトリにファイルが生成される

```bash
#!/bin/bash
statement="hello"
fileName="newFile"
extension="txt"
fileNum=0

while ls | grep -w $fileName >/dev/null; do
  fileNum=`expr $fileNum + 1`
  fileName=${fileName}_${fileNum}
done
echo $statement > ${fileName}.${extension}

#####################################
<<readme
変数の説明
  statement : あらかじめ入力したい内容
  filename  : 作成したいファイル名
  extension : 拡張子
  fileNum   : ファイル名重複時にファイル末尾につける数字
readme
#####################################
```

説明
---

while文で、カレントディレクトリ内に、変数`filename`と同名なファイルが存在する場合は`filename`の変更を行う

具体的には、同名ファイルが存在した場合、`filename`の末尾にカウントアップして重複を防ぐための番号をつけていく(_${fileNum})

`filename`が既存のファイル名と重複しない時、リダイレクトによりファイルを生成する
Universal-ctagsでTypeScriptを有効にする

平成30年3月8日現在、Universal-ctagsはTypeScriptに対応していないので、対応させました。

Vimで定義元ジャンプがしたかったので。

もちろん元となったExuberant-ctagsもTypeScriptには対応していないはずです。

要するにctagsはTypeScriptに対応していない。

#設定ファイル
https://github.com/jb55/typescript-ctags

ここから持ってきました。

基本的には、ここに書いてあるように、.ctagsファイルを所定の場所に置けば良いんですが

ここに書いてある「所定の場所」である`~/.ctags`は、Universal-ctagsでは読み込まれてくれません。

Exuberant-ctagsから仕様が変わってるわけですね

#設定ファイルの置き場所

https://github.com/universal-ctags/ctags

ここの下の方に`./.ctags.d/*.ctags`に置けって書いてありますね。

アスタリスクはワイルドカードでしょう。好きに置き換えろってことです。

そこで`./.ctags.d/typescript.ctags`に置いてみた所

無事読み込まれました。

相対パスになってますが、カレントディレクトリはプロジェクトのルートディレクトリです。

あとは`ctags -R`を実行して`./tags`を作ってやればOKですね。

#以下、余談

##homebrewがぶっ壊れていた
ctagsを入れるためにhomebrewを使ったんですけど

僕のhomebrewはここ5年くらいでいろいろやった結果ぶっ壊れていてですね

https://github.com/Homebrew/install

これをそのまま実行してアンインストール→インストールしました。

それしかなかった。

「El Capitanにアップデートした人はHomebrewが壊れるけど、こうすれば直るよ！」みたいな記事も見かけましたが

僕の場合は効かなかったです。

##他に必要な設定は？
あとは、tagsをgitでignoreする設定とか、vimで毎回tagsを読みこむ設定とかをすればいいのかな…　でも今のところ、vimでの読み込みは勝手にやってくれてるけどな…。わからん。
マイニングの選び方

![ゴールドラッシュ.jpg](https://qiita-image-store.s3.amazonaws.com/0/47880/3d8736d9-4344-b18f-c0f5-c282098b05f7.jpeg)
(出典: [Wikipedia - ゴールドラッシュ](https://ja.wikipedia.org/wiki/%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%89%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5))

## 概要

これからマイニングを始めるにあたって、どのくらいの温度感でマイニングを始めたいかを選ぶにあたり巷にあるマイニング手法を列挙する記事となります。
（※ 当然ですがこの記事を読んだ方が実際にマイニングを行って発生したいかなる損失においても筆者は責任を負わないものとします。）

大まかに以下のような選択肢があります。

- クラウドマイニング
  - 任意のマイニングプールに完全お任せ。初期費用がほぼないがリターンも少ない
- マイニングプール
  - 手持ちのリソースをマイニングプールに提供して共同で採掘し、分け前をもらう。クラウド参加以上、ソロマイニング未満。
- ソロマイニング
  - 初期費用が必要(電気代、パーツ代)、だが効率よく採掘できれば全て自分へのリターンになる

## クラウドマイニング

[クラウドマイニングとは｜2017年のサービス比較まとめ【初心者向け】](https://www.enigma.co.jp/media/page-11555/)

> クラウドマイニングとは、マイニング方法のうちの一つで「マイニングをおこなっているサービスに投資すること」によってマイニングに参加する方法です。マイニング団体やサービスに預けたお金がマイニング活動に使われ、そのマイニングで得られた利益をそれぞれ「投資した額」に応じて配当される仕組みだそうです。資産運用によって株式投資で配当を受け取るといったイメージです。
>
> 他のマイニング方法である「ソロマイニング」や「マイニングプール」との違いは、「マイニング専用のコンピュータを準備する必要がない」ことや、「電気代がかからない」といった点があげられます。また投資と同じく、長期でマイニングに投資しておくことで利益を得ることができる仕組みなので、短期で利益を得たい方にとってはあまりオススメできないサービスかもしれません。

引用の通り。記事内にもクラウドマイニングについての説明や登録できるサービスの紹介もあるので、さっと始めて見たい & あまり初期投資を行いたくない方はこちらから。

## マイニングプール

任意のマイニングプールに参加し、提供される worker プログラムを利用して採掘を行い掘れた仮想通貨 (あるいはリソースのみ？) をマイニングプールに提供する。
成績に応じて配当をもらう。（これが稼ぎになる）

マイニングプールについての説明や世界でのマイニングプールのシェアについてなど以下サイトにまとまっている。

[Bitcoin Mining Pools](https://www.buybitcoinworldwide.com/mining/pools/)

また同サイトでおすすめされている Slush Pool の初心者向けページに、マイニングプールに参加するにあたっての説明がある。

[Slush Pool - Getting started - Mining for Beginners](https://slushpool.com/help/get-started/mining_beginners)

ざっくり説明すると、`cgminer` `BFGminer` のどちらかを使って採掘に参加し、配当をもらってくださいとのこと。
収益予想シミュレーターもあるので、これで試算してみろとの案内もある。親切。

Slush Pool はあくまで一例で、マイニングプールの情勢だったり振る舞い（きちんと配当しているかなど）を見て選ぶのが良さそう。

(参考: 以下サイトにあるように、世界中のマイニングプールのうち 81% のシェアを中国が持っている。)

<img width="748" alt="mining-pool-share-graph.png" src="https://qiita-image-store.s3.amazonaws.com/0/47880/10d4dc09-cea5-9a82-b712-1282ee63c61c.png">


## ソロマイニング

任意のマイニングプールに属さず、自身のマシンパワーのみで採掘競争に立ち向かう。
PC の知識に自信がない人はやめておいた方が良い。
知識をフル活用して効率の良いマシンを組めるなら挑む価値あり。
ソロで挫折しても、前述したマイニングプールへの参加に切り替えても良い。

まず OS をどれにするかという選択がある。

- Windows (初心者向け)
- ethOS (中級者向け。リソース的にこれが一番おすすめ)
- その他 Linux ディストリビューションを探したり自作したり (超上級者向け)

その上で肝となるグラフィックボードを何枚刺すか、電源効率の良い電源を使うか、どのくらいの稼働率にするか（パーツの消耗や電気代を考慮して）、電力はどこまで使えるか、設置場所は...といったことを考えていく。

またどの通貨を掘るか（ビットコインはもはや非現実的、アルトコインのどれを掘るか）ということも考える必要がある。
これについては刻一刻と変わるため、日々情報を追いかける必要がある。

マシン構築にあたっては参考になるサイトがいくつもあるが、比較的落ち着いて選定されていた以下のサイトが分かり易かった。

[初心者向け　マイニング機材の選び方について](http://mininglog.hatenablog.jp/entry/2018/01/06/184229)

上記を参考に、複数のサイトを見て自分が可能な投資額や期待する採掘量を計画してマシンを組み、ソロマイニングを開始する。
無計画に実行すればパーツ代や電気代が掛かった割に十分な仮想通貨を得られずに終わるということも全く有り得るので、軌道に乗るまで根気強くチューニングが行えないなと思う人は手を出さない方が良い。
Gitの基本操作

<h3>ディレクトリの移動</h3>

```
$ cd /Users/user/workspace
``` 

---
<h3>クローン,プル</h3>
- クローン : リモートリポジトリをローカルに落とす(ダウンロードみたいなイメージ)
    - リポジトリのURLはGitHubなどの管理ページを参照

```
$ git clone URL
```

- プル : 現在のリモートリポジトリの状態をローカルに反映させる(最新バージョンへの更新のイメージ)

```
$ cd /Users/user/local
$ git pull
```


<h3>1.状態の確認</h3>

```
$ git status
```

変更があったファイルのpathが表示される

<h3>2.ステージにあげる</h3>


個別にstageにあげる方法

```
$ git add file/path
```

一括でstageにあげる方法

```
$ git add -A
```

<h3>3.コミット</h3>

```
$ git commit -m コミットメッセージ
```

<h3>4.プッシュ</h3>

```
$ git push
```
time.Date関数は繰り上がりを適切に処理してくれる

goのtime.Date関数がerrorを返さない関数だったので、通常の範囲外の値を渡したらどうなるのかと思ってやってみたら、ちゃんと繰り上がり処理されていた。

リファレンスにもちゃんと書いてあった。
> The month, day, hour, min, sec, and nsec values may be outside their usual ranges and will be normalized during the conversion. For example, October 32 converts to November 1.

以下のように実行することができる。

```go

package main

import (
	"fmt"
	"time"
)

func main() {

	// 月/日の繰り上がり
	fmt.Println(time.Date(2018, 14, 1, 0, 0, 0, 0, time.UTC).Format("2006-01-02 15:04:05")) // 2019-02-01 00:00:00
	fmt.Println(time.Date(2018, 1, 40, 0, 0, 0, 0, time.UTC).Format("2006-01-02 15:04:05")) // 2018-02-09 00:00:00

	// 時/分/秒/ナノ秒の繰り上がり
	fmt.Println(time.Date(2018, 1, 1, 26, 0, 0, 0, time.UTC).Format("2006-01-02 15:04:05"))             // 2018-01-02 02:00:00
	fmt.Println(time.Date(2018, 1, 1, 0, 80, 0, 0, time.UTC).Format("2006-01-02 15:04:05"))             // 2018-01-01 01:20:00
	fmt.Println(time.Date(2018, 1, 1, 0, 0, 80, 0, time.UTC).Format("2006-01-02 15:04:05"))             // 2018-01-01 00:01:20
	fmt.Println(time.Date(2018, 1, 1, 0, 0, 0, 2000*1000*1000, time.UTC).Format("2006-01-02 15:04:05")) // 2018-01-01 00:00:02

	// 全部
	fmt.Println(time.Date(2018, 13, 32, 24, 60, 60, 1000*1000*1000, time.UTC).Format("2006-01-02 15:04:05")) // 2019-02-02 01:01:01
}
```

自分の用途では27時とかを繰り上がりしたかったので、便利だった。
ベンチマーク報告のテンプレート

コミュ障の僕に「なぜ僕の説明は伝わらないのか」を教えてくれた書籍『ソフトウェアシステムアーキテクチャ構築の原理 第2版』の内容が、ベンチマーク報告にも適用できそうなことに気づきました。

本に記載されているような観点にそって記載していくことで「漏れなく分かりやすい記載」になると考え、ベンチマークレポートのテンプレートを考えてみました。

----

# テンプレート：

## はじめに、検証概要

..

## 検証環境

（『ソフトウェアシステムアーキテクチャ構築の原理 第2版』における配置ビュー、情報ビュー、開発ビューのようなものを記載します）

### リージョン、マシンスペック、構成

例：

- Athena
  - オレゴン

- Redshift
  - オレゴン
  - dc2.large
  - ノード数 (1ノード, 2ノード, 4ノード, ..)

- Spark
  - オレゴン
  - c4.xlarge
  - コアノード数 (1ノード, 2ノード, 4ノード, ..)、マスターノード数:1

### データフォーマット
例： 検証では下記のようなフォーマットのログのダミーデータを使用。データサイズは1レコードあたり xx バイト。

```js:log_record
{
  "id": "0dbe3c-db77-5984-b5ba-c964ae7a",
  "time": 1490123456789,
  ...
}
```

### データのバリエーション

例：

- 入力データのサイズ（1時間分, 2時間分, 4時間分, ..）
- 入力データ形式: JSON, Parquet, CSV, ..
- 圧縮の有無: gz, snappy, ..
- sort key / dist keyの工夫


### データのフロー、ライフサイクル

ベンチマーク対象のサービスがどのようにデータを取り扱うかを記載。

例： 

- Athenaを使う場合
  - S3からJSON/Parquet/... のデータを読み込み、SELECT結果をS3に書き出す。
  - 現在の出力はCSVのみのようで、自作ツールなどでParquetフォーマットへは変換が必要。

- Redshiftを使う場合
  - Spectrum層により、S3上のParquetファイル等を外部テーブルとして扱える。
      - Spectrum層がS3からデータを読む場合は、事前にAthenaなどでテーブルを定義しておく必要がある（Hiveメタストアを共有）。
      - JSONテキストファイルの読み込みはまだのようで、Spectrum経由で読めるようにParquet形式に変換するツールが必要。
  - SELECT結果を保持する場合はRedshiftローカルのテーブルとして保持。
      - 不要になったデータはUNLOADによりS3上にCSV/TSVで書き出し。

- Sparkを使う場合
  - S3から JSON/Parquet/.. のデータを読み込み、SELECT結果をメモリ上に保持。各種フォーマットでS3への書き出しも容易。
  - JSONの読み込みやParquetへの変換、Parquetでの書き出し、JOIN等がすべてSparkのジョブとして定義できるため開発が容易。


## 内部動作の補足

（『ソフトウェアシステムアーキテクチャ構築の原理 第2版』の機能ビュー、並行性ビューなども絡めて記載）

補足があれば。

## パフォーマンスとスケーラビリティの比較

### レイテンシー測定

例： 下記クエリで検証。

```sql:JOINクエリ
SELECT .. ;
```

SELECT/JOIN/Aggregate処理をログのデータサイズを変えて測定。
10回の試行の中央値を記載。timeコマンドでコマンド実行開始から終了までを測定。

| データサイズ | 実行時間(1ノード) | 実行時間(nノード) |
| --- | --- | --- |
| 1 時間分 | xx 秒 | yy 秒 |
| 2 時間分 | xx 秒 | yy 秒 |
| 4 時間分 | xx 秒 | yy 秒 |

## 可用性とレジリエンスの比較

各種サービスの可用性（ダウンタイム）、コールドからの起動やクラスタ作り直しにかかる時間について記載。

例：

- Athena
  - フルマネージドのためダウンタイムなし、起動・環境再構築にかかる時間なし。
- Redshift
  - 定期メンテあり。クラスターの作り直し時などはデータの再ロード（＋データ処理の再実行）など必要。
- Spark
  - フルマネージドでなくマスターノードが単一障害点の懸念あり。ただクラスタ内部にはデータを持たないため作り直しは容易。

## 運用の観点で比較

障害復旧・アラート、データ量の増加等にどのような手順で対応するかを記載。

## 発展性の比較
要件変更に対してどのくらい柔軟か、SQLの豊富さ、海外対応しやすさ（通貨、時差など）など

例：

- Athenaはお手軽だがインタラクティブシェルでの分析用のイメージ
- Redshiftは複雑な分析が得意そうなイメージ
- Sparkはスキーマレスのままいろいろなデータをあつかいやすそう

## セキュリティの比較

..

## コストの比較

（『ソフトウェアシステムアーキテクチャ構築の原理 第2版』では取り扱ってないがクラウド時代のベンチマークでは必要そう）

例えば1ヶ月あたりいくらになるかを記載（どのサービスを何時間実行した場合の計算なのか）。
請求画面に表示された額で答え合わせすると安心。

### Athena
例： データの読み込み課金のため、読み込み量が多くなると料金も上がる。
Mapbox GL JSで地理院標高タイル

[Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api) v0.43.0 から、標高タイルを使って陰影起伏(hillshade)を描画できるようになった。
[Realistic terrain with custom styling | Mapbox blog](https://blog.mapbox.com/realistic-terrain-with-custom-styling-ce1fe98518ab)

ラスターデータを基に演算するので、ベクトル化された陰影起伏よりも精細な表現ができるのが良い点。

Mapboxで提供されている標高タイル [Mapbox Terrain-RGB](https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb)は、アメリカやヨーロッパでは解像度5mなのに、日本では解像度30mでSRTMデータ[^1]のため精度が悪いのが残念な点。


そこで、国土地理院が提供している標高タイルを使って陰影起伏を描画できるように拡張してみる。

# 標高タイル
[標高タイル | 地理院タイル一覧](https://maps.gsi.go.jp/development/ichiran.html#dem)

今回は、日本全域がカバーされて、ズームレベル0〜14で利用できるDEM10B (地形図の等高線から作成された10mメッシュの標高データ)を使う。



異なるフォーマットの標高タイルを使えるようなPull Requestがマージされているので参考にする。
[mapbox#6110, Adds support for mapzen terrain](https://github.com/mapbox/mapbox-gl-js/pull/6110)


## 標高PNGタイルの仕様
> 画素値（RGB値）から標高値h（m）の計算式は下記のとおりです。
x = 2^16 R + 2^8 G + B
x < 2^23の場合　h = xu
x = 2^23の場合　h = NA
x > 2^23の場合　h = (x-2^24)u
uは標高分解能（0.01m）を表します。

> [標高タイルの詳細仕様 | 地理院地図](https://maps.gsi.go.jp/development/demtile.html)

この計算式をMapbox GL JS内で実装するだけ。

```javascript
let h = r * 256 * 256 + g * 256 + b;
return (h == Math.pow(2, 23)) ? 0 : 0.01 * ((h << 8) | 0) >> 8;
```
https://github.com/tattii/mapbox-gl-js/pull/1


## example

```javascript
map.addSource('gsi-dem', {
    "type": "raster-dem",
    "encoding": "gsi",
    "tiles": [
        "https://cyberjapandata.gsi.go.jp/xyz/dem_png/{z}/{x}/{y}.png"
    ],
    "tileSize": 256,
    "maxzoom": 14,
    "attribution": '<a href="https://maps.gsi.go.jp/development/ichiran.html#dem" target="_blank">地理院標高タイル</a>'
});
map.addLayer({
    "id": "GSI dem",
    "source": "gsi-dem",
    "type": "hillshade"
}, 'waterway-river-canal-shadow');
```

ref. https://www.mapbox.com/mapbox-gl-js/example/hillshade/

# 結果
demo https://tattii.github.io/terrain-japan/raster-dem/hillshade.html#11.99/31.92117/130.87554

地理院標高タイル
<img width="939" alt="gsi-dem.png" src="https://qiita-image-store.s3.amazonaws.com/0/103755/bc7ab23d-0d0f-71f1-6935-c714a36b3d91.png">


Mapbox Terrain-RGB
<img width="940" alt="mapbox.png" src="https://qiita-image-store.s3.amazonaws.com/0/103755/77ceb5ba-c0cd-3b3c-5e12-796e280e5a8f.png">



地理院標高タイルを使うことで、地形の表現がとても綺麗になった。


### 参考

- 標高PNGタイルと WebGL による地形表現
 https://qiita.com/frogcat/items/7e91d3070a7a8d3e2c94
- PNG標高タイル －Web利用に適した標高ファイルフォーマットの考察と実装－ https://www.jstage.jst.go.jp/article/geoinformatics/26/4/26_155/_pdf



[^1]: Mapbox terrain data update https://blog.mapbox.com/mapbox-terrain-data-update-988b100778b0
.gitignoreで.DS_Storeを削除しよう

## はじめに
GitHub に push した際に .DS_Store が上がってしまった時の対処法です。

## 対処法
まず .gitignore を作成します。

```bash
$ touch .gitignore
```

次に .gitignore に .DS_Store と記述します。

```text:.gitignore
.DS_Store
```

最後にキャッシュを削除し、 push します。

```bash
$ git rm -r --cached .

$ git add .
$ git commit -m "feat:　.gitignore を作成する"
$ git push origin main
```


## 追記（非推奨）
~~.gitignore をプロジェクトの度に作成したり、 .DS_Store 等を記述したりするのは正直面倒です。
.gitignore_global を作成し、グローバルに設定することで面倒な作業をなくすことができます。~~

~~作成する~~

```
$ touch .gitignore_global
```

~~.gitignore を有効化するか `~/.gitconfig` に直接追記する~~

```
$ git config --global core.excludesfile ~/.gitignore_global
```

```text:.gitconfig
[core]
    excludesfile = ~/.gitignore_global
```

~~.gitignore_global に .DS_Store を追加する~~

```text:.gitignore_global
.DS_Store
```

## 追記（推奨）
グローバルに設定するには `~/.config/git/ignore` に記述するのが相応しいということを知りました。この記事を閲覧し、 .gitignore_global を作成された方向けに設定方法を記載します。

まず、 `~/.config/git` ディレクトリを作成します。

```bash
$ mkdir ~/.config/git
```

次に .gitignore_global の名前を ignore に変更し、 `~/.config/git` ディレクトリへ移動させます。

```bash
$ mv .gitignore_global ~/.config/git/ignore
```

最後に、 .gitconfig の設定を削除します。

```bash
$ git config --global --unset core.excludesfile
```

---

参考資料
[.gitignore_globalを使うのをやめてデフォルトの置き場に戻す方法](https://qiita.com/takatin/items/1a50b840b6959aa29531)
[~/.gitignore_global を指定するのをやめ、デフォルトの置き場に置こう](https://zenn.dev/qnighy/articles/1a756f2857dc20)
MySQL5.7でONLY_FULL_GROUP_BYをOFFにする方法

#MySQL5.7でONLY_FULL_GROUP_BYをオフにする方法

・MySQL5.7からはONLY_FULL_GROUP_BYのデフォルト設定がONになっていた為OFFにする方法をメモ

1. /etc/my.cnf ファイルを編集
以下の内容を記載しておく
`sql_mode=ONLY_FULL_GROUP_BY`

2. SQL文を実行
以下のSQL文を実行
`SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));`

どちらかを実施後MYSQLを再起動する事で無事に設定がOFFになりました。

以上
osx86 上の Intel HD 4600 で 4k ディスプレイが使えるようにした

## 概要

osx86 上の Intel HD 4600 で 4k ディスプレイを繋いだが、解像度が 1080p までしか出ない。4k の解像度を選択できるようにしたい。
OS は High Sierra です。
ディスプレイは ドウシシャ 32インチ OD4K-32B1。

![Screen Shot 2018-02-16 at 22.03.15.png](https://qiita-image-store.s3.amazonaws.com/0/47880/fd04dcf2-be31-37cf-18e8-668d99f8854e.png)

## やったこと

(とても参考になった記事:
https://ez-net.jp/article/25/7cndVOZE/nLAALA24WeHz/ )

- Mac システム上で Override している箇所を知るために ioreg で調べる

```bash
ioreg -lw0 | grep IODisplayPrefsKey

    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-11f3-3200"
```

- `AppleDisplay-11f3-3200` が今回のディスプレイとわかる
  - `11f3` が DisplayVendorID、`3200 ` が DisplayProductID
- Overrides の設定ファイルを準備する

```bash
cd /System/Library/Displays/Contents/Resources/Overrides/

# ディレクトリ内の任意のディレクトリをコピーして、今回のディスプレイの設定ファイルを作成する
# ./DisplayVendorID-11f3/DisplayProductID-3200 が作成される
```

- 以下の内容に書き換える

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>DisplayProductName</key>
	<string>DOSHISHA OD4K-32B1</string>
	<key>scale-resolutions</key>
	<array>
		<data>AAAPAAAACHAAAAAB</data>
	</array>
</dict>
</plist>
```

- 本体を再起動する

## 結果

3840x2160 の項目を増やすことができた。しかし Intel HD 4600 側で 4K 出力ができていない (ハードウェア側の対応の問題？ HDMI の規格など) ため、画面はぼやけてしまう。（1920x1080 の画面を引き延ばしているので）
お使いのマザーボードによってはこれで 4K 出力までできるようになるかもしれませんが、自分の環境では解決できなかったため別途グラフィックボードを買うことで解決することにしました。
Intel HD4600 使いのどなたかに役に立てば幸いです。

![Screen Shot 2018-02-16 at 22.30.21.png](https://qiita-image-store.s3.amazonaws.com/0/47880/72934cd4-fd48-fdbf-66fd-d84495749528.png)