OmniAICreator/Qiita-1.07M huggingface dataset:
JetbrainsのIDEのDBクライアントがすごく良いというお話

今年、転職を期に今までのSublime Text3ベースだった開発環境から、IntelliJ IDEAに乗り換えました。
それはもう効率的な開発ができるようになったと思います。
今回のアドベントカレンダーではその良さの一つである、データベースクライアントが非常に良いのでその紹介になります。

ちなみに、IntelliJ IDEAで凄く良い点は複数あるので、余力があれば他のものについても書いていきたいと思います。
今まで使っていた複数のソフトが一つの画面で完結するのは本当に便利です。

- Dockerの作成、起動について
- VCS(Gitクライアントとして)
- コマンド起動やデバッガー

### IntelliJ IDEAをに移る前の話
私は今までWindowsの環境でLinux上のMySQLへ繋いで開発をするために、WindowsのDBクライアントを使用して来ました。
一番始めて使ったのは「CSE」というソフトで、わりと苦がなく使えていたのですがWindows8に十分に対応していなかったため、その後はWindows10 + HeigeSQLを利用してきました。

しかし、新たな職場ではMac＋PostgreSQLを使うという環境なため、これらの組み合わせが使えなくなってしまいました。
それなりにCLIでも叩けはしますが、アプリケーションを作成する際にはGUIで値をゴニョゴニョいじって開発するのが体に染み付いています。
なにかいいのはないかなと思っていたところ、JetBrainsの製品群にはDBクライアントのDatagripなるものがあり、使い始めたIntelliJ IDEAにもその機能が備わっていることを知りました。
そして、この製品は私のDBクライアントとしてのユースケースを十分に満たし、今まで使えていなかった素晴らしい機能も備えていることがわかりました。

### 良い点
- WindowsでもMacでも同じ機能が使える
- SQLの補完がちゃんとしてる
- IDE内で完結できる
- 単一のデータベースだけではなく、様々なデータソースに対応
    - MySQL
    - PostgreSQL
- SSHトンネリングできるので、レンタルサーバのMySQLポートを開けなくてもクライアントが繋げる
- 関係性が見える


### MySQL、PostgreSQLだけじゃなく、Amazon Redshiftにも対応する複数のデータソース
IntelliJ IdeaなどのIDEの場合、一番右の部分にDatabaseというのがあるかと思います。
そこからDatabaseツールウィンドゥを開き、＋ > Datasourceと進んで行くと様々なデータソースに接続ができるのがわかります。
それに加え、Jetbrainsの製品はWindowsでもMacでもLinuxでも動くため、これを使えてしまえば他の環境になったとしても大抵は開発できちゃいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/24049/cc403fb5-522e-eaa6-d6ab-2dc94c3fbcb3.png)

### SSHトンネリングについて
個人用に借りているレンタルサーバはアプリとDBを一台で動かしています。
そのサーバではアプリとDBをローカルで繋いでいて、MySQLは外部にポートを開けていません。
要はよくあるphpMyAdminが稼働しているような状況です。
HeigeSQLの時は繋ぐことができませんでしたが、IntelliJ IDEAではSSHトンネリングすることができます。
SSHさえつながる環境であれば、GUIで操作できるようになったのです！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/24049/548db02a-ed92-0fb2-d87d-ba97ebbad697.png)

### ダイアグラムが見れる
テーブルを右クリックして、下の方にあるshow diaglamを選ぶとそのテーブルと関連性があるダイアグラムが見れます。
今の職場のDB構造はER図を見たことがありませんが、たいていの関係性がわかるようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/24049/148b577f-be3f-5dac-f4c6-b0e0b66ca1a3.png)

### まとめ
色々なOSで動き、色々なデータソースにつながるDBクライアント。
それでいてコードを書きながら同じツールで参照できる。
と、開発が漲ること間違い無しです！
とくにPHPStorm + phpMyaAdminの環境とかでしたら、激的に使いやすくなると思います。
ぜひJetbrains製品を使っていたら一度使ってみてください。
systemd-nspawn+overlayfsについて


[systemd-nspawn Advent Calendar 2017](https://qiita.com/advent-calendar/2017/systemd-nspawn) 5日目の記事です。

systemd-nspawnは[overlayfs](https://en.wikipedia.org/wiki/OverlayFS)を使って簡単にCoW(Copy-On-Write)な環境を作れます

# 準備

overlayモジュールが必要なので読み込みます

```
modprobe overlay
echo overlay >> /etc/modules-load.d/modules.conf
```

# 使ってみる

overlayfsを使う場合は--overlay=オプションを指定します
overlayオプションは3つのファイルパスを取り(2つでもOKですが今回は3つの場合を説明します)

```
--overlay=一番最初のレイヤー:overlayfsの反映先:コンテナ側のマウントパス
```

となります

例えばこのようにした場合、ホスト側の/mntがコンテナ側の/mntに繋がるのですが、コンテナ側で行った変更はホスト側から見ると反映されません。逆にホスト側からの変更はコンテナ側には見れるようになります。

```
systemd-nspawn -D ubuntu --overlay=/mnt:/var/tmp:/mnt
```

実験してみます

* root@container: コンテナ内
* root@host: ホスト側

で打つコマンドを示しています

```
root@container:/# touch /mnt/container.txt
root@container:/# ls -l /mnt/container.txt # 存在する

root@host:/# ls -l /mnt/container.txt # 存在しない
root@host:/# ls -l /var/tmp/container.txt # 存在する
root@host:/# touch /mnt/host.txt

root@container:/# ls -l /mnt/host.txt # 存在する
root@container:/# rm /mnt/host.txt

root@host:/# ls -l /mnt/host.txt # 存在する
root@host:/# ls -l /var/tmp/host.txt # 削除を現す特殊ファイル
```

要するにコンテナ内の/mntで行った変更は差分情報を/var/tmpに書き込まれて、ホスト側の/mntには影響がないという挙動です

こんな感じで、簡単に使えるので便利です
その他詳しいことは`man systemd-nspawn`を参照ください
ちなみに新しいバージョンだと、+をファイルパス前につけるとコンテナからの相対パスを指定出来たり、2番目を省略すると自動的に/var/tmpを使ったりと色々便利になってます！
roslaunchのコードAPIを使う（**very_unstable**）

# Q. roslaunchをPythonから叩きたいやつおるか？ｗ
A. おらんなｗ

roslaunchはROSでロボットシステムを構築するのに欠かせない機能の1つでしょう。また、その文法は[『複雑なROSの構造に対応できるように』](http://wiki.ros.org/ja/roslaunch)よく工夫されていると思います。roslaunchそのものに不足している機能についても、例えば[timed_roslaunch](https://qiita.com/MoriKen/items/a1f29f5637732ac18a1c)のようなユーザが作成した仕組みによって十分カバーされているように感じます。

と、いうことで、roslaunchをPythonから叩くような必要はほとんどないはずなので、そういうことを思いつく前にまずはしっかり[roslaunchの文法ドキュメント](http://wiki.ros.org/ja/roslaunch/XML)とTag Referenceを読みましょう。おわり。

## おわりません
ここで終わるとただのポエムになってしまうので、続きを書きます。
roslaunchには神の慈悲でPython向けのAPIが提供されています。ただしこれは、[ここ](http://wiki.ros.org/ja/roslaunch#Stability.2BAC8-Roadmap)に書いてあるように、**very unstable**です。
APIは以下のように利用することができます。

```py

import rospkg
import roslaunch

# パッケージパスの取得
rospack = rospkg.RosPack()
pkg_path = rospack.get_path('hoge')
launch_path = path + '/launch/hoge.launch'

# uuidの取得とロギング設定
uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
roslaunch.configure_logging(uuid)

# ROSLaunchParentオブジェクトの作成
# roslaunch.parent.ROSLaunchParent(uuid, [launch_path1, launch_path2, ...])とすることで複数のlaunchを同時に立ち上げることも可能
launch = roslaunch.parent.ROSLaunchParent(uuid, [launch_path])

# roslaunchの立ち上げ
launch.start()

# roslaunchの終了
launch.shutdown()
```

一見すると便利なように見えますが、例えばlaunch.start()したあとで、起動したroslanuchが動作し続けているのかなどの情報を得ることはできません。そういう機能を必要としているのであれば、[diagnotics](http://wiki.ros.org/diagnostics)とかを使ったほうがよさそうです。

# まとめ
roslaunch APIはなるべく使わないようにしよう
Excel列名変換問題をRubyで解いてみた

# Excel列名変換問題とは
Excelって行名は番号なのに列名がAlphabetじゃないですか．
なので，1列目は'A'，2列目は'B'，みたいな変換がしたくなるわけです．(axlsx使っててなりました)

ぐぐったところどうやらこれをExcel列名変換問題というらしく，いろんな言語で実装してる人がいるみたいです．
おもしろそうなのでRubyで実装してみました．

# なにはともあれTest Code
関数のIN/OUTがはっきりしていて内部状態を持たない純粋関数みたいなものなので，まずまっさきにTest Codeから整備しておくべきである，というわけで ↓ のようなTest Codeを作りました．(Input/Outputの組み合わせはぐぐりました)

```ruby:Integer->String
def test_convert_col_num_to_alphabet
  assert_raises { convert_col_num_to_alphabet(0) }
  assert_equal('A', convert_col_num_to_alphabet(1))
  assert_equal('Z', convert_col_num_to_alphabet(26))
  assert_equal('AA', convert_col_num_to_alphabet(27))
  assert_equal('AZ', convert_col_num_to_alphabet(52))
  assert_equal('BA', convert_col_num_to_alphabet(53))
  assert_equal('ZZ', convert_col_num_to_alphabet(702))
  assert_equal('AAA', convert_col_num_to_alphabet(703))
end
```

```ruby:String->Integer
def test_convert_alphabet_to_col_num
  assert_raises { convert_alphabet_to_col_num('') }
  assert_raises { convert_alphabet_to_col_num(nil) }
  assert_equal(1, convert_alphabet_to_col_num('A'))
  assert_equal(26, convert_alphabet_to_col_num('Z'))
  assert_equal(27, convert_alphabet_to_col_num('AA'))
  assert_equal(52, convert_alphabet_to_col_num('AZ'))
  assert_equal(53, convert_alphabet_to_col_num('BA'))
  assert_equal(702, convert_alphabet_to_col_num('ZZ'))
  assert_equal(703, convert_alphabet_to_col_num('AAA'))
end
```
# できあがった実装
できるかぎりシンプルにしたかったのですが ↓ のくらいのところでいったん満足しました．

``` ruby:Integer->String
ALPHABET_COUNT = 26
ALPHABET_CODE_OFFSET = 'A'.ord

def convert_col_num_to_alphabet(count)
  raiase "count is 0 or minus" if count <= 0

  ret = ''

  loop {
    count = count - 1

    remainder = count % ALPHABET_COUNT
    char = (ALPHABET_CODE_OFFSET + remainder).chr
    ret = char << ret

    count = count / ALPHABET_COUNT
    break if count == 0
  }

  return ret
end
```

```ruby:String->Integer
def convert_alphabet_to_col_num(alphabet)
  raise "alphabet is nil" if alphabet.nil?
  raise "alphabet is empty" if alphabet.empty?

  ret = 0
  size = alphabet.size

  alphabet.each_char { |char|
    ret += (char.ord - ALPHABET_CODE_OFFSET + 1) * ALPHABET_COUNT ** (size - 1)
    size -= 1
  }

  return ret
end
```
とりあえずこれで上のTest CodeもPassしました．

文字を数字として扱うのに.ordと.chrというAPIを使っていますが，これを見つけられなかったらもっと長くなってたかも．
`['', 'A', 'B', 'C', ... 'Z']`
っていう配列作ってIndexでアクセスしたり，
`' ABC...Z'`
っていう文字列作ってIndexでアクセスしたりしてたかも．
(こっちのほうが直感的でわかりやすい，って話もあるか)

`count = count - 1`
の処理が直感的にわかりにくいのが悩みどころ．

# やってみた感想
Algorithm考えるのは楽しいです．
昔XML Parserを自力実装したことがありましたがそれと同じ雰囲気．(車輪の再発明感も)

しかしこんなLogic，超汎用なんだからどっかのFrameworkにAPI実装されててもおかしくないですよね． ← たぶんある

---///
AIで競輪予想 その3

[AIで競輪予想 その2](https://qiita.com/kenji_at_801/items/154e527a0ef5b2229079)で、参考にしたページでうまくいかないので、別のやり方を模索。

以下の本を参考にした。

<a href="https://www.amazon.co.jp/Python%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0-%E9%96%8B%E7%99%BA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-BeautifulSoup-scikit-learn-TensorFlow%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/dp/4802610793/ref=as_li_ss_il?ie=UTF8&qid=1512660826&sr=8-1&keywords=9784802610797&linkCode=li2&tag=baseball55-22&linkId=daf3b47bbfc6bc16c122489c6f4fc19d" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4802610793&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=baseball55-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=baseball55-22&l=li2&o=9&a=4802610793" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
[Pythonによるスクレイピング&機械学習 開発テクニック BeautifulSoup,scikit-learn,TensorFlowを使ってみよう](http://amzn.to/2AjWEmC)

#環境準備編
以下の順番で環境設定を行っていきます。
1.AWS（EC2）にubuntuを立ち上げる
2.MySql（5.6.16-1~exp1 (Ubuntu)）のインストール
3.Pythonのインストール
4.seleniumのインストール

##3.Pythonのインストール
```shell-session:shell
$ apt-get update
$ apt-get install -y python3 python3-pip
```

##4.seleniumのインストール
```shell-session:shell
$ pip3 install selenium
```


##4.BeautifulSoup4のインストール
```shell-session:shell
$ pip3 install beautifulsoup4
```

##5.Phanton.JSのインストール
```shell-session:shell
$ apt-get install -y wget libfontconfig
$ mkdir -p /home/root/src && cd $_
$ wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
$ tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
$ cd cd phantomjs-2.1.1-linux-x86_64/bin/
$ cp phantomjs /usr/local/bin/
```


##6.日本語フォントのインストール
```shell-session:shell
$ apt-get install -y fonts-migmix
```
[phina.js] clipをする時、絶対にやってはいけないこと

## clip関数内では、必ずbeginPath()を実行しないといけない[^1]

絶対に

**clip関数内で!!**

![beginPath() を!!!](https://qiita-image-store.s3.amazonaws.com/0/60690/1bf2f3df-fe51-ca5a-a5d4-528f87429b25.png)


![実行してください!](https://qiita-image-store.s3.amazonaws.com/0/60690/b073e5cb-0001-4537-3ec6-e19b227e8373.png)


**以上です。**

......(続きます)


## 絶対にやってはいけないコード

例えば、こんなコードがあったとします。

```js

// シーンinit内
var star = StarShape({
  x: 300,
  y: 300,
}).addChildTo(this);
star.clip = function(canvas) {
  canvas.arc(0, 0, 25, 0, 2 * Math.PI);
};

```

実行してから、1分後ぐらいにはただ星を一つ円でclipしているだけなのに、ものすごく重くなります。
意味がわかりませんね。

## 絶対にやってほしいbeginPath()を使用したコード

```js

// シーンinit内
var star = StarShape({
  x: 300,
  y: 300,
}).addChildTo(this);
star.clip = function(canvas) {
  canvas.beginPath().arc(0, 0, 25, 0, 2 * Math.PI);
};


```

## なぜbeginPath()を使わないと重くなるのか

[beginPath() メソッド - Canvasリファレンス - HTML5.JP](http://www.html5.jp/canvas/ref/method/beginPath.html)

>context . beginPath()
現在のパスをリセットします。



`beginPath()`をするまで、パスがずっと残り続けているので、1分後には、1800個の円をclipしていることになります。[^2]
それは重くて当然ですね...。
でも、phina.jsの中でいい感じに処理してるんじゃないかと思いますよね？
という勘違いがそもそもこれを引き起こした原因です。

## save(), restore() しても、パスの状態は変わらない

phina.jsではclipの前後で、`save()`して`restore()`することで、前後のオブジェクトがclipの影響を受けないようにしています。
しかし、clipされるされないとパスが消えるかどうかは別問題です。

[save(), restore() メソッド - Canvasリファレンス - HTML5.JP](http://www.html5.jp/canvas/ref/method/save.html)

>現在のパスと現在のビットマップは描画状態に含まれません。現在のパスは、beginPath() メソッドを使ってリセットするまで存在し続けます。現在のビットマップは canvas のプロパティであり、コンテキストではありません。

これに気づくまでにずっと`save()`, `restore()`でパスの状態も変わってるだろうと勘違いしていました。
引用の通り、 `beginPath()` を使用するまでは、どんなことをしてもパスは残り続けます。

## 気づいた経緯

**以下、ただの昔話です。**

昔々、何かを破壊する演出等でclipを使用していた事があり、なぜかだんだん重くなっていくという謎のバグに悩まされていました。
最初は、clipが原因というところまでは、調べることができましたが、どうしてclipで重くなるのか全くわからず、clipを使わない方法で演出の処理を行うことにしました。

それから、しばらく経って、[phina.jsアドベントカレンダー7日目](https://qiita.com/simiraaaa/items/52de20a30a02600f2486)を書くにあたって、clipを使用することがありました。
やはり、昔の経験があるので、clipを使うと重くなるだろうなと思いながらコードを書いていました。
案の定、重くなったのでちゃんと原因を探ることにしました...。

しかし、前回同様調べても、中々原因が判明しないので、手当たり次第、clipの仕方を変えてみることにしました。

まずは、パスを閉じないと前のパスが残り続けるのではないかと思い `closePath()` を実行。
当然変わりません。

次にパスが残り続けているかどうか調べるために、1フレーム目だけパスを設定をして、その後はパスをいじらないようにしました。(まだ`beginPath()`していません)
やっぱり、clipされ続けるのでパスが残ってるという認識は間違ってないことがわかりました。

その後、`fill()`とか`stroke()`とか色々試しましたが、改善しません。
`canvas clip 重い` とかでググるも関係ありそうなサイトを見つけることができず。

しょうがないので、clipのサンプルを漁っていると必ず`beginPath()`が呼ばれていることに気づきました。
その時、心の中では、`save()`と`restore()`してるから関係ないだろう...。と思いつつも、自分のコードでも`beginPath()`を使ってみることにしました。

すると、信じられないことに今まで重くなっていたのが、嘘のように軽くなりましたとさ...。

めでたし、めでたし。


## あとがき

ちゃんと、基礎は押さえておこう。
思い込みで試さないより、**関係ないと思っても**手当たり次第、試してみよう。


[^1]: 多少語弊がありますが、意図してやる分には全然構いません
[^2]: 30fps * 60秒 = 1800
C言語の関数ポインタを使ってみた話

この記事は香川大学工学部サークルSLPのアドベントカレンダー（[SLP KBIT Advent Calendar 2017](https://adventar.org/calendars/2492)）の8日目の記事です。

アウトプットをするのは今回が初めての挑戦となります。

いろいろとガバガバなのは見逃してください。

#はじめに

新しく得た知識ってやたら使いたくなりますよね！

私も最近知った関数ポインタというものを使ってみたくなったので勉強ついでに使ってみました。

何かの開発として使っていけたらよかったのですが、なかなかそうもいかず、、、

にわか仕込みの知識しかないですが、とりあえず今回はとある講義の課題に無理やり使ってみました。~~課題としては使う必要はなかった。~~

#関数ポインタとは

関数ポインタとは、簡単にいうとポインタの関数版です。

ポインタの参照先を関数にすると、そのポインタが指し示す関数を呼び出すことができます。

ポインタに格納する関数のアドレスを変えることで、呼び出す関数を動的に変更することが可能です。

##使い方

関数ポインタは、アドレスを格納する関数と**同じ戻り値の型**を使って宣言します。

関数ポインタの仮引数の型と、ポインタに格納する関数の型は一致する必要があります。

関数ポインタを使うときには、ポインタ名に()を付けて使いましょう。

**型 (*変数名)(仮引数)**

```c:sample1.c
#include <stdio.h>

int addition(int x, int y);       // 足し算
int subtraction(int x, int y);    // 引き算

int main(void){
    int a = 3;
    int b = 5;
    int answer;
    int (*funcp)(int, int);

    funcp = addition;
    answer = (*funcp)(a, b);
    printf("a + b = %d\n", answer);

    funcp = subtraction;
    answer = (*funcp)(a, b);
    printf("a - b = %d\n", answer);

    return 0;
}

int addition(int x, int y) {
    return (x + y);
}

int subtraction(int x, int y) {
    return (x - y);
}
```
一回目の関数呼び出し時は、funcpに関数additionのアドレスが格納されていて、二回目の呼び出し時には関数subtractionのアドレスが格納されています。

このようにしてポインタに関数のアドレスを格納することで、呼び出す関数を変更することができます。

関数ポインタの仮引数を入れる部分は、仮引数の型だけを入れて宣言しておけば大丈夫なようです。

上記のコードの実行結果は、

```
a + b = 8
a - b = -3
```

となります。

ちなみに、以下のように宣言して配列として使うこともできます。

```c:sample2.c
int main(void){
    int a = 3;
    int b = 5;
    int answer;
    int (*funcp[])(int, int) = { addition, subtraction };

    answer = (*funcp[0])(a, b);
    printf("a + b = %d\n", answer);

    answer = (*funcp[1])(a, b);
    printf("a - b = %d\n", answer);

    return 0;
}
```

実行結果は上のコードと同じになります。

#実践してみた

使ったのが講義の課題なので実際のコードを載せるのは避けますが、以下のような感じで関数の引数に関数ポインタを利用しました。

```c:sample3.c
#include<stdio.h>

typedef void (* FUNCPT)(char *); 

void printText1(char *s);        // 文字列をそのまま出力
void printText2(char *s);        // 文字列を""で囲んで出力
void exec(char *s, FUNCPT p);    // 関数を呼び出す

int main(void) {
    FUNCPT p;

    p = printText1;
    exec("ぷりんとてきすと1", p);

    p = printText2;
    exec("ぷりんとてきすと2", p);
    
    return 0;
}

void printText1(char *s){
    printf("%s\n", s);
}

void printText2(char *s){
    printf("\"");
    printf("%s", s);
    printf("\"\n");
}

void exec(char *s, FUNCPT p){
    p(s);
}
```

実行結果

```
ぷりんとてきすと1
"ぷりんとてきすと2"
```

関数ポインタを関数の引数に利用する際には、typedefでプロトタイプ宣言しておくと使いやすくなります。

##余談

個人的には、main文をこのように書けるのがスマートでかっこいいと思いました。（小並）

```c:
int main(void) {

    exec("ぷりんとてきすと1", printText1);
    exec("ぷりんとてきすと2", printText2);
    
    return 0;
}
```

#おわりに

実際に取り組んだ課題は、関数を使った処理を複数回繰り返したときの実行時間を計測する内容でした。

~~ばかみたいに~~時間はかかりましたが、時間取得などの処理を1つにまとめることができたのは個人的に良かったと思っています。

ポインタに関してはまだまだよくわからないことも多いですが、今後少しずつ活かしていけたらいいかなって思ってます。

###追記

調べてて分かったんですけど、関数の引数として渡す関数のことをコールバック関数って言うようですね。

~~どこかで聞いた覚えがあるようなないような。~~

##参考にしたサイト

以下、今回の学習で参考にしたサイトです。

関数ポインタを利用して呼び出す関数を動的に変更する
(https://www.kishiro.com/programming/c/function_pointer.html)
関数ポインタ
(http://wisdom.sakura.ne.jp/programming/c/c54.html)
関数の引数として関数ポインタを渡す
(http://blog.panicblanket.com/archives/2920)
Fritzing　プリント基板表面にジャンパー線を配線するには

Fritzingは良い。

- ブレッドボードのイメージを手軽にかける。部品の下にジャンパー線を這わせる必要があったとき、実物をボードから抜き差しせず試せる。
- ブレッドボードから基板化するときパターンや部品配置を決定する支援をしてくれる。基板の裏表ビューがあるので部品の方向をまちがったりしない。

Fritzingを使いこなそう！

---

Fritzingのプリント基板ビューで、基板表面（部品面）にジャンパー線を配線することを表現するには、以下の手順で出来る。

1. Viaインスペクターを２つ配置しその間を線で結ぶ。
2. 線を右クリックしてメニューから「Move to top layer」をクリックする。

【Viaインスペクター】
![fritzing_tips3.jpg](https://qiita-image-store.s3.amazonaws.com/0/89689/b929d814-b6d1-3293-1d14-34de743eb9de.jpeg)

【線を右クリックした時のメニュー】
![fritzing_tips1.jpg](https://qiita-image-store.s3.amazonaws.com/0/89689/0adf9ee3-3ca0-4c69-71f6-6dd6f4f280ee.jpeg)

【線をtop layerに移動出来た！】
![fritzing_tips2.jpg](https://qiita-image-store.s3.amazonaws.com/0/89689/4006fd4f-8def-cd8e-fbac-96dca8ab7417.jpeg)


うまくいかない場合は以下確認。
Fritzingの下部の左から３番目のボタンを「BothLayers」にセット

【この黒丸で囲んだボタン　↓】
![fritzing_tips4.jpg](https://qiita-image-store.s3.amazonaws.com/0/89689/ec8b0705-9d9c-234c-6391-5d9491514870.jpeg)
Fritzing　プリント基板の穴を数えやすくする

Fritzingは良い。

- ブレッドボードのイメージを手軽にかける。部品の下にジャンパー線を這わせる必要があったとき、実物をボードから抜き差しせず試せる。
- ブレッドボードから基板化するときパターンや部品配置を決定する支援をしてくれる。基板の裏表ビューがあるので部品の方向をまちがったりしない。

Fritzingを使いこなそう！

---
Fritzingのプリント基板ビューを見ながら実際のユニバーサル基板にはんだ付けするとき、部品を挿す穴の位置を数えるのが大変だと思ったら、
Viaインスペクターを使おう。

こんな風に、１，５，１０，１５・・・・穴目にViaインスペクターを配置すると穴を数えるのがグッと楽になる。
おまけに、回路図、ブレッドボードビューには影響しないぞ。

【参照】
![fritzing_tips5.jpg](https://qiita-image-store.s3.amazonaws.com/0/89689/7fd33f25-5d69-671d-e96f-78a69e9572f8.jpeg)
風変わりなC言語処理系たち

C言語（とC++言語）の`int`や`char`といった基本型では、他のプログラミング言語とは少し異なる定義がされています。一般的なPC環境では「`char`は1バイト(8ビット)の文字型、`int`は4バイト(32ビット)の整数型」のように簡易的に説明されることもありますが、厳密なプログラミング言語Cの仕様説明としては正しくありません。実際には次のように定義されます：

- `int`型：**16ビット以上**のビット幅をもつ符号付き整数型。**負数表現**は"2の補数"とは限らず、"1の補数"または"符号ビット＋絶対値"でもよい。
- `char`型：**8ビット以上**のビット幅をもつ整数型。負数表現は`int`型に同じ。

かなり偏執的に思えるでしょうが、C言語は多種多様な計算機環境で利用されることを想定しており、`int`や`char`といった基本部品に対してさえ非常に緩い制約しか課さないのです。


# もう2017年なんだけど？
と、ここまでが歴史的経緯です。ANSI Cとして標準化されてから30年近く経とうとしている2017年現在、`char`型が8ビットより大きい環境は現存するのでしょうか？

StackOverflowで見つけた "[Exotic architectures the standards committees care about](https://stackoverflow.com/q/6971886/684921)" によると、UNISYS社メインフレーム [ClearPath Forward Dorado Systems​](http://www.unisys.com/offerings/clearpath-forward/clearpath-forward-products/clearpath-forward-dorado-systems)が **現役の9ビットマシン**、つまり`CHAR_BIT==9`な環境のようです。これ以外にも：

- **36ビット** ワード
- 負数表現は **"1の補数"**
- 浮動小数点数がIEEE 754 **非互換**

という変わり者っぷりを発揮しています。同マシンのOSには [OS 2200](https://en.wikipedia.org/wiki/OS_2200) が搭載されており、少なくとも2015年に最新版がリリースされているようです。

なお上記以外だと、DSP(Digital Signal Processor)環境などでは`char`型のビット数(`CHAR_BIT`)が16や24や32の場合もあるようですが、9ビットマシンのインパクトには敵いませんね...
PostgreSQLのデータベースクラスタ作成～データベース作成まで

# はじめに
PostgreSQLインストール後、データベースクラスタ作成、データベースユーザ作成、テーブルスペース作成までの一連の手順についてまとめました。

##前提条件
・本手順の$で記載している箇所は、事前に作成したpostgresユーザで実行すること
・データベースクラスタ作成時のオプションは例

###データベースクラスタの作成
- データベースクラスタを作成する。  
 `$ initdb -D /usr/local/pgsql --pgdata=/usr/local/pgsql/data --xlogdir=[walファイル出力先] --lc-collate="C" --lc-ctype="C" --encoding=UTF8 --username=postgres`
- インスタンスを起動する。  
 `$ pg_ctl start -w -D /usr/local/pgsql/data`

###psql接続
- psqlに接続する。    
 `$ psql`

### データベース作成
- データベースを作成する。  
 `postgres-# create database データベース名  encoding=UTF8;`
- データベースが作成されたことを確認する。  
 `postgres-# \l`
- 作成したデータベースに接続できることを確認する。  
 `postgres-# \c データベース名`

### データベースユーザ作成
 - データベースユーザを作成する。  
  `postgres-# create user ユーザ名 with password 'パスワード';`
 - データベースユーザが作成されたことを確認する。  
   `postgres-# select usename from pg_user;`

### データベース権限確認
 - データベースに対する権限を確認する。 ※権限がある場合は、"t"、権限がない場合は、"f"が表示される。  
`postgres-# select * from pg_user;`

### データベースユーザ権限設定
- データベースユーザに対する権限を設定する。 ※追加、変更、削除、参照が可能。    
  `postgres-# grant insert, update, delete, select on all tables in schema public to ユーザ名;`

### データベースユーザ権限確認
- データベースユーザに対する権限を確認する。 ※権限がある場合は、"t"、権限がない場合は、"f"が表示される。    
  `postgres-# SELECT * FROM pg_authid;`

### テーブル権限確認
- テーブルに対する権限を確認する。  
  `postgres-# \z`

### テーブルスペース作成
- テーブルスペースを作成する。  
  `postgres-# create tablespace [テーブルスペース名] LOCATION 'テーブルスペースのパス';`
- テーブルスペースが作成されたことを確認する。  
  `postgres-# \db`
jsを勉強してみた！基礎から抜けられない無駄な学習

書き途中です。
アドベントカレンダーには間に合いませんでした、






























































































# はじめに
一時期、Webの技術的な業務から離れていた時期が3年程あり、その間に独学でjavascriptを身に付けようと学習を始めてから路頭に迷い続けて無駄が多かったこと、やるべきだったことのまとめ。

現在は未熟ながらもフロントエンドとして業務に従事

# 技術書
## 無駄だったこと
- 分厚い技術書をきっちり最後まで読む

## こうすべきだった
- 技術書はざっと読んで何となく理解出来る程度で十分だった
- きっちり読むなら内容を自分なりにまとめておいた方が良かった
- 読むよりも書籍のコードを写経することが重要

# スクール
## 無駄だったこと
- 出費が結構大きい
- 出費が多いのに内容が薄い

## こうすべきだった

# 学習動画
## 無駄だったこと

# コードを書く
## 無駄だったこと
Apache2.4インストール手順

# はじめに
Apache2.4系をソースインストール際の手順についてまとめました。
大きく、2.2系と比べてインストールする際の手順での違いは、apr及びapr-util等が同梱されていないため、[Apache公式サイト](https://apr.apache.org/download.cgi)からダウンロードし、合わせてインストールする必要があります。またpcreも[pcreのサイト](https://www.pcre.org/)よりダウンロードしてインストールします。

## 前提条件
・gccのコンパイラがインストールされていること
・/usr/local/srcに資材があること(※)本手順での例
・/opt配下に必要パッケージをインストールする(※)本手順での例
・httpsの設定を行うため、opensslも合わせてインストールする
・本手順で使用しているapr等のバージョンは、執筆時のバージョン(注)

### apr
- aprのソースがあるディレクトリに移動する。  
     `# cd /usr/local/src`
- aprのソースを展開する。  
     `# tar xzvf apr-1.6.3.tar.gz` 
- 展開されたaprのディレクトリに移動する。  
   `# cd apr-1.6.3/`
- コンフィグレを実行する。  
   `# ./configure --prefix=/opt/apr-1.6.3`
- コンパイルを実行する。  
   `# make`
- インストールを実行する。  
   `# make install`
- aprがインストールされたことを確認する。  
   `# ls -l /opt`

### apr-util
- apr-utilのソースがあるディレクトリに移動する。  
   `# cd /usr/local/src`
- apr-utilのソースを展開する。  
   `# tar xzvf apr-util-1.6.1.tar.gz`
- 展開されたapr-utilのディレクトリに移動する。  
   `# cd apr-util-1.6.1`
- コンフィグレを実行する。  
   `# ./configure --prefix=/opt/apr-util-1.6.1 --with-apr=/opt/apr-1.6.3`
- コンパイルを実行する。  
   `# make`
- インストールを実行する。  
   `# make install`
- apr-utilがインストールされたことを確認する。  
   `# ls -l /opt`

### pcre
- pcreのソースがあるディレクトリに移動する。  
   `# cd /usr/local/src`
- pcreのソースを展開する。  
   `# tar xzvf pcre-8.38.tar.gz`
- 展開されたpcreのディレクトリに移動する。  
   `# cd pcre-8.38`
- コンフィグレを実行する。  
   `# ./configure --prefix=/opt/pcre-8.38`
- コンパイルを実行する。  
   `# make`
- インストールを実行する。  
   `# make install`
- pcreがインストールされたことを確認する。  
   `# ls -l /opt`

### openssl
- opensslのソースがあるディレクトリに移動する。  
   `# cd /usr/local/src`
- opensslのソースを展開する。  
   `# tar xzvf openssl-1.1.0g.tar.gz`
- 展開されたopensslのディレクトリに移動する。  
   `# cd openssl-1.1.0g`
- コンフィグレを実行する。  
   `# ./config --prefix=/opt/openssl --shared`
- コンパイルを実行する。  
   `# make`
- インストールを実行する。  
   `# make install`
- opensslがインストールされたことを確認する。  
   `# ls -l /opt`
- /etc/profileに以下のパスを追記する。  
   `export LD_LIBRARY_PATH=/opt/openssl/lib`

### httpd 
- httpdのソースがあるディレクトリに移動する。  
   `# cd /usr/local/src`
- httpdのソースを展開する。  
   `# tar xzvf httpd-2.4.29.tar.gz`
- 展開されたhttpdのディレクトリに移動する。  
   `# cd httpd-2.4.29`
- コンフィグレを実行する。  
   `# ./configure \
--with-apr=/opt/apr-1.6.3 --with-apr-util=/opt/apr-util-1.6.1 --with-pcre=/opt/pcre-8.38 \
--bindir=/usr/bin --sbindir=/usr/sbin --datadir=/var/www --enable-mime-magic \
--enable-proxy --enable-proxy-ajp --enable-rewrite \
--enable-ssl --with-ssl=/opt/openssl`
- コンパイルを実行する。  
   `# make`
- インストールを実行する。  
   `# make install`
- httpdがインストールされたことを確認する。  
   `# ls -l /usr/local/`

### 起動スクリプト
以下のファイルを配備します。
*/etc/systemd/system/httpd.service*

[Unit]
Description=Apache Web Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/sbin/apachectl -k start -f /usr/local/apache2/conf/httpd.conf
ExecStop=/usr/sbin/apachectl -k stop -f /usr/local/apache2/conf/httpd.conf
ExecReload=/usr/sbin/apachectl graceful -f /usr/local/apache2/conf/httpd.conf
PrivateTmp=true
LimitNOFILE=infinity
[Install]
WantedBy=multi-user.target

### 参考
コンフィグレのオプションで、apacheのインストール場所を分けて、起動スクリプトでhttpd.confの指定場所を変更すれば、apacheを複数インスタンスで起動することができます。
KONAMIコマンドを作る技術

上上下下左右左右ba
はkeyCodeにすると

```
38 38 40 40 37 39 37 39 66 65
```

これを連続で押すと関数を実行させたい。
だが一定時間入力がない場合とKONAMIコマンド以外の入力はクリアにさせたい。

```js
(() => {
    const KONAMI_PATTERN = "38384040373937396665"
    let input = ""
    let timeout = null
    document.addEventListener("keydown", (e) => {
        if(KONAMI_PATTERN.indexOf(e.keyCode) < 0) {
            clear()
            return
        }
        input += e.keyCode
        if (input == KONAMI_PATTERN) {
            called()
            clear()
        }
        clearTimeout(timeout)
        timeout = setTimeout(clear, 2000)
    })
    const clear = () => {
        input = ""
        clearTimeout(timeout)
    }
    
    const called = () => {
        // any operations
    }
})()
```

[DEMO](https://jsbin.com/codujugena/edit?html,js,output)

また一つクソコードを書いてしまった。。。
Windows環境にRust環境を構築する際のメモ


## 下準備

BuildToolsをインストール
http://landinghub.visualstudio.com/visual-cpp-build-tools
C++再配布可能パッケージをインストール
https://www.microsoft.com/ja-JP/download/details.aspx?id=48145

### インストール
Rustインストーラをダウンロードして実行する
https://www.rust-lang.org/ja-JP/install.html
環境変数PATHに追加

```
 %USERPROFILE%\.cargo\bin 
```

ここまででrustのビルド・実行コマンドである、cargoがつかえるようになっているはず。
コマンドプロンプト(Windows+xで”cmd”、あるいはcortanaにcmd)でつかえるかを確認する。

```
$cargo --version
cargo 0.23.0 (61fa02415 2017-11-22)
```

### Visual Studio Codeの設定をする

コーディングを楽にするために自動フォーマットや保管ツールであるところのrustfmt, racerなどをインストールするが、VisualStucioCodeのプラグイン、[RustyCode](   https://github.com/saviorisdead/RustyCod )がとても便利。。
[chikoski]( https://qiita.com/chikoski/items/53590914cc6aacc8916d )さんの記事にそって導入する。

## Rustプラクティス
説明つきにRustの雰囲気を味わうなら[The bookの和訳]( https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/ )で解説つきのコードを勉強するのがよかった。

また、ほかの言語でいうところのクラスインタフェースのような概念であるtraitとジェネリック表現はエン転職の記事、[「Rustの構造化プログラミング」]( https://employment.en-japan.com/engineerhub/entry/2017/07/19/110000 )がわかりやすかった。

ある程度わかって何かしたいものが思いついたら[サンプル集]( https://rustbyexample.com/ )から探して勉強する予定。


## 参考
WindowsでのインストールーRustドキュメント
https://www.rust-lang.org/ja-JP/install.html
Visual Studio Code で Rust 開発を始めるには
https://qiita.com/chikoski/items/53590914cc6aacc8916d
Nockを触ってみた

こんにちは、鈴木です。ネタが思いつかなかったので、今日はhttpをmockingしてくれるnodejsライブライのNockを紹介したいと思います。

~~ふう、アドベントカレンダーなんとか間に合った。。。~~

# [Nock](https://github.com/node-nock/nock)
サードパーティAPIを使っている箇所のテストをするとき、毎回、サードパーティAPIを叩きたくないはずです。もし、そのサードパーティAPIが有料だったら。。。

ってことで、Httpをmockingしてくれるライブラリであるnockを使えば、サードパーティーへのリクエストを疑似的に作ることができるようになります。これによって、何の心配もせずに好きなだけテストを書けるようになのではないでしょうか。

## どうやって動いているのか
Node moduleの`http`の関数をオーバーライドしています。なので、`http`を使用しているmoduleのリクエストをmockできます。
また、httpsにも対応しています。

## インストール
```bash
$ npm i —D nock
```

## 簡単な例
```hogeClient.test.js
import nock from 'nock'
import hogeClient from 'hoge-client'

describe('mock test', () => {
  before(() => {
    // hoge.com/huga?message=Hello でリクエストが来た時、Hiを返す
    nock('http://hoge.com')
      .get('/huga')
      .query({message: 'Hello'})
      .reply(200, 'Hi')
    return
  })

  it('hiが返ってくるか', (done) => {
    hogeClient.get({message: 'Hello'}, (err, res) => {
      assert(res, 'Hi')
      done()
    })
  })
})
```

## 基本的なAPI

### hostname
```js
const scope = nock('http://example.com')
// or
const scope = nock(/example\.com/)
```

### route
```js
scope.get('/huga').reply(200, 'Hi')
// or
scope.get(/huga/).reply(200, 'Hi')
//or
scope.get((uri) => {
  return true // or false
}).reply('Hi')
```

### request
```js
// get
scope.get('/huga').reply(200, 'Hi')

//post
scope.post('/huga', {
  message: 'Hi'
})

scope.delete('/users', {id: 'huga'})
scope.put('/huga', {})
```
### 指定した数だけレスポンス
400回だけレスポンスを返す。それ以降は普通にリクエストを投げてしまう。

```js
scope.get('/huga').times(400).reply(200, 'Hi')
```

常にレスポンスを返す。

```js
scope.persist().get('/huga').reply(200, 'Hi')
```


### etc
その他、headerを変えたりと色々できますので、そこらは[document](https://github.com/node-nock/nock)を参考にしてください。
ダイナミッククリエイティブに機械学習を導入した話

8の付く日です。

# はじめに
## ダイナミッククリエイティブ
広告主のサイトに訪れたことがあるユーザーに対して、閲覧履歴をもとに興味がありそう（クリックやコンバージョンしそう）な広告を自動で生成することです。ユーザー一人一人に最適化した広告が表示できます。

## unis
株式会社オプトには [unis](http://lp.unis.tokyo/) というダイナミッククリエイティブのツールがあります。
ちょっとLPは放置気味にしか見えないですね・・・。

<img width="1044" alt="unisレコメンドロジック" src="https://qiita-image-store.s3.amazonaws.com/0/42777/e933d367-34c9-fe54-cabc-813315200888.png">

こちらでは商品の固定表示とCV順についてしか説明してないですが、他にも

- 指定した商品（カテゴリ）の固定表示
- ランキング（CV、接触など）
- 閲覧履歴からCVしていないものを再度表示
- 協調フィルタリング

などがあります。
商品のプロモーションにも使えるしパーソナライズもできるってことですね。
協調フィルタリングにはsparkを使っています。

# 仕組み
## 訓練データの作成
unisを導入しているクライアントのサイトにはunisのタグが埋め込まれていて、閲覧や購入などのイベントを取得しています。これらのイベント情報（閲覧履歴）を1時間ごとにRedshiftに読み込んで集計します。
集計したデータはクライアントごとに `(ユーザーID, 商品ID, レート)` の形にしてS3にアンロードします。

## 学習
S3に置いた訓練データを使って学習します。
学習にはEMRでsparkの協調フィルタリング（ALS）を使用します。
学習の結果得られたユーザーの特徴行列と商品の特徴行列を再びS3に保存します。
学習は12時間ごとに行なっています。
cf. https://www.slideshare.net/uryyyyyyy/spark-mllib-70290015

## 推薦
サーバーにユーザーの特徴行列と商品の特徴行列を読み込みます。
ユーザーIDと商品IDを受け取り、ユーザーIDが読み込んだ行列に存在すればそのユーザーへのおすすめ度を計算します。
ユーザーIDが存在しない場合、今度は商品IDを用いて商品の特徴行列を使いその商品の類似商品を計算します。
スコアが高い商品N件を推薦します。

# 苦労（工夫）した点
## レスポンスは100ms以内に返しやがれ
広告配信を行なっているため、バナーの表示に数秒とかかかるのは致命的です。
サーバーにはscalaを使用していましたが、行列計算はけっこう遅かったのでそこだけjavaで書いています。

## 200QPSでも遅延しないようにしやがれ
100ms以下で計算できればそれでいいというわけではなく、配信強化時は秒間数百件以上の配信が行われます。
キャッシュを用いて同じユーザーや商品のときの計算を行わないようにしたり、訓練データの作り方を変えてそもそも不人気な商品を取り除いたり、使うユーザー数に上限を設けるなど特徴行列が小さくなるようにしました。
それでも限界を超えるようなリクエストがくると爆発します。

# おわりに
広告の効果が向上し、配信量が増えると上記の苦労した点で述べた箇所が爆発する諸刃の剣みたいなシステムが完成しました。
1年前に導入し、今日まで小さな改善を積み重ねてますが、クライアントの業種やサイトのユーザーによって全く効果がないということもわかり始めてきました。手法一つで汎用的に何にでも使えるということはありえません。
来年は欠点を克服した新システムの導入に努めていきます。
laravelでトップページ以外に遷移できない


##対応策
ググったところ、対応策は以下の通り。


-権限をきちんと設定する
chmod -R 777 [アプリケーションフォルダ]/storage
chmod -R 777 bootstrap/cache

-apahce でbase rewriteする
[アプリケーションフォルダ]/public/.htaccess


##対応結果
自分の環境では、base rewriteをするでうまく動かすことができた。


##参考
https://stackoverflow.com/questions/16885467/laravel-sends-the-server-on-10-redirects
https://teratail.com/questions/63174
http://momoiro-tj.hateblo.jp/entry/2016/01/12/221657
firewalld設定

# はじめに
RHEL7系のfirewalldを使用して、NIC毎にゾーンを作成し、IPアドレス及びポート番号を指定して、通信を許可するための設定手順についてまとめました。

# firewalld設定手順
- firewalld の状態を確認する。  
  `# firewall-cmd --state`
- アクティブなゾーンと、それらに割り当てられているインターフェースの一覧を確認する。  
  `# firewall-cmd --get-active-zones`    
-  下記のコマンドを実行し、ゾーンを作成する。(※)ゾーン名は任意  
    `# firewall-cmd --permanent --new-zone=ゾーン名(※)`
-  firewalld で許可する通信を設定する。(※)IPアドレス、ポート番号、プロトコルは可変　  
   `# firewall-cmd --permanent --zone=ゾーン名 --add-rich-rule='rule family="ipv4" source address="IPアドレス/32(※)" port port="ポート番号(※)" protocol="tcp/udp(※)" accept'`   
-  NICのゾーン変更を行う。(※)NICのデバイス名は例  
   `# firewall-cmd --permanent --zone=ゾーン名 --change-interface=ens0(※)`
- firewalld の設定を反映する。  
   `# firewall-cmd --reload` 
- アクティブなゾーンと、それらに割り当てられているインターフェースの一覧を確認する。   
-  `# firewall-cmd --get-active-zones`
-  firewalld の設定が反映されたことを確認する。  
   `# firewall-cmd --zone=ゾーン名 --list-all`
LaravelでPOSTが失敗する

#Laravelでformをポストしたら以下のエラーがでた
The page has expired due to inactivity.
Please refresh and try again.

##対応策
csrf対策をする


##対応案
公式ドキュメントによると、以下のようにすれば良いとのこと

```
<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>
https://readouble.com/laravel/5.3/ja/csrf.html
```


まだ、サンプルプロジェクトで、ヒアドキュメントでHTMLを直接書いていたので、
以下のように対応

```
$csrf = csrf_field()

$html = <<<EOF
<form method="POST" action="/profile">
    {$csrf}
    ...
</form>
EOF
return $html;
```

すると、html中には以下のようなhiddenフィールドが挿入されていた。
<input type="hidden" name="_token" value="nx4Up001trzgJfgl5umfGZwElkKGaWLLv1IYxo52">
これによりエラーは解消した。
RailsのI18nの紹介

# I18n とは
みなさん、I18nとは何のことかご存知ですか。
あまり馴染みがないかもしれませんが、実はこれ **Internationalization** の略なのです。
日本語でいう **国際化**ですね。
"I"と"n"の間に18文字あるので、こう略されています。
プロダクトを国際化するとなったときに、こんなに長いスペルの単語を何回もタイプしたくないですもんね笑
ちょっとかっこいいネーミングです。

今回は、そんなI18nに欠かせない存在であるtメソッドとlメソッドを簡単に紹介します。

# t メソッド
まずはtメソッドです。
tはtranslateの頭文字からきています。

早速コードを見てみましょう。
ビューファイルに次のように書くと、

```erb
<%= t("fruits.apple") %>
<%= t("fruits.orange") %>
```
ロケールの設定がja(日本語)であればja.ymlを、en(英語)であればen.ymlを読み込みます。

```config/locales/ja.yml
ja:
  fruits:
    apple: "りんご"
    orange: "みかん"
```

```config/locales/en.yml
en:
  fruits:
    apple: "Apple"
    orange: "Orange"
```

こうすることで、日本語でアクセスされたときは日本語で、英語のときは英語で表示されます。

#l メソッド
次はlメソッドです。
ややこしいですがI(アイ)ではありませんよ。Localizeの頭文字であるl(エル)です。

lメソッドは日付や時刻を表す際に用います。
国や地域によって時刻は異なりますが、lメソッドを使えば現地時間に対応できます。

例えば

```erb
<%= l(Time.current) %>
```
上のようにして日付を表示したい場合、

```config/locales/ja.yml
ja:
  time:
    current: "%Y年%m月%d日"
```

```config/locales/en.yml
en:
  time:
    current: "%m %d, %Y"
```

とすればそれぞれの現地時間を、現地の言葉や表記方法で表示できます。

#参考
以上、tメソッドとlメソッドの超簡単な紹介でした。
もっと詳しく知りたい方は、これらの記事をおすすめします！
[rails での config/locales 配下の扱い](https://qiita.com/naopontan@github/items/08bf7da25f85c22bcd8b)
[i18nについて](http://morizyun.github.io/ruby/rails-function-i18n-internationalization.html)
[【Rails】国際化機能使い方](https://qiita.com/kinako0909/items/c786f17c0032c1124c02)
vue-loaderのScoped CSSのスタイルが子コンポーネントのルート要素に効いてしまって辛い

vue-loaderの[Scoped CSS](https://vue-loader.vuejs.org/en/features/scoped-css.html)には、1つ辛い点がある。それは、スタイルが**子コンポーネントのルート要素に効いてしまう**ことである。だから、意図せず子コンポーネントのスタイルを崩してしまう危険性がある。

次のような場合、page.vueの`.container`のスタイルは、page-header.vueの`<div class="container">...</div>`にも効いてしまう。

```html:page.vue
<template>
  <div class="container">
    <page-header date="2017-12-07" heading="Hello!" />
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  </div>
</template>

<script>
import PageHeader from './page-header.vue'

export default {
  components: {
    'page-header': PageHeader
  }
}
</script>

<style scoped>
.container {
  ...
}
</style>
```

```html:page-header.vue
<template>
  <div class="container">
    <div class="date">{{ date }}</div>
    <h1 class="heading">{{ heading }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    date: String,
    heading: String
  }
}
</script>

<style scoped>
.container {
  ...
}
.date {
  ...
}
.heading {
  ...
}
</style>
```

## バグ？いえ、仕様です

最初、これはバグなのではないかと思ったが、どうやら仕様らしい。

> With scoped, the parent component's styles will not leak into child components. However, a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS. This is by design so that the parent can style the child root element for layout purposes.

― [Child Component Root Elements](https://vue-loader.vuejs.org/en/features/scoped-css.html#child-component-root-elements)

## 回避策

回避策はいくつかある。

### 無名のラッパーで囲む

子コンポーネントのルート要素のみが親コンポーネントのスタイルの影響を受けるので、子コンポーネントを無名のラッパーで囲めば問題を回避できる。

```html:page-header.vue
<template>
  <div><!-- 無名のラッパー -->
    <div class="container">
      <div class="date">{{ date }}</div>
      <h1 class="heading">{{ heading }}</h1>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    date: String,
    heading: String
  }
}
</script>

<style scoped>
.container {
  ...
}
.date {
  ...
}
.heading {
  ...
}
</style>
```

### コンポーネントの一番外側の要素のクラス名をプロジェクト内でユニークにする

コンポーネントの一番外側の要素のクラス名をプロジェクト内でユニークにする（たとえばコンポーネント名を接頭辞として付ける）ことでも、問題を回避できる。

```html:page-header.vue
<template>
  <div class="page-header-container">
    <div class="date">{{ date }}</div>
    <h1 class="heading">{{ heading }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    date: String,
    heading: String
  }
}
</script>

<style scoped>
.page-header-container {
  ...
}
.date {
  ...
}
.heading {
  ...
}
</style>
```

しかし、これは命名規則で解決するということなので、前時代的な感がある。

### Scoped CSSの代わりにCSS Modulesを使う

Scoped CSSの代わりに[CSS Modules](https://vue-loader.vuejs.org/en/features/css-modules.html)を使うのが最も安全だと思われる。

```html:page-header.vue
<template>
  <div :class="$style.container">
    <div :class="$style.date">{{ date }}</div>
    <h1 :class="$style.heading">{{ heading }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    date: String,
    heading: String
  }
}
</script>

<style module>
.container {
  ...
}
.date {
  ...
}
.heading {
  ...
}
</style>
```
UIViewを指でリサイズしたい人のためにライブラリ作った

UIViewを指でリサイズできるいい感じのライブラリが調べても見つからなかったので作りました。

![OTResizableViewDemo.gif](https://qiita-image-store.s3.amazonaws.com/0/152335/4247576c-8532-e632-c335-6445634904b7.gif "OTResizableVIewDemo.gif")

#とりあえずgithub
[OTResizableView](https://github.com/PKPK-Carnage/OTResizableView)

#機能
・Swift4・Xcode9対応
・Objective-Cからも使える
・UIViewのリサイズ・移動
・枠線、グリップポイントの色変更
・superviewからはみ出さない制御
・アスペクト維持リサイズ

#導入
CocoaPodsとCarthageで導入できます。

**CocoaPods**

```PodFile
pod 'OTResizableView'
```

**Carthage**

```Cartfile
github "PKPK-Carnage/OTResizableView"
```

#使い方

```swift:Swift
let resizableView = OTResizableView(contentView: yourView)
resizableView.delegate = self
        
//色の変更はここでできます。

view.addSubview(resizableView)

//リサイズ許可はaddSubView後のみ可能です。
resizableView.resizeEnabled = true
```

```objc:Objective-C
OTResizableView *resizableView = [[OTResizableView alloc] initWithContentView:yourView];
resizableView.delegate = self;

//色の変更はここでできます。

view.addSubview(resizableView)

//リサイズ許可はaddSubView後のみ可能です。
resizableView.resizeEnabled = YES;
```

#OTResizableDelegate
デリゲートは以下の４つのメソッドがあります。

```swift:Swift
@objc public protocol OTResizableViewDelegate: class {
    
    @objc optional func tapBegin(_ resizableView:OTResizableView)
    
    @objc optional func tapChanged(_ resizableView:OTResizableView)
    
    @objc optional func tapMoved(_ resizableView:OTResizableView)
    
    @objc optional func tapEnd(_ resizableView:OTResizableView)
    
}
```

##tapBegin
OTResizableViewをタップした際に実行されます。
このタイミングで **resizeEnabled** プロパティを切り替えたりするといいんじゃないかと思います。

##tapChanged
OTResizableViewがリサイズしている時に実行されます。

##tapMoved
OTResizableViewが移動している時に実行されます。

##tapEnd
OTResizableViewがリサイズ、移動を終了した時に実行されます。

#まとめ
よかったら使ってみてね。
高専OBが AR / VR 入門セミナーの講師をしてきた

# 熊本高専OB ガチ本です！ 
[熊本高専 Advent Calendar 2017](https://adventar.org/calendars/2149) 7日目の記事です！ (Adventarの記事をQiitaで書くというw）
AR / VR 入門セミナーの講師をしてきたので、その内容について？過去と今と未来を語りたいと思います。
資料はこちら [KISオープンセミナーVRAR入門vol.1](https://www.slideshare.net/satoshibfujimoto/kisvrarvol1)

# ARとの出会い
高専の画像処理の授業で座学とは別にARToolkitで何か作って最後に発表というやつでした。
食堂のメニューにマーカーを配置して、カメラで見るとカツ丼？の写真が出てくるみたいなのだったと思います。
食堂が暗くてうまくいかなかったのを覚えていますｗ

# 高専の研究
高専では、上肢用のリハビリ装置を開発していました。
半身麻痺の方が健常な腕でアームを動かすと麻痺した腕側のアームを追従制御するものです。
遠隔地の熟練の医師によりリハビリも可能です。

圧力センサを使って、麻痺した腕の抵抗力を健常な腕へフィードバックすることで、柔らかいリハビリを実現しました。（バイラテラル制御）
また、遠隔地の場合、患者の抵抗力が医師に伝わるため、安全にリハビリを行うことができます。（マスタースレーブ制御）

# 大学の研究
高専で制御を学んだので、人間の五感に関することや制御のための「計測」に関することを学びたいと思い大学に入りました。
実際には、電動車いすの自動運転のために、SLAMの研究をしていました。
SLAMというのは、Simultaneous Localization and Mapping の略で、同時に自己位置推定と地図作成を行う技術です。
2D LidarやKinectを用いてセンシングした情報から、車いすの位置と屋内のマップを作成しました。
自己位置とマップが分かれば、A地点からB地点まで自律して移動することが可能になります。
まさか、そのSLAM技術がARに関連しているとは最初は思っていませんでした。
PTAMの[動画](https://youtu.be/Y9HMn6bd-v8)を見て、なにこれヤベー、マーカー使ってないし、自然マーカーだとしてもどうやってやってるんだろうって思っていました。

# HoloLensの登場
HoloLensというのは、Microsoftが開発したMixed Reality(複合現実 = 現実とバーチャルの融合) デバイスです。
現実世界にあたかもそこにいるかのように3Dのホログラムを配置し、レンズを通して見ることができます。
HoloLensは、SLAM技術が詰まった集大成なんです。
頭をガンガン動かしてもホログラムは固定されているし、マップは綺麗に取れるし、スタンドアロン、最高です。

# これからのMR
空間や動いている人間・物体を丸ごとスキャンして転送し、遠隔地でも同じ空間にいるかのように体験することができるようになります。
引きこもりが加速しますね。引きこもっていても現実のように繋がれるんですけど。

以上
GitHubでセマンティックバージョニングを運用する

# tl;dr

ちょうど `dep` (golang用のvendoringツール）を使っている中で、妙なバージョン運用をしているリポジトリに悩まされたので、
いまさらとは思いつつも「GitHubでバージョン管理するならこうだよね」ということをまとめてみました。

# Semantics Versioning

バージョン番号自体の運用方法については、割と大きなスタンダードがすでにあって、[Semantics Versioning](https://semver.org/)(以下semver)がよく使われています。
意外と細かいところで悩まされることも多いので、一度文書には目を通しておいたほうがいいでしょう。英語が難しいという人には[日本語の文書も公開されています](https://semver.org/lang/ja/)。

# GitHubでの運用

GitHubでこのsemverで運用しようと思った場合、やりかたは色々あるとは思いますが、基本はTagsとブランチの運用になるでしょう。　
先の文書に示されたスタンダードと、いくつかsemver関連のツールを触ってみた感じ、次のような運用が良さそうです。

## ブランチ

* masterブランチは、最新の **安定した** バージョン
    * バージョニングなんてしらん！というツールやユーザーのためには、masterは安定していることが大切

* メジャーバージョンごとにブランチ（以下メジャーブランチとする）を用意する
    * 過去のメジャーバージョンにもメンテの可能性が当然ある
    * 破壊的変更を企んだ瞬間、新しいメジャーブランチを用意する
        * masterは安定していることが大切（大切なことなのでｒｙ）
    * 昔懐かしいjQueryとか、1.xと2.xの共存期間が長かったですね。 ~python2?え？~

* メジャーブランチの名は `v1.x` の様に、 `vメジャーバージョン番号` + `.x`(固定文字列) とする
    * 一部のツールは、タグもブランチも一絡げに捉えようとする
    * "ブランチ" はあくまで開発が行われる場所なので、単一のバージョンを指している "タグ" とは命名規則を分けたほうがいい
    * semverに詳しくない人にとっては、 `v1` ブランチと `v1.0.0` タグの両方がある世界は混乱するだけ
        * `.x` がどの程度効くかは不明だけど

## タグ

* 作業ブランチでは打たず、メジャーブランチのコミットに対して打つ
    * squash mergeなんかされて、対象のコミットがない、みたいな話もちょっと悲しい

* 命名はsemverの仕様に則る（大事）
    * 例：1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

* 罠としては、vを先頭につけるとオーダーひっくり返ったりする場合があるかも？
    * v0, v1, v10, v2, ...v9 とかなっちゃったり
    * semverは先頭のvを定義していない。先頭に付くvをどう処理するかは処理系次第（そんなー）

* プレリリースバージョンは極めて分かりづらいので注意
    * RCの９番目を `0.0.0-rc9` とするのは間違い。 `0.0.0-rc.9` が正
    * 正直、よほど大規模なOSSでもない限り運用しないに越したことはなさそう
        * 詳しくは仕様文書の#11とか参照

# まとめ

ただしいバージョンの運用は、OSSをやっていく上でとても大事なことです。
世の中のためにも、よりよいバージョン運用で、楽しいOSSライフを。
New Relic Insights の NRQL の Facet 句がパワーアップ

New Relic Advent Calendar 2017 7日目。どんどん公開時間が遅くなっている今日このごろ。

今日は時間がないので、小ネタですます。

本日(2017年12月7日)、New Relic ブログで 「[[翻訳] New Relic Insights の NRQL クエリの Facet 句で複数属性をサポート開始](https://newrelic.degica.com/blog/2017-12-06-facets-nrql-queries-insights)」とい記事が公開されました。

ということで、新たに追加された Facet 句の複数属性サポートについて紹介する。

その前に、New Relic Insights はあまり使われているイメージないので、そっから紹介。New Relic Insights は、New Relic APM とかの製品が集めたデータをテーブルみたいな扱いにして、それに対して、NRQL という SQL チックなクエリを書いて、問い合わせて、その結果を見るというもの。で、そのクエリと結果を事前に用意しておくことで、複数の結果を１つのダッシュボードで見ることができる。まぁ、New Relic が集めたデータに対するダッシュボードサービスだと思ってもらえればと思う。

(New Relic Insights について気になる方は[こちら](https://qiita.com/kumatronik/items/7c115d574c698b81baac)をご覧ください。

で、NRQL というクエリ言語に、SQL チックというだけあって同じような構文を使える。簡単な NRQL の例はこんな感じ。

```sql
Select count(*) From PageView Where pageUrl = "http://example.com/register"
```

なんとなくわかるよね。PageView というテーブルから URL が "http://example.com/register" のページビュー数は？ というクエリ。(ちなみに、期間指定していない場合は、直近1時間のデータということになる)。**PageView** というのは、New Relic Browser が集めたデータが入っている。APM が集めたトランザクションデータは、**Transaction** に入っている。`pageUrl` はカラム名で、デフォルトでパフォーマンス等に関わる様々なカラムが用意されている。さらに、カスタム属性というのを使うと、任意のカラムも追加できる。これが便利。

で、今回の Facet の話。Facet ってのは SQL にないように思うけど、同じ意味なのが、`Group By`。つまり、指定した属性でグルーピングしてくれる。さっきの例を使うと、以下のようになる。

```sql
Select count(*) From PageView Facet pageUrl
```

これを実行すると、以下のようにページURL毎に直近１時間のページビュー数を表示してくれる。

![スクリーンショット_2017-12-08_0_03_30.png](https://qiita-image-store.s3.amazonaws.com/0/46003/50fe6965-5105-54ed-0800-8691f9074bda.png)


なんとなくわかっただろうか。で、ここまでは以前もできた。

で、ここからさらに、URLごとのブラウザ種別の違いを見たいとする。つまり、`http://example.com/hoge` の Chrome と Firefox の差とかを URL のページビュー数の多い順にみたい。このように、２つ以上の軸で、グルーピングすることはできなかった。

で、今日くらいからそれができるようになったらしい。以下のように、`userAgentName` を追加して、実行する。

```sql
Select count(*) From PageView Facet pageUrl, userAgentName
```

![スクリーンショット_2017-12-07_23_58_18.png](https://qiita-image-store.s3.amazonaws.com/0/46003/97ca6c13-a04d-77ab-3a95-ded70fea1675.png)

こんな感じで、URLだけでなく、URLとブラウザの組み合わせで、ページビューがわかるようなった。これで、同じ URL でもどのブラウザからのアクセスが多いのかわかるようになった。

こんな感じで、今回は２つだけ指定したけど、３つとか、もっと多く指定することもできる。これによって、よりきめ細やかにデータを見ることができるようになる。

ということで、是非、Insights を活用してパフォーマンス分析にしてみてください。

NRQL をもっと知りたい方用の情報

- [ドキュメント: NRQL 構文、構成要素、関数](https://newrelic.degica.com/docs/insights/nrql-new-relic-query-language/nrql-resources/nrql-syntax-components-functions)
- [New Relic Insights: NRQL をいろいろ試しみよう（基本編）](https://qiita.com/kumatronik/items/f8c93fdeed7f945b7d32)
- [New Relic Insights: ファンネルやヒストグラムなど NRQL でいろいろ試してみよう（応用編）](https://qiita.com/kumatronik/items/6c751d59f0bf403fd20c)
いいUXを考えるためのコンテキストって何？

この文章は[Fringe81 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/fringe81)の7日目の投稿です。
また、この文章で述べる考えは[UX DAYS TOKYO](https://uxdaystokyo.com/)主催のワークショップ、コンテキストの理解と実践に基づいております。

### 対象者

- UXという言葉しか知らない方

### わかること

- コンテキストはUXの一端を担っている
- コンテキストの種類

それでは始めましょう

### UXって何？

はじめにこの文章中でのUXについて定義してみます。
**この文章中での**と断ったのには理由があります、UXという言葉は色んなシーンや人によって解釈されていますが、決まりきった定義がないと私が考えているからです。
気になる方は情報を収集してみてください。山ほど資料が見つかるはずです。

*UX = ユーザーのタスク + コンテキスト*

今回はこのようにUXを解釈します。みなさんがサービス開発者であればユーザーは何らかの目的をもってサービスを利用するはずです。ここで言うところのユーザーのタスクとはこのことを指しています。ユーザーのタスクとコンテキストがあってUXとなります。次にコンテキストについてお話します。

### コンテキスト

エンジニアであればよく議論の最中にもコンテキストという言葉を連呼されている方もいるのではないでしょうか。UX世界でのコンテキストとは「状況」「環境」「前後関係」のようなユーザーのタスクを達成する上で影響を与える事柄と捉えます。

![smartphone4_woman.png](https://qiita-image-store.s3.amazonaws.com/0/61131/bd387530-4a5c-fb25-59c9-173880eaf8f6.png)

例えば、上記の画像からコンテキストを読み取ると、片手でデバイスを操作、一人、うつむきながら、といったことがコンテキストに当たります。移動していそうと言うような事実ではない想像の域を出ないものはコンテキストと考えないこととします。

普段開発しているときにはついつい画面の中だけで完結しがちですが、コンテキストを考慮するとより広いユーザー体験を設計できるようになります。

### コンテキストの種類

コンテキストには7つの種類があると[Cennydd Bowles氏の記事](https://uxdaystokyo.com/articles/context00/)で語られています。

1. デバイス
2. 環境
3. 時間
4. 行動
5. パーソナル
6. 場所
7. ソーシャル

特に一番気になるのは5の個性についてです。

>スマートフォンを常にユーザーと共に、あるいは少なくとも手の届くところに置いていると親しみを感じ、そこにパーソナルスペースを見出します。(中略)
>それらは、私たちが秘密を打ち明けられるパートナーであり、かつ超人的な力を与えてくれるツールなのです。(中略)
>このパーソナルスペースが侵害されると、人は強く反応します。煩わしいSMSのスパムを誰もが嫌がることや、掲示板での痛烈な議論もそうです。。ポータブルデバイスを利用したサービスを考えているならば、ユーザーがそれを使おうと選択した時点で、こうしたパーソナルな性質があることを考えるべきです。
>[コンテキストを理解する(切り口-5: パーソナル) | UX TIMES](https://uxdaystokyo.com/articles/context05/)

パーソナルスペースは人が持つ安全圏のことであり、一般的に親しい人ほど近くにいても嫌悪感がないことが多いです。公共交通機関で間隔を開けたがる人が多いのはこの性質によるものと考えられます。
普段私達が使うデバイスもパーソナルスペースに侵入している以上ある程度心を許す存在です。PCよりもスマートフォンの方が常に持ち歩いている分、親しい感じがするのではないでしょうか。

当然親しい存在のスマートフォンで運用するサービスもユーザーのパーソナルスペースにいることに気を配るべきだと思います。必要のない通知を送っている場合などは気をつけたほうがいいかもしれません。

実は、**コンテキストはここで紹介されている7つだけではないです**。
常に想像を膨らませて各々のサービスでのコンテキストを考えてみてはいかがでしょう。

### コンテキスト全部盛りでサービス作ればいいの？

コンテキストは必ずしも盛り込まないといけないものではないです。コンテキストがユーザーの行動に特に影響ない限りコンテキストの優先順位は高くありません。大切なのはサービス開発する上で、**どのコンテキストを選択するのか (大切にするのか) ということ**です。
コンテキストが変わらないものでない以上、時代やシーンに合わせて考え直していくことが重要です。

### まとめ

- コンテキストとはユーザーのタスク達成に影響する様々なこと
- コンテキストを考慮すると画面外のことにまで気に出来るようになる
- コンテキストには７つの代表的な切り口が存在する
- コンテキストの切り口はもっと存在する
- どのコンテキストを選択するのかが大切
RxSwiftを使ったMVVMアーキテクチャ

# はじめに
この記事はSP2LC Advent Calendar 2017 7日目の記事です．
# SP2LCとの関わり
1年生の頃からSP2LCと全国高専プログラミングプロジェクトに入っており，現在4年生です．  
SP2LCについては[1日目の記事](https://qiita.com/Shimizu_sp/items/47394efcbcb1b2d33aee)をご参照ください.　
# 本題
技術的なことをなにか書けと言われたので今回はiOS開発で使うアーキテクチャについて書きたいと思います． 
# RxSwiftとMVVMについて
## RxSwiftとは
非同期処理・イベント処理等を宣言的に記述することができるライブラリのSwift実装です．
## MVVMとは
MVVMはMVCパターンの問題を解決するためのアーキテクチャです． 
ViewControllerが大きくなりすぎないようにするためにModel・View・ViewModelと分割して開発しましょうといった感じです.
- Modelはデータを扱う
- ViewはViewとViewModelのBinding，UIを扱う
- ViewModelはViewに関する処理を行います
# RxSwiftを使ったMVVMなアプリのサンプル
[github.com/Taillook/SwiftMVVMSample](https://github.com/Taillook/SwiftMVVMSample)
天気情報を取得するアプリ
# おわり
時間なくて書けなかっt...
適宜更新します
Android Things Preview6  Launcher UIについて

Android Things Preview6で、Lancher UIがアップデートされたので簡単にまとめます。
表示はすべてRaspberry pi 3のものです。
操作は、マウスまたはタッチパネルより行ってください。

# Lancher UI

#### OverView
Preview５までと違ってリッチな感じに変わってます。
機種やバージョン、接続されているWifi情報、GPIOのピン情報などが表示されます。

![起動画面](https://qiita-image-store.s3.amazonaws.com/0/189829/d8e7b1d9-43c7-4581-2ee5-df804de71dad.png)

I/O Pinoutを選択すると、機種のport名が表示されます。
残念ながら、並び順はピンの位置には合っていません。。

![pinout](https://qiita-image-store.s3.amazonaws.com/0/189829/b772e7ed-e3fe-3807-3d1a-49ba6bf62a14.png)


右の`（三）`を選択するとメニューが表示されます。
メニューを選択しなくても、Overview上の各項目を選択しても各種画面へ遷移します。

![メニュー](https://qiita-image-store.s3.amazonaws.com/0/189829/7f5e18df-bffe-a1b9-99e8-784f19f790a3.png)



####　Networks

端末のネットワーク情報が表示されます。

![ネットワーク情報](https://qiita-image-store.s3.amazonaws.com/0/189829/861201c1-16c0-0034-3519-e9b850c237a9.png)

WiFiを選択するとアクセスポイントの一覧が表示されます。

![アクセスポイント一覧](https://qiita-image-store.s3.amazonaws.com/0/189829/4452a35f-818e-201e-0ff5-b0747f7515aa.png)

SSIDを選択してすると、パスワード入力が可能です。
パスワードが正しく入力された場合は、WiFiへの接続が可能となります。
残念ながらIPの固定化等の操作はできません。

※すべてマウスから操作が可能たため、キーボードは不要です。

![接続](https://qiita-image-store.s3.amazonaws.com/0/189829/af70aa9c-dc70-ee3d-bda7-7cf3ec92a22f.png)



#### System

システム画面では、OSバージョンや、アップデート確認、Factoryリセットが可能です。

![SYSTEM](https://qiita-image-store.s3.amazonaws.com/0/189829/0ab97ce8-a483-93d5-6b11-cc565d66278c.png)

Factory data reset画面

![Factory data reset](https://qiita-image-store.s3.amazonaws.com/0/189829/23b22589-b8b3-d7d9-5bf3-e39e8bb26424.png)
Djangoでモデルオブジェクトの変更前のデータをチェックする

## 概要

-  **便利そうだから、いつか使いたいなと思いつつ、ニッチなのでなかなか使えない機能シリーズ**
- [django-model-utils](https://django-model-utils.readthedocs.io/en/latest/) というライブラリがある
- その中でも [FieldTracker](https://django-model-utils.readthedocs.io/en/latest/utilities.html#field-tracker) という機能が気に入っている。
- **実際に仕事で使ったことはない**

## FieldTracker is 何？

簡単に言うと、saveする前のモデルオブジェクトに何かしら変更があったらそれを検知できる機能

```python
from django.db import models
from model_utils import FieldTracker

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()

    tracker = FieldTracker()
```

例えば、こういうモデルがあるとする

### 変更前の情報を取得する

変更が入ったフィールドの変更前のデータが取得できる

```python
>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.tracker.previous('title')
u'First Post'
```

### 変更したかどうかチェックする

そのフィールドに変更があったか判定できる

```python
>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.tracker.has_changed('title')
True
>>> a.tracker.has_changed('body')
False
```

### 変更前のデータを辞書で取得する

変更前のデータを辞書として丸っと受け取れる

```python
>>> a = Post.objects.create(title='First Post')
>>> a.title = 'Welcome'
>>> a.body = 'First post!'
>>> a.tracker.changed()
{'title': 'First Post', 'body': ''}
```

## 特定のフィールドだけ対象にしたい

fieldsを指定すれば良い

```python
title_tracker = FieldTracker(fields=['title'])
```

```
>>> a = Post.objects.create(title='First Post')
>>> a.body = 'First post!'
>>> a.title_tracker.changed()
{'title': None}
```

**どうですか便利じゃないですか！？ けどイマイチよし使おうってケースに遭遇しないんですよね...w**

## 注意点

- これはモデルのバージョン管理をしてくれるわけじゃない
- 単純にモデルオブジェクトがsaveされるまでに変更があったら直前のデータを持ってくれてるというだけ。
- saveすると直前のデータはリセットされる。

## 参考

- https://ryu22e.org/post/2014/04/09/django_model_utils__fields
- http://y0m0r.hateblo.jp/entry/20130507/1367939365