OmniAICreator/Qiita-1.07M huggingface dataset:
Redisインストール〜起動まで

# はじめに
他のRedis構築に関するページは以下をご参考ください。
[Redis構築のまとめ](https://qiita.com/ono-soic/items/d63ac849ebccee68b5bc)

# 環境
CentOS 6.8
Redis 3.2.5(当時の安定バージョン)

# インストール手順
- パッケージインストール
yum,wgetを使用します。

### 1. CentOSに下記の諸々をインストール

```
yum install wget gcc tcl vim-enhanced -y 
```
wgetはredis取得のため、gccとtclはmake実行のためです。(vim-enhancedはファイル編集でvim使いたいからインストールしときます。)

### 2. Redisをダウンロード

```
$ cd /usr/local
$ wget http://download.redis.io/releases/redis-3.2.5.tar.gz # ここはお好きなバージョンで
$ tar xzf redis-3.2.5.tar.gz
$ cd redis-3.2.5/
$ make # make testをやっておくといいかも
$ make install
```
make実行時に以下のエラーが出たら

```
jemalloc/jemalloc.h: No such file or directory
```
make discleanを実行(参考：http://qiita.com/A-gen/items/345c07d830205a7ea6cb)

### 3. シンボリックリンクを張る
redis-3.2.5/src/の下にredis-serverとredis-cliのバイナリファイルができるので、/usr/local/binの下にシンボリックリンクを作成する(既存のredis-serverとredis-cliがあれば削除)

```
$ ln -s /usr/local/redis-3.2.5/src/redis-server /usr/local/bin/redis-server
$ ln -s /usr/local/redis-3.2.5/src/redis-cli /usr/local/bin/redis-cli
```

### 4. Redisユーザ及びグループの作成
Redis インスタンスを起動するユーザとグループを作成
ログインが不要な場合はnologin を指定

```
$ groupadd redis
$ useradd -s /sbin/nologin -M -g redis redis
```

### 5. ワークディレクトリの作成
/etc/redis：設定ファイルの格納先
/var/run/redis：データファイルや起動プロセスIDファイルの格納先
/var/log/redis：ログ出力先

```
$ mkdir /etc/redis /var/run/redis /var/log/redis
$ chmod 755 /etc/redis /var/run/redis /var/log/redis
$ chown redis:redis /etc/redis /var/run/redis /var/log/redis
```

### 6. Redis設定ファイルのコピー

```
$ cp -p /usr/local/redis-3.2.5/redis.conf /etc/redis/6379.conf
```

### 7. 設定ファイルを編集
設定ファイル編集は「redis.confの設定内容」を参考にしてください

```
$pwd
/etc/redis/

# 各サーバの/etc/redis/6379.confに下記の設定を行う
# ポート番号が6379以外の場合は適宜変更して設定

$ vim /etc/redis/6379.conf
---- vim編集(redis.confファイルの設定内容から一部抜粋) ----
daemonize yes
loglevel notice //本番環境等で利用される場合はnoticeが良いかと
logfile "/var/log/redis/6379.log"
pidfile redis_6379.pid
dir /var/run/redis
---------------
```
参考)http://tweeeety.hateblo.jp/entry/2016/03/14/135551

### 8. 自動起動スクリプトの設定
ソースからインストールした場合は、自動起動のスクリプトを設定する必要があります。

```
$ cp -p /usr/local/redis-3.2.5/utils/redis_init_script /etc/init.d/redis
```

○自動スクリプトファイルを修正
ヘッダの５行目に chkconfig: 345 70 15 を追記します(数字は自動起動の優先度を表します)
プロセスIDファイルの配置場所も変更します

```
$ vim /etc/init.d/redis
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 345 70 15
：
CLIEXEC=/usr/local/bin/redis-cli
#CLIEXEC="/usr/local/bin/redis-cli -a hoge" //Redis接続時にパスワード設定したい場合のみ変更
#PIDFILE=/var/run/redis_${REDISPORT}.pid
PIDFILE=/var/run/redis/redis_${REDISPORT}.pid
  
$ sudo chkconfig redis on
```

### 9. 起動させる

```
$ /etc/init.d/redis start # service redis start
Starting Redis server...
$ ps -ef | grep redis
root       3328      1  0 05:27 ?        00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379
  
$ redis-cli
127.0.0.1:6379>ping
PONG
```
起動成功です。
複数条件をトライするロバストな処理

たとえば、こんな感じの複数条件を次々とトライしていく処理を書くとき、caseで書くと、ネストが深くなって、とにかく醜い

```elixir 
def to_datetime( str ) when is_binary( str ) do
	case str |> case str |> Timex.parse( "%Y/%m/%d", :strftime ) do
		{ :ok, result } -> result
		{ :error, _   } -> case Timex.parse( "%Y/%m/%d %H:%M:%S", :strftime ) do
			{ :ok, result } -> result
			{ :error, _   } -> case str |> Timex.parse( "%Y/%m/%d %H:%M:%S.%L", :strftime ) do
				{ :ok, result } -> result
				{ :error, _   } -> case str |> Timex.parse( "%Y-%m-%dT%H:%M:%SZ", :strftime ) do
					{ :ok, result } -> result
				end
			end
		end
	end
end
```

条件判定後の処理に類似性があるなら、リスト処理でまとめられて、エレガント（処理的には途中抜けしないため、若干効率は悪いかもだが、条件追加したいときは、リスト追加だけで済む）

```elixir
def to_datetime( str ) when is_binary( str ) do
	[
		"%Y/%m/%d", 
		"%Y/%m/%d %H:%M", 
		"%Y/%m/%d %H:%M:%S", 
		"%Y/%m/%d %H:%M:%S.%L", 
		"%Y-%m-%dT%H:%M:%SZ", 
	]
	|> Enum.map( &( str |> Timex.parse( &1, :strftime ) ) )
	|> Enum.filter( &elem( &1, 0 ) == :ok )
	|> List.first
	|> Tpl.ok
end
```

[※上記Tpl.ok()は、タプルで結果を返す関数をパイプ内で止めないための処理](https://qiita.com/piacere/items/f82a1e45c8650271a7eb)

もし、条件判定後の処理に類似性が無いなら、手前で文字列を分解し、後続の関数でパターンマッチ

String.split()の代わりに、Regex.named_captures()を使い、関数側はmapでパターンマッチすることもできる

```elixir
def to_datetime( str ) when is_binary( str ) do
	str |> String.split( "/" ) |> to_datetime
end
def to_datetime( [ y, m, d, others ] ) do
	# %Y/%m/%d ～のパターンの処理
end
def to_datetime( [ y, m, d ] ) do
	# %Y/%m/%dのパターンの処理
end
def to_datetime( [ tz ] ) do
	# %Y-%m-%dT%H:%M:%SZのパターンの処理
end
```

手前の関数での文字列パターンマッチも可能ではあるが、表現力が弱く、複雑になるので、早々にあきらめている

```elixir
def to_datetime( <<number::bytes-size(4)>> <> "/" <> <<number::bytes-size(2)>> <> "/" <> <<number::bytes-size(2)>> ) do
	# %Y/%m/%dのパターンの処理
end
def to_datetime( <<number::bytes-size(4)>> <> "-" <> <<number::bytes-size(2)>> <> "-" <> <<number::bytes-size(2)>> ) do
	# %Y-%m-%dのパターンの処理
end
```

p.s.上記をアレコレしている中で、if内部でパターンマッチができることが分かった（ただし複数条件を並べるには、elseが入ってきて、あまりキレイとは言えないが、caseの冗長性よりはマシな気がした）

```elixir
if { :ok, result } = Timex.parse( str, "%Y/%m/%d %H:%M:%S", :strftime ), do: result
```
Javascriptで数値配列を扱うためのtips

# はじめに

Javascriptで数値の入った配列に対して何らかの操作をしようとしたとき、簡単な処理でも適当なapiがないために自分で実装しなくてはならないことが多い。またモダンな記法を知らないがために、愚直に実装しコードが冗長になってしまうこともある。そこでここでは数値配列を扱うときによく出てくる操作を効率的に実装するためのtipsをまとめる。

*順次更新していきます。

# 1次元配列

## 配列[0,1,2,...,n]の生成

```Javascript
[...Array(5).keys()]; // => [0,1,2,3,4]
Array.from(Array(5).keys()); // => [0,1,2,3,4]
```

どちらも同様な結果を与える。短いので以下では上の記法を用いる。

## 配列[0,0,...,0]（要素が全て0の配列）の生成

```Javascript
[...Array(5)].map( e => 0 ); // => [0,0,0,0,0]
```

## 配列のクローン

単に

```Javascript
let x = [1,3,5,-2,4];
let y = x;
```

とすると、`y`の要素を変えると、`x`の要素も変わってしまう。

```Javascript
let y = x.slice();
y; // => [1,3,5,-2,4]
```

とすれば`x`の要素が`y`にクローンされ、`y`の要素を変えても、`x`の要素は変わらない。

他にも

```Javascript
let y = [].concat(x);
let y = [...x];
let y = Array.from(x);
```

と言う方法もあるようです。調べてみると`[...x]`と`Array.from(x)`を使う方法はスピードが遅いようです。要素数が100000の配列に対するクローンの時間を計測してみると（1000回平均）、以下のようになりました。

| x.slice() | [].concat(x) | [...x] | Array.from(x) |
|:----------:|:-----------:|:------------:|:------------:
| 0.48ms    | 0.50ms        | 3.9ms       | 7.7ms

＊@felisさんに`slice()`に関するコメントをいただきました。ありがとうございました。

## 配列のソート

in-placeにソートしたいときには、

```Javascript
let x = [1,3,5,-2,4];
x.sort();
x; // => [-2,1,3,4,5];
```

とすれば良い。

ソートした値を他の変数にコピーしたいのならば、一旦コピーを作ってからソートすれば良い。

```Javascript
let x = [1,3,5,-2,4];
let y = x.slice().sort();
y; // => [-2,1,3,4,5]
```

## 配列をソートしたときのインデックスの配列

配列のインデックス`[...x.keys()]`を要素の大小関係に従ってソートすれば良い。

```Javascript
let x = [1,3,5,-2,4];
[...x.keys()].sort( (i,j) => x[i]-x[j] ) // => [3,0,1,4,2] 昇順
[...x.keys()].sort( (i,j) => x[j]-x[i] ) // => [2,4,1,0,3] 降順
```

Javascriptの`sort`関数は大小関係を定義するコールバック関数を渡すことができるので、インデックスを要素の値に従って並べ替えれば良い。

## 最大値・最小値を求める。

```Javascript
let x = [1,3,5,-2,4];
Math.max(...x); // => 5
Math.min(...x); // => -2
```

スプレッド演算子(...)で配列を展開してからMath.max() or Math.min()に渡すのがポイント。

## 最大値・最小値のインデックスを求める。

```Javascript
let x = [1,3,5,-2,4];
x.indexOf( Math.max(...x) ); // => 2
x.indexOf( Math.min(...x) ); // => 3
```

## 平均値を求める。

```Javascript
x.reduce( (a,c) => a+c )/x.length; // => 2.2
```

reduce()を用いて配列の要素をひとつづつ足していく。
暗算するときに利用しているライブラリ（足し算と引き算）

_※筆者はそろばんが得意なわけでも暗算コンテストに出たことがあるわけでもないです。_

日常生活を送っていると、何かと暗算が必要となるシーンに出会うことがあると思います。
例：割り勘、数値の見積もり、乗換案内、人月計算、麻雀のスコア計算、etc...

その時、咄嗟に数字が出てくるようになるために、日頃から心がけていることを書いてみました。

# 足し算と引き算

## 100を作る
たとえば、以下のような足し算があったとします。

```math
62 + 97 \\\
89 + 51 \\\
99 + 101 \\\
\\\
Fig1.1: 足し算その1
```
これくらいであれば簡単に計算ができると思いますが、一工夫してみましょう。

例えば、以下の計算はどうでしょう。

```math
59 + 100 \\\
100 + 40 \\\
100 + 100 \\\
\\\
Fig1.2: 足し算その2
```

これは簡単です。100を足すだけなので、暗算が苦手な方でも、簡単に計算できると思います。
そして、これらは_Fig1-1_の足し算を、以下のように式変形した形です。

```math
62 + 97 = (62 - 3) + (97 + 3) = 59 + 100 \\\
89 + 51 = (89 + 11) - (51 - 11) = 100 + 40 \\\
99 + 101 = (99 + 1) + (101 - 1) = 100 + 100 \\\
\\\
Fig1.3: 式変形
```

100を作ることによって、計算でややこしくなりがちな「繰り上がり」「繰り下がり」計算を減らすことができます。
**何を足したら100になるのか**を意識することで、100を作るのに慣れてくると思います。
10の倍数以外は、「1の位は足して10、10の位は足して9」になる値ということがポイントです。

## 足し算、引き算のルールを使う
足し算と引き算は、順番を入れ替えても答えは変わりません。
また、マイナスの値を引くことは、プラスにした値を足すことですし、連続した引き算は、一つの引き算にまとめることができます。

```math
a + b = b + a \\\
a - b = -b + a \\\
a + b + c = a + c + b \\\
a - b - c = a - (b + c) \\\
\\\
Fig2.1: 足し算、引き算のルール
```

上記を踏まえて、以下の計算を暗算してみてください。（解答例は章末にございます）

```math
172 + 999 + 28 \\\
11 + 57 + 89 + 43 \\\
59 - 9 - 25 - 24 - 1 \\\
1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 \\\
\\\
Fig2.2: ルールを使ってみよう
```

## 10の倍数を作る

もちろん、100を作りにくいシーンは多々ありますが、その場合は、50や、40など、10の倍数にすることを心がけるだけで、途端に計算しやすくなるケースも多いです。

```math
68 + 37 = (68 + 2) + (37 - 2) = 70 + 35 = 105 \\\
\\\
992 + 586 = (992 + 8) + (586 - 8) \\\
          = 1000 + (586 - 10 + 2) \\\
          = 1000 + (576 + 2) \\\
          = 1000 + 578 \\\
\\\
Fig3.1: 10の倍数を作るケース
```

Fig3.1のケースでは、586 - 8で繰り下がりの引き算が出てきていますが、ここも10を引いて2を足す、とすると繰り下がりの計算を回避することができます。
_※そもそも繰り下がりの計算の仕組み自体が、nを引く場合に、10を引いて10-nを足すことを言っています。_


## 引き算を回避する
麻雀のスコア計算の時に，2桁がたくさん並んだものを計算するシーンがあると思います。
例えば以下です。

```math
27 + 52 + 93 + 41 - 23 - 59 - 84 \\\
\\\
Fig4.1: 麻雀のスコア計算(1)
```

これも左から順番に足して後は頑張って引けばいいのですが、引き算は繰り下がりもあり、間違えの元です。
特に負の値になってしまうケースは間違いが発生する可能性が高くなります。

ですので、以下のように式変形してしまいましょう。

```math
27 + 52 + 93 + 41 - (23 + 59 + 84) \\\
\\\
Fig4.2: 麻雀のスコア計算(2)
```

書いてしまえば当たり前のことですが、引き算の連続は、足し算したものを引くのと等しいです。
ちなみに、１の位に繰り上がりがないケースは、普通に足してしまったほうが計算が早いです。

```math
27 + 52 + 93 + 41 - (23 + 59 + 84) \\\
= 79 + 93 + 41 - (82 + 84) \\\
= 172 + 41 - 166 \\\
= 213 - 166 \\\
= 200 + 13 - (200 - 34) \\\
= 13 + 34 = 47 \\\
\\\
Fig4.3: 麻雀のスコア計算(2)
```
213 - 166は一見面倒な引き算ですが、200を2つ作ってしまえば両方とも削除できることに気づくと、最後は足し算で計算出来ます。

## 章末：Fig2.1の答え
以下の計算方法が唯一の答えというわけではありません。
4問目は2通りの計算方法を示しています。

```math
172 + 999 + 28 = 172 + 28 + 999 = 200 + (1000 - 1) = 1199\\\
\\\
11 + 57 + 89 + 43 = (11 + 89) + (57 + 43) = 100 + 100 = 200\\\
\\\
59 - 9 - 25 - 24 - 1 = 59 - (9 + 25 + 24 + 1) = 59 - (10 + 49) = 0\\\
\\\
1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 \\\
= (1+3+5+7+9) - (2+4+6+8) \\\
= (1+9+3+7+5) - (2+8+4+6) \\\
= (10+10+5) - (10+10) = 5 \\\
\\\
1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 \\\
= (1-2) + (3-4) + (5-6) + (7-8) + 9 \\\
= -1-1-1-1+9=5 \\\
\\\
Fig5.1: Fig2.2の解答例
```
【Zabbix】history_logから詳細なログデータを抽出

###【まえがき】
別のシェルでeventsテーブルからイベントデータ一覧を抽出し、
アラート内容を定期的にチェックする運用を試験的に始めてみたのですが、
Windowsのアプリケーションログ/システムログや、
SNMPTrapログ、/var/log/messagesのエラーログなどの
いわゆるログ系のアラートについての対処に困りました。

アラートが飛んでイベントデータに表示されるのはいいのですが、
どういったエラー内容なのかはWebGUI上でひとつひとつ専用ページに飛んで、
確認しなければなりませんでした。

面倒だったので、イベントデータでエラー内容が不明瞭なアラートは、
itemidで紐づけて、詳細なログ内容を表形式で取り出すシェルを作成してみました。

###【動作環境】
簡単ですが、動作環境です。

Zabbix：3.09
MYSQL ：5.7.20

###【シェル内容】

```eventdetail.sh
#!/bin/bash
#指定したitemidの詳細内容をヒストリログから出力する
#ある一定の期間から出力する
#
###基本設定
OUT_DIR=/home/ToolAdmin/eventdata
OUT_FILE=eventdetail_`date +%Y%m%d%H%M%S`.log
MY_CONF=/home/ToolAdmin/mysql.conf
ITEM_LIST=/home/ToolAdmin/shell/itemidlist.txt #txtにitemidを列で並べてます
STIME=`date +%s -d '7days ago'` #1週間分のログを出力
ETIME=`date +%s`

###mysqlでデータ抽出
CNT=0
while read LINE
do
if [ $CNT -eq 0 ]; then
mysql --defaults-extra-file=${MY_CONF} <<SQL > $OUT_DIR/$OUT_FILE
SELECT
 i.itemid 'アイテムID',
 h.name 'ホスト名',
 FROM_UNIXTIME(hl.clock) '日時',
 hl.severity 'Win深刻度',
 hl.source 'Winソース',
 hl.logeventid 'WinEVT_ID',
 hl.value 'エラー内容'
FROM history_log hl
INNER JOIN items i ON hl.itemid = i.itemid
INNER JOIN hosts h ON i.hostid = h.hostid
WHERE hl.clock BETWEEN ${STIME} AND ${ETIME}
AND hl.itemid = $LINE
SQL
CNT=`expr $CNT + 1`
else
###else側は単純に一行目をsedで削除したいために条件分岐してます
mysql --defaults-extra-file=${MY_CONF} <<SQL | sed -e "/^ア.*/d" >> $OUT_DIR/$OUT_FILE
SELECT
 i.itemid 'アイテムID',
 h.name 'ホスト名',
 FROM_UNIXTIME(hl.clock) '日時',
 hl.severity 'Win深刻度',
 hl.source 'Winソース',
 hl.logeventid 'WinEVT_ID',
 hl.value 'エラー内容'
FROM history_log hl
INNER JOIN items i ON hl.itemid = i.itemid
INNER JOIN hosts h ON i.hostid = h.hostid
WHERE hl.clock BETWEEN ${STIME} AND ${ETIME}
AND hl.itemid = $LINE
SQL
CNT=`expr $CNT + 1`
fi
done < $ITEM_LIST
```

これで結果としてこんな感じのログが出ます。
EXCELに転記した画像です。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/198785/b3caaa4d-67b6-99f6-40f3-3440c4911933.png)

###【残課題】
今日、帰ってきてパパっと作成してみたのですが、
以下の点がまだ不明瞭でもう少し調べて綺麗に出力されるようにしたいです。

　・history_log.severityのそれぞれの番号の意味

severityはWindowsの深刻度のことですが、
実際どれがどの番号なのかわからないため、ネットや実機で情報を確認しながら、
CASE～WHEN文で綺麗に変換できるようにしたいです。

Zabbixはデータベースの各カラムの番号の意味などを
調べだすと、面白いですね。SQLが好きだから楽しいです。

◆参考URLページ
下記URLの「Log history」の項は参考になりました。
https://www.zabbix.com/documentation/3.2/manual/api/reference/history/object


もしなにかアドバイス頂ければありがたいです。

おやすみなさい。
【cordova】install時に起きたエラー。

cordova install時に当たったエラー。

[こちら](https://qiita.com/u4da3/items/14c98487fa85df21ea0d)を参考に、
cordovaのinstallをしていたとき。

#Requirements check failed for JDK 1.8 or greater

JDKのinstallで1.9をinstallしたところ、
このエラーが出ました。

##対処

1.9をuninstallして、
1.8をinstallしたらいけました！

#Could not find an installed version of Gradle either in Android Studio,

Gradleがねーよう、ばーろう！！

##対処

brew update
brew install gradle

→したらば。

cordova run android

んで、下のエラー。


※また編集します。
#No emulator images (avds) found.

Android端末のimageがないんだが。

##対処

①Android Studioの、
「Start a new Android Studio project」から適当なプロジェクトを作る。

②メニューバー＞Tools＞Android＞AVDManagerで、
真ん中or左下の「Create Virtual Device」押して、適当にdeviceを追加する。

③追加し終わったら「Your Virtual Devices」という画面に、
追加した端末が表示される。
その追加された端末の列の一番右。Actionsの＞ボタンを押すと、
emulatorが起動する。

④その状態で、
cordovaのプロジェクトルートで「cordova run android」を押すと・・・？

#Cannot read property 'semver' of null

１個上の③の再生ボタンを押してないまま、
「cordova run android」をやると、
これがでる。
dropboxAPIでバックアップ 2019/08/14版

#いくつかアプリを作っていることが前提

https://www.dropbox.com/developers/apps

1 アプリを選択
2 Settings > OAuth2 の横、もしくは下の Generated access token のボタンをクリック

**アクセストークン取得 APIキーじゃないので注意！
下準備OK**


#shを取得

```

curl "https://raw.githubusercontent.com/andreafabrizi/Dropbox-Uploader/master/dropbox_uploader.sh  " -o dropbox_uploader.sh
chmod +x dropbox_uploader.sh
sh dropbox_uploader.sh

```

>The access token is xxxxxxxxxxxxxxxotoGjKqxxx Looks ok? [y/N]: y

#アップロード

cron.txt を アプリ名/cron.txt に転送

```

./dropbox_uploader.sh upload cron.txt /cron.txt



```



```

> Skipping file "/home/hideki/cron.txt", file exists with the same hash



オーバーライドできないので、
vim ./dropbox_uploader.sh

を same でぐぐって、そこらへんの return を返さないようにコードを改造する。

```

オーバーライドできないので、
vim ./dropbox_uploader.sh

を same でぐぐって、そこらへんの return を返さないようにコードを改造する。



**アップロードOK**

#mysqlのバックアップを取得


vim /var/shell/backup.sh

```

#!/bin/sh
mkdir -m 777 /var/backup

#mysqlをバックアップとして取得
mysqldump --default-character-set=utf8mb4 -uroot -p[yourpass] --all-databases | gzip > /var/backup/love-db.sql.gz

#dropboxにアップロード (絶対パスで指定。でないとcronで動かない)
#(アプリケーション名/love-db/ の中に保存)
/home/username/dropbox_uploader.sh upload /var/backup/ /love-db/

```

#パーミッション変更

```

chmod -R 777 /var/shell/backup.sh

```

#うごくかテスト

```

sh /var/shell/backup.sh

```


#cronに設定

```

27 * * * * /var/shell/backup.sh

```
Proxyに触れる


https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy

基本的な認識としましては、オブジェクトの動作を邪悪にするやつです。

```js
const handler = {
  get(obj, prop) {
    return prop in obj ? obj[prop] : 100
  },
  set(obj, prop, value) {
    obj[prop] = value * 2
  }
}

const p = new Proxy({}, handler)

p.a = 1
p.b = 200

console.log(p.a) // => 2
console.log(p.b) // => 400
console.log(p.x) // => 100
```

`new Proxy(ターゲット, ハンドラー)`という感じで定義します。

上記の例では、代入時に数値を2倍、存在しないプロパティにアクセスすると100が返ります。

## 気持ち

基本的にショートハンドを提供する装置としての役割が大きいように見えます。
`immer`などはこのProxyを使い、ミュータブルな操作でイミュータブルな処理が書けるようになっています。

https://github.com/mweststrate/immer

何か面白い使い方ができそうですね。
WPF:CanvasなどのコントロールはBackground/Fillを明示的に指定しないとマウスイベントが発生しない

# Canvasとマウスクリック  
WPFでCanvasコントロールにおいて,  コンテキストメニューなどのマウスクリックイベントが無効になっていた原因と解決法の備忘録

## 問題のコード
マウスの右クリックイベントやContextMenuを設定してるのに, 右クリックしても反応ナシ...  

```xml
<Canvas Name="MainCanvas" Width="400" Height="300" MouseRightButtonDown="MainCanvas_MouseRightButtonDown">
    <Canvas.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Hello!"></MenuItem>
        </ContextMenu>
    </Canvas.ContextMenu>
</Canvas>
```  

## 解決法と原因  
どうやら**Backgroundがnull**だと「空洞扱い」になってしまい, マウスダウンイベントが取れていなかったようです.  
↓のコードなら上手くいきました :)  


```xml
<Canvas Name="MainCanvas" Width="400" Height="300" MouseRightButtonDown="MainCanvas_MouseRightButtonDown" Background="Transparent">
    <Canvas.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Hello!"></MenuItem>
        </ContextMenu>
    </Canvas.ContextMenu>
</Canvas>
```  

「Transparent」や「AliceBlue」など, nullでないBackGroundを設定してあげることで解決しました.

### 参考  
<a href="https://stackoverflow.com/questions/871617/why-doesnt-this-wpf-code-generate-a-context-menu">Why doesn't this WPF code generate a context menu?
</a>


余談:  
こんなん初見じゃわからんがな orz
英語がスラスラと読める様になるための手引き

英語が読めるエンジニアと、日本語しか読めないエンジニアでは、成長のスピードが格段に違います。

英語が読めれば、英語のドキュメントを読めるし、英語のエラーメッセージを読めるし、英語でしか提供されてない便利ツールも使えます。

日本語しか読めないと、世界にある膨大な英語のリソースを自分のために役立てる事ができません。

英語がスラスラと読める様になるために、どのように学習したら良いのか、私の経験から、おすすめの方法を紹介します。

## 単語は語源からイメージをつかむ

日本人なら、知らない漢字を見たとき、部首などの構成から、なんとなく意味がイメージできると思います。
例えば、「机」という字を見たとき、「木」がついてるから木に関する何かかな、とか、「肝」という字を見たとき、「月」がついてるから、体に関することかなとか。
(なぜ「月」は体に関する事なんでしょうね！)

英単語にも、こういった法則があります。
例えば、re-がついてたら、反対方向、もしくは繰り返すイメージとか、-ceptだったら、何かを受け取るイメージとかです。

語源を理解した上で、英単語は、イメージで意味を覚えましょう。決して日本語に変換して覚えようとしてはいけません。

例えば、haveは持っているという意味の他に、助動詞として使えて後ろに動詞の過去分詞形を取って、現在完了の意味になるとかなんとかと、学校で教わったと思います。(世代にもよるのかも？)

でも、ネイティブに取ってみれば、haveはhaveという意味でしかありません。
何かを自分に付属して持っているというイメージだけです。

I have read the book.

と言ったら、「その本を読んだ」という状態を持っている、つまり読んだことがあるよという意味になるのです。
この時haveは助動詞だとか、意識せずに使ってるはずです。

辞書で単語を検索すると、その単語の語源も出てきます。

例えば reception なら

```
 re →逆に、反対方向に
 cept →取る
 tion →動詞を名詞に変える役割
```

等と載っています。

よって、receptionは、歓迎、応接、(世間の)反応、歓迎会、受付などの意味で使われます。
イメージ湧きましたか？


## 文章は前から理解する

次に、文章を読む際には、日本語に訳してはいけません。前から順番に読み、単語のイメージを頭に浮かべながら、そのまま理解してください。

例えば、

I've read a csv file with MemoryStream and insert all data into datatable

これを読むなら

```
私は
読んだ
csvファイルを
MemoryStreamで
そして
入れた
全部のデータを
datatableに
```

こんな感じです。日本語で書きましたが、読むときに頭の中に日本語はなくて良いのです。
最初のうちは日本語が浮かぶかもしれませんが、言葉そのもののイメージだけで、理解するように、慣れていきましょう。

## おわりに

以上が、私のおすすめする英語学習法です。
英語は日本語とまったく違うので、初めは苦しいかも知れませんが、学習していくと、ある時を境に、一気にわかるようになってきます。

そこまで、少しずつでも勉強していくと良いと思います。
TypeScript で書いた React コンポーネント名が Unknown になる対策

## 問題

[React Developer Tools](https://github.com/facebook/react-devtools) を用いると、コンポーネントの確認が出来ますが、TypeScript でコンポーネントを実装していると `<Unknown>` という表示になってしまうことがあります。

以下の場合、本来であれば `<Foo>` と `<Bar>` と表示されて欲しいところですが `<Bar>` ではなく `<Unknown>` と表示されてしまいます。

<img width="1085" alt="スクリーンショット 2018-01-24 18.37.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/31403/a1915c34-4997-96c9-3a24-20499d41a8f6.png">


### ファイル

```ts:index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Foo } from "./components/Foo";
import { Bar } from "./components/Bar";

ReactDOM.render(
  <div>
    <Foo />
    <Bar />
  </div>,
  document.getElementById("root")
);
```

```ts:components/Foo.tsx
import * as React from "react";

const Foo = () => {
  return (
    <div>
      <p>foo</p>
    </div>
  );
};

export { Foo };
```

```ts:components/Bar.tsx
import * as React from "react";

export const Bar = () => {
  return (
    <div>
      <p>bar</p>
    </div>
  );
};
```

## 対策

以下のように、直接 `export` せず、一度 `const` で変数に代入してから `export` するようにしています。 
サンプルリポジトリは [こちら](https://github.com/yami-beta/typescript-react-devtools-unknown-demo) です。

直接 `export` してしまうと React Developer Tools でコンポーネント名が `<Unknown>` になってしまいます。
なお `App.displayName = "App"` のように `displayName` を設定する場合は、直接 `export` してもコンポーネント名が入ります。

### NG

```ts:components/Bar.tsx
import * as React from "react";

export const Bar = () => {
  return (
    <div>
      <p>bar</p>
    </div>
  );
};
```

### OK

```ts:components/Bar.tsx
import * as React from "react";

const Bar = () => {
  return (
    <div>
      <p>bar</p>
    </div>
  );
};

export { Bar };
```

<img width="1085" alt="スクリーンショット 2018-01-24 18.54.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/31403/03e22451-400e-d285-55ea-d779964e3f3f.png">


## バージョン

- React Developer Tools 2.5.2
ScanNCutを使ってフリー素材をカットする

# 環境構築
初回のみ以下の作業が必要

1. 画像の２値化用 AzPainter2([ダウンロード](http://hp.vector.co.jp/authors/VA033749/soft/azpainter2.html))
2. SVG変換用 Inkscape([ダウンロード](https://inkscape.org/ja/))
3. ユーザー登録 ScanNCutCanvas([リンク](https://scanncutcanvas.brother.com/jp))

# 作業
## 画像を用意する
適当なフリー素材を用意する。
形式はjpgでもpngでもOK

## 画像の２値化
イラストの色がグラデーションがかっているようだときれいに取り込めない場合があるので白黒化しておく。

AzPainter2を起動して、変換したい画像をとりこみむ

メニューのフィルタ > カラー > 2値化
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/69136a00-bcac-90cb-76f3-aca8aa45eb38.png)

しきい値を適当にずらしてきれいな黒白画像になればOK

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/b672f94a-eb81-69a0-e7e5-e6f9af8f8d92.png)

変換したら適当な名前で保存

## SVG変換
ScanNCutCanvasに取り込むために変換が必要

まずはInkScapeを起動

メニューのファイル > 開く
から先程用意した画像ファイルを取り込む

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/e8db7130-c184-b2ae-38cf-7f66601f9360.png)

こんなのが出るがそのままOKで良い

Ctrl + Aを押して画像を選択する(メニューの編集 > すべて選択 でも可)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/a52707ba-3ff3-1a02-3a24-9bd8d0a67137.png)

メニューのパス > ビットマップのトレース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214653/e92eb0df-a05a-f8dc-9cbe-f9188bef5287.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/8d0315c9-ea14-5d30-6ef7-f40d250c87ce.png)
OKを押してプレビュー画像が表示されたら右上のXを押して子ウインドウを閉じる

メニューのファイル > 名前を付けて保存

## fcmファイル変換 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/2e1fb5ac-0e4b-2844-55c0-86123e54bbaf.png)
新規作成

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/349623d4-ee36-11ac-53ff-152bc39d1d93.png)
SVG取り込み

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/ab00d89a-2bb6-ddc5-73f6-38d8283157b7.png)
こんなエラーが出るが気にしない

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/7f296cf5-c538-d0c4-265e-56c0d07e5b3b.png)
ダウンロードする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214653/ff494fe9-20bc-5291-d1e4-a03bfe34d676.png)

fcmファイルが保存されるのでUSBなどでスキャンカットに取り込もう


おしまい
rails5,devise_token_authでのエラー対応もろもろ

## エラー「Filter chain halted as :authenticate_user! rendered or redirected」

以下ファイルで、 exceptを追記しました。配列内はメソッド名です。

```ruby:app/controllers/application_controller.rb
# before_filter :authenticate_user!
before_action :authenticate_user!, except: [:new, :create]
```

[Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en)から /auth/sign_in にPOSTして、401が帰ってくることがなくなりました。

## 続いて出たエラー「Can't verify CSRF token authenticity」

同じく、app/controllers/application_controller.rb での記述を変更したところ、200が帰ってくるようになりました。

```ruby:app/controllers/application_controller.rb
# protect_from_forgery with: :exception
protect_from_forgery with: :null_session
```

## Can't verify CSRF token authenticity.
いろいろ調べると、

```ruby
# protect_from_forgery with: :exception
protect_from_forgery with: :null_session
```

をすると解決すると書いてあるのですが、エラーは消えませんでした。
[devise_token_authのcorsに書いてある記述](https://github.com/lynndylanhurley/devise_token_auth#cors)を追記する必要がありました。

```ruby:config/application.rb
module YourApp
  class Application < Rails::Application
    config.middleware.use Rack::Cors do
      allow do
        origins '*'
        resource '*',
          :headers => :any,
          :expose  => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
          :methods => [:get, :post, :options, :delete, :put]
      end
    end
  end
end
```

##参考
https://github.com/lynndylanhurley/devise_token_auth/issues/603
[devise token auth を使って簡単に早くAPIを作る 1](http://clc.gonna.jp/2017/01/post-1306/)
簡単にAndroid端末のキャプチャをPCに送る方法

Androidアプリを開発してて、端末の画面キャプチャをPCに送りたい場面って多々あると思います。


僕はそうしたい時は[Pushbullet](https://www.pushbullet.com/)を使ってたのですが、もっと良い感じにコマンド一発で出来ないかなぁなんて思っていたらありました。


[Android Debug Bridge (adb) | Android Studio](https://developer.android.com/studio/command-line/adb.html)


ちゃんと公式を見ようぜって話でした。本当にいつもいつもお世話になります。

(以降手順は`adb devices`で接続されている端末が表示されていることを確認できている状態からのスタートを想定しています。)

### スクリーンショットを撮る

端末がadb接続されていることを確認し、以下のコマンドを打ちます。

`$ adb shell screencap /sdcard/screen.png`


`/sdcard/screen.png`というのがスクリーンショットした画像ファイルが端末に保存されるところなので、パスとかファイル名は良い感じにしたら良いと思います。


### スクリーンショットを端末からPCに送る

`$ adb pull /sdcard/screen.png ~/Desktop/`

* (pullしてきた画像は適当にDesktopに配置する感じにしました。)

あとは、上記のコマンドをまとめたエイリアスなど作って、ファイル名をタイムスタンプにしたりすればコマンド一発でスクショがPCに転送出来そうです。Amazingですね。

[(ブログにも書いてます。)](http://namaninotiteti1026.hatenadiary.jp/entry/2018/01/17/135311)
in 引数のOperator overloadとdynamicの相性が悪い件

#TL;DR
dynamic経由で呼べなかった

#どーいうことか

以下のような構造体をこさえたとして

```csharp

public struct UseValue
{
    public int Value;

    public UseValue(int value)=>Value = value;

    public static UseValue operator +(UseValue a, UseValue b) => new UseValue(a.Value + b.Value);
}


```

これを､以下のように使ったとする

```csharp

static void Main(string[] args)
{
    dynamic a = new UseValue(10);
    dynamic b = new UseValue(20);

    var ans = a + b;
    Console.WriteLine(ans.Value);
}


```

このとき､何の問題も無く`+`は動的に解決されて､`30`が表示される｡

他方､`C#7.2`から演算子オーバーロードにも`in 引数`の利用が可能になったので､以下のように書いてみる｡

```csharp

public struct UseReadonlyRef
{
    public int Value;

    public UseReadonlyRef(int value) => Value = value;

    public static UseReadonlyRef operator +(in UseReadonlyRef a,in UseReadonlyRef b) => new UseReadonlyRef(a.Value + b.Value);

}

```

で､こいつを同様に呼び出す

```csharp

static void Main(string[] args)
{
    dynamic a = new UseReadonlyRef(10);
    dynamic b = new UseReadonlyRef(20);

    var ans = a + b;
    Console.WriteLine(ans.Value);
}


```

このとき､`var ans=a+b`のステートメントで､`RuntimeBinderException`が発生する｡

恐らく､ランタイムバインダがin引数の演算子オーバーロードに対応していないためと思う｡
これが､将来的に修正されるのかどうかは不明ですが､結構引っかかりやすいかなぁと思ってまとめました｡
ChaliceとBoto3を使って、AWS LambdaからS3にアクセスする

- [Chalice](http://chalice.readthedocs.io/en/latest/): AWS Lambda使ったアプリが簡単に作れるPythonライブラリ
- [Boto3](http://boto3.readthedocs.io/en/latest/): S3にアクセスするためのPythonライブラリ

以下のような構成で、S3からjsonデータを取得したり、保存したりできるアプリを作ります

```
WebBrowser -- AWS (API Gateway -- Lambda -- S3)
```

```
POST /api/save/ : S3にjsonデータを保存
GET /api/load/{key} : S3からjsonデータを取得
```

## 準備: インストール

```bash
$ pip install awscli
$ pip install chalice boto3
```

## アプリの作成

```bash
$ chalice new-project <project-name>
$ nano app.py
```

```python:app.py
from chalice import Chalice
import boto3
import json

BUCKET_NAME = 'msrks'
s3 = boto3.client('s3')

app = Chalice(app_name='save2s3')
app.debug = True


@app.route('/load/{key}')
def load(key):
    key = str(key)+'.json'
    resp = s3.get_object(Bucket=BUCKET_NAME, Key=key)
    data = json.loads(resp['Body'].read())
    return {'load': data}


@app.route('/save', methods=['POST'], content_types=['application/json'])
def save():
    data = app.current_request.json_body
    if 'key' not in data:
        return {'error': 'please input key'}
    key = str(data['key'])+'.json'
    s3.put_object(Bucket=BUCKET_NAME, Key=key,
                  Body=json.dumps(data))
    return {'save': data['key']}
```

## デプロイ

```bash
$ chalice deploy
Regen deployment package.
Updating IAM policy for role: save2s3-dev
Updating lambda function: save2s3-dev
API Gateway rest API already found: m1iu65vuuk
Deploying to API Gateway stage: api
https://m1iu65vuuk.execute-api.ap-northeast-1.amazonaws.com/api/
```

## 動作確認

```bash
$ echo '{"key" : "lang", "val" : "python"}' | http https://m1iu65vuuk.execute-api.ap-northeast-1.amazonaws.com/api/save/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 16
Content-Type: application/json
Date: Tue, 23 Jan 2018 06:16:02 GMT
Via: 1.1 10885a2c24fad0ff660a4e3a8e3fb801.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ODXxBS7Yq7SNy5RBy3l0N10_awp-z8038s3an0DuMVvyKPbvXwxqXw==
X-Amzn-Trace-Id: sampled=0;root=1-5a66d322-d4765ed44785091e48df33ca
X-Cache: Miss from cloudfront
x-amzn-RequestId: e30e3c23-0004-11e8-88a5-537da6fd5cfc

{
    "save": "lang"
}
```


```bash
$ http https://m1iu65vuuk.execute-api.ap-northeast-1.amazonaws.com/api/load/lang
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 42
Content-Type: application/json
Date: Tue, 23 Jan 2018 06:16:40 GMT
Via: 1.1 d653c211343f4b2370c41baf3b65bed6.cloudfront.net (CloudFront)
X-Amz-Cf-Id: FRpHr6jcrOO0-VzC_sZBrhr6G6tntH4OTZADPz9Ey_yeXOiR4v5rqA==
X-Amzn-Trace-Id: sampled=0;root=1-5a66d348-c33cfc4a6f0dc0538d6b2ed3
X-Cache: Miss from cloudfront
x-amzn-RequestId: f9a6b059-0004-11e8-ade1-b3a163f5bf18

{
    "load": {
        "key": "lang",
        "val": "python"
    }
}
```

## 参考：ダッシュボード画面

<img width="1153" alt="スクリーンショット 2018-01-23 15.24.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/158680/f5c36467-6a42-cb48-4243-d0020e442acd.png">
Javaでもa == 1 && a == 2 && a == 3でtrueって出力させたい（Javassist二番煎じ編）

# 前置き

『Javaでもa == 1 && a == 2 && a == 3でtrueって出力させたい』のJavassistを使って変数aの値を書き換えるバージョンです。

* deaf_tadashiさんの[Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい（黒魔術編）](https://qiita.com/deaf_tadashi/items/f145bc4645127b88281b)
* https://twitter.com/backpaper0/status/956007834025635841
* https://twitter.com/tada_suzu/status/956009590818263046

# ソース

```java:EqualsA.java
package com.example;

public class EqualsA {

	private int a;

	public void execute() {
		System.out.println("start");

		if (a == 1 && a == 2 && a == 3) {
			System.out.println(true);
		} else {
			System.out.println(false);
		}

		System.out.println("end");
	}
}
```
```java:EqualsMain.java
package com.example;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.expr.ExprEditor;
import javassist.expr.FieldAccess;

public class EqualsMain {

	public static void main(String[] args) throws Exception {
		convert();

		new EqualsA().execute();
	}

	static void convert() throws Exception {
		ClassPool classPool = ClassPool.getDefault();
		CtClass cc = classPool.get("com.example.EqualsA");
		cc.instrument(new ExprEditor() {

			private int i = 1;

			@Override
			public void edit(FieldAccess f) throws CannotCompileException {
				if (f.getFieldName().equals("a")) {
					f.replace(String.format("$_ = %d;", i++));
				}
			}
		});

		cc.toClass();
	}
}
```

ExprEditorではローカル変数は扱えないようですがフィールドは扱えました。

# おまけ（Scala）

```scala
object EqualsA {
  def main(args: Array[String]): Unit = {
    val a = Int(1)
    if (a == 1 && a == 2 && a == 3) {
      println("true")
    } else {
      println("false")
    }
  }

  case class Int(n: scala.Int) {
    override def equals(other: Any) = true
  }
}
```
Typescriptコンパイル時にDuplicate Identifierと出た時の対処法

# はじめに

[TypescriptのHandbookのInterfaces Extending Classes](https://www.typescriptlang.org/docs/handbook/interfaces.html)を写経していたとき、次のコードを`tsc main.ts`でコンパイルしようとしたところエラーが発生。

```typescript:main.ts
class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {

}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    select() { }
}

class Location {

}
```

# 対策

以下のように`tsc`の`lib`オプションを`es5`や`es6`にすることで解決。

```bash
tsc --lib es5 main.ts
``` 

# 何が起きているのか

コンパイル時のエラーは次の通り。

```
$ tsc main.ts
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(11522,11): error TS2300: Duplicate identifier 'Location'.
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(11538,13): error TS2300: Duplicate identifier 'Location'.
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(18989,13): error TS2300: Duplicate identifier 'Image'.
main.ts(18,7): error TS2300: Duplicate identifier 'Image'.
main.ts(18,7): error TS2420: Class 'Image' incorrectly implements interface 'SelectableControl'.
  Property 'state' is missing in type 'Image'.
main.ts(22,7): error TS2300: Duplicate identifier 'Location'.
```
下から2つ目のエラーは`Image`クラスが`SelectableControl`インターフェースを実装できていないということで予想通りのエラーだが、他のエラーは「LocationやImageが既に宣言されている」という内容になっている。
どうやら`tsc`はデフォルトで`node_modules/typescript/lib/lib.d.ts`を読みに行っているらしい。対応する行を確認すると確かに宣言されていた。

```typescript:node_modules/typescript/lib/lib.d.ts
// 18989行目
declare var Image: { new(width?: number, height?: number): HTMLImageElement; };

// 11522行目
interface Location {
....
}
```

[公式ドキュメント](https://www.typescriptlang.org/docs/handbook/compiler-options.html)によると`tsc`はデフォルトで`--lib es5,dom,scripthost`で走るようで、domに関する宣言ファイルを読み込んでいるため上のようなエラーが出てしまっているようだ。 [^1]

# まとめ
ドキュメントをしっかり読んでデフォルトオプションには気をつけたいところだ。

[^1]: 正確には`--target`が`ES5`の場合に`--lib`が`es5,dom,scripthost`になります。デフォルトの`--target`は`ES3`なので、`--target`が`ES5`の場合と同じ挙動なのかわかりませんが、`dom`はES3の場合にも含まれているようです。
C#でスクリーンリーダー対応のWindowsデスクトップアプリを開発するときの落とし穴

  私が色々なサンプルを参考にC#でWindowsのデスクトップアプリを作っていて地味に困ったことをメモしておきます。

----

## 問題点
  TextBoxやRichTextBoxを配置して入力をするときに
日本語のOn/Offが通常全角半角キーを押す度に[スクリーンリーダー](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC)によってアナウンスされます。
これが下記のコードではされません。
ただ実行すると入力ボックスとしての役目は果たしています。
[ナレータ](https://support.microsoft.com/ja-jp/help/22798/windows-10-narrator-get-started) [NVDA](https://www.nvda.jp/) で確認しました。
  
### サンプル1
using System;
using System.Drawing;
using System.Windows.Forms;
  
class form: Form
{
  
public static void Main()
{
form app=new form();
  
TextBox box=new TextBox();
box.Parent = app;
box.Width = box.Width*3;
box.Text = "こんにちわ";
  
Application.Run(app);
}
  
}
  

-----

## 解決策
  色々試してみた結果Main関数の前に **[STAThread]** を入れればOKでした。
  
### サンプル2
using System;
using System.Drawing;
using System.Windows.Forms;
  
class form: Form
{
  
[STAThread]
public static void Main()
{
form app=new form();
  
TextBox box=new TextBox();
box.Parent = app;
box.Width = box.Width*3;
box.Text = "こんにちわ";
  
Application.Run(app);
}
  
}
  
----
 
## 原因
  書き加えた **[STAThread]** は以降のMain関数をシングルスレットで実行するという宣言です。
そもそもGUIアプリを作成するときにはお約束の事項なようです。
この1行がないとシングルスレットにならず、これが原因でスクリーンリーダーに情報が渡されないようです。
  
<dl>
<dt>STAThread属性</dt>
<dd>
<http://home.a00.itscom.net/hatada/csharp/thread/stathread01.html>
</dd>
</dl>
  
  
  
## Visual Studio で作成した場合
  初めから記入されており、問題ありませんでした。
ただし、TextBoxやRichTextBoxは別ファイルに作成されるため、下記サンプルには記入されていません。
  

### サンプル3
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
  
namespace winapp
{
    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
久しぶりにHomebrew使ったら色々詰んだ。

#きっかけ
Macでtreeコマンドを使いたくなり、以下の方法があることを知った。

```
brew install tree 
```

しかし、brewを使うのが約半年ぶりのため、そこに至るまでに微々たる困難があった。どなたかの参考になるかと思い、ここに記録しておく。

#Homebrewとは
パッケージマネージャー。パッケージのインストールやら、パッケージ同士の依存・競合関係やらを解決してくれるスグレもの。

実は先日LPIC101試験を受験したのだが、その出題範囲でもある「パッケージ管理システム」に近いものらしい。ちなみにこの試験はほとんど実機を使わずに合格出来た。何のための試験なのかと疑問に思っていたのだが、後々この知識が役に立つことになる。

インストール自体は以前通っていたプログラミングスクールで行っていたので、今回は割愛する。

#Xcodeでつまづく
試しに何かコマンドを入力してみようとした。しかし拒否された。

```
$ brew -v
Error: You have not agreed to the Xcode license. Please resolve this by running:
  sudo xcodebuild -license accept
```

どうやらXcodeをアップデートした後に起こる現象であるらしい。

以下のコマンドを入力し、ライセンスを表示して同意したら進めた。（手っ取り早く終えるためにはqを入力する。その後agreeで同意。）

```
sudo xcodebuild -license
```

#Homebrewの更新

brewコマンドは使えるようになったが、念のためアップデートも行った。以下の3つのコマンドを順に実行する。

```
$ brew update
$ brew upgrade
$ brew cleanup
```

そして最終チェック。ここでエラーになった。

```
$ brew doctor
```

#エラーの原因
- configが含まれているファイルが邪魔。

該当ファイルは全てMAMPがらみのファイルだったため、MAMP自体ををAppCleanerで削除した。（環境構築をMAMPに頼らず行おうと考えていたため、逆に良かった。）

今回は該当ファイルの削除という暴挙に出たが、本来ならば環境変数の設定で回避できるらしい。

```
Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and what additional flags to use when
compiling and linking.
```

- 以前Homebrewでインストールしたはずのphpのリンクがおかしい。

```
Warning: You have unlinked kegs in your Cellar
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
  php71
```
以下3つのコマンドを実行した。リンクを外し、ファイルを消し、デッドリンクを削除した。

```
$ brew unlink php71
$ rm -drf /usr/local/Cellar/php71/
$ brew prune
```

もう一度チャレンジ。これでよし。

```
$ brew doctor
Your system is ready to brew.
```

#treeコマンド
`brew doctor`で警告が出ている状態でもインストール可能でした。しかしこのままの状態ではスッキリせず。勉強も兼ねて遠回りしました。

```
brew install tree 
```
picodom de FontAwesome 5

[以前紹介した](https://qiita.com/jkr_2255/items/2631f9f889ddd9cebf01)ように、大幅に進化したFont Awesome 5ですが、picodomと組み合わせてみることにしました（というより、もともと`<i class="fa..."></i>`でpicodom中に埋め込んでいたアイコンもアップデートの必要が出てきたので考えないといけなくなった、というのが正直なところですが）。

# Font Awesome側のデータ形式

JavaScriptライブラリとしてFont Awesomeを使う場合、アイコンのデータは3通りの方法で取得できます（[リファレンス](https://fontawesome.com/how-to-use/font-awesome-api#icon)）。

0. HTMLテキスト（`.html`）
1. DOMノード（`.node`）
2. 仮想DOM向けのデータ構造（`.abstract`）

この前のRiotではDOMノードを流し込みましたが、せっかく仮想DOMのpicodomで組む以上は、`.abstract`でどうにかしたいものです。

# あれ、なんかなかったっけ…？

ただ、この`.abstract`のデータ構造は、`tag`、`attributes`、`children`の3つからなっていること、そして`style`がベタ書きになっていることなどがあり、そのまま`picodom.h`に投げるのも難しそうです。

変換コードを書かないといけないのかな…と思っていたところ、[公式のReactバインディング](https://github.com/FortAwesome/react-fontawesome)があることに気づきました。picodomにもReactのJSXが流用できるように、`React.createElement`に渡す引数と同じものを`picodom.h`に流せれば、（細かい違いはあるかもしれませんが）picodomのVDOMを生成できることになります。

`FortAwesome/react-fontawesome`を調べていくと、[仮想DOMの変換関数](https://github.com/FortAwesome/react-fontawesome/blob/master/src/converter.js)を発見しました。これを利用すれば、picodomでもFont Awesomeを仮想DOMに組み込むことができます。

[実際にアイコンを表示させたjsFiddle](https://jsfiddle.net/0k5nn6rj/)
【サルが書く】phpで今日から2週間の日付を出力したい

phpで今日を含めた日付を2週間分出力したいって時**あるよね！？**

そんな要望をピンポイントで書いていきたいと思います。

```php


date_default_timezone_set('Asia/Tokyo');

foreach(range(0,13) as $i){ 
  echo date("Y/m/d", strtotime("+$i day")) . "\n";
};

```

```
2018/01/24
2018/01/25
2018/01/26
2018/01/27
2018/01/28
2018/01/29
2018/01/30
2018/01/31
2018/02/01
2018/02/02
2018/02/03
2018/02/04
2018/02/05
2018/02/06
```
Flaskのデフォルトでは同時アクセスを処理できない

## 1. はじめに

Flaskのデフォルトでは複数のリクエストを同時に処理することができません。HTTPリクエストを並列処理するのではなくシングル（直列）処理で行うため、同時アクセスがあると最初のリクエストの処理が完了するまで待ちが発生します。
これは[公式ドキュメント](http://flask.pocoo.org/docs/0.12/deploying/#deployment)にも書かれています。

> While lightweight and easy to use, Flask’s built-in server is not suitable for production as it doesn’t scale well and by default serves only one request at a time. Some of the options available for properly running Flask in production are documented here.

並列処理を有効にして同時アクセスを可能にするには`threaded=True`パラメータを設定します。

```python:同時アクセスを処理できるようにする設定方法
# 同時アクセスができる（並列処理が可能）
app.run(host='localhost', port=3000, threaded=True)
```

![flaskThreadedTrue.jpg](https://qiita-image-store.s3.amazonaws.com/0/195748/e7e83024-a31a-f20f-fe52-00dd698b95b2.jpeg)



**（注意）**
`WSGI（Web Server Gateway Interface）`サーバを利用している場合はこの限りではありません。例えば`Gunicorn`の場合、`pre-fork`で複数プロセス（ワーカー）で処理を行うため、全体として並列処理が可能です。

## 2. ソースコード

```python:同時アクセスの動作を確認するためのサンプルアプリ
# -*- coding: utf-8 -*-
from flask import Flask, make_response, jsonify
import time

# flask
app = Flask(__name__)

# rest api
@app.route('/hello/<string:value>', methods=['GET'])
def hello(value):
    result = 'hello {0}'.format(value)
    print('[start] ' + result)

    time.sleep(10)

    print('[end] ' + result)
    return(make_response(result))

# main
if __name__ == "__main__":
    # 同時アクセスができない（並列処理が不可能）
    # app.run(host='localhost', port=3000)

    # 同時アクセスができる（並列処理が可能）
    app.run(host='localhost', port=3000, threaded=True)
```

## 3. 動作確認

Webブラウザの画面（タブ）を２つ開いてURL①、URL②にそれぞれアクセスします。並列処理が有効であればコンソールに`[start]`が続くはずです。

* 画面１　：　URL①
 * http://localhost:3000/hello/shiro

* 画面２　：　URL②
 * http://localhost:3000/hello/kuro

```console:threaded=Trueパラメータが設定されている場合
C:\Temp>python sampleApp.py
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
[start] hello shiro
[start] hello kuro
[end] hello shiro
127.0.0.1 - - [23/Jan/2018 20:54:30] "GET /hello/shiro HTTP/1.1" 200 -
[end] hello kuro
127.0.0.1 - - [23/Jan/2018 20:54:33] "GET /hello/kuro HTTP/1.1" 200 -
```

`threaded=True`パラメータが設定されている場合、`[start]`が続けて出力されているため並列処理になっていることが分かるかと思います。

```console:デフォルトの場合（threadedパラメータが設定されていない）
C:\Temp>python sampleApp.py
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
[start] hello shiro
[end] hello shiro
127.0.0.1 - - [23/Jan/2018 21:10:37] "GET /hello/shiro HTTP/1.1" 200 -
[start] hello kuro
[end] hello kuro
127.0.0.1 - - [23/Jan/2018 21:10:48] "GET /hello/kuro HTTP/1.1" 200 -
```

デフォルトの場合、最初にアクセスのあったURL①の`[end]`が出力された後、URL②の`[start]`が出力されています。つまり並列処理になっておらず、最初の処理が終わるまで待ちになっているのが分かるかと思います。

## 4. さいごに

今回はFlaskのデフォルトでは複数のリクエストを同時に処理することができないこと、および並列処理を有効にするには`threaded=True`パラメータの設定が必要であることを説明しました。
実際のシステムでは`WSGI`サーバを利用することが多いため、この仕様／制約を気にすることは少ないと思います。Flask単体で動作させる場合には注意する必要があります。
spliceは切り取るだけのメソッドではなかった

恥ずかしながらJavaScriptの`Array.prototype.splice`メソッドについて勘違いしていたのでちゃんと使い方を理解しておく。

# 勘違いしていたこと
`splice`の語感が`slice`や`split`と似ているし、こういう使い方↓をするので**"切り取る"**ためのメソッドだと思っていた。

``` js
let arr = [1, 2, 3, 4, 5];
arr.splice(1, 2);    // [1, 4, 5]
```

しかし`splice`はそれ以上の使い方ができるメソッドだし、調べてみるとそもそも`splice`という言葉は"切り取る"とはまるで逆の意味を持っていた。この意味を知っていたらこんな勘違いをすることもなかった気がする。

> **splice**
> 解いて組み継ぎする、より継ぎする、継ぎ合わせる
> https://ejje.weblio.jp/content/splice

# 要素を削除してつなぎ合わせる

まずは基本的な使い方。インデックスと個数を指定して配列から要素を切り取る。

``` js
let arr = ['a', 'b', 'c', 'd', 'e'];
arr.splice(
    1,    // インデックス1（'b'）からスタートして
    2     // 2個の要素を切り取る（'b', 'c'）
);
console.log(arr);    // ['a', 'd', 'e']
```

ちなみにspliceの戻り値で切り取った要素を受け取ることができる。

``` js
let cut = arr.splice(1, 2);  // ['b', 'c']
```

# 要素を差し込んでつなぎ合わせる

配列の指定した位置に要素を差し込むことができる。

``` js
let arr = ['a', 'b', 'c'];
arr.splice(
    1,    // インデックス1に
    0,    // 切り取る数は0で
    'x'   // 'x'を差し込む
);
console.log(arr);    // ['a', 'x', 'b', 'c']
```

`splice`の言葉の意味を汲むと、

- 配列arrをインデックス1で切り離して、　　['a'] ['b', 'c']
- 'x' を接ぎにして　['a'] 'x' ['b', 'c']
- つなぎ合わせる　['a', 'x', 'b', 'c']

といったほうがあっているかもしれない。

差し込む要素は複数あってもいい。

``` js
let arr = ['a', 'b', 'c'];
let cut = arr.splice(1, 0, 'x', 'y', 'z');  // ['a', 'x', 'y', 'z', 'b', 'c']
```

ES6のスプレッド演算子を使うとスマートな感じになる。

``` js
let arr = ['a', 'b', 'c'];
let cut = arr.splice(1, 0, ...['x', 'y', 'z']);
```

# 要素を入れ替える

ということで以上２つを組み合わせて要素を入れ替えることができる。

``` js
let arr = ['a', 'b', 'c', 'd', 'e'];
arr.splice(1, 3, ...['x', 'y', 'z']);    // ['a', 'x', 'y', 'z', 'e']
```

# 配列を分割する

第2引数がなければ指定したインデックスで配列を分割する操作になる。

``` js
let arr = ['a', 'b', 'c', 'd', 'e'];
let arr2 = arr.splice(2);
console.log(arr);    // ['a', 'b']
console.log(arr2);   // ['c', 'd', 'e']
```
EDINETのXBRL用のPythonライブラリを作った - Parser編

## 1. はじめに
まず、EDINETとXBRLについて軽く。
### 1.1 EDINETとは
[EDINET](http://disclosure.edinet-fsa.go.jp/)は、「金融商品取引法に基づく有価証券報告書等の開示書類に関する電子開示システム」のことで、有価証券報告書、有価証券届出書、大量保有報告書等の開示書類について、その提出から公衆縦覧等に至るまでの一連の手続きを電子化するために開発された[^1]ようで、株式投資の重要な判断材料になる決算書が、後述するXBRLという特殊なXMLファイルでダウンロードできる（[検索もできる](https://disclosure.edinet-fsa.go.jp/E01EW/BLMainController.jsp?uji.verb=W0EZA230CXP001007BLogic&uji.bean=ee.bean.parent.EECommonSearchBean&TID=W1E63010&PID=currentPage&SESSIONKEY=1516791272280&lgKbn=2&pkbn=0&skbn=1&dskb=&askb=&dflg=0&preId=1&mul=%E3%83%A4%E3%83%95%E3%83%BC&fls=on&cal=1&era=H&yer=&mon=&pfs=4&row=100&idx=0&str=&kbn=1&flg=&syoruiKanriNo=)）。まとめてドカっとダウンロードしたいひとは[これ](https://qiita.com/shoe116/items/a7b688d05b699cf403a1)を参考にしてほしい。

## 1.2 XBRLとは
[XBRL JAPAN](https://www.xbrl.or.jp/)によると、XBRL（eXtensible Business Reporting Language）は、各種事業報告用の情報（財務・経営・投資などの様々な情報）を作成・流通・利用できるように標準化されたXMLベースのコンピュータ言語[^2]らしいが、とてもそのまま利用できるシロモノではない。例えば、2017年の仕様は[2017年版EDINETタクソノミの公表について](http://www.fsa.go.jp/search/20170228.html)にまとまっているが、まぁ意味不明である[^3]。

## EDINETのXBRLをPythonでパースする
ひとまず、せっかくXBRLという構造化されたファイル（しかも、仕様が複雑とは言え所詮はXML）なので、parserさえ作ればなんとかなるだろうということで作ったのが[edinet-xbrl](https://pypi.python.org/pypi/edinet-xbrl) である。

```bash
$ pip install edinet-xbrl
```

でインストール後、こんな感じでxbrlファイルへのpathを渡せば~~クソみたいな~~XBRLを、Pythonのオブジェクトとして扱える。

```python3
from edinet_xbrl.edinet_xbrl_parser import EdinetXbrlParser

## init parser
parser = EdinetXbrlParser()

## parse xbrl file and get data container
xbrl_file_path = "set your xbrl file path"
edinet_xbrl_object = parser.parse_file(xbrl_file_path)

## 例えば、該当年度の総資産を取ってみる
key = "jppfs_cor:Assets"
context_ref = "CurrentYearInstant"
current_year_assets = edinet_xbrl_object.get_data_by_context_ref(key, context_ref).get_value()
```

keyとcontext_refを特定するのは相応に大変だけど、有報のPDFとXBRLを並べてにらめっこすればなんとかなるはずだ。コードは[GitHub](https://github.com/BuffetCode/edinet_xbrl)に置いておくので、後は良しなに[^4]。

## 最後に
これを使って大量のXBRLと格闘して[バフェット・コード](http://www.buffett-code.com/)というウェブサービスを作ってるので、興味があればのぞいてみてください。繰り返しになりますが、EDINETからXBRLから入手する方法も[このエントリ](https://qiita.com/shoe116/items/a7b688d05b699cf403a1)にまとめたので、是非ご利用ください。
Parserの使い方がわからない、XBRLについて相談したいことがある等については[Twitter](https://twitter.com/shoe116)からお気軽にご連絡いただければと思います（DMでも大丈夫です）。

### 注釈等
[^1]: [金融庁のページ](http://www.fsa.go.jp/search/20130917.html) より引用
[^2]: [XBRL JAPAN: XBRLとは](https://www.xbrl.or.jp/modules/pico1/index.php?content_id=9)より引用
[^3]: そもそも、どの要素に何が入っているかを確認するのには[このページ](http://www.fsa.go.jp/search/20170228.html)の"タクソノミ要素リスト"というexcelファイルを参照する必要があるのだが、これを開いて心が折れない人は皆無であろう。
[^4]: 内部では、[python-xbrl](https://github.com/greedo/python-xbrl)を利用させてもらっている
Googleのスプレッドシートでphpの連想配列を作る自作関数

phpのテスト用データ作るときによく使うので備忘録として

1行目をキー、2行目以降を値とした以下のようなテーブルがあったとする

|    | A  | B     | C     |
|:--:|:---|:------|:------|
|  1 | id | label | value |
|  2 |  1 | 'abc' | 'ABC' |
|  3 |  2 | 'def' | 'DEF' |

下記スクリプトを用意し、`=PHP_ARRAY(A1:C1, A2:C2)`のように記述すると`array('id' => 1, 'label' => 'abc', 'value' => 'ABC'),`のような連想配列ができる
※ヘッダは""を省略した文字列として扱い、その他はそのままとする


```js:script
/**
 * phpの連想配列作成
 * @param {array} header ヘッダ文字列
 * @param {array} values 値
 */
function PHP_ARRAY(header, list) {
  var result = 'array(';

  if(header[0].length == list[0].length) {
    for (var index = 0; index < header[0].length; index++) {
      if(list[0][index] != '') {
        result += "'" + header[0][index] + "' => " + list[0][index] + ",";
      }
    }
    result += ')';
  } else {
    throw new Error('header, list length not match');
  }

  return result;
}
```

範囲を引数に渡した場合、関数側では以下のような情報を受け取る
つまり2行目の1列目のセル内容が欲しい場合は`args[1][0]`のようにすれば取得できる

```js:array
[
    [1行目1列目 セル内容],
    [1行目2列目 セル内容]
],
[
    [2行目1列目 セル内容],
    [2行目2列目 セル内容]
],
```
AutoHotkey でよく使うコードスニペット13選

個人的によく使うコード片をまとめてみました。

# AHKの管理

## キー一発で ahk スクリプトの編集や再読込を行う

```ahk
; Ctrl + Alt + E でスクリプトを編集.
; Ctrl + Alt + R でスクリプトを再読み込み.
^!r::Reload
^!e::Edit
```

## 任意のフォルダに置いた ahk ファイルを使用するコマンドライン

```
"C:\Program Files\AutoHotkey\AutoHotkey.exe" "D:\Dropbox\autohotkey.ahk"
```

# リマップ

## Space に Tab を割り当てる

```ahk
; space キーに tab キーを割り当てる.
space::tab
```

## Ctrl + XXX のタブ操作をもうちょっと使いやすく

```ahk
; タブクローズを Ctrl + F4 から Alt + W に.
!w::Send {Ctrl down}{F4}{Ctrl up}

; タブ切り替えを Ctrl + (Shift +)Tab から Alt + ←/→ に.
!Left::Send {Ctrl down}{Shift down}{Tab}{Ctrl up}{Shift up}
!Right::Send {Ctrl down}{Tab}{Ctrl up}
```

## ScrollLock キーを無効にする

```
scrolllock::Return
```

Return 文しか書いてない = 何もしない、というトリッキーなテクニック。

## デスクトップ上でのみ F1 キーを無効にする

```
#IfWinActive ahk_class Progman
F1::Return
#IfWinActive
```

デスクトップのクラス名は「Progman」。

# ホットキーで起動

## Windows + Enter でメモ帳を開く

```
#enter::run,notepad.exe
```

## Ctrl + Alt + E で好きなエディタでahkスクリプトを編集する

```
; Ctrl + Alt + E でスクリプトを編集.
; ここではエディタとして秀丸エディタを指定.
!^e::Run,"C:\Program Files (x86)\Hidemaru\Hidemaru.exe" %A_ScriptFullPath%
```

# ホットストリング

## ホットストリングが終了文字無しで発動されるようにする

```ahk
; 終了文字無しで発動させる
#Hotstring *
```

## ホットストリングで自動置換後、最後に終了文字を入力しないようにする

```ahk
; 自動置換後、最後に終了文字を入力しない
#Hotstring O
```

## `m@@` でメアドを入力

```ahk
#Hotstring *
#Hotstring O
::m@@::mailaddress@mail.address.com
```

## `m@@` でメアドを入力（ただしコピペで一気に貼り付ける）

```ahk
#Hotstring *
#Hotstring O
::m@@::
	Clipboard = mailaddress@mail.address.com
	Send,^v
return
```

## `d//` で現在日付時刻を入力

```
; この例ではコピペで一気に貼り付ける.

#Hotstring *
#Hotstring O
::d//::
	FormatTime, now,, yyyy/MM/dd HH:mm:ss
	Clipboard = %now%
	Send,^v
return
```

## `w[[` で現在曜日文字列を入力

```ahk
get_dowstr()
{
	FormatTime, downum,, WDay
	dowtable := "SunMonTueWedThuFriSat"
	startpos := ((downum-1)*3)+1
	dowstr := ""
	StringMid, dowstr, dowtable, %startpos%, 3
	return dowstr
}
::w[[::
	dowstr := get_dowstr()
	Clipboard = %dowstr%
	Send,^v
return
```

※配列だと上手くいかなかったので文字列操作で強引に... :sweat:

# おわりに
以上、よく使うコード片をまとめてみました。

間違いや「こんなのもあるよ！」等がありましたらぜひ教えてください :smile: