OmniAICreator/Qiita-1.07M huggingface dataset:
Node-REDにOpen Jtalkを組み込んでText to Speech !

ホームディレクトリを、/home/user1 とします。
[Open Jtalk](http://software.web.nitech.ac.jp/?p=209)は、名古屋工業大学開発の日本語音声合成ソフトウェアです。
今回は、ローカルのLinux環境に構築したNode-REDにOpen Jtalkを組み込み、テキストデータを音声で読み上げてみたいと思います。スマートスピーカーを作る上で、音声合成は必須です。

# Open-Jtalkのインストール
Node-REDはローカル環境のLinux上に構築してあり、Ubuntu16.04ベースのものを使っていますから、Ubuntu向けのパッケージのおかげでインストールは非常に楽です。

```
先ずはOpen-Jtalkをインストールします。
$ sudo apt-get update
$ sudo apt-get install open-jtalk

インストール時に、下記提案パッケージが表示されますので、こちらもインストールします。
$ sudo apt-get install open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001

```

# Node-REDで呼び出すシェルスクリプトの作成

Open-Jtalkのインストールは完了です。 標準出力のものをテキストから音声に変換する処理を行いますので、テキストファイルを作成します。
- ホームディレクトリ内に、voice.txt を作成 --> $ nano /home/user1/voice.txt
- こんにちは、せかい　と記述

execノードで実行するシェルスクリプト

```
$ nano jtalk.sh

#!/bin/sh

cat /home/user1/voice.txt | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -ow /home/user1/jtalk.wav
play /home/user1/jtalk.wav
rm -f /home/user1/jtalk.wav

$ chmod a+x jtalk.sh
```
Node-REDで、execノードを使用する際に、|(パイプ)でコマンドをつなぐとエラー起きるため、シェルスクリプトとしてまとめています。
このシェルスクリプトは、Open-Jtalkを用いてテキストファイル内の文章をjtalk.wavに変換し、jtalk.wavを再生、再生後は、jtalk.wavを破棄という流れです。
Node-RED内のノードから出力されたテキストデータをテキストファイルとして一度保存する工程にしておけば、別に作っておいた天気予報やチャットボットと組み合わせ易くなります。

# Node-REDに組み込み

作成したシェルスクリプトを「exec」ノードに組み込み、「inject」ノード(下図のtimestampと表示されているノード)と、「file in」ノード(voice.txtと表示)、debugノードで線でつなぎます。あるいは、Node-RED画面右上の「三」→「読み込み」→「クリップボード」にて、サンプルフローを読み込みます。

![node-red-openjtalk.png](https://qiita-image-store.s3.amazonaws.com/0/41414/97eb650e-a145-5454-a1e8-a220cc071deb.png)


サンプルフロー

```
[{"id":"5182ef17.5027f","type":"tab","label":"Open Jtalk","disabled":false,"info":""},{"id":"4b2e227b.1625ec","type":"file in","z":"5182ef17.5027f","name":"voice.txt","filename":"/home/user1/voice.txt","format":"utf8","chunk":false,"sendError":false,"x":273,"y":44,"wires":[["a9f80fce.6ca6"]]},{"id":"f120b0e9.f651f","type":"inject","z":"5182ef17.5027f","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":108,"y":45,"wires":[["4b2e227b.1625ec"]]},{"id":"a9f80fce.6ca6","type":"exec","z":"5182ef17.5027f","command":"/home/user1/jtalk.sh","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"open-jtalk","x":457.5,"y":43.5,"wires":[[],[],["9a7d5b65.81d768"]]},{"id":"9a7d5b65.81d768","type":"debug","z":"5182ef17.5027f","name":"","active":true,"console":"false","complete":"false","x":668,"y":58,"wires":[]}]
```

実装後、先頭の「inject」ノードの左端をクリックすると音声で「こんにちはせかい」と聞こえるはずです。「inject」ノードの編集画面を呼び出すと定期的に実行する処理を設定することができます。

#まとめ
Open-Jtalkを使用することで、Text to Speechをローカル環境に実装することができました。ただ、Open Jtalkは日本語専用で「ひらがな」「カタカナ」「漢字」「数字」を理解して読み上げます。アルファベットは、たとえばHello Worldでは、エイチイーエルエルオー　ダブリューオーエルディー と読み上げます。日本語と英単語が混在するような文章については、無料枠がある「Watson Text to Speech」の方がまだまだ優秀です。
今回の「Open Jtalk」は、スマートスピーカー利用者に音声で伝える際に、「ひらがな」「カタカナ」「漢字」「数字」で構成された文章であれば使いどころがあるでしょう。

# 関連コンテンツ

- ローカル環境のLinuxでスマートスピーカーにチャレンジ(1) → [ここをクリック](https://qiita.com/kolinz/items/b61f5b135be7fac0d9a8)
- Node-REDで、Julius使って音声認識する → [ここをクリック](https://qiita.com/kolinz/items/ee132ec7bae229e37ac6)
暗号化ファイルのアーカイブ化

これは[Siv3D AdventCalendar 2017](https://qiita.com/advent-calendar/2017/siv3d) 18日目の記事です。

# 概要
暗号化したファイルのアーカイブから、復号したデータを読み込む機能を作成しました。
また、指定したフォルダを暗号化してアーカイブファイルを作成する機能も作成しました。

[ここ](https://github.com/ao1415/AdventCalendar2017/tree/master)でソースコードを公開しています。

# 利用方法
## CryptoArchive::Create

```C++:暗号化アーカイブの作成
CryptoArchive::Create(L"アーカイブ化したいフォルダパス", L"アーカイブの出力パス", AES128Key);
```

指定したフォルダをアーカイブ化する関数です。AES128Keyで指定した鍵で暗号化を行います。
作成したアーカイブ内の、フォルダとファイルの構成は元の構成と同じになります。
>例
>元フォルダの構成　Example/Siv3D-kun.png
>アーカイブの構成　Example/Siv3D-kun.png

## ArchiveCryptoFile

```C++:暗号化アーカイブの読み込み
ArchiveCryptoFile file(L"アーカイブファイルパス", AES128Key);
Texture texture(file.load(L"アーカイブ内のファイルパス"));
```

ArchiveCryptoFileで作成したアーカイブを読み込む機能です。
コンストラクタで読み込むアーカイブファイルと鍵を指定します。
指定する鍵は、アーカイブ化する際に使用したものと同じ鍵です。

ArchiveCryptoFile::loadでアーカイブ内のファイルを読み込みます。

### 補足
コンストラクタでアーカイブファイルと鍵をしていない場合、loadは指定されたファイルのデータを読み込むようになります。

```C++:コンストラクタを指定しない場合
ArchiveCryptoFile file;
Texture texture(file.load(L"ファイルパス")); //ファイルパスで指定したファイルを読み込んでくる
```

この機能により、読み込み先の変更が容易になります。

```C++:読み込み先の切り替え
//アーカイブファイルの読み込み
ArchiveCryptoFile file(L"./Example.ecp", AES128Key(0, 0));
Texture texture(file.load(L"./Example/Siv3D-kun.png")); //Example.ecpアーカイブ内のSiv3D-kun.pngを読み込む

//通常のファイルの読み込み
ArchiveCryptoFile file;
Texture texture(file.load(L"./Example/Siv3D-kun.png")); //ExampleフォルダのSiv3D-kun.pngを読み込む
```

# 以下作成した動機や、使用した機能などの説明
## 背景
Siv3Dで作成したプロジェクトを公開する際に、画像ファイルや設定ファイルなども一緒に添付すると思います。
しかし、ファイルの数が増えると圧縮・解凍に時間がかかったり、編集されたくないファイルを編集されるなどの問題があります。

ファイル数が増えた場合にはアーカイブファイルを作成し、編集されたくないファイルは暗号化すれば解決します。
だけど、いちいち行うのはちょっとめんどくさいので、今回それらを一括して行える機能を作成しました。

## アーカイブファイルについて
Siv3Dでは "Archive::Create" と "FileArchive" でアーカイブファイルが操作できます。([リファレンス](https://github.com/Siv3D/Reference-JP/wiki/%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB))

しかし、これで作成したできるアーカイブファイルには元のデータがそのまま記載されています。
以下の画像は作成したアーカイブファイルを、バイナリエディタで開いたものです。

![アーカイブファイル中身.png](https://qiita-image-store.s3.amazonaws.com/0/102316/6d80b474-cf7b-a9e7-1025-7c0bba41c95a.png)

フォルダ構成
Siv3Dアーカイブ
┗テキストファイル.txt

「Siv3Dアーカイブ」フォルダをアーカイブ化したのですが、その中の「テキストファイル.txt」に記載した文章が見えてしまっています。
このようにただアーカイブ化するだけでは、データを編集される可能性があります。

## 今回作成した機能
今回は、暗号化したファイルをアーカイブ化し、それからデータを読み取る機能を作成しました。
以下の画像は今回の機能でアーカイブ化したファイルをバイナリエディタで開いたものです。

![暗号化アーカイブファイル中身.png](https://qiita-image-store.s3.amazonaws.com/0/102316/6a39d6dc-122e-51cf-d55b-2596396906ed.png)


フォルダ構成
Siv3Dアーカイブ
┗テキストファイル.txt

ファイル名は見えてしまっていますが、「テキストファイル.txt」に記載した文章は意味の分からないものになっています。
【2018年版】macのhomebrewでnodebrew入れてからnode.jsを入れるまで




色々あって自分のmac book proを先日、工場出荷状態に戻しました…
なので開発環境の再構築中で、イケてるやり方で改めて構築してます

###環境
- OS High Sierra ver 10.13.2
- homebrew インスコ済み


##nodebrewをインストール

nodebrewとは
node.jsを自分のマシン内でversion管理するためのtool

[git-hub nodebrew](https://github.com/hokaccha/nodebrew)



####１、homebrewでnodebrewをイントールして設定

```command
$ brew install nodebrew

##install確認
$ brew list
nodebrew

##nodebrewセットアップ
$ nodebrew setup
```

####２、環境変数の設定
.bash_profileに以下を追記

```.bash_profile
# nodebrew setup時に打つと出てきたやつ
export PATH=/usr/local/var/nodebrew/current/bin:$PATH
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

```command
#環境変数の反映
$ source .bash_profile
```

####３、nodebrewを使って最新のnode.jsをインストール
latest = 最新版
stable = 安定版


```command
#安定版のインストール
$ nodebrew install-binary stable

#インストール後の確認
$ nodebrew list

v8.9.3

current: none

#使用するための設定と、その確認
$ nodebrew use stable
$ node -v
v8.9.3

$ npm -v
5.5.1

#npmの更新
$ npm update -g npm
```


####４、Done！！

node.jsインストール完了です
お疲れ様でした
Arcserve エラー

Arcserve Backup r17.5でのエラー

・イベントログにでるエラー
>==================================================
ログの名前:         Application
ソース:           CA_LIC
イベント ID:       5000
レベル:           エラー
説明:
ライセンス使用許諾 -3T18 CA ARCserve Backup r16.5 Agent for Virtual Machines - ライセンス エラーです。ライセンスを取得するためには製品の購入元、もしくは CA ジャパン >ダイレクトまでお問い合わせください。  LRF=3T18, 005056bd7492, PC_8664_2_2800, ><Machine Name>
[Arcserve Backup r17.5 によるソース展開時/バックアップ実行時に Agent for Open Files のライセンス エラーが記録される – Arcserve](http://arcserve.zendesk.com/hc/ja/articles/115004003863-Arcserve-Backup-r17-5-%E3%81%AB%E3%82%88%E3%82%8B%E3%82%BD%E3%83%BC%E3%82%B9%E5%B1%95%E9%96%8B%E6%99%82-%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%...)


r17.5を使用しているのに何故以前のバージョンであるr16.5のライセンスエラーが？と思ったが、バックアップやリストアの動作に影響はないらしい。パッチもでている。

・アクティビティログにでるエラー
W29729 "テープ エンジンの圧縮が無効です"。
>以下の設定で FSD バックアップを実行する場合、アクティビティログに [W29729 "テープ エンジンの圧縮が無効です。] が記録されます。
- データの暗号化 : [バックアップ中にバックアップ サーバで処理]
- データの圧縮: [バックアップ サーバで処理]
[Arcserve Backup r17.5 for Windows 注意/制限事項 – Arcserve](http://arcserve.zendesk.com/hc/ja/articles/115000910286-Arcserve-Backup-r17-5-for-Windows-%E6%B3%A8%E6%84%8F-%E5%88%B6%E9%99%90%E4%BA%8B%E9%A0%85)


見た目あんまよくないがこれは無視するしかないらしい
WebサーバにGitをインストール


## gitのインストール

以前作った[RaspberryPi で作った無線Webサーバ(nginx)](https://qiita.com/yuuki_tf/items/9adb3825d8841c17d777)に
Gitをインストールしました。


```shell
# インストールしたいサーバに入る
ssh ユーザ@IPアドレス

# Gitをいれる
sudo apt-get install git
```
同じ問題をオブジェクト指向な方法と関数型な方法で解いてみる

Scalaを使って同じ問題をオブジェクト指向なアプローチで解く方法と関数型なアプローチで解く方法とを例示出来るといいなーと思って書いてみます。

# はじめに
こんなコードがあったとします。
制約としては同じ通貨どうししか足し合わせられないようにしたい。
違反した場合はコンパイルエラーに。

```scala

object Main extends App {

  trait Currency
	
  case class Yen(value: Int) extends Currency {
    def +(other: Yen) = Yen(value + other.value)
  }

  case class Dollar(value: Int) extends Currency {
    def +(other: Dollar) = Dollar(value + other.value)
  }

  val y1 = Yen(300)
  val y2 = Yen(500)
  val y3 = y1 + y2
  println(y3) // Yen(800)
	
  val d1 = Dollar(3)
  val d2 = Dollar(5)
  val d3 = d1 + d2
  println(d3) // Dollar(8)
  
  val x = y1 + d1 // コンパイルエラー
```

次に、具体的な通貨クラスを指定するのではなくて任意の同じ通貨クラスどうしを足し合わせられるようなちょっと抽象的な関数を追加したくなったとする。
以下を定義する。

```scala
def add[C <: Currency](c1: C, c2: C) = c1 + c2
```

が、これはコンパイルエラー。
Currencyに `+` メソッドなんて定義されてないから。

じゃ、定義するか。

...というように進むのがOOPに慣れ親しんだプログラマが自然に思いつくアプローチといったところでしょうか。
データに操作を増やして、親側に共通のメソッドを追加して抽象的なプログラムに耐えられるようにしていく。
少なくとも自分はこんな感じでした。

で、いざやろうとするとこれはなかなか難しい事に気づきます。
２つの通貨クラスの親のCurrencyに定義する+メソッドはどうやって自分を継承した子クラスの型情報を取ればいいだろう？？

雰囲気的には以下のような感じで動けばいいのですが、、、、これはうまく動きません。

```scala
trait Currency {
  def +(other: this.type): this.type
}
```

# Way1

この方向でいくとするとこのようにちょっと冗長だけど型情報Selfを増やしてやらないと解決は厳しそう。

```scala
trait Currency[Self] {
  def +(other: Self): Self
}

case class Yen(value: Int) extends Currency[Yen] {
  override def +(other: Yen): Yen = Yen(value + other.value)
}

case class Dollar(value: Int) extends Currency[Dollar] {
  override def +(other: Dollar): Dollar = Dollar(value + other.value)
}

def add[C <: Currency[C]](c1: C, c2: C): C = c1 + c2
```

ま、でも、これで無事動きました。

# Way2
今度は別のアプローチで。

まず通貨クラスはこんな感じに定義します。

```scala
sealed trait Currency

case class Yen(value: Int) extends Currency
case class Dollar(value: Int) extends Currency
```

先のadd関数を次のように少し変える。

```scala
def add[C <: Currency](c1: C, c2: C)(implicit addable: Addable[C]): C = addable.run(c1, c2)
```

Addableを定義。

```scala
trait Addable[T] {
  def run(v1: T, v2: T): T
}

implicit val y = new Addable[Yen] {
  def run(v1: Yen, v2: Yen) = Yen(v1.value + v2.value)
}

implicit val d = new Addable[Dollar] {
  def run(v1: Dollar, v2: Dollar) = Dollar(v1.value + v2.value)
}
```

これでaddは正しく動くようになります。

ただしこのままだとadd関数を使った足し合わせは出来ても `val y3 = y1 + y2` のような処理が書けないので以下を追加。

```scala
implicit class AddableOp[T: Addable](v1: T) {
  def +(v2: T): T = implicitly[Addable[T]].run(v1, v2)
}
```

これで動きました。

こっちは通貨クラスをあくまでデータ型として扱い、データどうしの操作はデータ型毎に用意した関数として定義するようになっています。

# さいごに
別のアプローチがあるとか、もっといい書き方があるとかあればコメントお願いします。
また、こういう事例がたくさんあるようなサイトとかあれば知りたい。
systemd-nspawnのログ連携

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

systemd-nspawnでは--link-journal=オプションによってjournaldの制御が可能です

これによって、ホスト側からコンテナをジャーナルログを見れたりします。
以下のうちどれかを指定します

* "no" => journalはリンクしない
* "host" => ホスト側にjournalログを置く
* "guest" => ゲスト側にjournalログを置く
* "try-host" => hostと同じだけどログディレクトリ(/var/log/journal)が無くても失敗しない
* "try-guest" => guestと同じだけどログディレクトリ(/var/log/journal)が無くても失敗しない
* "auto" => /var/log/journalの中にコンテナIDに対応するディレクトリがあれば使う

ちょっと分かりにくいかと思いますので以下にまとめました

| link-journalの指定 | ログの実体                           |
|--------------------|--------------------------------------|
| no                 | リンクしない                         |
| host               | host側の/var/log/journal/machine-id  |
| guest              | guest側の/var/log/journal/machine-id |
| try-host           | host側の/var/log/journal/machine-id  |
| try-guest          | guest側の/var/log/journal/machine-id |
| auto               | 前回と同じ                           |


"try-host", "try-guest"はhost側に/var/log/journalがなくても下のようなエラーにならずに進めてくれます

```
Failed to symlink /var/lib/machines/./ubuntu/var/log/journal/e60dfec6da884e6eafc17391c925fb23 to /var/log/journal/e60dfec6da884e6eafc17391c925fb23: No such file or directory
```

"auto"もその挙動なのですが、前回が"host"ならhost側に置くように、前回が"guest"ならguest側に置くように計らってくれます
またmachine-idに対応するディレクトリが無ければ何もしません

なおどのオプションでもホストから`journalctl -M コンテナ名`とすればコンテナ内部のログは見れます
家猫を外出先で監視するために、RaspberryPiを無線サーバーにする(nginx)

# 経緯

保護猫を引き取り、初めて猫との共同生活をしています。
平日は帰宅の時間が遅いので、仕事の間猫がどうしているか心配でならず..

市販のペット監視ソリューションを見ていたのですが、
いい値段がしたので購入に踏み切れず..
それならば、自分がRaspberryPiでサーバ立てて、カメラ（¥1000）を設置したら
安くで作れるんじゃないかなと思い、トライしてみた次第であります。


# RaspberryPiを無線サーバにする迄

RaspberryPiの組み立て方はここには載ってませんので悪しからず。

◆前提条件
下記サイトにて、イメージを落としてくる。
https://www.raspberrypi.org/downloads/raspbian/

#### 1.イメージの作成
```shell
diskutil list
diskutil eraseDisk FAT32 NEKOBERRY /dev/disk4
diskutil unmountDisk /dev/disk4
cd /Users/[ユーザ名]/Downloads
sudo dd bs=1m if=2017-09-07-raspbian-stretch-lite.img of=/dev/rdisk4
cd /Volumes/boot/
touch ssh
```

#### 2.RaspberryPiへの接続（まずは有線で）
```shell
ssh pi@IPアドレス
sudo apt-get update
sudo apt-get upgrade
```

#### 3.RaspberryPiの設定
```shell
sudo raspi-config

hostname：(3)を選択後、名前を変更
localazation option：(4)を選択後以下を変更
change local：ja-UTF8を選択
change timezome：Tokyoを選択
```
#### 4.無線LANでの接続設定
```shell
sudo apt-get install vim
sudo update-alternatives —config editor
「/usr/bin/vim.basic」を選択
cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.bk
sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

# Wi-FiのIDとPWを入力
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="YOUR_WIFI_SSID"
    psk="YOUR_WIFI_PASSWORD"
    key_mgmt=WPA-PSK
}
sudo reboot
ifconfig # IPアドレスを確認
```
#### 5.確認
```shell
別途、同じWiFiに接続した Macでターミナルを起動し、SSH接続。以下のメッセージが出たらOK。
ssh pi@IPアドレス

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Nov 18 17:21:24 2017 from [IPアドレス]
SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.
```

#### 6.IPアドレスを固定する
```shell
sudo cp /etc/dhcpcd.conf /etc/dhcpcd.conf.bk
sudo vi /etc/dhcpcd.conf

#追記
interface wlan0
static ip_address=192.168.0.100/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

sudo reboot #再起動
sudo shutdown -h now #シャットダウン
```

#### 7.nginxのインストール
```shell
sudo apt-get install nginx
sudo /etc/init.d/nginx start
```


ラズパイ、前々から気になってました。
今も家で地味に動いてます。
家にサーバがあるってなんかweb屋さんぽいです。。
『オートエンコーダ』で進化したニューラルネットワーク紹介　カプセルネットワークっぽい

　
#　はじめに
オートエンコーダの人気が落ちている！！
ということで
オートエンコーダを使った独自のニューラルネットワークを作ろうと思い立ち
考えついたものを書きます！！
まあ、昔からあったら教えてください…

#　説明
まず、オートエンコーダを１つ用意します。(^^♪
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/216255/fcea1a82-fcf6-999f-0984-cd58ad3ca9a8.jpeg)絵が下手だと！！（~~センスがないな～～( ´∀｀ )~~）
そんなことはどうでもいい！！！！
次にもう一つ用意します。(^^♪
![３無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/216255/a4a2d3e5-09b5-7ce8-d992-d156c62c3c1c.jpeg)
**時系列もつけていきます**。
番号が若いほど最近のものです。
時系列ごとにオートエンコーダをやるのは処理的に難しい。
なので過去のオートエンコーダを転移学習していこうと考えました。
![４無題..jpg](https://qiita-image-store.s3.amazonaws.com/0/216255/be059c03-5330-bcdd-49bc-4ecf692b3208.jpeg)
その時重要なのは
**過去のオートエンコーダに計算しているデータをそのまま入れること**
**現在のオートエンコーダは過去のオートエンコーダの重みｗを変更することができない（ただし、影響として１つしかない層に現在のオートエンコーダの層の値に重みｗを与えた値を足すことができる）**
**過去のオートエンコーダは影響を記録しすべてを計算する**
**過去、現在関係なく影響自体が与えられていないオートエンコーダは計算しない**
**そして現在の影響、重みｗすべてが０に近くなるようにする**
です。（キャラ崩壊中）
そうするとできるかぎり０にしたとき
![無題.５.jpg](https://qiita-image-store.s3.amazonaws.com/0/216255/49b34568-ffbc-0125-a1c3-f725850ae508.jpeg)
５と９は１と１０という範囲でかかわりを持っており
また同じようなオートエンコーダの種類分布だとオートエンコーダをしなくても
影響を少しおなじものに与えるだけでデータを再現できそれにより次のものや
オートエンコーダを物の識別子に見立てられると考えています。
# 終わりに
数学の式を書かなかったので
次に投稿するときはがちがち図なしで書きます。
**よくわからなかった**
とか
**数式で見てみたい**
と思った人はストックしてください。
コメントに文句かいてもいいですよ。
WebGLでレイマーチングの中でマウスとの当たり判定を作った

#はじめに
WebGLのレイマーチングの中でマウスとの当たり判定を作ってみました。

動機は、綺麗なデモは素晴らしいんだけど、ゲーム屋の俺としては当たり判定入れてゲームにしたいとなと思ったからです。

動作確認
http://ai5.jp/conflict/

#ソース
レイマーチングのソースは @doxas さんのコードをコピペしています。
https://qiita.com/doxas/items/477fda867da467116f8d
このリンクの記事のレイマーチングにマウスとの当たり判定を、ちょびっと書き足しました。

```glsl:fragment.txt

precision mediump float;
uniform vec2  m;//mouse -1.0 〜 1.0
uniform float t;//time
uniform vec2  r;//resolution

struct Ray{
    vec3 origin;
    vec3 direction;
};

struct Sphere{
    float radius;
    vec3  position;
    vec3  color;
};

bool intersectSphere(Ray R, Sphere S){
    vec3  a = R.origin - S.position;
    float b = dot(a, R.direction);
    float c = dot(a, a) - (S.radius * S.radius);
    float d = b * b - c;
    if(d > 0.0){
        float t = -b - sqrt(d);
        return (t > 0.0);
    }
    return false;
}

void main(void){
    // fragment position
    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    // ray init
    Ray ray;
    float z = 10.0;//書き足した
    ray.origin = vec3(0.0, 0.0, z);
    ray.direction = normalize(vec3(p.x, p.y, -1.0));

    // sphere init
    Sphere sphere;
    sphere.radius = 4.0;
    sphere.position = vec3(0.0);
    sphere.color = vec3(1.0, 1.0, 1.0);

    // ray hit check
    vec3 destColor = vec3(0.0);
    float flag = 0.0;
    if(intersectSphere(ray, sphere)){
        destColor = sphere.color;
        flag += 1.0;
    }

    // mouse hit check　ここも書き足した
    vec3 a = sphere.position - vec3(m.x * z, m.y * z, 0.0);
    //何故か半径を1.1倍にしないと上手くいかなかった。1.0倍でもそこそこいける。
    float radius = sphere.radius * 1.1;
    if (dot(a, a) < radius * radius && destColor.x == 1.0) {
        destColor = vec3(1.0, 0.0, 0.0);
    }
    gl_FragColor = vec4(destColor, 1.0);
}
```
#おわりに
フラグメントシェーダからシェーダ呼び出し元に値を返す事が出来れば完璧なのですが、この記事に書かれている https://qiita.com/emadurandal/items/4c7bd2a26ef2d732d734 WebGL2.0からのTransform Feedbackの機能を待つしかないようです。
Google Cloud FunctionsからSlackへ通知を送る

### Google Cloud Functionsとは

![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/23101/b8c96ba3-fac4-413f-5a2f-e4443bea6adf.png)

サーバーを準備、管理しなくてもコードを実行できるサーバーレスなコンピューティングサービス。AWSでいうLambdaに該当する。コードが実行される時間に対してのみ、最も近い100ミリ秒単位で課金される。
※2017年12月17日時点ではBeta版


### Google Cloud Functionsで関数を作成
##### 1. GCPコンソールのメニューから「Cloud Functions」を選択
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/a81c9657-3ae1-00f2-07d5-d85767af5e02.png)

##### 2. 「関数を作成」ボタンを押下
![キャsプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/af685815-d65c-d75d-4e29-a6fdde8f2481.png)

##### 3. 関数の詳細を入力
![キャプsssチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/dd453d7f-48db-4986-2d5b-832e1440ed80.png)

入力内容は以下の通り。

|入力項目|説明|
|:--|:--|
|名前|任意の関数の名前を入力。ここで設定した名前は変えることはできない|
|割り当てられるメモリ|関数実行時に割り当てられる最大メモリサイズ|
|トリガー|何をトリガーにこの関数を実行させるかを選択|
|ソースコード|関数のソースコードをどう管理・編集するかを選択|
|ステージ バケット|コードをステージングするCloud Storageを指定|

上記を入力したら「作成する」ボタン押下する。
しばらくすると、以下のような形で関数ができあがる。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/30ff66ee-8f4e-b5e1-756f-5fc2d4588e14.png)


### Slackのトークンを確認

[Slack APIのTokenの取得・場所](https://qiita.com/ykhirao/items/0d6b9f4a0cc626884dbb)を参考に、Slackのトークンを控える。

### スクリプトの作成
Cloud FunctionsはNode.jsのランタイムで実行される。そのため、スクリプトはNode.jsでの実装となる。

```index.js
const request = require('request');

// デフォルトでhelloWorldで作成されるのでよしなに変更する
exports.helloWorld = function helloWorld(req, res) {

	var headers = {
		'Content-Type':'application/json'
	}

	var options = {
		url: 'https://slack.com/api/chat.postMessage',
		method: 'POST',
		headers: headers,
		json: true,
		form: {
			token: '控えてあるSlackのトークン',
			channel: '通知を送りたいSlackのチャンネル名',
			username: 'Slackに通知を送るユーザ名',
			text: 'Slackに通知するメッセージ'
		}
	}

	request(options, function (error, response, body) {
	// 必要に応じてコールバック処理
	})

	res.status(200).send('Success');
};
```

```package.json
{
	"name": "sample-http",
	"version": "0.0.1",
	"dependencies": {
		"request": "^2.81.0"
	}
}
```

### 通知が飛ぶか試してみる

URLは「関数の詳細」の「トリガー」タブで確認できるので、ブラウザ等のHTTPクライアントで、上記で作成した関数をコールする。
![キャプsチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/e814c504-fa6e-3ba9-27b6-42893bb9c3f2.png)

こんな感じで通知が届けばOK。
![キャプチsャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/d78fbe02-cbc2-cf9f-0c74-dda7db33c5ae.png)

### 参考
* [Google Cloud Functions](https://cloud.google.com/functions/?hl=ja)
SVMで世界人口を回帰分析

# 初めに
今回はSVMを使って世界人口を予想しようと思います。
前回、[pythonで世界経済を予想する](https://qiita.com/pengincoalition/items/7b9e841634ad7ce9c0f6)という記事を書いたのですが、これは一次関数が当てはまってSVMでやる意味がないように思えたので、よい題材を探しました。
世界人口は近年(と言ってもここ100年くらい)急激に増加しており、一次関数が当てはまらないと思われます。

# データを手に入れる

[データ](http://www.un.org/esa/population/publications/sixbillion/sixbilpart1.pdf)

こちらのpdfに世界人口の推移が載っていますのでこれを使います。
今回は古いデータを含めると学習がうまくいかなかったので1850年
より前のデータは含めませんでした。

# ソースコード
[pythonで世界経済を予想する](https://qiita.com/pengincoalition/items/7b9e841634ad7ce9c0f6)を元に作りました。

```python3
import sys
from sklearn.svm import SVC
from sklearn import svm
import numpy as np
import copy
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV
from sklearn.kernel_ridge import KernelRidge
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.linear_model import Ridge


args = sys.argv


def regression_main():
     # model = svm.SVR(kernel='rbf', C=1e3, gamma=0.1)
      data=[]
      with open(args[1],"r",encoding="utf-8") as f:
           data=[e.replace("\n", "") for e in f.readlines()]
           data=[[float(e) for e in e.split(",")] for e in copy.deepcopy(data) ]
      
      in_data=[e[:-1] for e in data]
      label_data=[e[-1] for e in data]
      
      print(in_data,label_data)
      
      tuned_parameters = [
        {'kernel': ['rbf'], 'gamma': [10**i for i in range(-6, 6)], 'C': [3]}#,
     #   {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}
      ]

     # model = GridSearchCV(svm.SVR(), tuned_parameters,  verbose=1,cv=5, scoring="mean_squared_error")
      model =svm.SVR(kernel='rbf',gamma=0.00001,C=1e3)

      
      model.fit(in_data,label_data)

      
      plt.scatter([e[0] for e in in_data], [e for e in label_data])
      test_in_data=[[e] for e in range(int(min([e[0] for e in in_data])),int(max([e[0] for e in in_data])),1)]
#      test_in_data=[[e] for e in range(2100)]
      plt.plot([e[0] for e in test_in_data], model.predict(test_in_data))
      plt.show()
      
      while True:
          user_input=input("end?>")
          if user_input=="end":break
          user_in_data=[]
          for i in range(len(in_data[0])):
               t=float(input(">"))
               user_in_data.append(t)
          
          print(model.predict([user_in_data])[0])
      


def main():
     print("1:label\n2:回帰")
     n=int(input(">"))     
     if n==1:
         #label_main()
     if n==2:
         regression_main()


```

上記を実行すると、
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/206651/16ce312f-5f0e-f8c7-7d4e-18dd999699de.png)
こうなりました。
一次関数は当てはまらない形になっています。

# 予想する

2050と入力してみます。
結果は10.8245358213と出てきました。(単位は10億人です。つまり108億2453万5821人のことです)
国連が予測では98億人なので誤差はありますが予想できました。

# まとめ

今回はSVMを使った意味がありました。
このモデルだと2100年はうまく予想できませんでした。
本来、SVMなどを使わず、ロジスティック方程式などを活用したほうが良かったと思います。
Futureの中で発生した例外を放置した場合を確認した


Futureのなかで例外が発生して、対処しなかった時の確認をした。
Dartが良さげに対処すると聞いたので、確認したのが主な理由。

# Dart

```
$ dart -version
Dart VM version: 1.24.2 (Thu Jun 22 08:42:17 2017) on "macos_x64"
```

```dart
main() {
  (() async => throw 'error')();
}
```

実行結果

```
Unhandled exception:
error
#0      main.<anonymous closure> (hoge.dart:2:16)
<asynchronous suspension>
#1      main (file:///Users/eiel/hoge.dart:2:30)
#2      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:265)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151)
```
ハンドルしてない例外があるってでるし、その箇所もわかる。


ちゃんとハンドリングした場合の確認

```dart
main() {
  (() async => throw 'error')()
    .catchError(print);
}
```

実行結果

```
error
```

# Node.jsの場合

```
$ node -v
v8.9.3
```

```javascript

new Promise(() => { throw 'error' })
```

実行結果

```
(node:9008) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): goro
(node:9008) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```

残念ながら場所まではわからない

ちゃんとハンドリングした場合の確認

```javascript
new Promise(() => { throw 'error' })
  .catch(console.log)
```

```
error
```

そういえば、以下のようにかいても良い気がする

```javascript
(async () => { throw 'error' })()
```

# Scala

```
$ scala -version
Scala code runner version 2.12.4 -- Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc.
```

```scala
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.concurrent.duration._

Future(throw new Exception("error"))
```

実行結果

```
```
なにも起きない

ハンドリングしてみる。

```js
import ExecutionContext.Implicits.global
import scala.concurrent.duration._

Future(throw new Exception("error"))
  .recover{ case e => e.getMessage }.foreach(println)
```

実行結果

```
error
```
Rspecのテスト結果をブラウザで見てみよう！

#Rspecのテスト結果をHTML形式で見たい

##.rspecの設定
1,フォーマットをHTMLにします。
2,`--out`はテスト結果を出力するHTMLファイルを指定します。

```:.rspec
--format html
--out result.html
```

設定はこれだけです！

##テストを実行しよう
`$ bundle exec rspec`

テストを実行すると.rspecに指定したファイルに自動的にHTMLが書き込まれます。
ブラウザで見てみると。。。

テスト結果によって色も分けて表示してくますし、チェックボックスでソートすることもできます。
<img width="1277" alt="スクリーンショット 2017-12-15 18.20.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/201127/30a39337-0abe-d04f-30e6-5b4667540300.png">

<img width="1277" alt="スクリーンショット 2017-12-15 18.20.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/201127/1b8c1155-ae70-22da-1e24-401023d2ed53.png">

#結論！！
ブラウザで見るのもいいね:thumbsup:
[Ruby]数当てゲームのヌメロン作ってみた

# ヌメロン(Numer0n)とは
マスターマインドをベースに、相手が選んだ数字を当てる推理ゲーム
[Numer0n (wikipedia)](https://ja.wikipedia.org/wiki/Numer0n)

# ヌメロンの基本ルール
1. それぞれのプレイヤーが**0～9までの数字**が書かれたカードのうち3つを使って**3ケタの番号**を作成する。ただし、「112」「121」といった**同じ数字を2つ以上使用した番号は作れない**。
2. 先攻のプレイヤーは相手が作成したと思われる番号をコールする。相手はコールされた番号と自分の番号を見比べ、コールされた番号がどの程度合って いるかを発表する。
 - 数字と位置が合っていた場合は「**EAT**」
 - 数字は合っているが位置は合っていない場合は「**BITE**」
 - 例として相手の番号が 「765」、コールされた番号が「746」であった場合「1 EAT - 1 BITE」となる。
3. これを先攻・後攻が繰り返して行い、先に相手の番号を完全に当てきったプレイヤーの勝利となる。
 
ルールは [Numer0n数当てゲーム](https://dyama.org/2012/06/numer0n/) から抜粋しました。

# 仕様
今回は対戦ではなく、ランダムに生成された相手の番号を一方的に当てるだけにしました。
ターミナル上で動かせます。
# ソースコード

```Ruby:numeron.rb
class Numeron
  attr_reader :condition

  def initialize
    # 相手の番号
    @opp_nums = [*"0".."9"].sample(3)
    # ゲームが続いているかの状態
    @condition = true
    puts "コールしてください"
  end

  # EAT と BITE の数を調べる
  def check(call_nums)
    @eat_count = 0
    @bite_count = 0
    call_nums.chars.each_with_index do |call_num, call_position|
      opp_positon = @opp_nums.index(call_num)
      next unless opp_positon
      if opp_positon == call_position
        @eat_count += 1
      else
        @bite_count += 1
      end
    end
  end

  # EAT と BITE の数を知らせる
  def announce_result
    if @eat_count == 3
      puts "3 EAT"
      @condition = false # ゲーム終了
    else
      puts "#{@eat_count} EAT - #{@bite_count} BITE"
    end
  end

end


numeron = Numeron.new

while numeron.condition
  call_nums = gets.chomp # 3桁の数字をコール
  numeron.check(call_nums)
  numeron.announce_result
end
```

# 出力
```
$ruby numeron.rb 
コールしてください
345
0 EAT - 0 BITE
678
1 EAT - 1 BITE
617
0 EAT - 1 BITE
728
3 EAT
```

# さいごに
Ruby勉強中なので、もっとこうしたらいいとかあればアドバイスお願いします。
angular-google-maps agm-snazzy-info-windowが正しく表示されなかった


[angular-google-maps](https://angular-maps.com/)の「[agm-snazzy-info-window](https://angular-maps.com/guides/snazzy-info-window/custom-info-windows-with-snazzy-info-window/)」が正しく表示されなかった。
備忘録の意味も込めて投稿します。

#コード
```
<agm-map [latitude]="latitude" [longitude]="longitude" [zoom]="zoom">
	<agm-marker *ngFor="let marker of markers" 
	    [latitude]="marker.lat" 
	    [longitude]="marker.lng" 
	    [iconUrl]="marker.iconUrl"
	    [label]="marker.label"
	    (markerClick)="makerClick(marker.label,$event)"
	    >
		<agm-snazzy-info-window [maxWidth]="200" [closeWhenOthersOpen]="false" [isOpen]="true">
			<ng-template>
				{{marker.label}}
			</ng-template>
		</agm-snazzy-info-window>
	</agm-marker>
</agm-map>	
```

```.angular-cli.json(抜粋)
      "styles": [
        "styles.css",
        "../node_modules/snazzy-info-window/dist/snazzy-info-window.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],

```

#起きていたこと
![キャプチ222ャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/108431/2d4d0ce1-1722-f5fd-5be6-64d329384648.png)

CSS読み込まれてない？ でも設定入れているのに……

#原因
ng serveでサーバ起動したまま「.angular-cli.json」を修正していたため。
どうやら再起動しないと反映されないもよう。
（issue漁ってたら見つけた https://github.com/SebastianM/angular-google-maps/issues/1244）

見つけてよかった……。　知らないまま明日直ってたら余計悩んでいたと思われる。
PeerCast プログラミング配信 Advent Calendar 2017 15日目

メモ
[もげRPGサーバー](https://github.com/fusuya/mogeRPGserver)のAIを改良した。
50階にいる中ボスを倒しに行く条件を色々いじっているが安定したものが見つからない。
レベルアップ時にステータスポイント振り分けの条件も弄る必要がありそうだ。
systemd-nspawnをAWSで使ってみる

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

今回はAWSでやってみます

と言っても[GCPの時](https://qiita.com/yaasita/items/3e46d7d8efc40aa09e3c)とほぼ同じなので、Ubuntu16.04で使う部分の注意点というかunitファイルの書き方的なところを書いておきます

debian 9とは違いmachines.targetじゃなくてmulti-user.targetに入れてます

https://gist.github.com/yaasita/e6b89aec1c287f1dfe06e035f38ff5ea

```
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Container %i
Documentation=man:systemd-nspawn(1)
After=multi-user.target

[Service]
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit -b --machine=%i --network-bridge=br0
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Slice=machine.slice
Delegate=yes
TasksMax=8192

# Enforce a strict device policy, similar to the one nspawn configures
# when it allocates its own scope unit. Make sure to keep these
# policies in sync if you change them!
DevicePolicy=strict
DeviceAllow=/dev/null rwm
DeviceAllow=/dev/zero rwm
DeviceAllow=/dev/full rwm
DeviceAllow=/dev/random rwm
DeviceAllow=/dev/urandom rwm
DeviceAllow=/dev/tty rwm
DeviceAllow=/dev/net/tun rwm
DeviceAllow=/dev/pts/ptmx rw
DeviceAllow=char-pts rw

# nspawn itself needs access to /dev/loop-control and /dev/loop, to
# implement the --image= option. Add these here, too.
DeviceAllow=/dev/loop-control rw
DeviceAllow=block-loop rw
DeviceAllow=block-blkext rw

[Install]
WantedBy=multi-user.target
```
TinkercadのCircuitsでLチカシミュレーション


[IoTLT Advent Calendar 2017](https://qiita.com/advent-calendar/2017/iotlt) 15日目の記事です。間に合ってる！！

TinkecadというオンラインCADサービスにある**Circuits**で電子回路のシミュレーションをすることができます！

[![スクリーンショット 2017-12-15 23.30.07.png](https://qiita-image-store.s3.amazonaws.com/0/119003/f2469d12-ff7d-eea0-e03c-9ff5031a497a.png "スクリーンショット 2017-12-15 23.30.07.png")](https://www.tinkercad.com/circuits)
[Tinkercad circuits](https://www.tinkercad.com/circuits)

サインアップして「Launch」から始めましょう〜〜


ブレッドボードを配置して、まずはLEDを適当においてみる。
![スクリーンショット 2017-12-15 23.35.47.png](https://qiita-image-store.s3.amazonaws.com/0/119003/95f30633-4dcf-7f45-711e-075685b324ed.png "スクリーンショット 2017-12-15 23.35.47.png")

色も変えられます。哀しみブルー！
![スクリーンショット 2017-12-15 23.35.58.png](https://qiita-image-store.s3.amazonaws.com/0/119003/2b3c1c31-51e8-6db4-3e14-0f9a339d68cf.png "スクリーンショット 2017-12-15 23.35.58.png")


Arduino UNOをおいて、適当に配線。
![スクリーンショット 2017-12-15 23.56.10.png](https://qiita-image-store.s3.amazonaws.com/0/119003/ee391431-c5a6-e3df-7f90-ea31ff3f1794.png "スクリーンショット 2017-12-15 23.56.10.png")

だいたいこんな感じだったっけ、、？

なんにせよ壊れないので**とりあえずやってみるが吉**！！

[![https://gyazo.com/e3224f78481f7c805ed5245e6fdf2616](https://i.gyazo.com/e3224f78481f7c805ed5245e6fdf2616.gif)](https://gyazo.com/e3224f78481f7c805ed5245e6fdf2616)

うごいた！！

## まとめ
回路シミュレーションTinkerCAD Circuitsでもう故障知らずですね！

ちなみにシミュレーションなのでブレボなくてよかったです。そりゃそうか。
![スクリーンショット 2017-12-15 23.52.11.png](https://qiita-image-store.s3.amazonaws.com/0/119003/d9060160-8316-a031-f144-bb4cd191afa6.png "スクリーンショット 2017-12-15 23.52.11.png")


以上！

明日は @m_ando_japan さんですー！
OpenCV 3.3.1のUMatで処理時間の短縮を確認してみた

![lenas.PNG](https://qiita-image-store.s3.amazonaws.com/0/105738/10c48d85-fec1-d5cd-7421-eddde4cd97dd.png)
Lena の検出結果画像　（1/2に縮尺）

#はじめに

* この記事は、[OpenCV Advent Calendar 2017](https://qiita.com/advent-calendar/2017/opencv)  16日目の記事です。
* 予定では、”仮） OpenCV 3.4 RC版で何か” を書く予定でしたが、まだRC版がリリースされていないので変更しました。
* 代わりに、今年のAdvent Calendar でも高速化に関していくつかエントリーされており、特に3日目の記事 [ASUS tinker boardのMali T764をOpenCV 3.3.1のOpenCLで酷使してみる](https://qiita.com/hon_no_mushi/items/e201890dcc78dc0d88f0) を読み気になったので、OpenCL を利用している UMat を試してみた。
* 実は、[4年前にOpenCLを試してみた](https://iwaki2009.blogspot.jp/2013/11/opencv-247opencl-1.html)ことがあったのですが、想像していたよりも使えなかったために、それ以降触れる機会がほとんどありませんでした。

##UMatとは
* UMatは、OpenCV 3.0 から取り入れられた高速化の手法の１つです。[OpenCL をベース](https://github.com/opencv/opencv/wiki/OpenCL-optimizations)としており、OpenCV 2系では、OCLクラスとして実装されていました。

* 3系でもOCLクラスは、実装されていますが、OCLクラスを意識しなくても、利用できるようになっており、["Transparent API" design](https://github.com/opencv/opencv/wiki/opencv3#transparent-api)と呼ばれています。

##テスト環境
マシンスペック

* CPU　Intel(R) Core(TM) i3-6006U CPU @ 2.00GHz
* グラフィックス： Intel(R) HD Graphics 520
とほぼエントリーマシンに近い性能のものです。

ソフトウェア

* ほとんど素に近いWindows10 Home 64bit 
* windwos 版バイナリの OpenCV 3.3.1 ダウンロードして展開
* Visual Studio 2017 community Editionをインストール

今では、OpenCL SDK は、インストールしなくても利用できるようになっているようです。

##テストプログラム
* 今回時間があまりとれませでしたので、OpenCVの定番である顔検出に利用される **detectMultiScale** で処理時間を計測しました。パラメータは、デフォルトのままです。
* CPU 利用の Mat と グラフィックスモジュール利用の UMat を用い、ばらつきを抑えるため10回実行の平均値を求めています。
* また、UMatに関しては、カーネルのコンパイル時間が加算される１回めを計測から外し、また、グラフィックスモジュールへのデータ転送と ch変換の処理時間も別途計測しています。
* 計測対象の画像は、お馴染みのLena、画像サイズは、512 x 512

##ソース
計測プログラムから、関連部分のみ抜粋
インクルード関連

```c++
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
#pragma comment(lib, "opencv_world331d.lib")
```
Matによる10回計測部

```c++
	cv::Mat mat = cv::imread("c:\\tmp\\lena.jpg");
	cv::CascadeClassifier faceCascade("c:\\tmp\\haarcascade_frontalface_alt.xml");

	std::vector<cv::Rect> facesM, facesU;

	cv::TickMeter t1;
	t1.start();
	for (int i = 0; i < 10; i++) {
		faceCascade.detectMultiScale(mat, facesM);
	}
	t1.stop();
```
UMat 最初の計測部。この時、カーネルのバイナリコードがコンパイルされ、メモリにキャッシュされるために、2回め以降は、コンパイルのオーバーヘッドがない。

```c++
	cv::TickMeter t2;
	t2.start();
	cv::UMat umat = mat.getUMat(cv::ACCESS_READ);
	t2.stop();

	t2.reset();
	t2.start();
	faceCascade.detectMultiScaleumat, facesU);
	t2.stop();
```
UMatによる 10計測部

```c++
	cv::TickMeter t3;
	t3.start();
	for (int i = 0; i < 10; i++) {
		umat = mat.getUMat(cv::ACCESS_READ);
	}
	t3.stop();
	
	t3.reset();
	t3.start();
	for (int i = 0; i < 10; i++) {
		faceCascade.detectMultiScale(umat, facesU);
	}
	t3.stop();
```

##計測結果
Mat 10回平均の処理時間

* detectMultiScale 211.374ms 

UMat １回め処理時間

* 作成 0.238522ms 
* detectMultiScale 1196.11ms 

UMat 10回平均の処理時間

* 作成 0.0102297ms 
* detectMultiScale 84.8129ms

##結論
エントリーマシンでも、一部のAPIに限定されるが、従来のソースへの少しの変更点で、高速化の恩恵を受けることが確認できた。

##UMat の使用上の注意
* 一部のAPIしか対応していません。
* 最初の呼び出しでは、カーネルコンパイルのオーバヘッドが生じる
* CPUでの計算結果と一致しない場合がある。
* デフォルトでは、最初に認識されたGPUベースのOpenCLデバイスが使用される。変更できるが簡単ではない


##最後に
明日は、te20 さんの番です。
今回、時間の都合で省いたことをBlogに追記する予定です。
2011/01/14 死を現す色は黒なのか白なのか

昔書いた社内ブログ記事です。
※記事内の"■"には色がつきませんでした。

---

どうも（ｐ・&omega;・ｑ）

チャリティー関係の仕事でモックを作ったのですが、チャリティーって何色なのでしょうね。
明るい緑か、薄くて明るい茶色だと思う人～！？（つ&acute;&forall;｀ノ）＜ﾊｰｲ


こういった色の感覚は、国ごとに違うんですよね。

紫<span style="color: #800080;">■</span>を高貴な色だと称える人もいれば、卑猥な色だと卑下する人も・・
グローバルなサイトを作るときは、色の意味にも気をつけないといけませんね。

+

<a href="http://www.informationisbeautiful.net/visualizations/colours-in-cultures/" target="_blank">Colours In Cultures</a>を見て、だいたい世界共通だな～と思った色はこれ。

怒り　&hellip;　赤<span style="color: #ff0000;">■</span>
寒い　&hellip;　青<span style="color: #0000ff;">■</span>
悪　&hellip;　黒<span style="color: #000000;">■</span>
心臓　&hellip;　赤<span style="color: #ff0000;">■</span>
情熱　&hellip;　赤<span style="color: #ff0000;">■</span>
純粋　&hellip;　白□
休戦　&hellip;　白□

赤は結構世界共通だと思っています。


逆に、真っ二つに別れたっぽいのはこれ。

死　&hellip;　黒<span style="color: #000000;">■</span>（日本など）　白□（その他）
幸運　&hellip;　赤<span style="color: #ff0000;">■</span>（日本など）　緑<span style="color: #008000;">■</span>（その他）
不幸　&hellip;　黒<span style="color: #000000;">■</span>（日本など）　青<span style="color: #0000ff;">■</span>（その他）

誕生を現すのは白が多かったのですが、黒くなって死ぬ国と、死んだとき白に戻る国があるんですね（笑）


「バランスを現す色」とか、思いつかないものもたくさんありましたよｗ

+

もっと参考にしたい人はこちらのリンクなどを。

<a href="http://static.colourlovers.com/uploads/images/color-of-the-year-2010.html" target="_blank">Most Popular Colors of the Year 2010 [infographic]</a>
<a href="http://www.sibagraphics.com/colour.php" target="_blank">The Meaning of Colour in Web Design</a>

+

色って結構重要で、例えばリンクの色が少し違っただけで、クリックされる確率が大きく変わってしまうそうですね。

<a href="http://m-ishikawa.com/blog/2010/06/21/1301/" target="_blank">最適なテキストリンクの色は？ | ウェブ力学</a>
<a href="http://www.gizmodo.jp/2010/10/the-most-powerful-colors-in-the-web.html" target="_blank">Web上で最も強い力を持つ色は？ : ギズモード・ジャパン</a>


そういえば、友達に色覚障害のWebデザイナーがいましたが、リンクの青は区別できるみたいですよ。

<a href="http://www.webcreatorbox.com/tech/design-colorblind-users/" target="_blank">色覚障がい者に配慮したWebサイトの作り方 | Webクリエイターボックス</a>
<a href="http://kachibito.net/software/contrast-a.html" target="_blank">配色のアクセシビリティチェックを手軽に行えるシンプルなカラーツール・Contrast-A - かちびと.net</a>


+

ちなみにチャリティーの色は、<a href="http://www.sibagraphics.com/colour.php" target="_blank">ここ</a>によると、オレンジや、白だそうです。

それではまた。
MeCabのPythonラッパーを書いた話

形態素解析ソフトウェアの[MeCab](http://taku910.github.io/mecab/)をPythonから使うパッケージとしては、[mecab-python3](https://pypi.python.org/pypi/mecab-python3)や[natto](https://pypi.python.org/pypi/natto-py)などがよく使われていますが、どうもWindows環境へのインストールで壁にぶつかることが多いようです。

そこで、WindowsでもUnixでも pip コマンド一発でインストールできるPython用のMeCabラッパーを作成しました。PiPyに登録してあるので、

```bash
pip install mecabwrap
```

でインストール可能です。また、Python2系、3系の両方でテストしています。ソースコードは[GitHub](https://github.com/kota7/mecabwrap-py)に置いています。
なお、MeCabはすでにインストールしてあることが前提です（Windowsなら[公式サイト](http://taku910.github.io/mecab/#install)のインストーラを利用するのが簡単だと思います。Unixなら、`brew`や`apt-get`などがお手軽です）。

## 使い方の紹介

[janome](https://github.com/mocobeta/janome)の直感的なAPIを目指して、`tokenize`関数を実装しています。

```python
from mecabwrap import tokenize

for token in tokenize('すもももももももものうち'):
    print(token)

#すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
#も	助詞,係助詞,*,*,*,*,も,モ,モ
#もも	名詞,一般,*,*,*,*,もも,モモ,モモ
#も	助詞,係助詞,*,*,*,*,も,モ,モ
#もも	名詞,一般,*,*,*,*,もも,モモ,モモ
#の	助詞,連体化,*,*,*,*,の,ノ,ノ
#うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
```

もう少し自由度の高い処理をするために`do_mecab`関数を用意していて、MeCabのオプションを利用することが可能です。

```python
from mecabwrap import do_mecab

out = do_mecab('人生楽ありゃ苦もあるさ', '-Owakati')
print(out)
#人生 楽 ありゃ 苦 も ある さ 
```

入力する文字列が複数ある場合、ループを書く代わりに`do_mecab_vec`関数を用いることができます。

```python
from mecabwrap import do_mecab_vec

ins = ['春はあけぼの', 'やうやう白くなりゆく山際', '少し明かりて', '紫だちたる雲の細くたなびきたる']
out = do_mecab_vec(ins)
print(out)
#春	名詞,一般,*,*,*,*,春,ハル,ハル
#は	助詞,係助詞,*,*,*,*,は,ハ,ワ
#あけぼの	名詞,固有名詞,地域,一般,*,*,あけぼの,アケボノ,アケボノ
#EOS
#やうやう	副詞,一般,*,*,*,*,やうやう,ヤウヤウ,ヨーヨー
#白く	形容詞,自立,*,*,形容詞・アウオ段,連用テ接続,白い,シロク,シロク
#なり	動詞,自立,*,*,五段・ラ行,連用形,なる,ナリ,ナリ
#.....
```

あるいは、結果を一度に取得するのではなく、ジェネレータを用いて一文ごとに取得することも可能です。

```python
from mecabwrap import do_mecab_iter

ins = ['春はあけぼの', 'やうやう白くなりゆく山際', '少し明かりて', '紫だちたる雲の細くたなびきたる']
for ans in do_mecab_iter(ins, '-F%f[6] | ', byline=True):
    print(ans)
    print("----")
#春 | は | あけぼの | EOS
#----
#やうやう | 白い | なる | ゆく | 山際 | EOS
#----
#少し | 明かり | て | EOS
#----
#紫 | だ | ちる | たり | 雲 | の | 細い | たなびく | たり | EOS
#----
```


## 実装の仕組み

このパッケージでは、[subprocess](https://docs.python.org/3/library/subprocess.html) ライブラリを用いて`mecab`コマンドを実行し、結果を取得しています。
単純化すると、下記のようにしてPythonから`mecab`コマンドを利用することができます。

```python
from subprocess import Popen, PIPE

p = Popen(['mecab'], stdin=PIPE, stdout=PIPE)
o, e = p.communicate('すもももももももものうち'.encode())
print(o.decode())
#すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
#も	助詞,係助詞,*,*,*,*,も,モ,モ
#もも	名詞,一般,*,*,*,*,もも,モモ,モモ
#も	助詞,係助詞,*,*,*,*,も,モ,モ
#もも	名詞,一般,*,*,*,*,もも,モモ,モモ
#の	助詞,連体化,*,*,*,*,の,ノ,ノ
#うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
#EOS
```
パッケージでは、この仕組みをベースに、オプションへの対応や、文字コード回りの処理、Python2系への対応などを行っています。


## 処理速度について

厳密な比較はしていませんが、本パッケージは本家の`mecab-python3`より遅いです。特に短い文の場合に差は顕著で、`subprocess`のオーバーヘッドや諸々のエラー処理の比重が大きいためかと思われます。文が長くなるほど差は小さくなる傾向にあるようです。
[Java] Java環境

<p>macOSでJavaのバージョンをどう切り替えていますか？自分は、.bash_profile に以下を定義している。</p>

<pre><code># Java
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
</code></pre>

<p>確認してみよう。</p>

<pre><code>$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home
</code></pre>

関連情報
<a href="https://www.tensorflow.org/install/install_mac"> Installing TensorFlow on macOS </a><br />
<a href="https://qiita.com/advent-calendar/2017/cocoa">Cocoa Advent Calendar 2017</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
Reasonでcss-modules

`Flow`の中身を知るために最近`OCaml`に入門したものです。
昨日`Reason`を初めてちゃんと触ってみて、強く良さを感じたので一コマ埋めさせてもらいました。

さて、`Reason`には`OCaml`の方言でありながら`JavaScript`の既存のエコシステムにそのまま相乗り出来るという特徴があります。

そもそも`bsb`コマンドで生成されるプロジェクトはWebpackを用いてバンドルされていますし、文法からも既存の`JavaScript`の世界観から無理なく入門してこれるように気を使われていることが分かります。
（試しに手元のReasonファイルをJavaScriptファイルとして解釈させてみても、大抵シンタックスハイライトが壊れません）

これによって、普段のアプリケーション開発で使っているような仕組みをほぼそのまま使うことが可能なようです。
今回は`css`設計の救世主である`css-modules`を`Reason`のコードで使ってみたいと思います。

### css-modules関連のモジュールをインストール

まずは`bsb`コマンドでプロジェクトの雛形を作ります

```bash
bsb -init my-project -theme react
```

次にcss-modules関連のモジュールをインストールします
（css-modulesから脱線するので省略しましたが、`postcss-loader`等との併用も当然問題ありません）

```bash
yarn add -D css-loader css-loader extract-text-webpack-plugin
```

設定もいつも通りです

```javascript
  module: {
    rules: [{
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: [{
          loader: "css-loader",
          query: {
            modules: true,
            sourceMap: true,
            importLoaders: 2,
            localIdentName: "[name]__[local]___[hash:10]",
          }
        }, "postcss-loader"],
      }),
    }]
  },
  plugins: [
    new ExtractTextPlugin("style.css"),
  ]
```

いつも通りインストールして`webpack.config`に設定を書くだけですね。

最後にReason(BuckelScript)のFFIを用いてでCSSクラス名のオブジェクトを呼び出します。

```ocaml
[@bs.module] external style : Js.t({..}) = "./style.css";
```

これで`style`には`./style.css`で定義したCSSクラスのオブジェクトが入っているので、あとはそのまま適用するだけです。
いつも通りですね。

ついでに`classnames`で複数のCSSクラスを適用してみたコードを書いてみます。

```ocaml
[@bs.module] external cx : (string, string) => string = "classnames";

let make = (~status, _children) => {
  ...ReasonReact.statelessComponent("MyComponent"),
  render: (_self) => {
    <div
      className=(cx(style##myHead, style##myBody))
    />
  }
};
```

以上です。
ほとんど特別なことをせずに既存のJSライブラリの提供する仕組みが使えてしまいました。

個人的には、静的型付けを前提としない`JavaScript`に適切かつ健全に静的型付けをしようと試みた結果、Flowは難しくなってしまっていると思っているので、`JavaScript`の文法を強く残した`Reason`には希望を感じます。同僚にも勧めやすいし。

2018年は`Reason`ですね。
では。
tmuxにプラグインを導入する-2~install,uninstall(Using TPM)編~

## 目次

1. TPMの導入 -> [tmuxにプラグインを導入する-1](https://qiita.com/Cj-bc/items/7227c45cdfc86a927b44)
2. TPMでのinstall,uninstall(本編)
3. おすすめプラグインは -> [tmux-おすすめプラグイン](https://qiita.com/Cj-bc/items/9ecf9dcc334c6e50ce5c)

# Pluginをinstallする
 1. 新しいプラグインを、`.tmux.conf`に次の様式で記述する  `set -g @plugin '...'` [^1]
 2. tmuxを実行し、`prefix`[^2]+`I(大文字。Installの頭文字)`を押すことで、pluginがcloneされ、soureされました！

# Pluginをuninstallする
 1. pluginを、`.tmux.conf`のリストから消すか、コメントアウトします。
 2. tmuxを実行し、`prefix`[^2]+`Alt`+`u(小文字。uninstallの頭文字。)`を押すことで、pluginを削除できます。  
もしくは、pluginは全て`~/.tmux/plugins/`に管理されているので、そこからpluginを探し出して削除することでuninstallすることもできます

# Keybinds

 * `prefix`[^2]+`I` --> *'I'nstall*.　新たなpluginsをインストールします。また、tmux環境のリフレッシュも行います。
 * `prefix`[^2]+`U(大文字)` --> *'U'pdate*.　pluginのアップデートを行います。
 * `prefix`[^2]+`alt`+`u(小文字)` --> .tmux.confのリストにないpluginをremove/uninstallします


---
[^1]: <details><summary>'...'について</summary>次の書き方が使用できます。
 - 'github_username/plugin_name'
 - 'git@github.com/user/plugin'
 - 'git@bitbucket.com/user/plugin'`
</details>
[^2]: デフォルトでは`Ctrl+b`です
tmuxにプラグインを導入する-1~Tmux Plugin Manager導入編~

## 目次

1. TPMの導入(本編)
2. TPMでのinstall,uninstall -> [tmuxにプラグインを導入する-2](https://qiita.com/Cj-bc/items/15eac4e69ecb33052d1b)
3. おすすめプラグインは -> [tmux-おすすめプラグイン](https://qiita.com/Cj-bc/items/9ecf9dcc334c6e50ce5c)

# TPM(Tmux Plugin Manager)とは
 tmuxのプラグインを管理するためのツールで、記事執筆時での最終更新日は2017/09/02
 URL: https://github.com/tmux-plugins/tpm (この記事は、ここのREADMEの和訳です。)

# 必要環境(自分の環境)
 * Linux,OSX,Cygwinは動作確認済みとのこと(macOS Sierra 10.12.6)
 * tmux 1.9以上(2.6)
 * git (2.14.3)
 * bash (3.2.57)

# TPMをインストールする
 1. Gitからcloneしてくる。  
    `$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
    `
 2. ~/.tmux.confの**末尾に**、以下を追加する  

```
#List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'

# Other examples:
# set -g @plugin 'github_username/plugin_name'
# set -g @plugin 'git@github.com/user/plugin'
# set -g @plugin 'git@bitbucket.com/user/plugin'
 
# Initialize TMUX plugin manager (keep this line at the very bottom of   tmux.conf)
run '~/.tmux/plugins/tpm/tpm'  
```
 3\. Tmuxに.tmux.confを読み込ませる
  `$ tmux source ~/.tmux.conf`
  で、終了

# Pluginのインストール・アンインストール
  ページを分けたのでそちらへ -> [tmuxにプラグインを導入する-2](https://qiita.com/Cj-bc/items/15eac4e69ecb33052d1b)
ラズパイでステルスのSSIDへ内蔵WiFiで接続する

#  背景
私もそうでしたが、ステルスのSSIDへWi-Fi接続する方法はググれば出れども、まちまちだし、どれやっても繋がらないということがありました。
ですので、一旦メモを残そうと思った次第。
[予告編の参考URL](https://qiita.com/twissyorg/items/73d66d9a7211a34f8620)の[一番先頭](http://junsumida.hatenablog.com/entry/2014/11/24/160839)の手順がまさしくでした。ありがとうございます。
他のURLにしか書いていない部分をマージすると僕の欲しい答えでした。
要するに今回はそのまとめ記事の位置付け。

#  大まかな手順のおさらい
1. WPAクライアントを使ってSSIDとパスフレーズを生成します
2. 上記1.で標準出力されたテキストをベースにwpa_supplicant.confファイルをステルスモードにチューニング
3. interfaceファイルのパーミッション変更して流出防止
3. interfaceファイルをwpa_supplicant.conf、wlan0のみ利用、DHCPモードにチューニング

#  ターミナルでの実行を繋げるとこんな感じ
```
pi@raspberrypi:~$ wpa_passphrase (実際のStealthSSID) (パスフレーズ)

network={
　　　　　　　　ssid="(実際のStealthSSID)"
    #psk="(パスフレーズ)"
    psk=f04360e2d02207c61731c779a9775afc186f852d94bcac8e8c8bdf11686884a8
}

pi@raspberrypi:~$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf 

network={
　　　　　　　　ssid="(実際のStealthSSID)"
    psk=f04360e2d02207c61731c779a9775afc186f852d94bcac8e8c8bdf11686884a8
    scan_ssid=1 # これがステルスモードの場合必須
    proto=RSN # RSNとはWPA2のこと今の時代はこれが通常でいいと思います
    key_mgmt=WPA-PSK # APによって必要 今の時代はこれが通常でいいと思います
    pairwise=CCMP # AES だそうです。これつけるとダメなルーターもありました。
    group=CCMP # AES だそうです。これつけるとダメなルーターもありました。
}

(esc):wq

pi@raspberrypi:~$ chmod 0600 /etc/network/interfaces

pi@raspberrypi:~$ sudo vi /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

(esc):wq

pi@raspberrypi:~$ sudo reboot

```

#  要ポイント
- pairwise、groupパラメータを入れるとダメなルーターがありました
- 今の時代はPSKが標準と思っていいでしょう、というかこれ以外は精神的にダメでしょう
- wlan1があると安定しないらしいですが、チェックしていません
- 一度、ネットワークが切断されると再接続できないようですが、原因未特定
   - 省電力モードは不安定要素らしいが、結局繋がらなければ不安定は変わらない
   - 自動復旧は起動シェルを実装しないとダメらしい（未確認）
   - 結局、内蔵Wi-Fiはプアなんで外付けUSBの無線アダプタが必要？（未確認）
2010/12/17 CSSだけでWebページを作る方法

昔書いた社内ブログ記事です。

---

どうも（＠・&omega;・＠）
CSSには `:before` `:after` という**擬似要素**がありますよね。

英語のページで見ると擬似要素は「pseudo elements」なのですが、pseudoというスペルを見ると目がイガイガするのは私だけでしょうか。

この擬似要素を使うと、要素内の文字列の前後に文字や画像の追加ができます（ｐ・&omega;・ｑ）</div>

+

例えばこのDIV要素の

```html:HTML
<div id="letter">引っ越しました。</div>
```

前後に表示する文字を指定してあげると

```css:CSS
#letter:before {
 content: 'こんにちは。';
}
#letter:after {
 content: 'それではまた。';
}
```

[こんな風に表示されます。](https://jsfiddle.net/sayb7381/)

ページの見出しの左に画像を付けたり、「次のページ&rarr;」の「&rarr;」を付けたり、あるいはボックスエリアの影の画像を付けるのに使ったり・・

かなり応用範囲が広く便利な機能です。

+

そんな `:before` `:after` を使うと、CSSだけでWebページを作成することができます。

劇的（笑）

[デモ（jsFiddle）](https://jsfiddle.net/Lsguwe3a/)

最近のブラウザは賢いので、`<html>` や `<body>` が無くても、画面を表示するときに補完してくれるんですね。いやはや。


このCSSすらをHTMLファイルに書かずにできる方法があるのですが、それにはPHPでHTTPヘッダーを指定しないといけないので、こちらの情報元のサイトのデモを見てみてください。

[デモ](http://mathiasbynens.be/demo/css-without-html)
[Using CSS without HTML | CSS-Tricks](https://css-tricks.com/using-css-without-html/)

本当に一行もソースが書かれていないHTMLファイルです（ノﾟдﾟノ）
ダウンロードしてみるとわかります。

これを利用すれば、HTMLが空っぽのWebサイトを作ることができますね！
そんな需要はないと思いますが（笑）