OmniAICreator/Qiita-1.07M huggingface dataset:
BigQueryでJsonカラム内の配列を集計するSQL


SQLでは扱いJSON型の文字列ですが、BQではJSON関数、UNNEST関数、UDFを組み合わせて使うことでクエリ一本で配列内の集計も出来ます。

## テーブル例

テーブル名 : order_table

| order_id | order_detail |
| ---    |   ----     |
| 1       | {"user_id":1,"order_items":[{"item_id":"A","name":"みかん","price":"80","quantity":2,"order_date":"2017-01-01"},{"item_id":"B","name":"りんご","price":"100","quantity":1,"order_date":"2017-02-01"},{"item_id":"C","name":"水素水","price":"300","quantity":2,"order_date":"2017-04-01"}]} |

### json型のカラム

```json:json型のカラム
{
    "customer_id": 1,
    "order_items":[
        {
            "item_id": "A",
            "name": "みかん",
            "price": "80",
            "quantity": 2,
        },
        {
            "item_id": "B",
            "name": "りんご",
            "price": "100",
            "quantity": 1,
        },
        {
            "item_id": "C",
            "name": "水素水",
            "price": "300",
            "quantity": 2,
        }],
    "order_date": "2017-01-01"
}
```

## SQL

```sql:全体
CREATE TEMPORARY FUNCTION str_to_array(s STRING)
RETURNS ARRAY<STRUCT<item_id INT64, name STRING, price INT64, quantity INT64>>
LANGUAGE js 
AS "return JSON.parse(s);";

WITH flat_order_detail
AS(
SELECT
  str_to_array(JSON_EXTRACT(order_detail, "$.order_items")) as order_items
from
  `order_table`
)

select
    fod.item_id
  , sum(fod.price) * sum(fod.quantity)
from
  order_table o
  , unnest(flat_order_detail) fod
group by 1
order by 1
;
```

## 簡単な説明

SQLではSTRING型からARRAY型への変換はできなかったため、UDFを使う必要があります。

### UDFの定義

```
CREATE TEMPORARY FUNCTION str_to_array(s STRING)
RETURNS ARRAY<STRUCT<item_id INT64, name STRING, price INT64, quantity INT64>>
LANGUAGE js 
AS "return JSON.parse(s);";
```

#### 1. CREATE TEMPORARY FUNCTION str_to_array(s STRING)

セッション内でのみ有効なUDFを作成します。

#### 2. RETURNS `ARRAY<STRUCT<item_id INT64, name STRING, price INT64, quantity INT64>>`

UDFの戻り値ですが、`STRUCT<カラム名 型>`で取り出したい配列内のオブジェクトのデータ型を定義します。

#### 3. LANGUAGE js 

UDFは今のところjsのみ対応のようです。

#### 4. AS `"return JSON.parse(s);"`;

関数の実体です。シンプルな内容だったので１行で書いてしまいましたが、`"""`で囲めば複数行に渡って複雑な関数を書くことも可能です。

### SQL（with句）

```sql:配列をフラット化する
WITH flat_order_detail
AS(
SELECT
  str_to_array(JSON_EXTRACT(order_detail, "$.order_items")) as order_items
from
  `order_table`
)
```

読みにくくなりやすいのでWITH句を使うことを推奨します。

ポイントは

`str_to_array(JSON_EXTRACT(order_detail, "$.order_items")) as order_items`

この部分ですが'JSON_EXTRACT関数'で文字列として`order_items`の配列部分を取り出しています。
取得した文字列を先述のUDFを使ってARRAY型に変換します。
`CAST(JSON_EXTRACT(order_detail, "$.order_items"), ARRAY<>)`は出来ませんでした。

### SQL（集計部分)

```sql:集計
select
    fod.item_id
  , sum(fod.price) * sum(fod.quantity)
from
  order_table o
  , unnest(flat_order_detail) fod
group by 1
order by 1
;
```

UNNEST関数を使ってARRAYを展開することでGROUP BYによる集計が可能になります。
GNU Emacs 25.3 リリース

2017年9月11日、GNU Emacs 25.3 がリリースされた。

”悪意のある任意のLispコードを実行可能な脆弱性の修正”の緊急リリースとのこと。

https://www.gnu.org/software/emacs/

https://www.gnu.org/software/emacs/news/NEWS.25.3

ビルドしました。

https://document.wurlyhub.com/html/NTEmacs.html
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 第三章 モデルと実装を結びつける4

# モデルとView
> 理論上は、システムの根底に何があっても、ユーザに対しては任意のかたちで見せることができるだろう。

モデルがどうであっても、Viewは自由に実装することはできる。理論上は。
ただし、

> ユーザインターフェイスの中にドメイン以外のモデルの幻想を作り出そうとすれば、その幻想が完璧でない限り、混乱が生じるものだ。


本のIEお気にいりの例にあるような極端な体験はないのですが、モデルの構造とビューの構造が違うように実装されていたことはあるかも。。。これも混乱が生じる要因になるかもしれませんね。。。

> モデルが明らかになれば、ユーザはソフトウェアの潜在能力にもっと触れられるようになり、ふるまいは一貫した予測可能なものになる。

ビューによってユーザにもモデルをさらけ出す。
neural styleによる画風変換

neural styleを実装しました。
下記にてダウンロードできます。

```python
pip install Optimizer_with_theano
```

API化しているので実装は簡素です。

```python
import Optimizer_with_theano.API as API

neural = API.neural_style(content_img_path=None,
                          style_img_path=None,
                          out_img_path=None)
neural.build()
neural.generate_image()
```
content_img_path、style_img_path、out_img_pathにそれぞれコンテンツ画像のパス、スタイル画像のパス、出力画像を格納するディレクトリパスをそれぞれ入力します。何も入力しない場合はカレントディレクトリにimg_{}.jpg({}は番号)の名前でサイケデリックなインコが出力されます笑

出力結果：
![img_15.jpg](https://qiita-image-store.s3.amazonaws.com/0/85968/d304f301-ba2f-9dbd-4085-ae13c4b64912.jpeg)
python with pyenv and venv 

how to setup with python env
------

# setup python version with pyenv

```
$ mkdir test
$ cd !$
$ pyenv local 3.6.2
$ python -V
```

# setup virtualenv with vnev
```
$ python -m venv .
or
$ virtualenv .
$ source bin/activate
.
.
.
$ source bin/deactivate
```
[AWS]EC2初期設定でとりあえず設定したほうがよいもの

AWSのEC2を利用するときに基本として設定するものをまとめる。
WebサーバでもBatchサーバでも以下をとりあえず以下を設定しておくとよいのではないでしょうか。

### [設定する内容]
- マシン起動時スクリプト（per-boot) 　
    - SWAPファイル設定
    - HOST名設定
- ファイルディスクプリタ設定、スレッド設定
    - limit.conf
    - sysctl.conf

##### [マシン起動時スクリプト（per-boot)]

SWAPファイル設定を起動時に実施。EC2はデフォルトでSWAP設定がない。
（ほぼ参照：http://dev.classmethod.jp/cloud/ec2linux-swap-bestpractice/）

```bash:create_swap.sh
#!/bin/sh

SWAPFILENAME=/swap.img
MEMSIZE=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
MEMSIZE_D=`expr $MEMSIZE \* 2`
MEMSIZE_H=`expr $MEMSIZE / 2`

if [ $MEMSIZE -lt 2097152 ]; then
  SIZE=${MEMSIZE_D}k
elif [ $MEMSIZE -lt 8388608 ]; then
  SIZE=${MEMSIZE}k
elif [ $MEMSIZE -lt 67108864 ]; then
  SIZE=${MEMSIZE_H}k
else
  SIZE=4194304k
fi
fallocate -l $SIZE $SWAPFILENAME && chmod 600 $SWAPFILENAME && mkswap $SWAPFILENAME && swapon $SWAPFILENAME
```

HOST名設定を起動時に実施　EC2のタグ:NameがそのままHost名になるため、SSHログイン後の判別が簡単。

```bash:set_hostname.sh
#!/bin/sh

REGION=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone/ | sed 's/.$//'`

INSTANCE_ID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`

NAME_TAG=`/usr/bin/aws ec2 describe-instances --region ${REGION} --instance-ids ${INSTANCE_ID=} --query 'Reservations[].Instances[].Tags[?Key==\`Name\`].Value' --output text`

INSTANCE_NAME="${NAME_TAG}"

hostname ${INSTANCE_NAME}
sed -i -e "s/^HOSTNAME=.*\$/HOSTNAME=${INSTANCE_NAME}/g" /etc/sysconfig/network
```

##### [ファイルディスクプリタ設定、スレッド設定]

FD設定。大体やり忘れてアプリケーション実行時に足りなくなる。
また、スレッド数も同じことになるので、kernel.threads-maxで設定しておく。

```/etc/security/limits.conf
#以下を末尾に追加
* soft nofile 65536
* hard nofile 65536
```


```/etc/sysctl.conf

fs.file-max = 100000
kernel.threads-max = 100000
```
vendor/assetsをAssetPipelineにファイルを追加する方法（初心者向け）

たとえばサードパーティのファイルはvendor/assetに設置する。
vendor/assets/imagesに設置されたimage.jpgを読み込みたい場合、

config/assets/initializersに
Rails.application.config.assets.precompile += %w( image.jpg )
と追記する。（コメントに書いてある。）
これでviewで<%= image_tag 'image.jpg' %>などと出来るようになる。
上の行を加えたら必ず新しくrails s。

スマートなやり方として、
```
Rails.application.config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
```
と指定すると、語尾にjpgなどがつく大体の写真を一度に指定できる。

ちらみに
Rails.application.config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
Rails.application.config.assets.precompile += %w(*.js *.css)
のように二行で書いても問題ない。（二行で書く意味はない。）

app/assets/javascripts/application.jsなどにrequireするのが簡単にアセットパイプラインに追加する方法。
ただすべてのページでファイルが読み込まれてしまい、アプリが遅くなる。
必要なファイルのみを読み込みたい場合は個々で設定する必要がある。
WordPressをインストールする（CentOS7.4）

WordPressを導入したいのでここに手順を記載したいと思います。
以下記事に沿って進めます。
https://webkaru.net/linux/wordpress-install-centos/

**導入したいバージョン**
https://ja.wordpress.org/releases/
9/16時点の最新は4.8.1でした。
**必要なソフトウェア**
CentOS 7.4.1708 (Core) 
php
Apache
mariadb
## phpの導入
導入から初期設定まで

```shell-session
$ yum install php php-mysql
$ php -v
PHP 5.4.16
$ cp /etc/php.ini /etc/php.ini.org
$ vi /etc/php.ini
date.timezone =
→date.timezone = "Asia/Tokyo"
```

## Apacheの導入
phpインストールすれば依存pkgとして入るのでインストールは省略。ポート開放とサービス起動のみ。

```shell-session
$ firewall-cmd --add-port=80/tcp --zone=public --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-all --zone=public
$ systemctl start httpd
$ systemctl enable httpd
$ systemctl list-unit-files | grep httpd
```

## mariadbの導入
インストールから初期設定まで。公式のリポジトリにもあるけどクライアント含めてこちらを利用する。

```shell-session
$ vi /etc/yum.repos.d/mariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
$ yum install MariaDB-server MariaDB-client
$ systemctl start mariadb
$ systemctl enable mariadb
$ mysql -u root
mysql> update mysql.user set password=password('<PASSWORD') where user = 'root';
mysql> flush privileges;
mysql> exit;
$ mysql -u root -p
mysql> create database wp;
mysql> show databases(); 
```

## WordPressの導入
ファイル取得とApacheの設定。

```bash
$ cd /tmp
$ wget http://ja.wordpress.org/wordpress-4.8.1-ja.tar.gz
$ mkdir /var/www
$ tar -zxvf wordpress-4.8.1-ja.tar.gz -C /var/www/
$ cd /var/www
$ chown -R apache:apache *
$ cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org 
$ vi /etc/httpd/conf/httpd.conf
DocumentRoot "/var/www/wordpress"
<Directory "/var/www/wordpress">
 AllowOverride All
</Directory>
$ systemctl stop httpd
$ systemctl start httpd
```

インストールしたサーバの80番ポートにアクセスして画面からセットアップ開始。（所要時間90分）

### 2020/02/03 時点
いつか変更が必要な箇所があったので追記いたします。

**PHP7.2のインストール**
https://qiita.com/owlbeck/items/20f3e5402cb782f6291e

**WordPress 5.3.2**
https://ja.wordpress.org/latest-ja.tar.gz
mitmproxy に独自の content view を追加する

## content view とは

[mitmproxy](https://mitmproxy.org/) はリクエスト・レスポンスの中身を表示する際に、表示する形式を選ぶことができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10713/efa01d28-fca9-a518-b42c-58a4a54a3d10.png)

この形式ごとに表示する仕組みを mitmproxy では **content view** と呼びます。

html, css, json など基本的なものは標準で用意されています。

## 独自の content view を作る
mimproxy はPythonで拡張できるので、オリジナルの **content view** も作れちゃいます！

[公式のgithubリポジトリに実例がある](https://github.com/mitmproxy/mitmproxy/blob/master/examples/simple/custom_contentview.py)
ので、そのコードを例に解説します。

この例は**「リクエスト・レスポンスの中身の大文字小文字を入れ替えて表示」**というものです。


```python:custom_contentview.py
from mitmproxy import contentviews


# contentviews.View を継承したクラスを作る
class ViewSwapCase(contentviews.View):
    name = "swapcase"

    # CUIで起動した際に、この表示を適用するショートカットキーを指定
    prompt = ("swap case text", "z")

    content_types = ["text/plain"]

    # ここにメインの中身書き換え処理をいれる
    # data: リクエスト・レスポンスの中身
    # metadata: metadata["headers"] でHTTPヘッダを見ることができる
    def __call__(self, data, **metadata):
        return "case-swapped text", contentviews.format_text(data.swapcase())


view = ViewSwapCase()


def load(l):
    contentviews.add(view)


def done():
    contentviews.remove(view)
```

## load と start
自分の手元のmitmproxyではこのままでは上手く読み込めませんでした。
mitmproxyのソースコードを見て色々やった結果 `def load(l)` を `def start()` に変えることで読み込みに成功しました。

```diff
-def load(l):
+def start():
    contentviews.add(view)
```

mitmproxyのgithubをみると、途中で `start` から `load` に書き換えられているので、動かしているバージョンの違いみたいですね。

- 
 [addon loader: add boot_into, which replaces returning from start()](https://github.com/mitmproxy/mitmproxy/commit/65f0885bd6809966f694d1ffb965401b8ab2cffc)




## 拡張スクリプトを入れた状態で起動する

`mitmproxy` （または `mitmweb`, `mitmdump`）コマンドの引数に `-s` をつけてスクリプトファイルのパスを追加すればOKです。

自分は Windows 環境で `mitmproxy` が使えないため `mitmweb` を使ってます。

```
mitmweb -s custom_contentview.py
```

これで、リクエスト・レスポンスの形式選択に **swapcase** が追加されていたら成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10713/9607482b-bfa0-9bac-3f8a-7725286ff715.png)


## 参考リンク

- 
 [Overview — mitmproxy 2.0.2 documentation](http://docs.mitmproxy.org/en/stable/scripting/overview.html)
Debian Stretch を iPXE と IPMI Serial-over-LAN 経由でインストールする

自分用メモ

# PXE サーバの設定

## isc-dhcp-server の設定

```
  next-server 192.168.52.1;
  filename "pxelinux.0";
```

## tftpd-hpa の設定

```
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/kouhei/tftproot"
TFTP_ADDRESS="192.168.52.1:69"
TFTP_OPTIONS="--secure"
```

# debian イメージ

```
wget http://ftp.nl.debian.org/debian/dists/stretch/main/installer-amd64/current/images/netboot/netboot.tar.gz
```
を展開する。

## ttyS1, 19.2kbpsで設定
`debian-installer/amd64/boot-screens`の使いそうな`.cfg`項目の bootparam を `append console=ttyS1,19200n8`にする。

## syslinux.cfg
```
serial 1 19200
default linux
label linux
say Now booting the kernel from SYSLINUX...
kernel debian-installer/amd64/linux
append console=tty0 console=ttyS1,19200n8 initrd=debian-installer/amd64/initrd.gz
```

# IPMI
## Console Redirect設定
ExpressScope か iDRAC 経由で COM2 に Console Redirect. 19.2kbps.

## SOL接続
```
ipmitool -I lanplus -H foo -U user -P pass sol set non-volatile-bit-rate 19.2 1
ipmitool -I lanplus -H foo -U user -P pass sol set volatile-bit-rate 19.2 1
ipmitool -I lanplus -H foo -U user -P pass sol activate
```

## 電源操作
```
ipmitool -I lanplus -H foo -U user -P pass chassis bootdev pxe
ipmitool -I lanplus -H foo -U user -P pass power on
```

# インストール
インストーラ中でSSHサーバをインストールすること

# 追記: EFI boot
あたらしめのサーバだとEFI bootが必須だったりする。grub efiイメージを送り込んでやる。

## isc-dhcp-server
```
  filename "bootnetx64.efi";
```
## tftproot
```
cd tftproot
ln -s debian-installer/amd64/bootnetx64.efi
ln -s debian-installer/amd64/grub
ln -s debian-installer/amd64/grub/grub.cfg
```
## grub.cfg
```
serial --unit=1 --speed=19200
terminal_input serial
terminal_output serial
menuentry 'Install' {
    linux    /debian-installer/amd64/linux console=tty0 console=ttyS1,19200n8
    initrd   /debian-installer/amd64/initrd.gz
}
```
アプレットからアプリケーションへの書き換え


# AppletクラスからFrameクラスへの変更
http://wisdom.sakura.ne.jp/system/java/awt/Gjava33.html で紹介されているような単純な方法で移行できない場合の，アプレットをアプリケーションへ書き換える方法です。
継承するクラスをAppletからFrameに変更し，mainメソッドを持つクラスを作ってその中からFrameのinitメソッドを呼び出す，基本的にそれだけです。
下の例は，継承するクラスをAppletからFrameに変更したクラスFrameAppletをアプリケーションとして動かすmainメソッドの例です。
ウィンドウの閉じるボタンで終了する部分を書き加えています。
setBoundsのx，y，width，heightは任意の整数に置き換えて下さい。

	public static void main(String [] args )
	{
		FrameApplet frame = new FrameApplet();

		frame.init();
		frame.setBounds( x, y, width, height );

		frame.addWindowListener(
				new WindowAdapter() {
					public void windowClosing(WindowEvent e)
					{ System.exit(0);}
				}
		);

		frame.setVisible(true);
	}
# この知識を得た顛末
2005年に，仕事関係で公開するプログラムをJavaアプレットで作りました。
jarとhtmlを配布して，ローカルに置いてもらって実行する形です。
当時はWindowsはXPの時代で，まだ98も使われてました。
Macも含め，スキルもいろんな人が使うことを想定し，インストールフリー，プラットフォームフリーがよいと思い，アプレットで作りました。
しかし，アプレットはどんどん肩身が狭くなり，使用するには却ってスキルが必要になってしまいました。
アプリケーションに書き換えようと思いながら，アプレットとしても特殊な作り方をしていた（スキル不足でスマートなやり方がわからず）ため，どうしていいかわからず放置していました。
通常は，mainメソッドを使って簡単にできる (http://wisdom.sakura.ne.jp/system/java/awt/Gjava33.html)
ようですが，特殊な作り方，具体的には，2つのクラスを同時に動かしてお互いに通信させており，単純にこの方法は使えませんでした。
しかし今回，重い腰を上げてやってみたところ，思いの外あっさりとできてしまいました。
Javaの，プリミティヴなクラスから継承していろんなクラスができている構造のメリットがよくわかりました。
SDKがオープンソース化したステレオカメラが市販されている

　画像認識分野の開発速度の進展は激しい。

### **OpenCVがもたらしたもの**
　OpenCVに代表されるオープンソースは、画像認識技術を開発し続けることができる限られた組織のものから画像認識を使いこなそうとする個人（企業の中で働く人も含む）のものへ変えてしまった、
　そして、多数の人々の手でメンテナンスされて最適化されていることは、ある時点での企業の開発済みコードをどんどん陳腐化させる力となっている。
　企業の中の個人の場合も、所属部署を離れると同じ会社の中でさえ（それが自分ひとりで開発したものであっても）所属部署で開発したソースコードを利用できなくなるのが大半だろう。そのため、企業での開発コードも陳腐化のリスクを持ち続けている。
　そういった状況の中で、オープンソースというのは、職業人としてのソフトウェア技術者を、ソフトウェアを開発し続けることができる自由をもたらしていると言えるのだろう。

### **OpenCVと同等以上でなければ意味がない。**
　ステレオ計測は、古くからある画像技術の一つだ。独自開発するならば、OpenCVにあるコードよりも性能がなくては意味がない。OpenCVがGPU対応していることや、OpenCV互換のライブラリがFPGA対応していることも考量に入れよう。

　そのような状況においてステレオカメラモジュールを作って販売するには、既存のOpenCVと同等以上の性能と使いやすさを提供しない意味を成さない。
### **OpenCVと同等以上の移植性、ターゲットデバイスでの最適化のしやすさが求められる。**

　Windows、Linux(PC, Arm)、など複数のターゲットで動作することもOpenCVと同等以上を求める上で必要になってくる。
　さらには、ターゲットデバイスに固有の最適化ができることも必要になってくる。
　そうすると、ステレオ計測のソースコードのオープンソース化というのが、自然な延長線上に見えてくる。

### **オープンソース化することでステレオカメラハードウェアの利用可能性を高める**
 ソースコードをオープンソース化することで、WindowsのOSのバージョンが変わっても、ステレオカメラハードウェアが利用できなくなるというリスクは小さくなる。ARM系のCPUでのGPUを含む最適化の可能性などがステレオカメラハードウェアの利用者側の力次第でいくらでも可能性がでてくる。例えばRaspberryPiのGPUを数値計算のためのGPUとして活用することとか、ZYNQデバイスのFPGAを利用してステレオ計算を高速化するなど、利用者の力次第で可能性は変わってくる。


### **SDKをオープンソース化したステレオカメラモジュール**
SDKのオープンソース化
(MIT License)
http://ovrvision.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/8ef8d98d-0e5b-ff3c-d63d-7462f245efd8.png)


### **利益の源泉は他社に追随させないハードウェアへ**
これらの結果、利益の源泉は他社が容易に追随できないハードウェア、またこれらを組み合わせたシステムになる。
ソフトウェアで収益を上げようとする企業は、そのソフトウェアの手法が、他者によってオープン化可能性があることを念頭に戦略を組む必要がある。

この企業の場合
「ARやVRと組み合わせて使うことを前提としたステレオカメラ」という点に強い独自性がある。
そのハードウェアの利用を拡大して、他社が容易に追随できないハードウェア、またこれらを組み合わせたシステムの分野で利益を上げようとしているのだろうと推測する。

サポートしているOS、言語、ライブラリの幅が広い。
これならば、気に入った開発のしやすいOS・ライブラリで作っておいてから、Unityのゲーム化することも可能だろう。

http://ovrvision.com/product/


参考
[USB3.0 カメラについて調査中](https://qiita.com/nonbiri15/items/1b2123b76e8b6b88fe28)
[市販 Stereo Cameraについて調査中](https://qiita.com/nonbiri15/items/d341e68f9aa9345211a2)


追記：
ステレオ計測に対してパターン光を投影する場合には、受動的なステレオ計測と違ってきます。
受動的なステレオ計測の弱点を、パターン光によって補えるためです。
そのような可能性をいれこむ際には、OpenCVのライブラリそのままではなくて、更に追加のライブラリを必要とすることでしょう。

- 被写体との距離
- 視野角
- 画素数
- 奥行きの分解能
- フレームレート
の組み合わせで、どういう用途に対して価値をもつステレオカメラなのか、開発者はそれを明確にして開発することです。


-----------------------
参考情報
ROS [How to Calibrate a Stereo Camera](http://wiki.ros.org/camera_calibration/Tutorials/StereoCalibration#:~:text=How%20to%20Calibrate%20a%20Stereo%20Camera)
[Survey] Kaggle - Quora 14位解法まとめ

Kaggle - Quora Question Pairs[^1]の14位解法[^2]の調査記事です．

Author: Wojtek Rosinski
Title: 14th Place Solution - Code
Kaggle Discussion: https://www.kaggle.com/c/quora-question-pairs/discussion/34549
Code: https://github.com/Wrosinski/Kaggle-Quora

## 特徴量

### Data Encoding

- Textacy[^5]を用いたテキストクリーニング
- 品詞解析
- ステミング
- NER Encoding

### NLP

- カーネル上の特徴量(by Abhishek[^6], SRK[^7] [^11], Jared Turkewitz[^8], the_1owl[^9], Mephistopheles[^10]など)
- LSIやLDA, tSVD
- Word2Vec
- Doc2Vec
- 様々な距離や類似度
- テキスト関連の特徴量
- KNNを用いた特徴量

### リーク情報

- Jared Turkewitz's frequency features
- NetworkX features

## モデル

- XGBoost & LightGBM
- Decomposable Attention[^3](SpaCy[^4])
- LSTM
- MLP

## Stacking

- sklearn modelのアンサンブル
- LightGBMでStacking
- spacyの最小化関数を用いてアンサンブルに対する重みを算出

## References

[^1]: Kaggle, [Quora Question Pairs](https://www.kaggle.com/c/quora-question-pairs), 2017.
[^2]: Rosinski, [14th Place Solution - Code](https://www.kaggle.com/c/quora-question-pairs/discussion/34549)
[^3]: Parikh et al., [A Decomposable Attention Model for Natural Language Inference](https://arxiv.org/abs/1606.01933), 2016.
[^4]: spacy, https://github.com/explosion/spaCy/tree/master/examples/keras_parikh_entailment
[^5]: charbeat-labs, [textacy](https://github.com/chartbeat-labs/textacy)
[^6]: radder, [Abhishek's features](https://www.kaggle.com/c/quora-question-pairs/discussion/31284)
[^7]: SRK, [Simple Leaky Exploration Notebook - Quora](https://www.kaggle.com/sudalairajkumar/simple-leaky-exploration-notebook-quora)
[^8]: Jared Turkewitz, [Magic Features (0.03 gain)](https://www.kaggle.com/jturkewitz/magic-features-0-03-gain)
[^9]: the_1owl, [Matching ¿Que? for Quora - End to End 0.33719 PB](https://www.kaggle.com/the1owl/matching-que-for-quora-end-to-end-0-33719-pb)
[^10]: Mephistopheles, [0.29936 solution](https://www.kaggle.com/c/quora-question-pairs/discussion/32313)
[^11]: SRK, [Some interesting solutions from the web](https://www.kaggle.com/c/quora-question-pairs/discussion/30260)
[ まつもとゆきひろ氏 ]若手エンジニアの生存戦略

エンジニアになるのは10月からですが、参加してきました。

以下素人なりに、自分なりの解釈でザックリ、まとめたいと思います。


## 以下、本日の内容まとめたものになります。


# まつもとゆきひろ
皆様ご存知、Rubyの開発者です。

# 導入

ロールモデルの生存戦略は人によって違う。ただ、抽象化して当てはめることはできる。

成功者のパターン学習により、成功に近づく。

スタートアップ成功者共通の特質 : パターン認識能力

バタフライ・エフェクト : 些細な違いのインフルエンスが結果を大きく変える。

世の中のだいたいのHowTo本は美化されている。パターンとして認識し実行する程度にとどめておく。

# まつもとさんの略歴

`12歳でpcを触る。ボードマイコンに遭遇。
15歳でポケコン( ４００行制限、ユーザー定義関数なし、変数は一文字 )。pcについてわかってくるようになる。
「pascal入門」に出会う（ 当時で言うところのC言語 ）、ひたすら写経
世の中の、目的に沿ってデザインされた様々なプログラミング言語に興味を持つ。
大学に進学。コンピュータサイエンスを学ぶ。当時からプログラミング言語を作りたいと言う欲求はあった。研究室は言語開発でなく、コンパイルについて。
卒業後、東京で働きたくなかった。鳥取→筑波→？
浜松に就職。同期200人、CS専攻6人のバブル採用。
鶏口牛後。ソフトウェアがどうあるべきか若いうちから裁量を持てた。
「みんながやっている」は我慢の理由にならない。
我慢に価値はない。日本の社会的圧力としてある程度存在している。`

# プログラマ三代美徳

- 怠惰- サボるための労力を惜しまない。効率化を追い求める。
- 短期- コンピュータが怠慢な時に感じる怒り。改善しようとプログラム改変を行いがち。
- 傲慢- 自分の作品(プログラム)に自信を持つ。


# 死の鎖 : 日本社会的同調圧力


社会的な同調圧力に対しては鈍感であるべき。
Ex).少数派に所属し、競争を避ける。松本さんは、プログラミング言語がニッチな分野だったからこそ、突出できた。

- 積極的に裏技を見つける
- あえて空気を読まない
- 目的を明確化する

### Don’t work hard , work smart.

# 拒否の仕方

エンジニアは、上の言うことを聞くことが仕事ではない。
ソフトウェアを開発し、会社に利益を与えることが仕事。

ただ、わがままを受けてもらえる土壌は信頼関係があってこそ。

# WinとLoseの組み合わせ
7つの習慣より
永続的な取引ができるのは2/7
→　Win WinまたNo Deal

# 結局のところ、自分を知ることが一番大事。
武器を伸ばし、短所を認識する。
松本さんの武器はプログラミング言語だった。

# 思い込みについて自覚的になる

思い込み　==　キャッシュ
インバリデーションのないキャッシュ
意識的キャッシュインバリデーション
思い込みはとても怖いもの。知らず知らずに間違った方向に進んでしまう。プログラムのバグも同じ。
プログラマーの仕事は問題解決→問題把握→分析→ソリューション提案→ソリューション実装→テスト
Ex.) よくやる失敗を弾き出す。→もっと便利なツールを

同じ原則は人生に適用できる。プログラマは人生の勝ち組になりやすい。かも。


# コントロール意識

生産性を下げるものは何か？

一説によれば、叱るとエンジニアの生産性は60%下がる


まつもと氏の見解では、強制されると生産性が下がる、つまり個々人のコントロール意識を制限すると生産性は下がる。
逆を言えば、コントロール意識、裁量を持つ、持たせることが生産性を高めることにつながる。

# アルファシンドローム・逆アルファシンドローム

プログラマの楽しみの根源は万能感にある。
コンピュータをあくまで道具として使う。
コンピュータはあくまでツール、奴隷になるな。
恐れ、不安、疑念は自分の価値と関係はない。

# 勉強する

本を読む。インプットでは差別化要因になりづらい。
アウトプットこそが差別化要因につながる。
羞恥心を捨てる。
チャンスがない。　→　アウトプットを恐れている
人間の可塑性(環境適応能力)にかける。立場によって人間は成長、変化することができる。
心理的な怖さを乗り越えて、可塑性にかけアウトプットする。
ソフトウェアエンジニアにとって心理的、人間的な側面がとても大切。

# Q&A

・意思の強い部下ができたら
組織の秩序を守るか、エンジニアリングを大切にするのか。答えがどうであれ指導指針をブラさない。

・女性エンジニアとして生き残るには
根本として信頼関係を構築できればいいので、男性エンジニアと差のない組織に行けばいい。

・人格者として振る舞う
お互いが‘ フェア ’ であることを大切に。

・失敗について
Ruby開発中、Perlを参考に余分な機能を入れてしまった。

・会社員かフリーランスか
正解はない。柔軟に環境に時代に合わせて対応しよう。

・情報収集方式は？
大したことはしてない。
Twitter
RSSリーダー　→　hacker news ,stack overflow,Reddit

・大学は畑違いだったが、コンピュータサイエンスをまなびたい
今から体系的な勉強するのは現実的でないので、ボトムアップで知りたいことから広げていく。


### 以上、箇条書きですが、右も左も分からない状態で業界に飛び込もうとしている身として、とても充実した時間を過ごせました。
Ubuntuで、zipファイルをダブルクリックで開けるよ！

MacOS同様、Ubuntuでもzipファイルをダブルクリックで開く方法を教えてもらったのでシェアしておきます。

# デモ
![demo-extract.gif](https://qiita-image-store.s3.amazonaws.com/0/136124/b4bd3116-d021-f0db-4107-3dd3170ce721.gif)

# 環境
Ubuntu 16.04 LTS

# 手順
1. .desktopファイルを作成
2. xdg-mineコマンドを実行
3. シェルスクリプトを作る

# 1 .desktopファイルを作成

`/usr/share/applications/`に、以下のファイルを作ります。ファイル名は`extract-here.desktop`としておきましょうか。

```bash:extract-here.desktop
[Desktop Entry]
Name=extract-here
Exec=/usr/bin/extract-here.sh %U
Terminal=false
Type=Application
MimeType=application/zip;
```

# 2. xdg-mineコマンドを実行

```bash
$ xdg-mime default extract-here.desktop "application/zip"
```

なお、再起動してもこの設定は引き継がれます。

# 3. シェルスクリプトを作る

以下のシェルスクリプトを`/usr/bin/`以下に作ります。

```bash:extract-here.sh
#!/bin/bash
/usr/bin/file-roller -h "$1";
```

`file-roller -h`は、「ここで展開」と同じです。
$1をダブルクォーテーションで囲っていれば、圧縮ファイル名に空白が入っていても大丈夫です。

# tar.gzも展開できるようにする
まず、tar.gzのmimetypeを調べます。

```bash
mimetype hoge.tar.gz
```
すると以下のような結果が返ってくると思います。

```bash
hoge.tar.gz: application/x-compressed-tar
```

どうやら、tar.gzのmimetypeは`application/x-compressed-tar`のようですね。
mimetypeがわかったところで、xdg-mimeコマンドを実行しましょう。

```bash
xdg-mime default extract-here.desktop "application/x-compressed-tar"
```

こうすれば、tar.gzファイルもダブルクリックで解凍できるようになります。便利ですね！

# 参考
[Ubuntuで、zipファイルをダブルクリックで展開するにはどうすればいいか。](https://github.com/v97ug/question/issues/13)
[Use custom command to open files](https://askubuntu.com/questions/525953/use-custom-command-to-open-files%EF%BC%89)
[bash get the parent directory of current directory](https://stackoverflow.com/questions/8426058/bash-get-the-parent-directory-of-current-directory/8426110#8426110)

# あとがき
とても気軽に圧縮ファイルを展開できるので便利です。
jasmineとselenium-webdriverでシンプルにE2Eテストする

# 用意するもの

* npm で以下のモジュールをインストールする
    * `jasmine`
    * `selenium-webdriver`
* どうにかしてchromedriverを入手する(Chromeで試したい場合)
    * `chromedriver`という名前で(windowsだと`chromedriver.exe`かな？)カレントフォルダに置いておく(ほかにいい感じに管理する方法があれば教えてください・・・！)

# こう書く

シンプルに書いています。(ほんとはasync/awaitで書きたいけど)

```js:test.js
var wd = require("selenium-webdriver");

describe("e2e test", function() {
  var driver;
  beforeAll(function () {
    // デフォルトだと、5秒しか待ってくれないので、20秒くらい待たせる
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
    driver = wd.Builder().forBrowser("chrome").build();
  });
  afterAll(function() {
    driver.quit();
  });

  it("should get google.com", function(done) {
    driver.get("http://google.com")
    .then(function() {
      return driver.findElement(by.id("なんかてきとうに"));
    })
    .then(function(element) {
      return element.getText();
    })
    .then(function(text){
      expect(text).toBe("なんかてきとうに");
    })
    .then(done, done);
  });
});
```

# 実行する

`jasmine ./test.js`
WPTをChromeで実行してHTML5 APIを理解する

# WPTとは

[WPT (web-platform-tests)](https://github.com/w3c/web-platform-tests)という、ブラウザを作っている人のためのテストスイートがある。これは、ブラウザがどう動くべきかを定義している様々なWeb標準を、各ブラウザが満たしていてるかを確認するためのテストなのだが、Webサイトを作っているWebデベロッパーが新しいWebのAPIをどう使ったらいいかを調べるときにも役立つと思う。

という話を、電車で横に座っていたとある人に話したら「じゃあ、やり方を(日本語で)紹介してくださいよ。」と言われたので、簡単に紹介したい。

# 手軽に試す
手軽に試したければ、https://w3c-test.org 以下にある目的のテストファイルを開くといい。

例えば、[Service Worker Navigation Preload](https://developers.google.com/web/updates/2017/02/navigation-preload)のテストであれば https://w3c-test.org/service-workers/service-worker/navigation-preload/chunked-encoding.https.html を開くと、色々と実行されて、最終的に下のように表示される。
![w3c-test.png](https://qiita-image-store.s3.amazonaws.com/0/110601/6b139860-2e76-3a56-2ebe-2e95080fcfba.png)

F12またはCtrl+Shit+IでDevToolsを起動することができるので、ブレークポイントを仕掛けてページをリロードするとステップ実行していきながら挙動を確認することができる。

# ローカルで試す

テストファイルを少し変更しながら挙動を試していきたいという場合は、ローカルでサーバを立てればよい。

1. まず、https://github.com/w3c/web-platform-tests を手元の環境にcloneする。
2. `hosts`ファイルを書き換える権限がある場合は、[WPTのREADME](https://github.com/w3c/web-platform-tests/blob/master/README.md#running-the-tests)にかかれている通りに、テスト用のドメインを`127.0.0.1`に向くように`hosts`ファイルを書き換える。権限がない、もしくは面倒な場合は、`config.default.json`ファイルを`config.json`にコピーして、ファイルを開いて`check_subdomains`と`bind_hostname`の`true`を`false`に書き換える。
3. `./wpt serve`でサーバーを起動。Windowsの場合は`python wpt serve`。
4. Chromeを`--user-data-dir=適当な空のディレクトリ`と`--ignore-certificate-errors`の引数付きで起動する。(**注意**：証明書エラーを無視する設定で起動するのでこの環境はテスト以外の目的で使わないこと。) 2.で`hosts`ファイルを書き換えなかった場合は`--host-resolver-rules="MAP *.test 127.0.0.1"`も追加する。
5. https://web-platform.test:8443/ にアクセスし、目的のテストファイルを開く。


# ChromiumのLayoutTest

WPTのプロジェクトが始まる前は、ChromiumのWebのテストは[レポジトリ](https://chromium.googlesource.com/chromium/src/)の`third_party/WebKit/LayoutTests/`に置かれていた。徐々にWPTに移行していこうという動きはあるが、一部のテストはまだ移行されずに残っている。ChromiumのLayoutTestを試してみたい場合は、Chromiumのソースを[checkout](http://www.chromium.org/developers/how-tos/get-the-code)し、`third_party/WebKit/Tools/Scripts/run-blink-httpd`を[実行](https://chromium.googlesource.com/chromium/src/+/master/docs/testing/writing_layout_tests.md#Tests-that-use-an-HTTP-Server)し、http://127.0.0.1:8000 にアクセスすると良い。`http`以外のディレクトリにあるテストファイルは直接開いて実行できる。(ちなみに、LayoutTestという名前は歴史的な理由で、レイアウト処理以外のテストも含まれている。)

# どこにテストがあるか検索したい

WPTは定期的にChromiumの[レポジトリ](https://chromium.googlesource.com/chromium/src/)の`third_party/WebKit/LayoutTests/external/wpt/`と同期されているので、Chromiumのコードサーチ [cs.chromium.org](https://cs.chromium.org) でChromiumのLayoutTestとWPTの両方を検索することができる。[ここ](https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/)から使いたいAPIで検索すると、目当てのテストを見つけることができる。
Djangoでmarkdown対応のアプリを作った時のメモ

# はじめに
Djangoを使ってMarkdown対応の簡単なメモアプリを作った時の記録です．実現したかったのはこの2点です．

* Markdown形式で記述した内容をHTMLに変換して表示したい．
* メインはサンプルコードのメモに使いたいので，コードはシンタックスハイライトできれいに表示したい．

完成イメージはこのような感じです．

<img width="759" alt="無題.png" src="https://qiita-image-store.s3.amazonaws.com/0/45310/12d6e2a1-db31-4c56-0c12-fd9d2cef8f8e.png">

# 開発環境
Webアプリ自体はPythonが得意なこともありDjangoを使いました．

* Python: 3.6.2
* Django: 1.11.5

# MarkdownからHTMLへの変換
Markdownの変換は`Python-Markdown`を使用しました．pipでインストールします．

```shell-session
$ pip install markdown
```

変換は以下のようなイメージで簡単に行えます．

```py3
import markdown
markdown.markdown('# spam')    # <h1>spam</h1>
```

# Djangoのテンプレートで使う
HTMLへの変換処理はDjangoのテンプレート内で処理できたほうが便利なので，自作のフィルタを用意します．
[このあたり](https://docs.djangoproject.com/ja/1.11/howto/custom-template-tags/#template-filters-that-expect-strings)を参考に実装します．

`templatetags`ディレクトリを用意して，その中で自作フィルタを実装します．今回は例として`myfilter.py`としています．

```
app/
    __init__.py
    models.py
    templatetags/
        __init__.py
        myfilter.py
    views.py
```

```py3:myfilter.py
from django import template
from django.template.defaultfilters import stringfilter
import markdown

register = template.Library()

@register.filter
@stringfilter
def markdown2html(value):
    return markdown.markdown(value)
```

テンプレート内でmyfilterをロードして使用します．markdowntxtとしているのがMarkdown形式でのテキストが入った変数です．

```html
{% load myfilter %}
:
<div id="memo">
    {{ markdowntxt | markdown2html | safe }}
</div>
:
```

`safe`フィルタは[HTML の自動エスケープ](https://docs.djangoproject.com/ja/1.11/ref/templates/language/#automatic-html-escaping)への対策です．これを使わないとmarkdown2htmlの結果の文字列に対して，例えば`<`が`&lt;`と変換されてしまいます． 

# コードのシンタックスハイライト
シンタックスハイライトには[highlight.js](https://highlightjs.org)を利用しました．導入が簡単だったことと対応言語とテーマがとてもたくさんそろっていたことがポイントです．冒頭にのせたイメージは`Dracula`テーマを使っています．

```html
<link rel="stylesheet" href="/path/to/styles/dracula.css">
<script src="/path/to/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
```

シンタックスハイライトをよりきれいに表示するために，プログラミング言語の指定ができるように[このあたり](https://python-markdown.github.io/extensions/fenced_code_blocks/)を参考にしてDjango側のコードを少し更新します．

```diff:myfilter.py
def markdown2html(value):
-   return markdown.markdown(value)
+   return markdown.markdown(value, ['fenced_code'])
```

これでGitHubやQiitaでおなじみの書き方で，コードブロックの言語の指定が行えます．

    ```python
    # python code
    ```

```html
<pre><code class="python"># python code
</code></pre>
```

highlight.jsで指定可能な言語は[こちら](https://github.com/highlightjs/highlight.js/blob/master/SUPPORTED_LANGUAGES.md)を参考にしてください．また，highlight.jsをダウンロードするときに対応させる言語にチェックを入れておく必要があります．

# おわりに
Python-Markdownとhighlight.jsを使ってお手軽にMarkdownを取り扱うことができました．
PHPフレームワークごとのMVC構成

既存のWEBプロジェクトに放り込まれてメンテナンスするとき、
まずソースコードを追っていくわけですが、どこを取っかかりにしようかというお話。

＊PHP前提で。

# コントローラーから
大抵は何かしらのフレームワークを使っていると思うので、
MVC (*Model-View-Controller) の「コントローラー」から追っていきます。
URLがコントローラーを指すので、実際の画面から追っていきやすいかと。

以下、自分が当たったことのあるフレームワークのディレクトリ構造を簡単に。

### CakePHP
#### 2.x
[CakePHP 2.x クックブック](https://book.cakephp.org/2.0/ja/getting-started/cakephp-folder-structure.html)

[コントローラー]
app/Controller/XxxController.php
[モデル]
app/Model/Xxx.php
[ビュー]
app/View/Xxx/Xxx.ctp

#### 3.x
[CakPHP 3.x クックブック](https://book.cakephp.org/3.0/ja/intro/cakephp-folder-structure.html)

[コントローラー]
src/Controller/XxxController.php
[モデル] ※2017/12/03訂正
src/Model/Entity/Xxx.php
src/Model/Table/XxxTable.php
[ビュー]
src/Template/Xxx/Xxx.ctp

### Laravel
[Laravel 5.5 日本語ドキュメント](https://readouble.com/laravel/5.5/ja/structure.html)

[コントローラー]
app/Http/Controller/XxxController.php
[モデル]
app/Xxx.php
[ビュー]
resources/views/xxx.blade.php

### CodeIgniter
[CodeIgniter 3.x ユーザーガイド](http://codeigniter.jp/user_guide/3/installation/index.html)

[コントローラー]
application/controllers/Xxx.php
[モデル]
application/models/Xxx.php
[ビュー]
application/views/xxx.php

### Phalcon
[Phalcon 3.x Documantation](https://docs.phalconphp.com/ja/3.2/tutorial-base)

[コントローラー]
app/controllers/XxxController.php
[モデル]
app/models/Xxx.php
[ビュー]
app/views/xxx.phtml

### オレオレFW
必ずMVCのディレクトリ構成があるはず！

# MVC？　なにそれ？
まさかのベタphpであれば、URL＝ファイル名なので逆に分かりやすいかも？
メンテナンスするのは不幸ですが…。

# おわりに
あくまで取っかかりということで。
FWで提供している機能や規約はそれぞれ色々あるので、この辺から追っていって
どんどん深掘りしていけるといいですね。
Firebaseにおける環境変数の設定方法

## Firebaseでの環境変数のまとめ
FirebaseではAPIのキーなど外部に公開したくない情報を環境変数として、設定することができる。印象としては``heroku``などのように簡単に設定することができて便利。

~~ほとんど公式ドキュメントに書いてあることだが、備忘録も兼ねて残しておく~~
**追記**
[Firebase公式ドキュメント | 環境の設定](https://firebase.google.com/docs/functions/config-env?hl=ja)


## 手順

* firebaseにログイン

```
firebase login
```

* 設定したいfirebaseプロジェクトまで移動

```
cd ~/workplace/hoge-projects
```

* 環境変数のセット

```
firebase functions:config:set gmail.email="youremail@gmail.com" gmail.password="yourpassword"
```

* 設定した環境変数をチェック

```
firebase functions:config:get
```

設定した環境変数の一覧が以下のように見ることができる。

```
{
  "gmail": {
    "password": "yourpassword",
    "email": "youremail@gmail.com"
  }
}
```

* Cloud Functionsなどで環境変数を参照する場合

環境変数には``functions.config()``でアクセスできる。
あとは自分で設定したプロパティを指定することで取り出すことができる。

```index.js
const gmailEmail = encodeURIComponent(functions.config().gmail.email);
const gmailPassword = encodeURIComponent(functions.config().gmail.password);
```

## 最後に
``firebase``の場合、api keyやapp IDをコピペすることがあり、これも環境変数で扱った方が良いのでは？と思ったのだが、このような記事を見つけた。

http://testpy.hatenablog.com/entry/2016/09/18/093000

この内容によると
<img width="148" alt="スクリーンショット 2017-09-16 19.16.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/119261/3442b014-b190-30a5-7530-3c4b5400374c.png">

google apisの認証情報で個別のFirebaseプロジェクトの認証情報が漏れないかぎり不正な利用はされないとのこと。
treeコマンドもどきをpythonで書いてみた

#はじめに
WindowsのtreeコマンドみたいなものがLinux環境で使えれば良いなと思い調べてみたが、
どうやら標準コマンドではないらしい。

これでは手軽に tree をインストール出来ない環境だと使えない・・・と思ったので
pythonで実装してみることにした。

#treeコマンドの実行例（DOSコマンドの場合）
```
N:.
├─Document
│  ├─Backup
│  └─Download Files
├─Pictures
├─Video
└─Work
    ├─2010
    ｜  └─Event
    ├─2011
    └─2012

```

#ソースコード
walk関数を使ってカレントディレクトリ直下のディレクトリ・ファイルを取得。
ファイル構造が変わった時にdiffが取れるように
出力結果はtxtファイルに出力できるようにした。


```tree.py
# -*- coding: utf-8 -*-

import os

#export file
exportfile = "filetree.txt"

#current directory
searchdir = "."

print ("Export Start!")
wk = os.walk(searchdir)
with open(exportfile,mode="w") as f:
    for dirpath, dirs, files in wk:
        path = dirpath.split("/") 
        f.write("\t"*(len(path)-2) + path[-1] + "\n")
        for x in files:
            f.write("\t"*(len(path)-1) + "|" + "-" + x + "\n")
print ("Export Finished!")

```

#出力結果
出力先のディレクトリ構造を下記とする。
1〜10の名前のついたディレクトリの中に、
それぞれ"11.txt"と"12.txt"の2つのテキストファイルが入っている。


<img width="614" alt="スクリーンショット 2017-09-16 18.49.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/197189/96012121-7b56-6019-1be6-15ba2288592b.png">

出力結果はこちら
<img width="653" alt="スクリーンショット 2017-09-16 19.01.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/197189/b8633aae-4818-8df3-d927-d045c4ba656c.png">

全てのファイルを取得することには成功したが見た目がまだ微妙。
DOSのtreeコマンドみたいに見た目をもう少し改善したいところ・・・！
Vagrant  でファイル共有

# Vagrant でファイル共有

Vagrant でファイル共有してCUIでの編集ではなく、GUIでのコーディングができるとべんりである。

下記にその方法を記す、

```
config.vm.synced_folder "./html", "/var/www/html/"

```
前項が、ローカルの共有させたいファイルパスであり、 後項が仮想環境の共有させるファイルパスである。
CakePHP Error Warning: file_put_contents(/var/www/html/logs/error.log) 

# 表題のエラー

Warning: file_put_contents(/var/www/html/logs/error.log) [<a href='https://secure.php.net/function.file-put-contents'>function.file-put-contents</a>]: failed to open stream: Permission denied in /var/www/html/vendor/cakephp/cakephp/src/Log/Engine/FileLog.php on line 133

上記エラーが発生しページが表示されないなどの状態になったばあい、

## 原因再現

サーバーへあげてる、cakePHPのプロジェクトをsftpにより取得します。

そのごvagrant でファイル共有を行う。

# Vagrantfile　

下記項目がコメントアウトされてるのでパスを整えて編集し直します。

```
config.vm.synced_folder "./html", "/var/www/html/" 前項がローカルの共有したいディレクトリーのパス、 後項がvagrant 環境の共有させたいパスになります。
```

これを行うことにより、ローカル環境にてAtomや、GUIエディターでの編集が可能になります。

便利です。

これを行った際に発生しました。

SELinux が原因などの記事が多いですが、

実際はパーミッションなので、権限を変更するだけで解決できます。

/var/www/html/logs/error.log

とありますので、

/var/www/html/logs 左記権限を変更することにより解決できます。

logs ディレクトリーの権限を777に変更
logs直下のemptyを　６６４に変更
logs直下のerror.log を644に変更します。

```
chmod 0777 ./logs
chmod 664 ./logs/empty
chmod 644 ./logs/error.log
```

これで表題のエラーは解決できます。

これを解決すると、掲題の方法にて共有させますと、下記エラーが発生する可能性が高いと思われます。

私の場合発生しました。

下記ログになります。

Error: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database

上記も権限のエラーになるので、権限を書き換えます。

```
chmod 666 debug_kit.sqlite
drwxrwxrwx. 1 vagrant vagrant      170 Sep  9 12:44 cache
-rw-rw-rw-. 1 vagrant vagrant 10407936 Sep 16 08:53 debug_kit.sqlite
drwxr-xr-x. 1 vagrant vagrant      102 Sep  9 12:44 sessions
drwxr-xr-x. 1 vagrant vagrant      102 Sep  9 12:44 tests
```
権限を与えることによりこのエラーも解決できます。
gitのコミット時間を変更する

まずはじめに**Author**と**Commiter**について整理

## AuthorとCommiter

`$ git log`

```
commit 176eca240a37e7bfa3292eb99a0712aca23c3052
Author: yamada_taro <yamada_taro@mail.com>
Date:   Fri Jul 29 19:00:38 2016 +0900
```

`$ git log --pretty=fuller` でさらに細かく辿ると「Author」「Commit」がある

```
commit 176eca240a37e7bfa3292eb99a0712aca23c3052
Author:     yamada_taro <yamada_taro@mail.com>
AuthorDate: Fri Jul 29 19:00:38 2016 +0900
Commit:     yamada_taro <yamada_taro@mail.com>
CommitDate: Fri Jul 29 19:00:38 2016 +0900
```

項目の説明は以下の図の通り

| 　　   項目    | 　　                     説明                        |
|------------|--------------------------------------------------|
| **Author:**     | コミットの作者                                   |
| **AuthorDate:** | コミット時間                                     |
| **Commit:**     | リポジトリにコミットした人 |
| **CommitDate:** | コミット時間                                     |



AuthorとCommitが二つある理由は、
rebaseによる歴史の改ざんやcherry-pickした場合に、作者を残しておきたい為らしい。

ちなみに、オプション無しの`git log`で表示される **Date:** は **AuthorDate:** が表示されている


## 過去を改変する

rebase時にAuthorDateを好きな日時に変更し、CommitDateもそれに合わせる

```
$ git rebase -i HEAD~数字

#pick を edit に修正

# AuthorDateを変更する
$ git commit --amend --date="Wed Jan 10 23:59:59 2018 +0900"
$ git rebase --continue

# CommitDateをAuthorDateに合わせる
$ git rebase HEAD~数字 --committer-date-is-author-date
```

```
commit 234fcf0536052314fa83790009f4e30e19478706
Author:     yamada_taro <yamada_taro@mail.com>
AuthorDate: Fri Jul 1 15:10:34 2016 +0800
Commit:     yamada_taro <yamada_taro@mail.com>
CommitDate: Wed Jul 29 14:52:29 2016 +0900
```

↓↓↓↓

```
commit 11bbe54af0bd926978e0fe918508bf5b614e63a9
Author:     yamada_taro <yamada_taro@mail.com>
AuthorDate: Wed Jul 29 16:00:00 2016 +0900
Commit:     yamada_taro <yamada_taro@mail.com>
CommitDate: Wed Jul 29 16:00:00 2016 +0900
```


完了！
Flowtype+reduxにおけるreducerの正しい型付け


よく以下のような型付けを見ます。

```js
// @flow
import { Actions, type Action } from './actions'

export type State = {
  count: number,
  other: string,
}

const initialState: State = { count: 0, other: 'test' }

export default function(state: State = initialState, action: Action): State {
  switch (action.type) {
    case Actions.INCREMENT:
      return { ...state, counter: state.count + 1 }
    default:
      return state
  }
}
```

一見正しいように見えます。
flowの型エラーはでません。
しかし、よく見ると、**count**を**counter**とタイポしています。
これでは型安全などと言えませんね。

## $Shape\<T>を使った改善
この型のオブジェクトは、Tに記述されていないプロパティを含むことはできません。

```js
type T = {
  foo: string,
  bar: number
}
const a: $Shape<T> = {
  foo: '121', // no errors about not having bar 
  baz: true   // error, baz is not in T type
}
```

これをreducerで使うと以下のようになります。
reducerの戻り値の型を`$Shape<State>`に変更します。


<img width="459" alt="スクリーンショット 2017-09-16 17.18.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/f570e836-7dbb-0c9f-72ae-ec308187732a.png">


グレート！
定義されてないcounterで型エラーが起きました。
countに直しましょう。

<img width="453" alt="スクリーンショット 2017-09-16 17.19.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/6aa0c553-7f2b-f5af-9768-96ad1ec81cfd.png">


エラーが消えました。
しかし、残念ながら、これではダメです。
定義したStateの型は以下でした。

```js
type State = {
  count: number,
  other: string,
}
```

プロパティ`other`が消えているのに検知出来ていません。


## T & $Shape\<T> を使う
これを解決するには以下の型を定義します。

```js
type Exact<T> = T & $Shape<T>
```

これは、Tのプロパティ全てかつそれ以外のプロパティを許容しない型です。

するとプロパティが足りない場合正しくflowが検知します。

<img width="412" alt="スクリーンショット 2017-09-16 17.26.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/757f4826-5692-98bf-b742-f1884549bfe9.png">

`...state`を追加しましょう。
これで、reducerが型で守られるようになりました。

<img width="560" alt="スクリーンショット 2017-09-16 17.54.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/29e8c8ac-d924-43d3-9fb7-afdd08b02fed.png">

全体では、以下のようになります。もちろんExact<T>はreducerごとに定義するのではなくimport typeした方がよいでしょう。

<img width="616" alt="スクリーンショット 2017-09-16 18.08.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/bb37f7b2-ec9f-3fbb-0672-f7ecc45935e7.png">



## なぜ$Exact\<T>ではダメなのか？
$Exact\<T>だと全てのオブジェクトが正しくないとダメなので、`{...state}`を使うとその時点でエラーが起きてしまいます。
なので`{ ...state, count: state.count + 1 }`で型エラーが発生してしまいます。

<img width="671" alt="スクリーンショット 2017-09-16 18.17.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/731b0b59-3730-4d3d-b72e-ec821e97af2f.png">

### 追記
`{| |}`は`$Exact<T>`と同等です。


## おわりに
上記のスクリーンショットのエディタはAtom-IDEを使っています。

`Exact<T>`ですが、それぞれの`reducer`に毎回`import type`するか悩みますね。
どこでも使えるようにグローバルに定義してしまってもいいかもしれないとも思っています。
何かあればコメント欄またはtwitterにて議論しましょう。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">この型定義便利なのでflowのUtility Typesの仲間に入れてほしい。$Exact&lt;T&gt;と$Shape&lt;T&gt;の中間的な働きをする <a href="https://t.co/2DK4JA6w7A">pic.twitter.com/2DK4JA6w7A</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/908973869741912064">September 16, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## 関連記事
**Flowtypeのactionの型付け。String Literal型とString型について**
http://qiita.com/akameco/items/e7021e22da4c9e14463a
openFrameworks 0.9.8でofxCvが動かなかった時のメモ


oF 0.9.8で[ofxCv](https://github.com/kylemcdonald/ofxCv)を使おうとした時に動かなかったときのメモ
## 開発環境
- MacOS 10.12.6
- Xcode 8.3.3
- oF 0.9.8

## 原因と対処法
GitHubでダウンロードしたofxCvがmasterだったのが原因らしい，stableをダウンロードすればいける。

ちゃんとreadme読めよって話でした。


> # Installation
> 
> First, pick the branch that matches your version of openFrameworks:
> 
> * OF [stable](https://github.com/openframeworks/openFrameworks/tree/stable) (0.9.8): use [ofxCv/stable](https://github.com/kylemcdonald/ofxCv/tree/stable)
> * OF [master](https://github.com/openframeworks/openFrameworks) (0.10.0): use [ofxCv/master](https://github.com/kylemcdonald/ofxCv/)
> 
> Either clone out the source code using git:
> 
> 	> cd openFrameworks/addons/
> 	> git clone https://github.com/kylemcdonald/ofxCv.git
> 
> Or download the source from GitHub [here](https://github.com/kylemcdonald/ofxCv/archive/master.zip), unzip the folder, rename it from `ofxCv-master` to `ofxCv` and place it in your `openFrameworks/addons` folder.
> 
> To run the examples, import them into the project generator, create a new project, and open the project file in your IDE.
> 

## 参考
[kylemcdonald/ofxCv/readme.md](https://github.com/kylemcdonald/ofxCv/blob/master/readme.md)
Windowsでリソース監視

powershellコマンドでリソース状況をファイルに書き出す。

# コマンド
1秒ごとに100回リソース状況を取得してdata1.blgに出力する。

```
Get-Counter -SampleInterval 1 -MaxSamples 100 | Export-Counter -Path data1.blg
```

# 結果
data1.blgを開くとグラフがでる。
<img width="406" alt="SnapCrab_パフォーマンス モニター_2017-9-16_17-56-30_No-00.png" src="https://qiita-image-store.s3.amazonaws.com/0/143405/9bb79e01-bd95-09df-cab4-d7bf506fe023.png">

# 参考
https://technet.microsoft.com/ja-jp/library/ee872428.aspx
pyenv+pyenv-virtualenv環境で自動でvirtualenv環境を読み込む

# やりたいこと
pythonを`pyenv` + `pyenv-virtualenv`環境で利用している方向けです。
ディレクトリを移動した際に自動で`.python-version`を読み込み`activate`したい。

理由は、

`cd ~/foo`
`pyenv activate foo`

`cd ~`
`pyenv deactivate`

とactivateとdeactivateをいちいち行うのがめんどうくさため。

`direnv`を利用していれば`eval "$(direnv hook bash)"`を
`~/.bashrc`などに下記の通り記載していれば`cd`するごとに
hookしてくれているみたいなので、`direnv`を利用しなくてもできるはず。
少し調べてやってみれば簡単にできたので、備忘も兼ねて久々に投稿
（`direnv`使えばいいのかもしれないけど、個人的になんかなじめなかった）

訂正：
`eval "$(pyenv virtualenv-init -)"`
と、`~/.bash_profile`に記載されていれば自動で切り替わる...
上記、記載していたつもりであるが、記載位置が悪かったのか環境が切り替わらなかったことがあった...



# 設定
`pyenv`と`pyenv-virtualenv`環境の設定がされていることを前提としています。
その上で`.bash_profile`などに下記を`.bash_profile`に追記してください

```
cd(){
    now_path=`pwd`
    now_pyenv_filepath=$now_path/.python-version
    if [ -e ${now_pyenv_filepath} ];then
        now_pyenv=`cat ${now_pyenv_filepath}`
        pyenv deactivate
    fi

    new_pyenv_filepath=$1/.python-version

    if [ -e ${new_pyenv_filepath} ];then
        local_env=`cat ${new_pyenv_filepath}`
        pyenv activate ${local_env}
    fi

    builtin cd "$1"
}
```

上記を記載した上で、`source .bash_profile`と読み込みなおせば
自動で`deactivate`と`activate`してくれます。


一番最初に現在の場所を`pwd`で読み込み
そこに`.python-version`があれば`deactivate`するのが前半部分

さらに移動先のフォルダに`.python-version`があれば
それを読み込み`activate`し、最後にビルトインされている`cd`を読み込み
移動をしています。

`bulitin hoge` でビルトインされているコマンド呼び出せるのしらんかった。

# 参考
`shell hook`とかでぐぐった下記を参考にしました。
- https://unix.stackexchange.com/questions/170279/can-i-hook-into-the-cd-command
初めてのSlack -IT不得手でもできる最初のマニュアル/A4印刷版付き-

[コドモト](http://www.kodomoto.info)という子育て情報サイトを開発運営しています。
ライターなどのメンバー間でのコミュニケーションにSlackを使っていますが、メンバーの多くは普通のお母さんたちで特別ITに強いわけではありません。
そんな彼女達にSlackを使ってもらうための、一番最初の使い方マニュアルをまとめました。Slackには様々な機能がありますが、まず最低限ここがわかっていれば普通に使えるというラインです。

A4プリント版はこちら。
https://docs.google.com/document/d/18W3Xaua00HQbnaO5mPAhQVQ6ApKitqq5op0JrmNMvvo/edit?usp=sharing


#Slackの使い方
Slackとはグループで使えるLINEのようなチャットツールです。
iPhone、アンドロイド、Windows、Macなど各機器に対応したアプリがあります。
https://slack.com/downloads

## チャンネル　CHANNNELS
Slackにはチャンネルという機能があり、話す内容に応じてチャンネルを切り替えます。

```例：
#general　一般的な内容、メンバー全員が読めます。 
#reporter   レポートに関する話題でレポーターのみ見ます。
```
![スクリーンショット 2017-09-16 16.55.45.png](https://qiita-image-store.s3.amazonaws.com/0/31687/5063ec72-69f9-3162-c122-4cc8a0a7b8ff.png "スクリーンショット 2017-09-16 16.55.45.png")

## ダイレクトメッセージ　Direct Messages 
誰かに直接メッセージを送りたいときにはDirect Messagesから相手先を選んでメッセージを送ります。
Direct Messagesの一覧に名前がない場合にはDirect Messagesの横の＋ボタンを押すとすべてのメンバーから探すことが出来ます。
![スクリーンショット 2017-09-16 16.55.57.png](https://qiita-image-store.s3.amazonaws.com/0/31687/da38c545-ae76-8832-57ca-06bc43b9eb4b.png "スクリーンショット 2017-09-16 16.55.57.png")


## チャンネル内で誰かに向けてメッセージを送りたい時
各チャンネル内のメッセージは、「すべてのメッセージを通知する」と設定していない場合、メッセージが読み飛ばされてしまう可能性があります。
他の人に気づいて欲しいメッセージがある場合には @tomo のように、会話中に@ユーザー名と入れるとそのメッセージが相手に通知されます。
メッセージボックス内の@を押すと、相手先が選べます。
![スクリーンショット 2017-09-16 17.11.41.png](https://qiita-image-store.s3.amazonaws.com/0/31687/38539f25-3edb-a192-4b9a-84e110cf5d73.png "スクリーンショット 2017-09-16 17.11.41.png")


## スレッド Thread
チャンネルやダイレクトメッセージ内で返信をする場合、以下のようになってしまうと、話題が混在してわかりづらいですよね。

こういう場合に、メッセージAのところで「Start a thread」を選んで返信すると、一連の話題として見ることができるので便利です。
![スクリーンショット 2017-09-16 17.22.00.png](https://qiita-image-store.s3.amazonaws.com/0/31687/6988a774-fbee-cd5b-a463-2eb16708ffb9.png "スクリーンショット 2017-09-16 17.22.00.png")

## 通知の設定
アプリでメッセージの通知頻度を変える方法です。

**【PC版】**

- チーム名右の下向き>マークをクリック
- Preferencesを選択します

![スクリーンショット 2017-09-24 2.09.30.png](https://qiita-image-store.s3.amazonaws.com/0/31687/5f1a6fad-678d-be71-45bd-621d70257e2e.png "スクリーンショット 2017-09-24 2.09.30.png")

**【スマホ版】**

- 画面上部右側にある︙をタップ
- Settings（設定）をタップ
- Push Notifications（プッシュ通知）をタップ

![image](http://drive.google.com/uc?export=view&id=0B9A0EHRBDyDLUGxwMlpQZEpXOU0)

### 設定内容

- 基本的には下記①か②のどちらかに設定してください。
- ②にする場合、画面内３つの枠の下にある「Notify me about...」にチェックを入れてください。


----

**①All new messages** すべてのメッセージを通知
**②Direct messages, mentions & keywords** 
ダイレクトメッセージ、メンション（@tomoのように自分の名前がメッセージに入るもの）、キーワード
初期設定はこれになっています。
Notifications（通知）設定ページ内下部のMy Keywordsで通知して欲しいキーワードを追加できます。

**□ Notify me about replies to threads I’m following**
   フォローしているスレッドのメッセージを通知する
自分のメッセージに対してスレッドで返信が行われた場合、誰かのメッセージに対してスレッドで返信した場合には自動的にそのスレッドをフォローしたことになります。

※下の画像はPC版アプリです。
![スクリーンショット 2017-09-24 2.21.01.png](https://qiita-image-store.s3.amazonaws.com/0/31687/dc480c0d-4403-1040-6b28-2b4fc961b058.png "スクリーンショット 2017-09-24 2.21.01.png")
【JavaScript】選択項目によって入力させたい項目を切り替えるjs(要jQuery)

フォームとかでよくある
**選択項目によって入力させたい項目を切り替えるjsです。**
（改修の余地はありすぎますが、とりあえず動きます。）      
以下が  
**ラジオボタンの会社項目（inputのnameがcompany）で”qiita”を選択された場合は社員番号を入力させる。
また、会社項目を"qiita"以外を選択された場合は会社名を入力させる。**
というパターンの場合のjsです

```js:toggle.js
// jQuery読み込んでおく
$(function(){
    // 初期表示時、両方の項目を非表示にしておく場合は両方hideを設定
    $('.switch-AAA').hide();  // 項目employee_idを内包するclass
    $('.switch-BBB').hide();  // 項目company_nameを内包するclass

    // companyが選択されていたら＆その値が"qiita"だったら
    if ($('input[name="company"]:checked').val() 
        && $('input[name="company"]:checked').val() === 'qiita') {
         // employee_idのdisabledを外して表示させ、
         // company_nameをdisabledにして隠す。
        $('.switch-AAA').show();
        $('.switch-BBB').hide();
        $('[name="company_name"]').attr("disabled", true);
        $('[name="employee_id"]').attr("disabled", false);
    } else if ($('input[name="company"]:checked').val() 
        && $('input[name="company"]:checked').val() !== 'qiita') {
         // company_nameのdisabledを外して表示させ、
         // employee_idをdisabledにして隠す。
        $('.switch-AAA').hide();
        $('.switch-BBB').show();
        $('[name="company_name"]').attr("disabled", false);
        $('[name="employee_id"]').attr("disabled", true);
    }

    // companyがクリックされたら
    $('[name="company"]').click(function() {
        if ($('input[name="company"]:checked').val() 
            && $('input[name="company"]:checked').val() === 'qiita') {
            $('.switch-AAA').show();
            $('.switch-BBB').hide();
            $('[name="company_name"]').attr("disabled", true);
            $('[name="employee_id"]').attr("disabled", false);
        } else if ($('input[name="company"]:checked').val() 
            && $('input[name="company"]:checked').val() !== 'qiita'){
            $('.switch-AAA').hide();
            $('.switch-BBB').show();
            $('[name="company_name"]').attr("disabled", false);
            $('[name="employee_id"]').attr("disabled", true);
        }
    });
});
```

このjsを実装した場合、POSTされる項目とPOSTされない項目が出てきますので、  
そういう場合はPHP側で  
**array_key_exists**
を使って、配列に項目が入っているかをチェックした方がいいです（おそらく）  
  
以下例

```received.php
// POSTされた項目の中にemployee_idがあれば値に対してゼロサプレス処理を行う。
if (array_key_exists('employee_id', $attributes) === true) {
    $attributes['employee_id'] = ltrim($attributes['employee_id'], '0')
}
```


jQuery依存はいずれやめないとですねぇ
path.combineの結果まとめ

ドライブレター込みでcombineするときに、結果が期待通りじゃない場合があったのでいろいろ試した結果。

# コード
``` csharp
textBox3.Text = System.IO.Path.Combine(textBox1.Text, textBox2.Text);
```

# 結果

## "foo" + "bar"
<img width="210" alt="SnapCrab_Form1_2017-9-16_17-29-22_No-00.png" src="https://qiita-image-store.s3.amazonaws.com/0/143405/a61deb3f-8c22-d57f-a861-68eefea9a1b0.png">
正常系。

## "C:" + "hoge"
<img width="210" alt="SnapCrab_Form1_2017-9-16_17-36-39_No-00.png" src="https://qiita-image-store.s3.amazonaws.com/0/143405/28162581-c53d-4e75-cfa4-ba71e8c81ae2.png">
":"で終わると後ろと"\"でくっつけてくれない。


## "C:" + "\hoge"
<img width="210" alt="SnapCrab_Form1_2017-9-16_17-31-7_No-00.png" src="https://qiita-image-store.s3.amazonaws.com/0/143405/4f665f6d-0e49-e859-bf48-f10e4ce7c11d.png">
"\"で始まるときは前の文字列が消えるのでだめ。

## "C:\" + "hoge"
<img width="210" alt="SnapCrab_Form1_2017-9-16_17-33-4_No-00.png" src="https://qiita-image-store.s3.amazonaws.com/0/143405/406c4857-b681-4230-71af-38dd477563e8.png">
正常系。