OmniAICreator/Qiita-1.07M huggingface dataset:
CSS3の色の指定について

## 色の指定の種類
### カラーネームで指定する
```html
html lang="ja"
  head
    meta charset="utf-8"
    title
      | CSS3
    link rel="stylesheet" href="./stylesheets/default.css"
  body
    div id="box1" box1
    div id="box2" box2
    div id="box3" box3
    div id="box4" box4
```

```css
#box1 {
  background-color: wheat;
}

#box2 {
  background-color: khaki;
}

#box3 {
  background-color: lightpink;
}

#box4 {
  background-color: steelblue;
}
```

![Kobito.yOoxiU.png](https://qiita-image-store.s3.amazonaws.com/0/33823/0bd17c26-54e0-94b2-15cd-fba9c26f41d4.png "Kobito.yOoxiU.png")

* 指定できるカラーネームは以下を参照
* WEB色見本 原色大辞典 - HTMLカラーコード https://www.colordic.org/
* 変わった色の指定はOSやブラウザなどの環境によって正常に表示されない場合がある

### カラーコード(#)で指定する
* 色指定を16進数(0-f)で指定する
* 3桁と6桁で指定する方法がある

```css
#box1 {
  background-color: #f0f;
}

#box2 {
  background-color: #ff00ff;
}
```

* 重複する値は省略することができる。3桁以外は無理
* 色の指定は頻繁に行うので、省略できた方がコーディングが少し楽になる

### rgb, rgba(CSS3)で指定する
* 赤緑青の量で色を指定する方法
* 数値(0-255)、%(0-100%)で指定する方法がある
* 0(0%)が薄く255(100%)が濃い

```css
background-color: rgb(赤、緑、青)
```

```css
#box1 {
  background-color: rgb(255, 0, 0);
}

#box2 {
  background-color: rgb(0%, 100%, 0%);
}
```
* 0が透明で1が元の色

```
#box1 {
  background-color: rgba(255, 0, 0, 0.2);
}

#box2 {
  background-color: rgba(0%, 100%, 0%, 0.8);
}
```

### hsl, hslaで指定する (CSS3)
* 色相 (Hue)
* 鮮やかさ (Saturation)
* 明るさ (Lightness)
* 透明度 (Alpha)

```css
#box1 {
  background-color: hsl(0, 79%, 72%)
}

#box2 {
  background-color: hsl(0, 90%, 80%)
}

#box3 {
  background-color: hsla(210, 100%, 50%, .7);
}

#box4 {
  background-color: hsla(210, 100%, 40%, .7);
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33823/7bdc716f-2a07-1078-79ee-20476de73021.png)

* 少し色を明るくしたい、鮮やかにしたいといった時に直感的に変更できる
* 古いブラウザでは利用できない時があるので注意
* CSSは1未満の0の部分は省略できるので省略している

### 便利ツール
* HSL to RGB | RGB to HSL | Colour Calculator | Hex Color Converter http://serennu.com/colour/hsltorgb.php
  * HSLの変換に便利

* HSLA Selected (Hue, Saturation, Light, alpha) Color Codes http://www.december.com/html/spec/colorhsla.html
  * 色相の値を確認するのに便利

### 要素全体を透明にする (opacity)
* 背景色だけではなくて、要素全体を透明にしたい時はCSS3のopacityを使う

```css
#box1 {
  background-color: red;
  opacity: .5;
}
```
【iOS11】mlmodelファイルからSwiftコードを生成するコマンド【CoreML】

この記事はAppleの公式のドキュメントには（恐らく）記載されておらず、動作検証ベースでの内容になるので、ご留意ください。

# はじめに

iOS11から新しく加わったCoreMLフレームワークにて使用する「.mlmodel」ファイルについての記事です。
[こちら](https://qiita.com/taji-taji/items/8c5e889120788e17f389#1-xcode%E3%81%A7%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB)でまとめたように、Xcode9以降で.mlmodelファイルをプロジェクトのターゲットに加えると、Swiftのコードが自動生成されます。

今回は、XcodeによるSwiftコードの自動生成ではなく、コマンドラインからSwiftコードを生成する方法を紹介します。

# コマンドラインでmlmodelからSwiftコードを生成

## ▼ やり方

次のようなコマンドでmlmodelからSwiftコードを生成することができます。

```

/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc generate [mlmodel path] [output path] --language [Swift|Objective-C]　[--swift-version 4.0]

```


```:具体例はこんな感じ

/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc generate ./mymodel.mlmodel . --language Swift --swift-version 4.0

```


※`/Applications/Xcode.app/Contents/Developer`の部分は`xcode-select -p`のパス

## ▼ 使い所は？

例えば、mlmodelをアプリのバンドルに組み込むのではなく、ネットワークを介して取得するような設計をする場合（[参考](https://qiita.com/taji-taji/items/8c5e889120788e17f389#2-swift%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB)）、
Xcodeで自動コンパイルするのとは違って、mlmodelをSwiftのCoreMLで扱うためのSwiftのクラスを自分で書く必要が出てきます。

そのような時に、このコマンドを使ってボイラープレートとなるSwiftコードを生成することで、開発が楽になるかもしれません。

## ▼ 注意点

さて、このコマンドで生成されるSwiftコードの一部を下記に掲載します。

```swift
/// Construct a model that automatically loads the model from the app's bundle
convenience init() {
    let bundle = Bundle(for: mymodel.self)
    let assetPath = bundle.url(forResource: "mymodel", withExtension:"mlmodelc")
    try! self.init(contentsOf: assetPath!)
}
```

イニシャライザの一つですが、mlmodelをコンパイルした後のリソース(mlmodelc)が、アプリのbundleのなかにある前提でコードが生成されます。

上記のように、ネットワークを介してmlmodelを取得・コンパイルする場合は、その時に保存する**`mlmodelc`**のパスからイニシャライズするように書き換えてあげる必要がありそうです。
（実務レベルでは考えていないので、所感の注意点ですが。。）

そういった観点で、少し前の記述にて「ボイラープレート」という表現を使いました。

# おわりに

このコマンド、ドキュメントが見つからないので積極的に使うものではないかもですが、面白いですね。

# 参考

https://blog.zedge.net/developers-blog/hotswapping-machine-learning-models-in-coreml-for-iphone
rake db:migrate rake aborted! Gem::LoadError: You have already activated rake 12.0.0, but your Gemfile requires rake 12.2.1. Prepending `bundle exec` to your command may solve this.

##エラーの内容

rake db:migrate rake aborted! Gem::LoadError: You have already activated rake 12.0.0, but your Gemfile requires rake 12.2.1. Prepending `bundle exec` to your command may solve this.

##
エラーの原因
自分の　PCrake 12.0.0となっているが、入れたgemfilerake 12.2.1.となっている。バージョンが違うためにエラーが出ている。

##解決１

エラーが表示しているとおり、 bundle exec rake db:migrate とやる。

##解決法
　バーションを修正する。

まずターミナルにgem install rakeと打つ。

gem install rake
Fetching: rake-12.2.1.gem (100%)
Successfully installed rake-12.2.1
Parsing documentation for rake-12.2.1
Installing ri documentation for rake-12.2.1
Done installing documentation for rake after 1 seconds
1 gem installed



次にrake --version　と打つ。

rake --version
rake, version 12.2.1

そうすると修正された


参考文献

https://teratail.com/questions/25072
CSVとは？

:point_up:CSVとはCharacter Separated Values, 何らかの区切り文字で区切ったテキストファイルです。

よく使われるのはこんなの。

* カンマ区切りのCSV (Comma Separated Values)
* TAB区切りのCSV (Tab Separated Values, TSVと呼ぶこともある)
* セミコロン区切りのCSV (Semicolon Separated Values, SSVと呼ぶこともある)
* スペース区切りのCSV (Space Separated Values, SSVと呼ぶこともある)

区切り文字によって頭の一文字を変えると他と被ることがあるので**〇〇区切りのCSV**と呼ぶのが一般的になったとかならないとか。

> 「SSV? セミコロン区切りなの？スペース区切りなの？」

> 「TSV? TAB区切りなの？🍅区切りなの？」
GitHubのレポジトリをアーカイブする

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">Hey OSS maintainers! You can now stop getting any new PRs/issues/comments on your deprecated/unmaintained repos: <a href="https://t.co/ZfajGVGZD4">https://t.co/ZfajGVGZD4</a></p>&mdash; Mike McQuaid (@MikeMcQuaid) <a href="https://twitter.com/MikeMcQuaid/status/928286816112955392?ref_src=twsrc%5Etfw">November 8, 2017</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

レポジトリをアーカイブすることで、新しいPRs/issues/commentsを作成出来なく出来ます。

自分の場合は、モノレポに移行し以前のレポジトリを管理する必要がなくなったので、このアーカイブを使いました。
削除するのも手ですが、レポジトリへのリンクが記事などで使われている場合があり、404ではなく次のレポジトリへと導線として残すのは良い手段だと思います。

方法としては、`Archive this repository.`をクリックして、サブミットするだけです。

![](https://user-images.githubusercontent.com/125011/32273119-0fc5571e-bef9-11e7-9909-d137268a1d6d.png)

[Archiving repositories](https://github.com/blog/2460-archiving-repositories)
[Python] 2つの文書間のcos類似度を計算

## cos類似度とは
ベクトル空間モデルにおいて、文書間の類似度を調べる手法です。
cos類似度を計算することによって、文章の似てる度合いを計算できます。

```math
cos(A, B) = \frac{AB}{|A||B|}
```

分母はそれぞれの文書ベクトル長をかけ合わせたもので、
分子は文書Aと文書Bの内積です。

## 実装
```cos.py
# coding: utf-8
import math

def calc_cos(dictA, dictB):
    """
    cos類似度を計算する関数
    @param dictA 1つ目の文章
    @param dictB 2つ目の文章
    @return cos類似度を計算した結果。0〜1で1に近ければ類似度が高い。
    """
    # 文書Aのベクトル長を計算
    lengthA = 0.0
    for key,value in dictA.items():
        lengthA = lengthA + value*value
    lengthA = math.sqrt(lengthA)

    # 文書Bのベクトル長を計算
    lengthB = 0.0
    for key,value in dictB.items():
        lengthB = lengthB + value*value
    lengthB = math.sqrt(lengthB)

    # AとBの内積を計算
    dotProduct = 0.0
    for keyA,valueA in dictA.items():
        for keyB,valueB in dictB.items():
            if keyA==keyB:
                dotProduct = dotProduct + valueA*valueB
    # cos類似度を計算
    cos = dotProduct / (lengthA*lengthB)
    return cos


def words_to_freqdict(words):
    """
    単語の配列を、単語と頻度の辞書に変換する関数
    例: ["X","X","Y","Z","X"] => {"X":3, "Y":1, "Z":1}
    @param words 単語の配列
    @return 単語と頻度の辞書
    """
    freqdict = {}
    for word in words:
        if word in freqdict:
            freqdict[word] = freqdict[word] + 1
        else:
            freqdict[word] = 1
    return freqdict


def main():
    docA = ["リンゴ", "ぶどう", "リンゴ", "パイナップル", "リンゴ"]
    docB = ["バスケ", "サッカー", "野球", "ぶどう", "テニス"]
    docC = ["ぶどう", "リンゴ", "マンゴー", "ぶどう"]

    freqdictA = words_to_freqdict(docA) # {"リンゴ":3, "ぶどう":1, "パイナップル":1}
    freqdictB = words_to_freqdict(docB) # {"バスケ":1, "サッカー":1, "野球":1, "ぶどう":1. "テニス":1}
    freqdictC = words_to_freqdict(docC) # {"ぶどう":2, "リンゴ":1, "マンゴー":1}

    cosAB = calc_cos(freqdictA,freqdictB)
    cosAC = calc_cos(freqdictA,freqdictC)
    print(cosAB) # 0.134839972493
    print(cosAC) # 0.615457454897


if __name__ == "__main__":
    main()
```
## 参考
http://www.cse.kyoto-su.ac.jp/~g0846020/keywords/cosinSimilarity.html
ssh先でログアウトしてもプロセスを終了させずにバックグラウンド実行したい！

# ssh先でもバックグラウンド実行したい！ :punch: 
小ネタ
通常ssh先でプロセスを実行した際、sshのセッションが切れると実行中のコマンドも終了する。
デーモン化をサポートしてるプログラムならデーモンにすれば良いんだけど、```ping```とかは無理
何個か方法探したので備忘録。
環境：ubuntu 16.04 LTS

# 方法
## :one: &をつける
一番簡単でシンプルなな方法。

例えば〜pingのログを記録する時。

```zsh:~
$ ping 8.8.8.8 > log.txt &
[1] 5395
```
これだけ。簡単。終了する時は適当にkillコマンド送ってあげよう。

```zsh:~
$ kill 5395
[1]  + terminated  ping 8.8.8.8 > log.txt
```

ついでにまとめて何コマンドが実行する時はこういう感じで`()`で包む

```zsh:~
$ (sleep 10; print hoge;)%
```


## :two: nohupを使う

これも古典的な方法。標準出力が保存される。

```zsh:~
$ nohup ping 8.8.8.8
nohup: 入力を無視し、出力を 'nohup.out' に追記します
```

## :three: screenを使う
上記二つだと上手く対応出来ないようなグラフィカルなCUIを提供するアプリでもおなじみのscreenなら大丈夫。

例えば`top`コマンド

```zsh:~
$ screen top
```

とりあえずこれだけでバックグラウンド実行が可能。
screenの使い方は先人のステキな記事を読むと幸せになれる。
[screenのコマンドの備忘録
](https://qiita.com/mgoldchild/items/e336618487eb7d90f6d4)


# refs.
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230850/
https://www.codereading.com/nb/ignore-the-hangup-signal.html
[screenのコマンドの備忘録
](https://qiita.com/mgoldchild/items/e336618487eb7d90f6d4)
Raspberry pi上の音声認識(julius)認識率向上[julius辞書作成]



# 音声認識を使って辞書作成

ストックじゃなくていいねください。

## 前提条件　　　
- python3   
- [こちら](https://qiita.com/fishkiller/items/dfd1b13a4380c6aa6322)が終わってる前提で進んで行きます。

## julius辞書作り   
 [前回](https://qiita.com/fishkiller/items/dfd1b13a4380c6aa6322)作成しなかった辞書作りです。

#### 前回のディレクトリ構成
```
~/julius-4.4.2
｜--julius-kit
       ｜--dictation-kit-v4.3.1
       ｜--grammer-kit-v4.3.1
```
#### 辞書の作成
作成ディレクトリに移動
```
cd ~/julius-4.4.2/julius-kit
```
上記の場所でword.yomiを作成してください。

word + TABキー + ひらがなという書き方　　　

```　　　
おはよう      おはよう
こんにちは      こんにちは
こんばんは      こんばんは
おやすみ      おやすみ
バイバイ      ばいばい
```
このまま下に言葉を列挙していってください。

次にjuliusが認識できる辞書形式(.dic)に変換する必要があります。

```
$iconv -f utf8 -t eucjp ~/julius-4.4.2/julius-kit/word.yomi | yomi2voca.pl > ~/julius-4.4.2/julius-kit/dictation-kit-v4.3.1-linux/word.dic
```
久しぶりにちょっといじったのでおまけで追加。
ちょっと単語を辞書に追加するのが面倒。
そんな時に入力した単語が辞書に登録されるshell

```shell:edit.sh
#!/bin/sh                                                                                                                                                                                                                         
echo "What word do you want to register as a dictionary?"
read word #単語入力

echo "$word" >>~/julius-4.4.2/julius-kit/word.yomi #word.yomiに書き込み
cat ~/julius-4.4.2/julius-kit/word.yomi #word.yomiの中身を表示

iconv -f utf8 -t eucjp ~/julius-4.4.2/julius-kit/word.yomi | yomi2voca.pl > ~/julius-4.4.2/julius-kit/dictation-kit-v4.3.1-linux/word.dic #音素データにコンパイル
echo "Completed!" #完了

```

###shell　実行 (edit.sh)
```
$./edit.sh
What word do you want to register as a dictionary?
テスト てすと (登録単語)
... 
..
.
テスト てすと
Complete!
```

#### julius設定ファイルを作成   
ここでは、辞書の書き方通り、登録単語+tab+よみ　という入力ですが、
この書き方がめんどくさいという人は
登録単語とよみを別でreadして間にtabを入れるようにすればいいでしょう。

```
cd ~/julius-4.4.2/julius-kit/dictation-kit-v4.3.1-linux
```
上記の場所にjulisuの設定ファイルword.jconf

```      
-w word.dic       #単語辞書ファイル
-v model/lang_m/bccwj.60k.htkdic  #N-gram、または文法用の単語辞書ファイルを指定$
-h model/phone_m/jnas-tri-3k16-gid.binhmm #使用するHMM定義ファイル
-hlist model/phone_m/logicalTri   #HMMlistファイルを指定する
-n 5        #n個の文仮説数が見つかるまで検索を行う
-output 1     #見つかったN-best候補のうち、結果として出力する個数
-input mic      #マイク使用
-input oss      #オープンサウンドシステム使用
-rejectshort 600  #検出された入力が閾値以下なら棄却
-charconv euc-jp utf8 #入出力エンコード指定(内部euc-jp, 出力utf-8)
-lv 1000    #入力の振幅レベルの閾値(0~32767)
```
自由の個人設定を行ってください。
そして、個人設定に合わせて実行

```
julius -C ~/julius-4.4.2/julius-kit/dictation-kit-v4.3.1-linux/word.jconf
```

## まとめ   
これでjulisuの認識率が格段にUPします。
また、認識して欲しい言葉だけを辞書化することでその範囲でしか認識されなくなるので利用もでいます。
また、[次](https://qiita.com/fishkiller/items/c6c5c4dcd9bb8184e484)ではjuliusを使って、特定の言葉にリアクションを行すものを作成します。
Vim 変数とオプションをコマンドで確認する方法

Vimで変数とオプションの確かめ方を調べたのでメモしておく。
設定がちゃんと通っているか確かめたいという時に便利。

# 変数 (Variable)

```vim
:let samplevariable = 'foo'
:echo samplevariable
foo
```
結果はfooと表示されます。

# オプション (Option)

```vim
:set textwidth=80
:echo &textwidth
80
```
結果は80と表示されます。
注意すべき点は、オプションを呼び出すときは前に`&`をつけることです。


---
参考
http://learnvimscriptthehardway.stevelosh.com/chapters/19.html
FoxDot（音楽用ライブコーディング環境）をインストール

はじめまして。音楽系大学に通いながらプログラムを書いているものです。
Qiita初心者ですので、お手柔らかにお願いします。

#FoxDotとは？

FoxDotとは音楽制作用のライブコーディング環境です。

よく似たものでTidalCyclesというものがあって僕はもともとそっちを使ってました。
TidalCyclesのほうはHaskellで実装されたものであるのに対しFoxDotはpythonで実装されており、個人的にはpythonのほうがなじみが深いので、今回見つけてしまったのを機に乗り換えようかなと思ってます。

ただ問題点として、まだまだ情報が少ないです。ほぼ公式だけといっても過言ではないです。。。
FoxDotに関しては日本語の記事や日本人で使われているという方を未だ見たことがないです。
（TidalにしろFoxDotにしろニッチなツールなのでしょうがないですが...）

今回はWindows向けのインストール作業となりますが、Macでもほぼ変わらないと思います。（まだ試してないです。）

では早速インストールを進めましょう。

#必要なもの

FoxDotを使うために必要なものは、大きく三つで
・Python（2でも3でも大丈夫みたいです。）
・SuperCollider
・Git
です。

まず前提としてFoxDotはサウンドエンジンとしてSuperColliderを使っています。
SuperColliderは音響プログラミング言語？的なやつですが、TidalCyclesでも同じものが使われています。
それに対してPythonを使って命令を出すというのがFoxDotです。

#SuperColliderのインストール
SuperColliderの公式サイトからOSにあったexeファイルとsc3-pluginsをダウンロードします。
http://supercollider.github.io/download
ダウンロード出来たらexeファイルを実行してください。（つまるところは特にはないはず）

インストール出来たらsc3-pluginを解凍した中にあるsc3-pluginフォルダを
C:\Users\"ユーザー名"\AppData\Local\SuperCollider\Extensionsに入れてください。

#Pythonのインストール
pythonのインストール方法はいろいろありますが、今回は一番楽にいろいろ入ってるAnacondaを使います。
これも公式サイトからOSにあったものをインストールしてください。
https://www.anaconda.com/download/

これもexeファイルを実行して指示に従うだけです。

#Gitのインストール
これまた例によって公式サイトからダウンロード、インストールします。
https://git-scm.com/downloads

途中チェック項目がありますが、基本的にデフォルトのままで大丈夫かと思います。

#FoxDotのインストール
ではいよいよFoxDotのインストールです。

まずコマンドプロンプトかPowerShellを立ち上げて
```pip install FoxDot```
と打ち込みます。
Anacondaを管理者権限でインストールした場合は、コンソールも管理者権限のものを使う必要があります。

次にSuperColliderを立ち上げて、
``` Quarks.install("FoxDot") ```
と打ち込みます。

これでエラーが出た場合は
```Quarks.install("https://github.com/Qirky/FoxDotQuark.git") ```
```Quarks.install("https://github.com/supercollider-quarks/BatLib.git") ```
と打ち込み直接ダウンロードし、インストールします。

インストール出来たら、SuperColliderを再起動しておきましょう。
これで準備は完了です。

#テスト実行
まずSuperCollider側で
```FoxDot.start ```
と打ち込みCTRLキーとEnterキーを同時に押します。

次にコンソールに移って
```python -m FoxDot```
と打ち込みます。

これでFoxDotの画面が立ち上がれば成功です。
ついでにFoxDotのメニューバーのcodeから"Use SC3 Plugins"をチェックしFoxDotを再起動しておきましょう。

FoxDotの画面に
```p1 >> pluck() ```
と打ち込んで音が鳴ったらもう遊び放題です。

#まとめ
FoxDotは僕個人としてはあまりに便利なツールで、日本語記事が本当に少ないのでほぼただの和訳みたいなものですが投稿してみました。
公式のチュートリアルはとても分かりやすく、YouTubeには動画も上がっているのでぜひみてみてください。

個人的にはTidalよりもSuperColliderを使うことをより意識して作られているように感じています。
またpythonで実装されているためその他のpythonライブラリとの連携もとりやすく、かなり可能性を感じています。

今はTidal一強みたいな空気が漂ってますが（勝手にそう思ってるだけです）、今後FoxDotはもっともっと盛り上がるのではないかと思っています。（下手したらTidalを食うのではないかとさえ感じています。）
ぜひ遊んでみてください。

#参考
http://foxdot.org/index.php/installation/
Ubuntu 16.04 ApacheでのPHP7実行までの道のり

まずはapache2のインストール。

`sudo apt-get install apache2`

設定などは下記サイトなどを参考にさせていただいた。
>http://chee-s.net/ubuntu16-04%E3%81%ABapache2%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%BB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B

Apache再起動でindex.htmlの確認完了。
`sudo /etc/init.d/apache2 restart`

PHP7のインストール
`sudo apt-get install php7.0`

下記フォルダにphpinfoを書いたファイルを格納し、Apache再起動。
/var/www/html

無事phpも確認OK。
ユーザーのホームディレクトリにpublic_htmlを作成して、htmlやphpを格納して実行することに。
/etc/apache2/sites-available/にある000-default.confをdefault.confとしてコピーし、設定を変更。

`DocumentRoot /home/ユーザー名/public_html
<Directory /home/ユーザー名/public_html>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>`

設定を有効にするためにコマンド実行
`sudo a2ensite default`

確認してみると参照先が変わっていない。設定は間違っていないようなのに。。。
途方に暮れて再度ネットあさりをしてみるとどうやら000-default.confの設定が効いてしまっている模様なので、無効にするようコマンド実行。

`sudo a2dissite 000-default`

早速確認してみると参照先が変わった模様。
だが今度はPHPがソースのまま表示されて、実行されていない。

/etc/apache2/mods-available/php7.conf

`<IfModule mod_userdir.c>
    <Directory /home/*/public_html>
        php_admin_value engine Off
    </Directory>
</IfModule>`

上記のphp_admin_valueをコメントアウト。
Apacheの再起動で完了。
Debian sidのsystemdパッケージをUbuntuでビルドする簡単な方法

## 前提

* ビルドするUbuntuのバージョンは問いません
* ターゲットはartful（17.10）を指定していますが他のリリースでもかまいません
* とはいえbionicはまだうまくいかないかも
* ビルドできたからといって動くわけではありません

## 手順

```
$ sudo apt install packaging-dev cowbuilder
$ DIST=artful git-pbuilder create
$ gbp clone  https://anonscm.debian.org/git/pkg-systemd/systemd.git
$ cd systemd
$ gbp buildpackage --git-pbuilder --git-dist=artful -uc -us
```

## 説明

gitなどのVCSで管理されたソースパッケージのリポジトリには、ブランチ名などにルールが設定されています。ルールを把握しているのであれば`git`コマンドを使うことも可能ではありますが、git-buildpackage（`gbp`）などの専用のツールを使った方が簡単です。`gbp`を使うとパッチの適用・新しいupstreamバージョンの取り込み・`debian/changelog`の更新もコマンド一発か二発で行えます。

パッケージをビルドするにはBuild-Depパッケージをインストールしておく必要があります。作業マシンにビルドするパッケージごとにパッケージをインストールしていたらしっちゃかめっちゃかになりますし、他のリリースのパッケージをビルドできません。そもそもパッケージの依存関係を正しく記述する際にはクリーンな環境を別途用意する必要がでてきます。`pbuilder`/`cowbuilder`などを使って、最初からクリーンな環境のみでビルドするようにしましょう。

今回は`gbp`でcowbuilder環境を使うために、`git-pbuilder`で環境を構築しています。`--git-pbuilder`オプションでビルド時に`git-pbuilder`を使うように指定しています。

## 尚々

* `pq`サブコマンドでquiltパッチの管理
* `lintian`や`piuparts`によるテスト
* `git-ubuntu`でUbuntuの最新ソースパッケージの取得
ネットワークの通信状況を可視化する（CentOS,tcpdump）

ネットワークで疎通できているのかなど確認する際にtcpdumpを利用しますが、いつも必要に迫られて試行錯誤しているので今回コマンドとオプションを整理しておきたい。良くある利用方法として、dump取得してwhiresharkで表示していましたが今回はLinuxのみで完結します。

**環境とコマンド**

```shell-session
$ uname -a
Linux tk2-249-34492.vs.sakura.ne.jp 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ which tcpdump
/usr/sbin/tcpdump
$ /usr/sbin/tcpdump --version
tcpdump version 4.9.0
libpcap version 1.5.3
OpenSSL 1.0.1e-fips 11 Feb 2013
```

**tcpdump**

```
tcpdump [ -AbdDefhHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ]
 [ -c count ]
 [ -C file_size ] [ -G rotate_seconds ] [ -F file ]
 [ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ]
 [ --number ] [ -Q|-P in|out|inout ]
 [ -r file ] [ -V file ] [ -s snaplen ] [ -T type ] [ -w file ]
 [ -W filecount ]
 [ -E spi@ipaddr algo:secret,...  ]
 [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
 [ --time-stamp-precision=tstamp_precision ]
 [ --immediate-mode ] [ --version ]
 [ expression ]
```

**記載例**

```
$ sudo dist hostname:80 宛のパケット表示
/usr/sbin/tcpdump dst port 80 and host dst <<hostname>>
01:16:55.904796 IP <<srcip>>.port > <<dstip>>.http: Flags [S], seq 192944438, win 29200, options [mss 1460,sackOK,TS val 198347148 ecr 0,nop,wscale 7], length 0

$ sudo /usr/sbin/tcpdump [dit port 80 /src port 80] [dst <<hostname>> / scr <<hostname>> ]
```

**出力例**

```
01:16:55.904796 IP <<srcip>>.port > <<dstip>>.http: Flags [S], seq 192944438, win 29200, options [mss 1460,sackOK,TS val 198347148 ecr 0,nop,wscale 7], length 0
```

01:16:55.904796　パケット出力、受信時刻
srcip.port > dstip.http　送信元IP.ポート > 送信先IP.port
ExpressでCORSを有効にする


## Crossを有効にする。

以下のように設定する

```node.js
// Crossを有効
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
  next();
});

// Optionsも必要
app.options('*', (req, res) => {
  res.sendStatus(200);
});
```
日記アプリのMVP化工程記録・5

# Viewの更新で躓く

[前回の記事](https://qiita.com/poin-settia/items/ee38c9f557a1f36a350e)で一通りの問題は解決したので、ひたすらRepositoryにDB処理を移設するだけかと思いきやまたも問題が。

[Swipe削除のMVP化](https://github.com/poin-settia/Diary/commit/562ee10fd50f2a38907a38b2fb7b65b57f514c10)までコミットしました。

```
Presenter →　Repository　へと対象のIndexをもつRealmDB削除の要求。
Repository → Presenter　へと結果の返却。
```

ここまでくるとやってることは単純作業と化すのですが、
Presenter → View へと画面更新の指示である

```java:PersonFragment
    @Override
    public void notifyItemRemoved(int index) {
        mAdapter.notifyItemRemoved(index);
    }
```
を通知しても罫線（DividerItemDecorationで実装）が残ってしまいます。
明らかにRecyclerViewが上手く更新されていない。

# ItemTouchHelper.SimpleCallbackで躓く

本アプリのリストスワイプ削除は ` ItemTouchHelper.SimpleCallback ` を匿名クラスで実装することで実現しています。
なので本来は

```java:PersonFragment
                    @Override
                    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                        int index = viewHolder.getAdapterPosition();
                        // リストのスワイプ削除イベント
                        mPresenter.onSwiped(index);
                 →ココ  mAdapter.notifyItemRemoved(index);
                    }
```
でViewの更新を促すのが正解なのですが、それではMVP化として美しくない(えっ
というか仮に正規の場所でnotifyItemRemovedをコールしても、結果が同じだったのです。

# 躓いた原因を取り除く

よくよく考えてみるとnotifyItemRemovedをコールしているmAdapter(PersonAdapter)ですが、こいつの生成はPersonPresenterが

```java:PersonFragment
    @Override
    public void showList(RealmList<Person> personList) {
        mAdapter = new PersonAdapter(mActivity, personList, this);
        mRecyclerView.setAdapter(mAdapter);
    }
```
をコールする時に行っています。

**明らかにAdapterの生成と更新のタイミングがよろしくない**

匿名クラスでスワイプ削除イベントを拾っているというのに、チグハグな実装になっています。

という訳で、次回はここらへんをフォーカスしてバグを取り除いていきましょう。
（フラグになると分かっていて次回予告をするんですよね、やめられない。）
accepts_nested_attributes_for のバリデーションエラー発生時に特定の要素のInvalidのみ処理する

例えばこんなModelの関係があったとして

```user.rb
class User < ApplicationRecord
  has_many :telephone_books
  accepts_nested_attributes_for :telephone_books
end
```

```telephone_book.rb
class TelephoneBook < ApplicationRecord
  validates :number, length: { minimum: 10 } 
end
```

`User.create!`時にtelephone_booksのtelでRecordInvalidが発生した時のみ特別な処理を行いたいとする。
`record.errors.include?` を使って一応こんな感じで実現できた。

```users_controller.rb
class UsersController < ApplicationController
  def create
    User.create!({telephone_books_attributes: [{tel: '0120'}]}) # length: { minimum: 10 } に引っかかる
  rescue ActiveRecord::RecordInvalid => e
    # telephone_books.tel のInvalidのみ処理する
    notice_invalid_number(e) if e.record.errors.include?(:'telephone_books.tel')
  end
end
```
月一LP はじめようと思います。



自分のブログが改装中なのでこちらに投下。
Twitterでつぶやいたら思いのほか反応が良かったので、メモ代わりに残しておきます。

#月一LP（つきいちえるぴー）とは

####月に一つLPを作って公開する。以上！

だけだとさすがに不親切なので、、、

- 公開した作品をtwitterハッシュタグ　[＃月一LP](https://twitter.com/hashtag/%E6%9C%88%E4%B8%80LP?src=hash)　にて公開する。
- 個人の制作なのでクオリティは問いません。**しょぼくても完成させて出すことが大事。**
- 締め切りもありません。
- 参加自由。忙しい時期には休むのも大事。
- 一つとは言わず5000兆ページでも、LPと言わずコーポレートサイト並みのボリュームでもOK
- 一か月のスケジュールや技術の面での反省点をブログに書くなど
ご自由にご利用ください。

人が集まってきたら、テーマを作っても面白そうですね。

#こんな人に向いてるよ！！
- 転職・営業したいけど公開できる実績がない人
- 新しい技術を試したい人
- 業務で行なっていないテイストの作品を作りたい人
- 会社の外の人の意見を聞きたい人
- とにかく作品数を増やしたい学生の人


#なぜやろうと思ったのか
最近転職をしたのですが、その時に公開できる作品が少ない！と感じたことが主なきっかけです。

また職場が変わりデザインからコーディングメインの仕事になりました。
なのでデザインの腕をなまらせないためにも定期的に作らなくてはなーと思いました。

月に1ページであればそこまで負担にならずに制作ができる！と考えました。
しかし自分一人だとどうしてもさぼってしまうと思ったので、作りたい人がいたら巻き込もう・仲間が居ると心づよい！という思いでツイートしました。

思いのほかいいねをもらったので、ちょっと安心しています笑

とりあえず言い出しっぺは11月から1つずつ投下していく所存です！！
同じ思いの方が居ましたら、ぜひぜひ参加してみてください～！
minikubeのbuilt-in Docker daemonを使用する

ロカールのコンテナimageをminikubeが利用できるようにbuilt-in Docker daemonを使用するよう設定します。
この設定により、DockerHubにUPやprivate registryを作成しなくても、
ローカルでのimageの作成だけでminikubeがimageを取得してくれます。

#環境
下記で作成したものになります。
https://qiita.com/Manjiii/items/88699c52f5ade2bf4b6f



# minikubeのbuilt-in Docker daemonを使用するように設定

```
eval $(minikube docker-env)
```
上記コマンド実行後、


```
#Dockerfileのある場所へ移動
cd hoge
docker build -t hogehoge:v1 .

# 作成されたことを確認
docker images

# deployしてみる ＊簡略してコマンドでやってみる
kubectl run hoge--minikube --image=hogehoge:v1

```

管理画面で正常に稼働していることを確認
http://192.168.99.100:30000

# minikubeのbuilt-in Docker daemonを使用をやめる
使用をやめるときは

```
eval "$(docker-machine env -u)"
```

#注意点
imageにつけるタグは「latest」は使用できません。
また、同様にimagePullPolicyにalwaysを使用しているとdeploy時にImagePullBackOffエラーになります。


#参考URL
https://kubernetes.io/docs/getting-started-guides/minikube/#driver-plugins
App ExtensionのUnitTestを書く

#はじめに
App Extensionの一つであるToday ExtensionのUnitTestを書こうとしてハマったので解決策を記載します。

#App ExtensionのUnitTest
まずなにもせずにApp ExtensionのUnitTestを書こうとすると様々なエラーが出てテストコードのBuildが通りませんでした。
UnitTestではテストを実行するHostApplicationをTARGETS>General>Testingから設定しますが、そもそもプルダウンの選択肢にはApp Extensionは表示されません。
しかし以下の方法でUnitTestを実行することができました。

##1.新規UnitTestのTargetを作成する
App本体のUnitTestのTargetとは別に新規で作成してください。
その際に、新規作成Target>General>TestingのHost Applicationを**None**に設定します。
![スクリーンショット 2017-11-08 0.08.24.png](https://qiita-image-store.s3.amazonaws.com/0/121288/b3dd9f65-23fd-5d82-3183-5026dcc71f76.png)

##2.UnitTestから参照するファイルのTarget MembershipにUnitTestのTargetを追加する
![スクリーンショット 2017-11-09 0.43.26.png](https://qiita-image-store.s3.amazonaws.com/0/121288/b2f69865-6c95-7860-2437-532ef6accfec.png)
上記画像ではTodayViewControllerをテストするUnitTestを書く場合となります。
通常ではTarget MembershipではTodayExtensionにのみチェックが付いています。
そこに新たにTodayExtensionUnitTestにもチェックをつけています。

#おわりに
以上で手順としては完了になります。
あとはAppExtension用に作成したUnitTestのTargetで通常通りにUnitTestを書いて実行できるかと思います。

最初は``@testable import TodayExtension``だけ書けばいけるかな〜と思っていたのですがエラーが出てダメでした…
Ruby on Rails1日目memo

##やること
野球のwebアプリケーションを作成している。

##今日やったこと
1. prog-8で勉強 http://prog-8.com/languages/rails5
2. すでにあるもので必要な要素を検証
3. Twitter認証の機能について調べる

##わかったこと

- ルーティング：コントローラーの 操作説明書　
- →どのコントローラーのとき、どのアクションをするか、記載されている。
- コントローラー：作り手がコントローラーをもってどういう操作をするか
- e.g. トップページをブラウザに表示する
- ビュー：実際にコントローラーを使ってコマンドを押す指示
- e.g. top.html.erbをブラウザに表示させる

```rb 
"コントローラーの作成"
$ rails g controller hoge1(コントローラ名) hoge2(アクション名)
```
=>これで、Controllerにはhoge1_controller.rb
viewにはhoge2.html.erbがうまれる

すでに指定したコントローラーがフォルダに存在している場合は、ファイルを複製


##今後やること

https://qiita.com/hilotter/items/628fd54785d3c892d048
http://www.geekzshu.com/rails/1562

1. web app の中身をみる
2. bitbucket使って管理しているので、それのgit commitなど理解する
3. Twitterの認証やる
UNIXコマンド入門 2/3

●Vimについて
ファイルを編集する方法:vim というエディタがついてくる
vi +　ファイル名:vim の起動
-->コマンドモード（起動時）　と　編集モード　の2つある。
i（insert） をおす,もしくは下の表示で--INSERT--になっていれば、
編集モードであることが確認できる。

保存や終了する際には、コマンドモードに移る必要がある。
その際にはescapeキーで戻ることができる。

その後
:w で保存が可能。
:q　で終了
escape + : + q とその後にescape + : + q + ! で間違った際も保存せずに終了できる。

●シンボリックリンク
ln -s config/production/database dbconfig :
意味：config/production/database　は dbconfig　という別名

ls -l ：詳細まで表示することができる

作成されたシンボリックリンクは、通常のディレクトリと同じように扱うことができる。

touch : 空のファイルを作成する。
unlink　dbconfig: dbconfigというリンクの削除ができる。


●ユーザー､グループを確認してみよう
ls　-lの見方
ーーー
合計 8
drwxrwxr-x. 3 vagrant vagrant 4096  9月 26 22:55 2017 config
-rw-rw-r--. 1 vagrant vagrant 1572  9月 26 22:48 2017 hello.txt
ーーー

[最初の文字]
d だったらディレクトリ、 
- だったら通常のファイル、
l だったらシンボリックリンクを指す。

[それ以降]
ファイルのアクセス権、Permission に関わる情報

[最初のvagrantと次のvagrant]
ファイルを所有しているユーザとグループ

4096 , 1572 :ファイルサイズ

"config" "hello.text" :ファイル名

 cat /etc/passwd　：ユーザの一覧表示コマンド
 cat /etc/group　： グループ一覧の表示コマンド
 groups : 自分の所属するグループを確認コマンド

●Permission を理解する

drwxrwxr-x:
d--> ディレクトリ、
rwx : ファイルを所有するユーザu(ser)のアクセス権
rwx : ファイルを所有するグループg(roup)のアクセス権
r-x : その他のユーザo(ther)のアクセス権

r(ead)：読み込み可
w(rite)：書き込み可
e(xecute)：実行可能
（x：そのディレクトリを開ける。ディレクトリは実行できないので。）

Permissionを変えたい場合
1.グループのアクセス権にディレクトリを開けるのを含める
chmod g+x sample(ファイル名)
2.グループとその他のアクセス権にディレクトリを開けるのを含める
chmod go+x sample(ファイル名)
3.全てのアクセス権にxを削除
chmod a-x sample(ファイル名)
a:全てという意味

●数値によるパーミッションの表現
3桁の塊を、
左から4,2,1 or 0で表すことができる。
-rwxrw-r--　の時
ユーザーに関する権限は rwx なので、 
421の合計、7として表すことができる。
また、例えばグループに関する権限がrw-なので
420の合計の6と表すことができる。
一方、他のユーザーに関しては r-- なので、 
r にだけ数値が付いて 400 の合計に4となる。
-->このファイルのパーミッションはそれぞれの合計で 764 と表現することができる
この数字の変更で、権限の変更も可能。

例
chmod 774 sample とコマンドを打つと、以下のようなパーミッションになる。
-rwxrwxr--


●コマンドを作ってみよう
hi!と表示するhiというコマンドを作る

0: type hi　で　hi というコマンドが存在しないか調べることができる。
1: vi hi (コマンドモードになる)
2: i ...insertの意味
3.#!/bin/bash
*先頭の 2 文字はシェバンと呼ぶ。
これがあったら次に続くプログラムで実行しなさいよ、という意味。
bash で文字列を出力するには echo を使ってあげればいい。
4.echo"hi！"
5.escapeで、コマンドモード
6.:wqで保存と終了を同時に行う
7.chmod u+x hiユーザーにだけ実行権限を与えたいので 
8. ./hi カレントディレクトリ[./]をきちんと指定しているか確認したのちに。
*hi だけだとコマンドが見つからない

●PATHを通してみよう
UNIX ではコマンドを検索するディレクトリが決められている。
そのディレクトリ以外にあるコマンドを実行したい場合は、
ちゃんとそのファイルがどこにあるか指定してあげないといけないルールになっている

echo $PATH　でコマンドをどこから検索しているかがわかる。
※$PATHはコマンドを実行する際に使われる環境変数の一つ

printenv　で環境変数を確認することができる。

環境変数は自分で設定することができる。

今のディレクトリが /home/vagrant/unix_lessons/myapp の場合、
現在ある $PATH の先頭に加えるには、
export PATH=/home/vagrant/unix_lessons/myapp:$PATH 

export は環境変数を設定するための命令
PATH という名前でこのディレクトリと、すでに設定されている PATH の値を繋げて設定しなさい、という意味

環境変数＋＄（この場合は$PATH）でその値を意味する。

echo $PATH　で、myappディレクトリが加わっているのが確認できるはず。
つまり、コマンドを実行する際にmyappディレクトリも見るようになった
＝コマンドもそのまま入力してもオーケーな状況になった。と言える

実行しようとしているコマンドがどこのディレクトリから呼び出されているかは 
which コマンドで調べることができる。

*このPATHはログアウトすると無効になる。
（無効にしない設定は可能だが）
MySQLのフィールドに予約語を設定する方法

## 概要
MySQLのフィールドに予約語を設定する方法について情報をまとめてみます。

```注意
MySQLのフィールドには普通の方法では予約語を使えない = 使ってほしくないという意図があると考えられます。
あまり良い方法ではないので、使用するときは要注意です。
```

## 対応方法
フィールド名を引用符「`」で囲むことで、フィールド名に利用することができます。

```sql
CREATE TABLE `test` (
  `key` varchar(255) NOT NULL DEFAULT '' COMMENT '識別ID',
  `register_date` datetime COMMENT '登録日時',
  `stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'タイムスタンプ',
  PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=ujis COMMENT='TESTテーブル';
```

またこの場合はSQL実行時にもフィールド名に引用符をつける必要があります。

```sql
// 引用符がないとき
mysql> INSERT INTO test(key, register_date) VALUES ('api_a34b5e7ba87c459c1053370e6e7a63b7', NOW());
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, register_date) VALUES ('api_a34b5e7ba87c459c1053370e6e7a63b7', NOW())' at line 1


// 引用符があるとき
mysql> INSERT INTO test(`key`, register_date) VALUES ('api_a34b5e7ba87c459c1053370e6e7a63b7', NOW());
Query OK, 1 row affected (0.13 sec)

// WHERE句にも引用符が必要
mysql> SELECT * FROM test WHERE `key` = 'api_a34b5e7ba87c459c1053370e6e7a63b7';
+--------------------------------------+---------------------+---------------------+
| key                                  | register_date       | stamp               |
+--------------------------------------+---------------------+---------------------+
| api_a34b5e7ba87c459c1053370e6e7a63b7 | 2017-11-08 17:32:10 | 2017-11-08 17:32:10 |
+--------------------------------------+---------------------+---------------------+
1 row in set (0.00 sec)
```

## 参考資料
MySQL :: MySQL 5.6 リファレンスマニュアル :: 9.3 予約語
https://dev.mysql.com/doc/refman/5.6/ja/reserved-words.html
カード当てゲーム


左側に該当するカードの組み合わせを全列挙し、差集合が右側に該当するカードと合致するかを確認。
ただし全列挙をArray#combinationでやると遅いので、適当にスキップしています。
なお、カード番号は２倍・0-indexにて扱っています。

ただ、解くのに2時間ほどかかっていますので、試合としては負けですね…問題見た瞬間に面食らってるんですもの…

```rb:tyama_henae19.rb
#!/usr/bin/env ruby
#https://mtsmfm.github.io/2017/11/04/doukaku-e19.html
#http://qiita.com/mtsmfm/items/67bf5c121ecbd9b5fab3

T={'o'=>:odd?,'x'=>:even?}

def enum(a,d,s,n)
	(yield [s];return) if d==n-1
	s0=s
	if a[d]==a[d+1]
		s+=1
		s+=2 if s%2==0
		enum(a,d+1,s,n){|e|yield [s0]+e} if s<2*n
		((s+4)/2*2).step(2*n-1,4){|i|
			enum(a,d+1,i,n){|e|yield [s0]+e}
		}
	else
		s=s/2*2+2
		s.step(2*n-1,4){|i|
			enum(a,d+1,i,n){|e|yield [s0]+e}
		}
	end
end

while gets
	x,y=$_.chomp.split(',')
	n=x.size
	s=x[0]=='o'?0:2
	r=[]
	s.step(2*n-1,4){|i|
		enum(x,0,i,n){|e|
			b=([*0...2*n]-e).map{|z|z/2+1}
			a=e.map{|z|z/2+1}
			if y.chars.zip(b).all?{|_1,_2|_2.send T[_1]}
				r<<[a,b]*','
			end
		}
	}
	puts r*'|'
	STDOUT.flush
end
```
GCP始める前に躓いて死んだ話-G Suiteのアプリ制御-

俺です。

GCPはじめようとして弾かれたりしたけども私は元気です。
G SuiteアカウントでGCPの利用開始するときのクソどうでもいい/dev/nullなtipsです。

# プロジェクト作成時に不明なエラーが発生

GCPを組織契約後、プロジェクトを作ります。
プロジェクトに対してIAMなりAPIの有効化を行っていくのですが、最初のプロジェクトを作るときにエラーが...

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/8d0f5266-62bf-8e6d-fcec-bf4c55a81df3.png)

わからないことは無いはずの天上天下最強伝説Google先輩に不明って言われたもんだから自分を見失いました。

# 原因

- Google Developers Consoleをオフにしてたのを`忘れていた`(既定値オン)

契約時にG Suiteの組織デザインしながら、既定値オンだと不味そうなサービスを片っ端からオフにしていたんですねーということでした。はっはっはー。

GCPの制御操作はG Suite/個人のGoogleアカウントに紐付きます。
アカウントがGCPの操作を許可されてないからエラーが発生します。
しかし不明って表現はねーだろと。401とか返してくれればいいのにー


![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/f5c8acce-8c80-3ebf-550e-acb27b045910.png)

# 対策

- Google Developers Consoleを利用する組織/グループのみオンにする

組織, グループごとにアプリ制御ができるのでG Suiteは便利ですよーー
G Suiteは悪くない。悪いのはいつも俺。


おわり。
Arch Linux に Quartus や AOCL をインストールする際に詰まるところ

# インストール時に詰まるところの概要
Arch Linux に Quartus や Intel FPGA SDK for OpenCL(AOCL) をインストールする方法は次の2つがある．

1. [Arch User Repository(AUR)](https://wiki.archlinux.jp/index.php/Arch_User_Repository) (yaourt等) を使う
2. Intel のWebページから直截インストーラをダウンロードしてインストール

やっていることは基本的に同じで，ダウンロードしたファイルを解答して **setup.sh** を実行している．
この **setup.sh** が曲者で，そのまま実行すると Arch Linux では**ハングしてしまう．**

### 症状
setup.sh はいくつかのコンポーネントをまとめてインストールするが，コンポーネントのインストールが完了しても進捗バーのダイアログが消えず，次のコンポーネントのインストールが開始されない．

## 解決策
**解凍したコンポーネントを1つ1つ真心込めて手動でインストール**

インストール用ファイルを解凍し，**component**というディレクトリに含まれる**hoge.run**という実行ファイルをそれぞれ実行する．

### 例
```shell-session
$ tar xvf AOCL-17.0.590-linux.tar
$ cd components
$ sudo ./AOCLSetup-17.1.0.590-linux.run
```

## 解説
実は**setup.sh**というファイルは内部でhoge.runを呼び出しているだけ．(QuartusSetup-<version>.runを呼び出していたはず．中身確認してみて)
setup.shで複数コンポーネントを連続でインストールするとハングするなら1つ1つ真心込めてインストールすれば良いという話

下記コマンドでヘルプが表示されます．

```shell-session
$ hoge.run --help
```

## ちなみに
setup.sh でインストールした際にハングアップするのですが，Quartusの起動はできたりします．
ただ，IPを検索しようとすると何も無かったりとやはり正しくインストールされていないようです．

Intel が Intel FPGA SDK for OpenCL を[無償化](https://www.altera.co.jp/documentation/ewa1412772636144.html)したようなので試してみようと思ったらインストールで引っかかる．
前にも同じことをしたなと思い書きました．

>Removed requirement for Intel® FPGA SDK for OpenCL™ license.
>You can also now run your OpenCL kernel without a paid runtime license

https://www.altera.co.jp/documentation/ewa1412772636144.html から引用

### (しょうもない詰まりどころ)
Intel からインストールファイルをダウンロードしようとしたら，OS選択でLinuxが選べない．
と思ったらアクセスした段階で選択されてましたw
文字列の幅を算出する

# やりたいこと

文字列の幅を算出したい。ここでの幅とは全角文字の幅を 2、それ以外の文字の幅を 1 とした値の合計値のこと。

# 動機

[PrettyTable](https://github.com/vishvananda/prettytable) などのライブラリを使ってテーブルをテキスト出力する場合に、全角文字のせいで表が崩れて困ったので :sob:

# 方法

[unicodedata.east_asian_width](https://docs.python.jp/3/library/unicodedata.html#unicodedata.east_asian_width) を利用する。

なお east asian width ([東アジアの文字幅](https://ja.wikipedia.org/wiki/%E6%9D%B1%E3%82%A2%E3%82%B8%E3%82%A2%E3%81%AE%E6%96%87%E5%AD%97%E5%B9%85)) とは Unicode における文字幅の規定のことで、[Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) で定義されている。

Wikipedia の情報を参考に `unicodedata.east_asian_width` の結果が W, F, A となる文字を幅 2 とみなし、それ以外を幅 1 とみなす。

```py
from unicodedata import east_asian_width


width_dict = {
  'F': 2,   # Fullwidth
  'H': 1,   # Halfwidth
  'W': 2,   # Wide
  'Na': 1,  # Narrow
  'A': 2,   # Ambiguous
  'N': 1    # Neutral
}

string = 'Ꚋんは天使でｱﾙ 😇'

chars = [char for char in string]
print(chars)  # ['Ꚋ', 'ん', 'は', '天', '使', 'で', 'ｱ', 'ﾙ', ' ', '😇']

east_asian_width_list = [east_asian_width(char) for char in chars]
print(east_asian_width_list)  # ['N', 'W', 'W', 'W', 'W', 'W', 'H', 'H', 'Na', 'W']

width_list = [width_dict[east_asian_width] for east_asian_width in east_asian_width_list]
print(width_list)  # [1, 2, 2, 2, 2, 2, 1, 1, 1, 2]

print(sum(width_list))  # 16
```

# 参考

* [東アジアの文字幅](https://ja.wikipedia.org/wiki/%E6%9D%B1%E3%82%A2%E3%82%B8%E3%82%A2%E3%81%AE%E6%96%87%E5%AD%97%E5%B9%85)
* [UAX #11: East Asian Width](http://www.unicode.org/reports/tr11)
Anaconda仮想環境+win32ui,win32con

Anacondaの仮想環境に下記importでつまったのでメモ
・import win32ui
・import win32con

1.pip install win32ui ではない(conda installはない)
win32ui,win32conはpywin32モジュールでimportできるようになる
conda list でpywin32があればよい

2.pip install pywin32 でもない
pywin32はwindowsOSが提供するAPIを利用するライブラリのため，Windowsにインストールしなければだめっぽい.
https://sourceforge.net/projects/pywin32/files/pywin32/
(PCのアーキテクチャとpythonのバージョンが一致するインストーラダウンロード)

3.インストーラ(pywin32-XXX.winXX-pyX.X.exe)でもない
2のインストーラでインストールしても，anacondaのrootの環境でpywin32がインストールされるため，root環境ではimportできるようになるが，仮想環境だとimportできない.

4.結論（Anaconda仮想環境でwin32uiをimportするには）
下記で
i.pywin32をインストーラからインストール
ii.仮想環境をactivate
iii.pip pywin32

追記．上記のようなことをしなくてもcondaでできる．
下記コマンドで
conda install -c conda-forge pywin32=220
Slider COMP の向きを変える方法(TouchDesigner)

#TouchDesignerとは
TouchDesignerとは、3D・2Dイメージを直感的に編集できるノードベースのレンダリングソフトです。

このソフトを使うことでプロジェクションマッピング、ライブ照明演出なども制作することができます。

ノードベース(プログラム文でなく、エフェクトやパーツなどを表現したノード(節)をつなぎ合わせることでプログラムする)ので難しいプログラミングに気を取られずに映像の制作に集中でき、また、変更を加えたその都度リアルタイムに作品を確認できるので効率的な制作が可能です。

#この記事を書いた理由
TouchDesignerの入門書[VISUAL THINKING WITH TOUCHDESIGNER](http://www.bnn.co.jp/books/8842/)で勉強中に躓いてしまったので備忘録代わりに書こうと思いました。

#Slider COMP の向きを変える方法
はじめにSlider COMPを縦に動かすことができるようにします。
まず、図のようにSliderCOMPとNull CHOPを配置します。
![a.png](https://qiita-image-store.s3.amazonaws.com/0/212623/807cc3d9-6521-9290-5dee-dce44a2c12d7.png)

次に、Slider COMPに入ると、図のような構造が見えます。
![b.png](https://qiita-image-store.s3.amazonaws.com/0/212623/27f84144-a4dc-c1bd-35f3-e4902f0b00b8.png)

NullCOMPのパラメータ画面のPanelページを開き、Selectをvにします。
![c.png](https://qiita-image-store.s3.amazonaws.com/0/212623/9d718834-113e-ab01-7a87-aee1d14d6136.png)

Knobのパラメータ画面を開き、xを0に変更し、yのところで+タブをクリックし図のように以下の文を貼り付けます。
> parent().panel.v.val*parent().par.panelh-me.par.panelh/2

![d.png](https://qiita-image-store.s3.amazonaws.com/0/212623/8b1724d5-7cfc-3984-394c-a845e84e99c5.png)

これでSlider COMPを縦に動かすことができるようになりました。

最後に、Slider COMP の形を整えます。
Knob のパラメータ画面でwidthを20、heightを10にします。
次に階層を上がり、Slider COMPのパラメータ画面でwidth 20、height 100にします。
ここでは、とにかくKnobとSlider COMPのwidthが揃っていれば大丈夫です。

Slider COMPをアクティベートし、再生ボタンを押して再生すると、上下にスライドできるようになっているはずです。
読書メモ：Go ならわかるシステムプログラミング〜 delve を Emacs で動かすまで

### 環境

- macOS High Sierra 10.13.1
- Golang 1.9.2
- Emacs 25.3 (Homebrew)

### 手順

ソースコードをチェックアウトして make を使ってコンパイル＆インストール。

```
$ ghq get https://github.com/derekparker/delve.git
$ cd ~/src/github.com/derekparker/delve
$ make test
$ make install
```

Emacs で `M-x package-install RET go-dlv RET` して [benma/go-dlv](https://github.com/benma/go-dlv.el) をインストール。設定は割愛。(`(require 'go-dlv)` 的な事をするだけで良いはず)
go のファイルを開いて `M-x dlv-current-func RET` してデバッガが起動する事を確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/22442/d142be3b-1f1d-980b-2b04-63101d1bf075.png)

### メモ：dyld のパス解決方法がわからない

`make test` を実行した際に dyld 絡みのエラーが発生した。

```
Error compiling ../../_fixtures/issue877.go: signal: abort trap
dyld: Symbol not found: __cg_jpeg_resync_to_restart
  Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
  Expected in: /usr/local/lib/libJPEG.dylib
 in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
```

Homebrew の jpeg と libpng パッケージによってインストールされた dylib が優先された結果、存在しないシンボルを参照してしまうという事象が発生した模様。関連パッケージを一通り削除する事で対処したが、本来はサーチパスを調整する事で解決する問題な気がしている。

※ この問題は以下で再現可能。

```
$ brew install jpeg
$ cd ~/src/github.com/derekparker/delve
$ make test
```

### 参考

- [delve/install\.md at master · derekparker/delve](https://github.com/derekparker/delve/blob/master/Documentation/installation/osx/install.md)
- [benma/go\-dlv\.el: Go Delve \- Debug Go programs interactively with the GUD\.](https://github.com/benma/go-dlv.el)
- [Need documentation for lldb\-server · Issue \#838 · derekparker/delve](https://github.com/derekparker/delve/issues/838)
react-routerのページ遷移をhandleで行う時にはwithRouterを使う

# 概要
* react-routerでページ遷移の基本はLinkだが、onClickなどのhandleでは使えない
* handleで呼び出すには、`withRouter(XxxYyyy)`と`this.props.history.push(/zzzz)`を使う。


# 環境
* "react-router-dom": "^4.2.2"
* "react": "^16.0.0"

# 方法
## 事前準備
普通通りrouteを設定する。

```App.jsx
import {BrowserRouter, Switch, Route} from 'react-router-dom';

class App extends React.Component {
  render() {
    return (
        <BrowserRouter>
          <div>
            <Switch>
              <Route exact path={'/'} component={Home}/>
              <Route path={'/about'} component={About}/>
            </Switch>
          </div>
        </BrowserRouter>
    )
  }
}

export default App
```

## handleで呼び出す手順

1. export時withRouterで囲む。（propsにhistoryオブジェクトが渡される）
2. historyオブジェクトのpushメソッドを引数にurlを渡して実行する

実際に、Homeページ（`/`）からabout（`/about`）ページへ遷移する例を示す。Buttonを押せば`/about`ページにスムーズに遷移できることが確認できるはず。

```Home.jsx
import { withRouter } from 'react-router';

class Home extends React.Component {
  handleToAboutPage = () => {
    this.props.history.push('/about')
  }
  
  render() {
    return (
      <div>
        <Button onClick={this.handleToAboutPage}>
          aboutページへ遷移する
        </Button>
      </div>
    )
  }
}

export default withRouter(Home)
```

なお、reduxを使っている場合も簡単。connectも含めてwithRouterで囲むだけ。`export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Home))
`
これだけで、propsにhistoryオブジェクトが渡されるので、あと上記と同じようにthis.props.history.push('/about')でページ遷移出来る。

```Home.jsx
import { withRouter } from 'react-router';

class Home extends React.Component {
  handleToAboutPage = () => {
    this.props.history.push('/about')
  }
  
  render() {
    return (
      <div>
        <Button onClick={this.handleToAboutPage}>
          aboutページへ遷移する
        </Button>
      </div>
    )
  }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Home))
```

# 参考
* https://qiita.com/hoture/items/b4ca1773580317e7112e
* http://blog.hokuma.net/frontend/how_to_navigate_in_react_router/
WebディレクターにRailsを教える その１（学習環境構築編）

## 経緯
社内のWebディレクターからWebサイトを作りたいからPythonかRubyを教えて欲しいと頼まれたので（人に教える事で自分も必要に駆られ学習するかと期待し）承諾した

## 今回RubyというかRailsを選択した理由
- 私自身のスキルとしてPythonよりRubyの方が経験がある
- 初心者向けの日本語学習サイトが豊富

## 対象者
- プログラム未経験のWebディレクター
- Webサイトのシステム構成の理解はあり （Webサーバーがあって、DBがあってとかの理解）
- HTMLの理解はあり
- PCはMacBook Air

## ゴールの設定
- Railsで簡単なWebページを作成してHerokuにデプロイする
- アカウント管理してログインできるサイトを作る
- ゴールまでハンズオン4回ぐらいで行きたい

## 教えかた、気を付けること
- Webだけで学習出来るようにしたいので、Cloud9を使って行う
- 1回1時間のハンズオンで行う(1時間に乗らない部分を宿題でやってもらう)
- なるべく動くのを確認できる状態で進める
- モチベが続く学習方法を模索する（文字量多い公式ドキュメントよりかは、解説動画などから入ってもらう）

## 事前準備として以下のアカウントを作成してもらう（所要時間 15分）
- GitHubのアカウント
- Cloud9のアカウント
- Herokuのアカウント

### GitHubアカウントの作成（所要時間 5分）
- [Githubのアカウント作成方法](https://qiita.com/rshibasa/items/f62db870ed573ca4dced)

### Cloud9のアカウント作成（所要時間 5分）
- [github のアカウントを利用して、cloud9のアカウントを登録する。](https://qiita.com/january108/items/907b1a228ac24d794470)
- 無料で使えるがクレジットカードの登録が必要だったはず

### Herokuのアカウント作成（所要時間 5分）
- [Herokuにアカウント登録してアプリを作成する](https://codenative.xyz/stacks/heroku/signup-for-heroku-and-create-a-new-app)
- アカウントを作成する部分まで

## 学習に使うと便利なサイト（予習・復習で使ってもらう）
- [ドットインストール](https://dotinstall.com/)
- [Progate](https://prog-8.com/)

## 参考になるQiita記事を見つけた（こんな記事を書かなくても良かったｗ）
- [初めての、クラウドを利用してRuby on Railsを動かすまで（Cloud9、GitHub、Heroku）](https://qiita.com/HideakiSaito/items/5be1a45870a4c3d1a3c7)

## その他
- Cloud9がやり難かったら、Docker For Macをインストールしてローカルで勉強する
- DB系はFirebaseを使う感じで進めてみる（HerokuじゃなくGCPで良さそうな気がする）

最近はDockerもあるし、開発環境を作るの簡単で助かる
これからゴールのサイトを作ってから、ハンズオンの内容を用意する
railsにおける条件分岐について

条件分岐文の代表はif文です。英語でもifは「もし〜ならば」という訳になります。プログラムでも同じく、「もしこの変数が0以上であれば」のような条件を付けて、処理を分岐させることができます。

そして条件分岐で活躍するのが、比較演算子(==や<など)と、論理型の値（trueとfalse）です。

プログラムにおいて予め全ての値を予測することは不可能です。もしそうであれば、プログラムは必要ありません。プログラムを使ってわざわざ柔軟性を持たなくても答えがわかっているからです。

特に、ユーザの入力値は予想できません。例えばアンケートを考えてみましょう。「スマートフォンアプリを作りたい人はYes, 作りたくない人はNoと書いてください」というアンケートをWeb上でとったとします。このとき、スマートフォンアプリを作りたい人はYesを書くし、逆に作りたくない人はNoと書きます。それは予想できないし、どちらも取り得る値になります。

しかし、あらかじめ値を予想して、「こういうときはこうしてくれ」というプログラムを書いておくことはできます。例えば、さきほどのアンケートでYesを答えた人には、スマートフォンアプリを開発できるサービスを紹介するという条件分岐をプログラムに仕込んでおくことができます。

これは開発者が、予想された条件分岐をプログラムとして書いておいて、コンピュータがそれを忠実に実行するということです。コンピュータはそこまで書いてくれないと処理できません。条件分岐はコンピュータに判断させる手段となります。
hubの設定

# hubを使う

## hubとは
gitを使いやすくするためのコマンドラインツール

## インストール
基本homebrewでやったほうが楽

```bash
brew install hub
```

##　設定
### aliasを設定する

```text
alias git=hub
```
versionを確認する

```bash
git version
```
## 使い方

リポジトリのページに飛ぶ

```bash
git browse
```

issueに飛ぶ

```bash
git browse -- issues
```
分類問題の考え方

# 分類問題の考え方

よく巷にある画像の分類、ドキュメントのカテゴリ分けなどがあるが、それらは結局最終的には同じ出力形式になります。
それは以下のように、出力層で分類したいクラスの数値のユニットの数と同等になります。


例えば・・・ポジネガ判定はポジティブ、ネガティブの2つの値、MNISTは0-9などです。
ネガポジなどは実際の出力層は以下のような数式で表されます。
$$
f(x)=(0.4,0.6)^T
$$
ここでポイントなのは全ての項目を足すと1になるということです。
なので出力層ではそのそのまま確率を出すことが可能になります。

## シングルラベルの場合
ここで言う確率とはそのデータが必ずどれか1つに入っている場合であり、他方が高くなるともう片方が低くなってしまいます。

### Softmax関数
これを実装するにはSoftmax関数を使います。
$$
y_i = \frac{\exp(a_i)}{\sum_j^D \exp(a_j)}
$$
これは以下のように計算できますので、
$$
\sum_i^D y_i = \frac{\sum_i^D \exp(a_i)}{\sum_j^D \exp(a_j)}=1
$$
のように和が1となります。

### 交差エントロピー
これを損失関数として扱う場合には交差エントロピーを使います。
F.softmax_cross_entropyです。

$$
E=-\sum_n^N \sum_i^D t_{ni} \log y_i
$$

### マルチラベルの場合
上記のシングルラベルの方法だと、どちらかの数値が高くなると必ず他の数値が下がります。
そのため、答えが複数あるようなものには使えません。
例えば・・・一般のニュース記事などで、タグ付けをする場合、「経済」、「政治」など複数のラベリングが必要になるとき

このときは別の関数を使うことになます。
また、分類問題でも「その他」というものが存在する場合もこの手法が使えます。未知のものというのは非常に学習させるのは難しいので。

その際にはシグモイド関数を使うことになります。sigmoid_cross_entropyです。
シグモイド関数を使うことにより、一方的な数値の偏りがなくなります。
次は具体例で説明しようと思います。
AzureのBing Searchで画像検索

# Bing Search APIで画像取得

既に書かれている方も多いかと思いますが、Bing Search APIで
画像を取得してみました。
経緯としては人工知能で学習させるために必要な画像の準備のためです。
調べてみるとバージョンがいろいろあり、今はv5があり、v7がpreviewらしいです。
ということでv5でやってみます。[こちら](https://qiita.com/ysdyt/items/49e99416079546b65dfc)を参考にさせてもらいました。

## 事前準備
まずは事前準備として、Azureの契約が済んでいることとする。
Azure Portalにアクセスし、左側のメニューから「Cognitive Services」から追加で「Bing Search API」を選択します。
適当に名前を入れて作成が完了するとキーを確認します。
* Keys
xxxxxxxxx

## テストデータの接続
まずは接続できるか試してみる。

```bash
curl -H 'Ocp-Apim-Subscription-Key:{key}'  https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=cat | jq .
```

上記コマンドでズラズラっとデータが取得できればOKです。

## 実際のプログラムでの取得

次に実際のプログラムで取得してみます。
言語はわかりやすいpythonでやってみます。
いろいろ突っ込みどころは満載ですが・・・requestsが使いやすいのでそれを使っています。

```python:get_img_from_bing.py
import os
import sys

import json
import re
import requests
import urllib
import shutil

HOST='api.cognitive.microsoft.com'
REST_PATH='/bing/v5.0/images/search'
SAVE_PATH='/photos'
SUBSCRITION_KEY='xxxxx;


def makedir(dstpath):
    if not os.path.isdir(dstpath):
        try:
            os.makedirs(dstpath)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise  # raises the error again

def get_image(index,url,word):
    print(url)
    dstpath=SAVE_PATH+"/"+word+"/"
    makedir(dstpath)
    headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0'}

    try:
        r=requests.get(url, headers=headers,stream=True)
        if r.status_code== 200:
            kaku=r.headers['content-type'].split('/')[1]
            filepath=dstpath+str(index)+'.'+kaku
            with open(filepath,'wb') as f:
                r.raw.decode_content =True
                shutil.copyfileobj(r.raw,f)    
    except :
        pass

def main(argv):
    word='cat'
    #print(word)
    offset=0
    count=150
    headers = {'Ocp-Apim-Subscription-Key':SUBSCRITION_KEY}

    params = {
    'q': word,
    'mkt': 'ja-JP',
    'count': count,
    'offset': offset,
}
    url='https://'+HOST+'/' + REST_PATH +'?q='+word
    data=requests.get(url, headers=headers,params=params).json()
    #print(data['value']['contentUrl'])
    for i,v in enumerate(data['value']):
        url=v['contentUrl']
        #print(i['contentUrl'])
        pattern = r"&r=(http.+)&p="
        img_url = re.search(pattern, url)
        iurl= urllib.parse.unquote(img_url.group(1))
        get_image(offset+i,iurl,word)
    print('end')

if __name__ == '__main__':
    main(sys.argv)

```
これを実行して猫の画像がphotosの配下に出てくればOKです。
たまにサイトによってはUAがrequestのデフォルトだと弾くところもあるので設定をしています。
同一マシンで複数のJenkinsを動かす


- 前提: すでになんらかの方法で導入したJenkinsが稼働中
- やりたいこと: ポート番号とJENKINS_HOMEを別に設定したJenkinsを新たに入れたい。  
今動いているJenkinsとは全くの別のJenkinsを同時に動かしたい。

## 結論
1. [公式](https://jenkins.io/)からjenkins.warファイルを入手する。
2. jenkins.warファイルを保存した場所に移動。
3. → のコマンドを実行。`env JENKINS_HOME=(既存Jenkinsが使用しているJENKINS_HOME以外の場所のパス) java -jar jenkins.war httpPort=(既存Jenkins使用しているポート番号以外のポート番号)`
4. Jenkinsが起動するので、起動処理が終わったようだったら http://(稼働マシンのIP):(httpPortに指定したポート番号)にアクセス。

3をスクリプト化しておけば間違いが少なく済みそう。


## 経緯など
- HomebrewでJenkinsをインストールして使っていたけど、古くなった (ver1.5くらい) ので、新しいver2.xのJenkinsを試したかった
- けど、Macで動かす必要があった(iOSアプリのビルド用)ので仮想環境は用意しにくい
- 既存Jenkinsはバリバリ活躍中だったので、止めたくなかった

### 落ちた罠
- 管理者パスワードなどを設定せずに先に進んで、一度ログアウトしてしまうと入れなくなる  
→ [Jenkinsでログインできなくなった時の対処法 - としたにあんの左脳](http://toshitanian.hatenablog.com/entry/2013/09/07/200608)
- せっかくver2.xにしたんだしパイプラインとやらを使ってみたらワークスペースが見当たらない  
→ [Jenkins Pipelineを利用した時のworkspaceの場所 - Qiita](https://qiita.com/Jenkins_BBA/items/66b9683f37e7b5fa72e2)
スクロール用の要素の取得にはdocument.scrollingElementを使おう

ドキュメントのスクロールまたはスクロール位置の取得に使うべき要素はブラウザによって差異があり、SafariやChromeなどのWebKit系がbody要素を、それ以外はhtml要素を使う必要があります。が、遂にChromeがChrome 61でhtml要素派に変わりました。これによってブラウザ判定でbody要素かhtml要素かを使い分けるという処理が動かなくなりました。

Chrome Platform Status : Interoperable body/documentElement scroll behavior
https://www.chromestatus.com/feature/6386758136627200

スクロール関連の仕様は[CSS Object Modelのviewモジュール](https://drafts.csswg.org/cssom-view/)で定められていて、スクロール用の要素の取得に``document.scrollingElement``属性が用意されています。ChromeではChrome 41から使えるようになっています[^1]。結構前ですね。この属性は互換モードならbody要素を、そうでないならhtml要素を返すとなっているので、満を持して互換モードをやめたということなのだと思われます。

ということでスクロール用の要素の取得には``document.scrollingElement``属性を使いましょう。

が、MDNによると残念ながらまだIEが対応していないようです[^2]。なのでそのまま使うのではなく、何らかの代替手段を用意する必要があります。以下のブログによると、``document.scrollingElement``があればそれを、無い場合はWebKitならbody要素、それ以外は``document.documentElement``を使うみたいなことをすれば良いようです。

Dev.Opera — Fixing the scrollTop bug
https://dev.opera.com/articles/fixing-the-scrolltop-bug/


[^1]: https://www.chromestatus.com/feature/4819604295647232
[^2]: https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement