OmniAICreator/Qiita-1.07M huggingface dataset:
envchainでAWSのアクセストークン等を安全に管理する

[envchain]はAWSのアクセスキーのような機密情報を含む環境変数をmacOSのKeychainに保存し、コマンドを実行するときにそれを復号してくれるCLIツールだ。機密の環境変数を.bashrcなどに書いてしまうより、安全に管理することができる。

[envchain]: https://github.com/sorah/envchain

## 取説

```
❯ envchain
envchain version 1.0.1

Usage:
  Add variables
    envchain (--set|-s) [--[no-]require-passphrase|-p|-P] [--noecho|-n] NAMESPACE ENV [ENV ..]
  Execute with variables
    envchain NAMESPACE CMD [ARG ...]

Options:
  --set (-s):
    Add keychain item of environment variable +ENV+ for namespace +NAMESPACE+.

  --noecho (-n):
    Enable noecho mode when prompting values. Requires stdin to be a terminal.

  --require-passphrase (-p), --no-require-passphrase (-P):
    Replace the item's ACL list to require passphrase (or not).
    Leave as is when both options are omitted.
```



## AWSのアクセスキー等をKeychainに登録する

`envchain --set ネームスペース 環境変数名`の形式でコマンドを呼び出すと、環境変数をKeychainに登録することができる。ネームスペースは好みで決める。フォルダ名のようなものだ。環境変数は複数指定することもできる。例えば、`AWS_ACCESS_KEY_ID`と`AWS_SECRET_ACCESS_KEY`を登録するには次のようにする:

```
❯ envchain --set aws AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
aws.AWS_ACCESS_KEY_ID: (アクセスキーを入力)
aws.AWS_SECRET_ACCESS_KEY: (シークレットアクセスキーを入力)
```

コマンドを実行すると、変数の値を聞かれるので値を入力していく。

## 登録した環境変数を確認する

登録した環境変数を確認するには次のようなコマンドを実行する:`envchain ネームスペース env`。

```
❯ envchain aws env | grep AWS
AWS_ACCESS_KEY_ID=*******************
AWS_SECRET_ACCESS_KEY=*********************************
```

この状態でKeychain Accessを開いて`"envchain"`を検索すると、2つの変数が登録されているのが確認できる。

![](https://cdn.suin.io/574/1.png)

## 環境変数を復号した状態でコマンドを実行する

`envchain`は`envchain ネームスペース 実行したいコマンド`の順で引数を渡すと、環境変数を復号した状態でコマンドを実行してくれる。例えば、`aws iam get-user`を実行させるときは次のようになる:

```
❯ envchain aws aws iam get-user
{
    "User": {
        "Path": "/",
        "UserName": "suin",
        "UserId": "*************",
        "Arn": "arn:aws:iam::************:user/suin",
        "CreateDate": "2014-01-29T08:12:23Z",
        "PasswordLastUsed": "2017-01-16T00:41:34Z"
    }
}
```

この例の`aws aws`は誤植ではない。左はネームスペース、右はawscliだ。
あなたのMySQLは「KING」を全文検索できますか？

この記事は
===

MySQLで全文検索を設定していたら地獄のような仕様を踏んだのでメモです。

やりたいこと
===

* 単にMySQLでngramの全文検索を実施したかったです

事象
===

* 全文検索時に「一部の」単語が引っかからない
* 例えば、「QUEEN」は引っかかるけど、「KING」は引っかからない

原因
===

* MySQLではデフォルトでストップワードという、全文検索に引っかからなくなるワードが定義されていて、[下記の単語](https://github.com/mysql/mysql-server/blob/mysql-5.7.13/storage/innobase/fts/fts0fts.cc#L96-L141)が含まれています

```c:mysqlのソース
const char *fts_default_stopword[] =
{
	"a",
	"about",
	"an",
	"are",
	"as",
	"at",
	"be",
	"by",
	"com",
	"de",
	"en",
	"for",
	"from",
	"how",
	"i",
	"in",
	"is",
	"it",
	"la",
	"of",
	"on",
	"or",
	"that",
	"the",
	"this",
	"to",
	"was",
	"what",
	"when",
	"where",
	"who",
	"will",
	"with",
	"und",
	"the",
	"www",
	NULL
};
```

* このリスト内にある「in」にぶつかって、「KING」の場合だけ検索結果に含まれなくなっていたのでした。
* バイグラムでkingは```ki``` ```in``` ```ng```に分割されるので真ん中のgramが一致してしまってるわけです。
* 英語の場合はngramじゃなくてスペースで分かち書きすればいいので問題にならないのでしょうが。。

対処
===

* 作業前にこの機能がONになっていることを確認して、これが原因であることを確定させておきます。

```
mysql> SHOW VARIABLES LIKE 'innodb_ft_enable_stopword';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_ft_enable_stopword | ON    |
+---------------------------+-------+
1 row in set (0.01 sec)
```

* こんな機能は不要なのでmy.cnfとかRDSのパラメータグループでオフってしまいましょう

```my.cnf
innodb_ft_enable_stopword=0
```

* 反映させるためにmysqlを再起動します
* 念のためパラメータが落ちていることを確認します

```
mysql> SHOW VARIABLES LIKE 'innodb_ft_enable_stopword';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_ft_enable_stopword | OFF   |
+---------------------------+-------+
1 row in set (0.01 sec)
```

* すでに全文検索インデックスが作られているテーブルに手動で反映します

```
mysql> OPTIMIZE TABLE table1;
```

結果
===

* KINGが引っかかるようになりました！

終わりに
===

* これ気づかないと気づかないから、世の中でそのままになってるサーバたくさんありそう・・・

参考
===

* [MySQL InnoDBのフルテキストインデックスで、ストップワードフィルタを無効にする (in, by, is などで検索できるようにする)](https://qiita.com/ytyng/items/3c936caba6bcfe782614)
ファイル文字で使えるかどうか。4OS用。

### linux系は２文字しかないが、windows androidは多い。
大をとって linux apple windows androidでファイル文字として使えるかチェック。

```js
is.fileString=(s=>!/[\\\/\:\*\?\"\<\>\|\0]|^\.{1,2}$/.test(s))
//0 moji is not
//is.fileString=(s=>!/[\\\/\:\*\?\"\<\>\|\0]|^\.{1,2}$|^.{0,0}$/.test(s))
```

### 全部
```html
<style>input{width:22rem}</style><input></input><label></label>
```
```js
let is={}
is.fileString=(s=>!/[\\\/\:\*\?\"\<\>\|\0]|^\.{1,2}$/.test(s))
;
let fn={}
fn.q=(s)=>{return document.querySelector(s)};
fn.q('input').oninput =function(ev){fn.q('label').textContent= is.fileString(this.value)}
```
Raspberry Pi > C > タブと空白インデントの混在 | 行末の空白 > PEP8を使ってチェック

```txt:動作環境
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
Python 2.7.9
```

[Raspberry Pi > editor > geany > Cの実装に使ってみる](https://qiita.com/7of9/items/cb94445fb1726904539e)
にてCの実装にgeanyを使い始めた。

geanyの1つの問題は、空白とタブのインデントが明白でない点。
また、行末の空白が明示されない点。

gitリポジトリにpushする前にチェックして修正したい。

### PEP8

https://www.python.org/dev/peps/pep-0008/

PythonのコードチェックのPEP8を使う。

```bash
$ pep8 i2c_gpio_180309.c | grep mixed
i2c_gpio_180309.c:22:1: E101 indentation contains mixed spaces and tabs
i2c_gpio_180309.c:23:1: E101 indentation contains mixed spaces and tabs
```

22行目でタブインデントがある。
(空白4つのインデントで実装している）。

```bash
$ pep8 i2c_gpio_180309.c | grep trail
i2c_gpio_180309.c:14:36: W291 trailing whitespace
i2c_gpio_180309.c:20:44: W291 trailing whitespace
```

14行目と20行目に行末の空白がある。

C/C++用のチェックツールは未確認。
PC起動後、IPアドレスが取得できるようになってから、処理を行う

windowsでPCが起動したときに自動で処理を行いたい。
ただし、ルータやハブの起動よりも先に処理を始めてしまったら困る場合がある。
例えば、LANを認識できていないのにwebサービスへアクセスしてしまうとか、
端末自身に設定してあるIPを使って処理を分岐したいのに、ちゃんと判定できないなど。

そんなときは、バッチファイルでサーバや自身に向かってpingを投げ、
到達成功した場合のみ処理を行うようにする。

```
@echo off
echo IPアドレス取得のため待機中です
setlocal enableextensions enabledelayedexpansion

:CallPing
for /f %%i in (ip.txt) do (
   set hostUp=0
   rem エラーレベル0かつTTL=の文字を含んだメッセージが返ってきた場合は到達成功と見なす
   ping -n 10 %%i |find "TTL=" && set hostUp=1
   if !hostUp! equ 1 (
      call :Online %%i
   ) else (
      call :Offline %%i 
   )
)

:Online
rem 到達成功したら処理を開始する
start C:\App\GateServer
exit

:Offline
rem 到達成功するまで繰り返す
goto CallPing
```

同じ階層にターゲットとするIPアドレスを記載したテキストを置く。

```ip.txt
192.168.100.95
```
batchのstartコマンドは別プロセスを呼び出して次の行へ進むため、exitでコマンドのウィンドウは自動的に閉じて終了する。
RaspberryPiのCPU温度センサの使い方

RaspberryPiのSoCにはCPU温度センサが内蔵されています。
CPU温度センサのハードウェア仕様と使い方などを調べてみました。

# コマンドラインからのCPU温度センサへのアクセス

```
# cat /sys/class/thermal/thermal_zone0/temp
39000
# vcgencmd measure_temp
temp=39.0'C
```



# Linux Kernel　ソースコード
CPU温度センサドライバの最初のコミット「thermal: bcm2835: add thermal driver for bcm2835 SoC」
https://github.com/torvalds/linux/commit/bcb7dd9ef206f7d646ed8dac6fe7772083714253

温度センサのドライバソースコード
https://github.com/torvalds/linux/blob/master/drivers/thermal/broadcom/bcm2835_thermal.c
ソースコードを読むと、BCM2835_TS_TSENSCTL と BCM2835_TS_TSENSSTAT　 の二つのレジスタを使っていることが分かる。

# レジスタ仕様
* Brcm_Android_ICS_Graphics_Stack.tar.gz のヘッダファイルに定義がある。
* https://github.com/msperl/rpi-registers/blob/master/md/Region_TS.md

## BCM2835_TS_TSENSCTL 0x7e212000
* 制御に使うレジスタ
* リセットができる。

## BCM2835_TS_TSENSSTAT 0x7e212004
* 値取得に使うレジスタ
* センサの10bit AD値が読み出せる。



# CPU温度の取得
## 初期化
* offset と slope を取得
 * offset と slopeの値はSoCのdtsiに書いてある。これをkernelのAPI経由で取得する。
 * RPi1 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2835.dtsi の cpu_thermal
 * RPi2 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2836.dtsi の cpu_thermal
 * RPi3 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2837.dtsi の cpu_thermal
* 温度センサにクロックを供給する
* BCM2835_TS_TSENSCTLにデファルト値とレギュレータ有効の設定を書き込み
* BCM2835_TS_TSENSCTLに温度センサをリセットの指示

## CPU温度の取得
* BCM2835_TS_TSENSSTATレジスタを読む
* 読み出した値の、BIT10 / BCM2835_TS_TSENSSTAT_VALID が1であること確認
* 読み出した値の、BIT0 から BIT9 を取り出しtempに格納
* offset + slope * temp の計算値がCPU温度、計算値が 20000 なら　20.000°Cとなる。

# 温度補正値について
RPi1/RPi2 ではoffsetとslopeの値は、407000と-538だが、RPi3ではこれだと5°C低い値になる。
なので、RPi3ではoffsetに5000を足して412000, -538を使う。
参考： https://marc.info/?l=linux-arm-kernel&m=146309555908312

dtsiに書く温度補正値の記述のフォーマットは　thermal.txt　 に書いてある。
https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/thermal/thermal.txt

#  財団のLinuxカーネル
メインラインでなくでRaspberryPi Foundationのカーネルはどうなっているんだろうと調べたら、処理が違いました。

* GPUで動作するファームウェアにメールボックス経由してコマンドを送信してCPU温度を取得していました。
* https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/thermal/bcm2835-thermal.c
* GPUファームウェアで、温度を監視していたりするのでしょうか？


# todo
* ベアメタルな環境でCPU温度センサにアクセスしてみる。
* レジスタの物理アドレスを調べる。
テスト環境ごとにテストを切り替える。

# 問題点として
特定の環境に依存するようなモジュールを内包するプロジェクトのテストにおいて、JenkinsやCircle CIのような環境ではテストが通らなくなってしまう。

# 解決する手段として
nose のテストを選択する仕組みを用い、環境ごとにテストを切り替えます。

## 使用するツール、サービス

- nose
- Circle CI

※Python 3.6 を使用します。

# プロジェクトの構成

```tree
.
|____tests
| |____my_tools_tests
| | |____test_adder.py
| | |____test_pc.py
| | |____machine.py
|____my_tools
| |______init__.py
| |____adder.py
| |____pc.py
```

## モジュール **my_tools**

モジュール my_tools には以下のクラスが入ります。

- adder.py: 加算器のクラス。
- pc.py: ホストのLinuxディストリビューション名等を取得する機能を持つクラス。 

## モジュール **my_tools_tests**

モジュール my_tools_tests には以下のクラスが入ります。

- test_adder.py: adder.py のテストを行うクラス。
- test_pc.py: pc.py のテストを行うクラス その1。 (テストを実行する環境に依存したコードを含む)
- machine.py: pc.py のテストを行うクラス その2。 (テストを実行する環境に依存したコードを含む)


## テストの選択と切り替え

実行するテストを

1. デコレーションによる方法
2. ファイル名を直接指定する方法

の2パターンの方法で分岐させることができます。


### attr での選択

以下のようにattrのデコレーションが付与されたテストは nose のオプションから実行する/しないを指定できます。

```python
@attr('local')
def test_get_distribution(self) -> None:
    pc = PC()
    eq_("debian", pc.get_distribution())
```

このアノテーションが付与されたテストは nose のオプションから実行する/しないを指定できます。

`@attr('local')` が付けられたテストのみ実行する場合

```bash
nosetests --attr='local'
```

`@attr('local')` が付けられたテストは実行しない場合

```bash
nosetests --attr='!local'
```

### ファイル名での選択
ファイル名に **test** がついていないユニットテストは、ファイルを指定しない限り実行されません。
引数でファイル名もしくはモジュール名を指定することで実行されます。

```bash
nosetests tests/my_tools_tests/machine.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
```

### 使い分けとして

#### 通常は実行されるが、状況により特定のテストを実行しないようにする場合
attrを使用する。

```bash
nosetests --attr='!local'
```

#### 通常は実行されないが、状況により特定のテストを実行する場合
ファイル名を選択する。

```bash
nosetests tests/my_tools_tests/machine.py
```

# 別環境での実行

my_tools/pc.py および machine.py は Linux(Ubuntu) に依存したコードです。

Jenkins や Circle CI などからテストを実行する場合、環境に依存するコードは適切にテストができない可能性があります。
また逆に、開発環境ではテストできないコードを別のホストで実行する場合もあります。

このような場合に前述のテストの選択と切り替えにより、適切にテストが実行されるよう調整することができます。
一例として、Circle CIでの設定を取り上げます。

```yml:.circleci/config.yml
    steps:

      - run:
          name: Run tests
          command: nosetests --attr='!local'
```

ここでは --attr によりテストを選択しています。

# 結果として
テストを行う環境ごとに実行するテストが選択できるようになります。

# 参考元
- [nose](http://nose.readthedocs.io/en/latest/index.html)
[OF][xcode] ファイル追加時のオプション設定

#1. 問題 
プロジェクトにアドオンファイルを追加するとビルドエラーが発生した。

[[openFrameworks] xcodeセットアップガイド](http://openframeworks.cc/ja/setup/xcode/)
上記チュートリアルに沿ってアドオン追加を試みたが失敗。

# 2. 解決法
今回は「ofxOpenCV」を追加してみる。

1. addonsを右クリックしてnew Groupを作成。グループ名は追加するアドオンの名前(ofxOpenCV)とした。

2. Finderから追加したいアドオンを選択。xcode上で先ほど作ったグループ配下([プロジェクトフォルダ]/addons/ofxOpenCV/)に向かってドラッグ&ドロップする。

3. 以下の画面が表示されるので、フォルダ選択orグループ選択を選んで[Finish]。
※フォルダ・グループについては 3.補足を参照
[フォルダを選択する場合]
<img width="729" alt="スクリーンショット 2018-03-09 12.15.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/131118/5f917797-c174-88c5-5228-a59e5cd0f3a3.png">
以上でビルドが通るかと思います。

[グループを選択する場合]
<img width="732" alt="スクリーンショット 2018-03-09 14.17.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/131118/ccf092b6-f403-99fe-44c3-434f41ad59ac.png">

ここで一旦ビルドします。失敗した場合には次の設定も追加して再度ビルドしてください。

追加したアドオンのincludeフォルダまでのパスをHeader Search Pathsへ追加します。
下の画像の赤で示した部分が追加したパスで、$(OF_PATH)はOFのルートディレクトリを指します。
<img width="872" alt="スクリーンショット 2018-03-09 14.22.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/131118/409db76b-fc28-6981-0ccd-f46c96cceabf.png">


#3. 補足
xcodeにおける既存ファイルの追加オプションについて

* Destination

- [x] コピーしたファイルをプロジェクトに追加
- [ ] プロジェクト内にはファイルを追加せず、パスを参照

アドオンを一元管理するならチェックは外した方が良さそうですね。

* Added folders
  - Create Groups
  - Create folder reference
  
これらはプロジェクトで扱うファイルの階層管理方法に関するオプションです。

Finderを参照していただければ分かる通り、mac上で管理されるフォルダは基本的に
青色のアイコンです。しかし、グループの場合は黄色で表示されます。
なぜ色が違うかというと、グループを管理するのはmacではなくxcodeだからです。

フォルダを選択した場合はフォルダ配下に新規ファイルを置くことでmacが自動的に
階層設定をしてくれます。対して、グループの場合はxcode上で関連ファイル紐づける
ことが可能であり、ファイルの保存先を開発者が自由に決められます。

画像素材を同じフォルダで管理したい場合などはグループを選択すると便利そうですね。
また、画像を参照する際もフォルダ選択の場合はパス指定が必須ですが、
グループを選択すればファィル名だけで大丈夫なようです。

こちらのリンクが分かりやすいです。
[グループとフォルダ参照についてのスライド](https://www.slideshare.net/tomohirokumagai54/xcode-32343329)
Error: Your project is not referencing the "MonoAndroid,Version=v8.0" framework. Add a reference to....


#環境
VisualStudio for Mac 7.4

#現象
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">PrismProjectをAndroidでBuildするとErrorになるのですが解決方法分かる方教えて下さい<br>NuGet入れ直したりしたんですけど、上手くいきません<br>project.jsonってファイルも見つかりません<a href="https://twitter.com/hashtag/Xamarin?src=hash&amp;ref_src=twsrc%5Etfw">#Xamarin</a> <a href="https://twitter.com/hashtag/Mac?src=hash&amp;ref_src=twsrc%5Etfw">#Mac</a> <a href="https://t.co/W2TwtGBJP6">pic.twitter.com/W2TwtGBJP6</a></p>&mdash; 吉田カエル@長崎 (@Frog_woman) <a href="https://twitter.com/Frog_woman/status/971940556740837376?ref_src=twsrc%5Etfw">2018年3月9日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


Error内容

```
: Error: Your project is not referencing the "MonoAndroid,Version=v8.0" framework. Add a reference to "MonoAndroid,Version=v8.0" in the "frameworks" section of your project.json, and then re-run NuGet restore. (StoreApp01.Android)
```

#手順

`Preferences...` -> `SDK Location` -> `Android`-> で Android8.1の`SDK Platform`をinstellする
![Screen_Shot_2018-03-09_at_14_19_24.png](https://qiita-image-store.s3.amazonaws.com/0/72559/27144522-b485-4593-e35b-bac6fefb674d.png "Screen_Shot_2018-03-09_at_14_19_24.png")

#参考URL
[Your project is not referencing the “.NETFramework,Version=v4.5” framework.
](https://stackoverflow.com/questions/36190601/your-project-is-not-referencing-the-netframework-version-v4-5-framework)
Pythonでコマンドラインオプションでgzファイルを指定し処理


##はじめに

phpによるgzファイルの検索スクリプトを作ったことがあるが、pythonの勉強と、両者の違いと良さを確認する為に以下要件のものを作ってみる

筆者はpython入門者,phpの経験少々

###なぜスクリプトが必要なのか
linuxならgrep,windowsならfindコマンドがあるのではと言われそうですが、サーバー等の運用の仕事をしていると、容易に本番環境で抽出結果をファイル保存するのは危険なのと、自由に使えるサーバがなく支給されるのはwindowsPCだけというのが現状だったりします。
そこでwindows上でgzファイルのまま対象行を検索したり解析するためのスクリプトが役立つはずです（筆者は役立った）

###php経験者がpython入門してはまったところ

- インデントが重要なこと
    - 他のプログラム熟練者でさえインデントによるステートメントの管理をしていることが衝撃だと思うらしい
    - タブインデントとスペースインデントが混ざってると怒られる
- if分などでelseの前が空行でelseだけにコードを書くと動かない
    - 必ずコードが必要、何もしない場合はpassと記述する

```python
if value == 'Python':
    pass
else:
    print('pythonじゃないよ')
```

- bool値をfalseという風に頭文字を小文字すると怒られる
    - 本投稿とは関係ないが、falseとしたままでも怒られず、その行以降のステートメントが実行されないという事象があってなかなか気づけなかった。何故。 (centOS6.8 Python3.5)



##要件
- windowsの環境（linuxでもたぶんうごくだろうけど）
- Python3をインストールした環境で実行
- コマンドラインオプションで対象ファイルを指定
- gzファイルのまま1行ずつ表示（判定・解析もやれたら）


##コマンドラインオプションを利用する


###ファイルの作成
```python
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument("-f", "--file", dest="filename",help="入力ファイルを指定", metavar="FILE")
args = parser.parse_args()

print(vars(args)['filename'])

```

###コマンドプロンプトで実行
```
C:\PythonScript>gzopen.py -f aa
aa

C:\PythonScript>gzopen.py -h
usage: gzopen.py [-h] [-f FILE]

Process some integers.

optional arguments:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  入力ファイルを指定
```
###phpとの違い
phpの場合getoptという関数で-fという引数の後の引数が配列に格納される

```php
$options = getopt("f:hp::");
```
ベストプラクティスを知らないまま使っているだけかもしれないが、pythonのargparseと違い、デフォルトの値やヘルプ機能がない。
pythonのargparseは、デフォルト値や、ヘルプ機能が最初から用意されており、-hでヘルプを表示できるのがとても良い（以前からやりたいと思っていた）
これは素晴らしい:blush:

##gzファイルを1行ずつ読み込んで標準出力

###ファイルの作成
```python
import gzip
import codecs

filename = 'gzfile.gz'
zf = gzip.open(filename,'rb')
reader = codecs.getreader("utf-16-le")
contents = reader( zf )
for line in contents:
    print(line)
```

###phpとの違い
phpでは、下記のようなコードでgzファイルを1行ずつ取得でき、ただのテキストファイルでもそのまま処理可能。pythonではgzファイルのみのようだ。

```php
$zh = gzopen($filename,"rb");
while (gzeof($zh) == false) {
    $line = gzgets($zh);
}
```

##コマンドラインオプションとgzファイルを1行ずつ読み込んで標準出力を両方行う

下記の例ではunicode(UTF-16LE)のテキストファイルをgz圧縮したものを利用している

###ファイルの作成
```python
import gzip
import codecs
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument("-f", "--file", dest="filename",help="入力ファイルを指定", metavar="FILE")
args = parser.parse_args()

filename = vars(args)['filename']


zf = gzip.open(filename,'rb')
reader = codecs.getreader("utf-16-le")
contents = reader(zf)
for line in contents:
    print(line)

```

####UTF-8版

```python
zf = gzip.open(filename,'rb')

reader = codecs.getreader("utf-8")
contents = reader(zf) #encodings.utf_8.StreamReader

for line in contents:
    print(line) #str
```
####文字コードを気にしない書き方

```python
zf = gzip.open(filename,'rt')
for line in zf:
    print(line) #str
```


####以下でもできるようだが、いまいちしっくりこない

```python
zf = gzip.open(filename,'rt')

line = zf.readline()
print(line)
while line:
    line = zf.readline()
    print(line)
```


##個人的課題
windows環境だと標準出力の文字コードがcp932だとかでpython上での
文字コードの扱い方を勉強しないといけなそう。理解が深まり次第記事をアップデートする予定
Camoでプロキシした画像の元URLを展開するワンライナー

## ワンライナー

`ruby -r uri -e "puts [URI.parse(STDIN.read).path.split('/').last].pack('H*')"`

## 使用方法

標準入力として Camo のプロキシURLを受け取って、元画像のURLを出力するようになっています。

```bash
$ echo 'https://camo.qiitausercontent.com/.../....' | ruby -r uri -e "puts [URI.parse(STDIN.read).path.split('/').last].pack('H*')"
https://qiita-image-store.s3.amazonaws.com/0/7048/0ca50e9d-7428-5708-be67-1321af6465de.gif
```

## 解説

QiitaやGitHubでは埋め込んだ画像は Camo でプロキシして配信されます。(Camo については https://qiita.com/tomoasleep/items/6b50445d5a5eac06f7a8 をご参照ください。)
なので、↓のように元の画像のURLから変形されて異なるURLになります。

```
https://qiita-image-store.s3.amazonaws.com/0/7048/0ca50e9d-7428-5708-be67-1321af6465de.gif

↓

https://camo.qiitausercontent.com/4bfce19b86cb7d5eaf053c5aa4b9fb297904225a/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f373034382f30636135306539642d373432382d353730382d626536372d3133323161663634363564652e676966
```

ただ、変形後のURLには元のURLがエンコードされて埋め込まれているので、それを展開してあげれば、変形後のURLから元の画像URLを取り出せるというわけです。

ちなみに、Camoではsecret_keyと元画像URLをdigestを計算することで、sercet_keyを知らないとvalidなプロキシURLを作れないようになっているのですが、画像URLのエンコードではsecret_keyを使用していないので、secret_keyを知らなくても元画像が何なのか取り出すことができます。

### 参考URL

- エンコード処理の実装
    - https://github.com/jch/html-pipeline/blob/cdb943678efc905ec542487f33413e0ba0d322f3/lib/html/pipeline/camo_filter.rb#L54
- デコード処理の実装
    - https://github.com/atmos/camo/blob/e59df56a01c023850962fac16905269d264fba50/server.coffee#L250-L260

### ちなみに

Markdownの元ソース見れるならそっち見たほうが早いです。
pycURLでCurlMultiのレスポンスをアーカイブに保存する

[pycURL](http://pycurl.io/)の単体版は結構情報あったのですが、並行リクエストするCurlMultiの情報が少なかったのでサンプル。ストリームのまま直接アーカイブに保存しています。

```py3
import pycurl
import time
import io
import tarfile
import datetime

urls = [{"url":r"https://www.yahoo.co.jp/", "key":"yahoo"},
        {"url":r"https://qiita.com/", "key":"qiita"}]
TIMEOUT = 10# 10秒

mh = pycurl.CurlMulti()
reqs = []
for url in urls:
    c = pycurl.Curl()
    r = io.BytesIO()
    c.setopt(pycurl.URL, url["url"])
    c.setopt(pycurl.TRANSFERTEXT, True)
    c.setopt(pycurl.WRITEDATA, r)
    c.setopt(pycurl.SSL_VERIFYPEER, False)
    c.setopt(pycurl.SSL_VERIFYHOST, False)
    #c.setopt(c.VERBOSE, True) #デバッグ用
    if TIMEOUT > 0:
        c.setopt(pycurl.TIMEOUT, TIMEOUT)
        c.setopt(pycurl.CONNECTTIMEOUT, TIMEOUT)
    mh.add_handle(c)
    reqs.append((c, r, url))

performed = False
while True:
    if performed:
        ret = mh.select(TIMEOUT)
        if ret == -1:  continue
    while True:
        ret, num_handles = mh.perform()
        time.sleep(1)
        performed = True
        if ret != pycurl.E_CALL_MULTI_PERFORM: break
    if num_handles == 0: break

with tarfile.open("archive.tar.xz", "w:xz") as tar:
    for req in reqs:
        req[1].seek(0) #これをしないとエラー
        info = tarfile.TarInfo(f"{req[2]['key']}.html")
        info.size = len(req[1].getbuffer())
        info.mtime = datetime.datetime.now().timestamp()
        tar.addfile(info, req[1])
```

pycURL自体がlibcurlをPythonに持ってきただけなので、同じような実装をしているPHPの情報が参考になりました。curlのオプションはPHPのページを見るといいでしょう。pycURLとほぼ一緒です。

**cURL 転送用オプションを設定する - PHP.net**
http://php.net/manual/ja/function.curl-setopt.php


とりあえず動くレベルのものなので、サーバーがエラー返してきたときの対応はしていません。PHPですが、以下の記事を参考にするともっと良くなると思います。

curl_multiでHTTP並行リクエストを行うサンプル
https://qiita.com/Hiraku/items/1c67b51040246efb4254

追記：環境によっては「pycurl: libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl)」と怒られることがあります。解決法は以下の通りです。
https://qiita.com/kirishimaru/items/722776766da890fd853f

追記：結構メモリ使うので、メモリ溢れそうなら一度中間ファイルを作りましょう。
terraformでAPIGatewayのステージが自動更新されない時

# 起きた現象
terraformを編集してもステージが過去のデプロイ経歴から復元されて、
新しいものが反映されない。。。

# 対処法
使わない変数を設定して、
新しく編集するたびに値が変わるようにする

```groovy
resource "aws_api_gateway_deployment" "MyDemoDeployment" {
  depends_on = ["module.functions"]
  rest_api_id = "${aws_api_gateway_rest_api.chatops-api-blt.id}"
  stage_name  = "${terraform.env}_chatops_apigateway_stage"
  variables = {
    "check_change_hash1" = "${md5(file("変更するファイルのパス.tf"))}"
    "check_change_hash2" = "${md5(file("変更するファイルのパス.tf"))}"
  }
}
```
AWS を無料で学習　~Qwiklabs~

## 先に結論：2018年3月時点の無料かつ日本語版のレッスンを紹介

# Qwiklab という学習サイト
AWS公認のオンライン学習環境(要登録)
[Qwiklabs](https://qwiklabs.com/?locale=ja)

## 様々な演習と演習環境が用意されている
- **無料**、有料のレッスンが用意されている。
- AWSだけでなく**GCPのほうもレッスンが用意**されている。
- **日本語対応されているレッスン**がある
- **Qwiklabのほうで演習用アカウントを用意してくれる**のでこんな方が救われる
    - 個人アカウントを持っていない
    - あまりお金をかけずに勉強したい
    - 無料枠アカウントを持っているが、あまり知らないサービスには怖くて手を出せていない。

## 現時点で無料かつ日本語対応されているレッスンを紹介
- Introduction to AWS **Device Farm** (日本語版)
    - https://run.qwiklab.com/focuses/2968
- Introduction to AWS **Internet-of-Things (IoT)** (日本語版)
    - https://run.qwiklab.com/focuses/2967
- Introduction to AWS **Identity and Access Management (IAM)** (日本語版)
    - https://run.qwiklab.com/focuses/6211
- Introduction to AWS **Key Management Service** (日本語版)
    - https://run.qwiklab.com/focuses/2367
- Introduction to AWS **Lambda** (日本語版)
    - https://run.qwiklab.com/focuses/2966
- Introduction to Amazon **API Gateway** - JP
    - https://run.qwiklab.com/focuses/2380
- Introduction to Amazon **CloudFront**（日本語版）
    - https://run.qwiklab.com/focuses/2362
- Introduction to Amazon **DynamoDB**（日本語版）
    - https://run.qwiklab.com/focuses/2376
- Introduction to Amazon **Elasticsearch Service** (日本語版)
    - https://run.qwiklab.com/focuses/2375
- Introduction to Amazon **Machine Learning** (日本語版)
    - https://run.qwiklab.com/focuses/2964
- Introduction to Amazon **Redshift** (日本語版)
    - https://run.qwiklab.com/focuses/2366
- Introduction to Amazon **Route 53**
    - https://run.qwiklab.com/focuses/2989
- Introduction to Amazon **Simple Storage Service (S3)**（日本語版）
    - https://run.qwiklab.com/focuses/2355
- Introduction to Amazon **Virtual Private Cloud (VPC)** (日本語版)
    - https://run.qwiklab.com/focuses/7317

## 終わりに
他におススメな学習サイト、方法があればご教示ください。
また、リンク切れ、他にもレッスンあったよという場合も教えてくださればその都度編集していきます。
自分が考えるSassのメリット


よくSassの特徴としてネストが挙げられる。
中にはこれをメリットとして捉える人もいるようで、ネストさせないとSassを使う意味あるのかと質問を受けることがあった。昨今はCSSにも設計思想が持ち込まれており、ほとんどのタグにユニークなクラスをつけることが多いため、個人的にはネストさせる状況はほとんどないと思っている。

その上でSassを使う自分なりの利点をまとめてみた。
あくまで個人的な見解なので、他の意見とかあればぜひ伺いたいです。

## Sassの利点
個人的に思う利点は以下の2点だ

* ファイルを分割できる
* 変数やmixinで特定の値や記述を使いまわせる

### ファイルを分割できる
10,000行のCSSとかを今でも稀に見ることがある。
パーシャルでコンポーネントごとにファイルを分割すると1ファイルの記述量が圧倒的に減り、視認性もよくなる。また複数人で開発するときにも楽だ。CSSでもimportを使えば同じことができるが、ファイル分リクエストが発生するためパフォーマンスの観点から良い選択とは言えない。

### 変数やmixinで特定の値や記述を使いまわせる
煩わしいカラーコードやviewportの指定などは変数にぶち込む。
また、`flex系`の指定はIEやSafariでバグがあったりもするので、プレフィックスやポリフィル的な指定も含めmixin化するのがいいと思う。

``` .scss
@mixin flex {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  display: -webkit-flex;
  -webkit-flex-wrap: wrap;
}
```

## ネストのデメリット

ネストに関してはデメリットもあると思っており、よく以下のような記述を目にする。

``` .scss
.parentClass {
  &__child {
  }
}
```
↑はアンチパターンだ。改修とかでコードを追う場合、`parentClass__child`では検索できず、`.parentClass`を検索して、ネストされているセレクタの中から`__child`を見つける必要がある。かなりめんどい。

以下がベストプラクティス。

```.scss
.parentClass {
  ...
}

.parentClass__child {
  ...
}
```
## extendは利点じゃないの？
Sassにはextendという便利な機能も備わっている。extendについては以下の説明がわかりやすい。
https://terkel.jp/archives/2011/12/sass-extend/

個人的にextendは極力使わないほうがいいと思っている。影響範囲がつかみにくく、予期せぬ崩れを起こす場合があるからだ。
どうしても使いたい場合はコンポーネントの以下に注意を払う。

* コメント
* コンテキスト

### コメント
継承元ファイルには必ずどのコンポーネントでextendしているかを明記する必要がある。これをしないと影響範囲がわからない。

### コンテキスト
見た目が同じというだけの理由でextendしていると、改修の時に予期せぬ崩れが発生する。
例えば商品一覧とブログ一覧が同じ見た目でも役割が全然違うため、商品一覧を改修したからブログ一覧も改修するとはならない。コンテキストが同じもののみextendを使用するのが良いと思う。

## 最後に
フロントエンドを生業にしている人からすれば当たり前の内容かもしれない。
しかしあまりフロントに馴染みのないサーバーサイドよりの人やSassをそこまで学んでいないデザイナーには参考になるのかなと思いまとめてみました。少しでもこの記事が役に立つことを願う。
AOJを使ってアルゴリズムの勉強をしよう

こんにちわ
[グローバスセンス株式会社](https://gb-sense.com)のskanehiraです。

ぼく自身は凄腕のプログラマでも、まして一人前にプログラマではないですが
プログラムで一番大事なのはアルゴリズムじゃないかなと思っています。（当たり前…）

# **なぜ？**
最初は言語を覚えればプログラムも書けると思っていました。

それは間違いではないが言語はあくまでも手段であって
プログラムを使ってものづくりが目的と思っています。

モノを作るにあたり、仕組みを考えたり
その仕組を実現するためのアルゴリズムを考えたりするので
アルゴリズムを考えれなければモノを作れません。

なので
プログラミングでは言語を覚えるよりもいかにアルゴリズムを組めるか
が大事になってくるじゃないでしょうか。

アルゴリズムを組めるのであれば
あとは言語でできることと出来ないことを把握しておけば
という感じかなと思います。

# **AOJについて**

[AOJ（AIZU ONINE JUDGE）](http://judge.u-aizu.ac.jp/onlinejudge/)ではアルゴリズムの問題をいくつかの言語を使って解いて
ソースを提出することで正解かどうかを判定してくれます。

メモリ使用量や実行時間も正解判定に含まれますので
効率良いアルゴリズムじゃなければ行けないです。

AOJのマニュアルは[こちら](http://judge.u-aizu.ac.jp/onlinejudge/AOJ_tutorial.pdf)で見れますので
使い方に困ったら見てみると良いと思います。

# **AOJを使ってみる**
[チュートリアル](http://judge.u-aizu.ac.jp/onlinejudge/introduction.jsp)に沿って試しにやってみようと思います。
ユーザ登録は済ませておきましょう。

- [Hello World](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A&lang=jp)

まずはHello Worldを画面に出力するだけのプログラムを作ります。
問題文を一通り読んだら一番右のアイコンをクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/d4c678c1-c556-2671-ea7c-f04826898d38.png)

ソースをアップロードする画面に遷移するので
言語を選んでソースをペタッと貼りましょう。

```java
class Main {
    public static void main(String args[]) {
        System.out.println("Hello World");
    }
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/e86e854c-7860-07b8-6807-bc6913bdd7f5.png)

ソースを貼ったら提出を押下するとジャッジの画面に遷移します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/b71fbcd0-5ed9-0ccc-904c-815f7ea4988b.png)

ここでは提出したプログラムの判定結果が載っています。
結果がAcceptedになっているので、正解ということです。

どんな結果があるのか、マニュアルに載っています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/6a09fa45-b89d-6dee-7825-8a1af69fe704.png)

# **最後に**
こういった競技プログラミングは
１人で解くのもありだし、仲間と一緒に解くのもありと思います。

楽しく、そして解いた時の達成感を感じれるところが成長につながるのではないかなと思います。

今の世の中にはプログラミングを学ぶのに沢山のサービスが存在していますので
今後は素晴らしいプログラマが沢山生まれてくると思います。

置いていかれないように自分も頑張ります。
プライベートDocker-Registryにhttpで接続 [Docker-ce Linux]

###環境
CentOS 7.4.1708
docker-ce.x86_64                      17.12.1.ce-1.el7.centos        @docker-ce-stable
docker-distribution.x86_64            2.6.2-1.git48294d9.el7         @extras

----
###対象のプライベートDocker-Registry
my-docker-registry:5000
とした場合

----
###設定
daemon.jsonを作る。

```command:/etc/docker/daemon.json
{
 "insecure-registries": ["my-docker-registry:5000"]
}
```
----
###確認
適当なDockerfileでbuildしてみる。

```command:
$ sudo systemctl restart docker
$ sudo docker build -t test .
Sending build context to Docker daemon  8.192kB
Step 1/2 : FROM my-docker-registry:5000/centos:7.4.1708
7.4.1708: Pulling from centos
6fd64836e300: Extracting [================================>                  ]  47.35MB/73.36MB
```

 http: server gave HTTP response to HTTPS client
て怒られなくなった:sunny:

参考：[Daemon CLI(dockerd)-Stable](http://docs.docker.jp/engine/reference/commandline/daemon.html)
「x > 0 and x < 100」と「0 < x < 100」ってどっちの書き方するのがいいか試してみた

# はじめに

Pythonでは、

```py
if x > 0 and x < 100:
```

みたいな範囲条件を以下のように書けます。

```py
if 0 < x < 100:
```

英語っぽく書けるようにって配慮でしょうね。
ふとどっちの方が速いのか気になりました。

# ともかく測ってみよう

計測用コード

```py:perf.py
import random
import time
import numpy as np

random.seed(1234)
arr = []
for _ in range(10):
    s = time.time()
    for _ in range(1000 * 1000):
        x = random.random()
        if x > 0.2 and x < 0.8:
            pass
    e = time.time()
    arr.append(e - s)
print(np.average(arr))

random.seed(1234)
arr = []
for _ in range(10):
    s = time.time()
    for _ in range(1000 * 1000):
        x = random.random()
        if 0.2 < x < 0.8:
            pass
    e = time.time()
    arr.append(e - s)
print(np.average(arr))
```

実行結果

```
0.322909283638
0.334062027931
```

実行ごとに差はあるけど自分でand書いた方が速い。

# どう実行されるのか見てみよう

「x > 0 and x < 100」と「0 < x < 100」がそれぞれどういう命令コードになるのか見てみます。

```py
>>> import dis
>>> co1 = compile('''
... x = 50
... x > 0 and a < 100
... ''', '', 'exec')
>>> dis.dis(co1)
  2           0 LOAD_CONST               0 (50)
              2 STORE_NAME               0 (x)
  3           4 LOAD_NAME                0 (x)
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               4 (>)
             10 JUMP_IF_FALSE_OR_POP    18
             12 LOAD_NAME                0 (x)
             14 LOAD_CONST               2 (100)
             16 COMPARE_OP               0 (<)
        >>   18 POP_TOP
             20 LOAD_CONST               3 (None)
             22 RETURN_VALUE
```

```py
>>> co2 = compile('''
... x = 50
... 0 < x < 100
... ''', '', 'exec')
>>> dis.dis(co2)
  2           0 LOAD_CONST               0 (50)
              2 STORE_NAME               0 (x)
  3           4 LOAD_CONST               1 (0)
              6 LOAD_NAME                0 (x)
              8 DUP_TOP
             10 ROT_THREE
             12 COMPARE_OP               0 (<)
             14 JUMP_IF_FALSE_OR_POP    22
             16 LOAD_CONST               2 (100)
             18 COMPARE_OP               0 (<)
             20 JUMP_FORWARD             4 (to 26)
        >>   22 ROT_TWO
             24 POP_TOP
        >>   26 POP_TOP
             28 LOAD_CONST               3 (None)
             30 RETURN_VALUE
```

xが50とした場合、「0 < x < 100」の方がROT_THREE, JUMP_FORWARD分、命令が多いです。これが「0 < x < 100」の方が遅い理由と思われます。[^1]

[^1]: 「x > 0 and x < 100」と「0 < x < 100」を見比べた場合、前者ではLOAD_NAME、後者はDUP_TOPでxの値をスタックに積んでいます。命令単体としてはLOAD_NAMEの方が時間はかかると思います。

# まとめ

というわけで「x > 0 and x < 100」って書くのと「0 < x < 100」って書くのどちらが速いか、何故速いのかを見てきました。前者の方が速く、後者が遅いのは余分な命令が実行されるからなようです。

ここでちゃぶ台ひっくり返しますが、個人的には後者の書き方の方が好みです。100万回ループして0.01秒しか違わないのなら人間が読みやすい方を選ぶべきです。

# 余談

身近にあるいくつかの環境で試してたのですがたまに「0 < x < 100」式の方が速い環境がありました。gccの違い？関係あるのかな。

# 余談その2

言うまでもないかもしれませんが、大体の言語では「0 < x < 100」と書くと予想に反する結果になります。初心者の人がついついこう書いてしまいがちですよね。

多くの言語では、

```
x = 200
0 < x < 100 → (0 < x) < 100 → true < 200 → true
```

となってしまいます。Javaみたいにbooleanとintの比較ができない言語だとコンパイル時点でエラーになったかな。
Webpack 4を使ってみたらビルド時に[WARNING]が出たので

とりあえず最新構成を使用してVue × TypeScriptの開発をしようしたらWARNINGが出たのでメモを残しておきます。

# 環境
| モジュール名 | バージョン |
|:--|:--|
|mpm|5.7.1|
|Webpack|4.1.1|

# エラー内容
```bash
WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
```
# 原因
`pagckage.json`に本番または開発の構成を追加しないといけないらしい。

# 解決方法
`pagckage.json`に以下の構成を追加

```json
"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}
```
# 使い方
```bash
# 開発時
npm run dev

# 本番時
npm run build
```

# 参考
[公式チュートリアル](https://www.valentinog.com/blog/webpack-4-tutorial/)
nginxのエラーページをphpのheaderで別ページに飛ばせなかった

初投稿です。かなり見苦しい記事になっていますがご容赦ください。

#やりたかったこと
nginx+phpで動いてるサーバーで404のエラーページを別のページに飛ばしたい(404のリクエストはhttp://ドメイン/example/index.phpを参照させたい)。
nginxのlocationで飛ばせば楽なんだけど複数ドメインを1つのserverディレクティブで管理していて、ドメインごとにエラーページの仕様が違う(元々404は/html/ドメイン/error_page.phpを参照することになっている)のでそれは無理。なのでphpでリダイレクトを掛けることにした。

#headerで飛ばそうとしたらうまくいかない
phpのリダイレクト方法を調べたら

```
<?php
header('Location: http://example.com/');
exit;
?>
```

を使ってる記事が多かった。
この方法でパパっとerror_page.php作ってサーバーに置いて動作確認。
http://ドメイン/error_page.phpにアクセスしたらちゃんとhttp://ドメイン/example/index.phpに飛んでるし問題ないかと思った。
だけど、試しにhttp://ドメイン/hoge.html(存在しないファイル)にアクセスしたら画面が真っ白で何も表示されない。nginxからリダイレクト掛けるとphpが動作しないのかと思ってechoとかphpinfo()とか試したらこれは動く。これで見事にハマった。

#原因
色々調べてたら[このフォーラム](https://stackoverflow.com/questions/29953113/php-header-redirect-works-on-apache-but-not-nginx)が見つかった。
要は「header関数はページの先頭で呼び出す必要があってnginxとかのホストから呼び出された時は上手くいかないよ！代わりに別のリダイレクト使ってね。」みたいな事らしい。

header関数を使う時はファイルの先頭を<?phpから始めないとダメで改行1個あるだけで動かないらしく、その辺が影響したのかと思われる。

#まとめ
言われた通り別のリダイレクトを使うことにした。
さっきのフォーラムに書いてあった

```
echo "\<meta http-equiv='refresh' content='0;url=http://ドメイン/example/'>";
```

でリダイレクトしてあげれば無事に飛ばせるようになりました。
【React Native】Facebookログインで使用してるFacebookアプリ切り替え時にする管理画面の操作とソース変更箇所 for Android

## やりたいこと
AndroidでFacebookログイ認証を使用しています。
Facebookの管理画面で別のアプリ(スマホアプリではなく、Facebook管理画面上のアプリ)に
向き先を変更したいです。

## 前提
すでにFacebookログインの実装が完了している前提のため、
Facebookログインを導入っする方法は記載していません。

## 管理画面
https://developers.facebook.com/apps/

## 変更箇所
### 管理画面
Google Playパッケージ名：バンドルID
クラス名：.MainActivity
キーハッシュ：
＊キーハッシュの取得方法
https://qiita.com/kondoakio/items/9ec5c78bee21720dfb19

### strings.xml
android/app/src/main/res/values/strings.xml

```
<string name="facebook_app_id">{アプリID}</string>
<string name="fb_login_protocol_scheme">fb{アプリID}</string>
```
XCTest + Carthage でフレームワークをリンクさせる手順

#問題
Carthageでライブラリを導入したものをXCTestでテストしようとしたら、`ld: framework RxCocoa not found for architecture x86_64` のようなエラーが出ました。

#解決
Test targetの`Link Binaries With Libraries`にCarthageで入れたフレームワークを追加します。

#参考
https://github.com/Carthage/Carthage#adding-frameworks-to-unit-tests-or-a-framework
メンテナンスしやすいコードを書こう（その３）

#1. 今回お話しすること
+ 「メンテナンスしやすいコード」という軸でまとめたよ
+ [前回](https://qiita.com/tie1120/items/f7445e410cab79c94d0c) [前々回](https://qiita.com/tie1120/items/2f491469f7f384db6715)の続きだよ
+ Javaやjavascriptコードを想定して説明を書くけど、全言語共通で使えるテクニックだよ
+ 私個人の考えなので、「いいな」と思うものだけピックアップしてもらえたら何よりです


#2. テクニック集

##2.1. 定数や変数に入れる数値は、根拠があるなら式も書こう

何らかの処理を許可する時間の上限を保持する定数を例に考えます。

``` java:修正前
public static final long ACCEPT_TIME_LIMIT = 259200000L;
```

どうですか？
この数字を見ただけで、何を意味しているか分かりますか？


``` java:修正後
public static final long ACCEPT_TIME_LIMIT  = 3 * 24 * 60 * 60 * 1000;
```

こう書かれているとどうでしょうか。
24 * 60 * 60という箇所で「1日の秒数」というところがわかり、さらに1000倍しているところで「ミリ秒」を、3を掛けているところで「あ～3日分をあらわすミリ秒なのね」と想像がつきます。定数として値を持つときに、何らかの計算を行った最終的な結果の値だけを書いてしまいがちです。これをきちんと分解して書いておくことで、コードレビュー時にレビュワーが仕様との突き合わせもしやすいですし、かつ今後メンテナンス時も見ただけで数字の意味が分かります。

##2.2. 範囲をあらわす比較演算子は、並びを工夫しよう

※ここで紹介するテクニックは、世間一般的な文化とは相反するものです。コメント欄にいろんなご意見を頂いています。世間と異なることをするデメリットもあると思うので、実際に導入する際はご注意ください。

``` java:修正前
// 100以上500以下の場合のみ処理を行う
if(value >= 100 && value < 500){
  // 処理
}
```

``` java:修正後
// 100以上500以下の場合のみ処理を行う
if(100 <= value && value < 500){
  // 処理
}
```

人間が数字を認識するときは、左ほど数字が小さく、右に行くほど数字が大きくなる数直線をイメージします。そのため数字の範囲を示すときはその数直線通りの順番になるように入れ替えることで、可読性が上がります。

ただし、「valueは100以上、valueは500未満」という形で主語述語形式で理解したほうがわかりやすい方もいます。各組織に合わせて、わかりやすいほうを使うといいでしょう。


##2.3. ListやMapを返すようなメソッドを作る場合、なるべくnullを返さない

``` java:修正前
public List<Long> getList(){

  if(XXX == 0){
    return null;
  }

  List<Long> list = new ArrayList<>();
  for(i = 0; i < XXX; i++){
    list.add(YYY);
  }

}

```

``` java:修正後
public List<Long> getList(){

  List<Long> list = new ArrayList<>();
  for(i = 0; i < XXX; i++){
    list.add(YYY);
  }

  return list;

}

```

何かのListを返したり、Mapを返したりというメソッドを使うとき、そのメソッドがnullを返すかどうかで受け手は身構え方が変わります。nullを返すことがないのであれば、わざわざ毎回``` if(list != null) ```なんて書く必要はないですし、listが空かどうかを判別したければ```list.size() ```で事足ります。nullかどうかが重要になる特別な理由がない限り、利用者にnullを意識させないメソッドは可読性を良くできると考えています。
DOBOT Magicianの初期設定

#DOBOT Magicianが届いたの使ってみる
2018.3.8に研究室のDOBOT Magicianが届いたので箱を開いて設定してみました．しかし，結構苦労してた．そのため，このページに初期設定の記録を留めておくことにしました．

以下は，WIN7で動作確認が成功したときの手順

1. 開梱
2. 本体の通電
3. 制御ソフトのインストール（単純に成功すれば,6.へ）
4. ファームウェアの書き込み
5. 本体と制御ソフトの接続
6. Play-Back Modeで動作確認

#1. 開梱
結構しっかりとした梱包がされている．マニュアル類にはあまり詳しい情報がない．以下のサイトからマニュアルをダウンロードして手順を確認する．

- [最新版マニュアルのURL](https://www.dobot.cc/downloadcenter.html?sub_cat=73#sub-download)

#2. 本体の通電
本体のスイッチをいれるときに中外が必要．マニュアルにある初期状態にロボットアームを持ち上げてからスイッチを押す．インジケータのLEDがオレンジから緑に代わり，ビープ音がなる．

#3. 制御ソフトのインストール
以下のサイトから最新版をインストールする．インストール後は，制御ソフトを起動して，接続ボタンを押し，接続ができれば，成功！

エラーがでたり，接続がうまくいかない場合は，本体裏のResetボタンを短く一度押す．数秒後本体のLEDが緑なれば，接続を再度試みる．これでうまく行けばOK！

その場合は，6.で動作確認ができるはずです．

- [インストールするファイルのURL](https://www.dobot.cc/downloadcenter.html?sub_cat=70#sub-download)

#4. ファームウェアの書き込み
３．でResetボタンを押しても，うまく接続できない場合は，以下を行う．

まずは，デバイスマネージャでCOMポートがUSB-SERIAL CH340で認識されていることを再確認．確認方法はマニュアルに記載されている．

[TechShareさんのサイトのFAQ](https://physical-computing-lab.net/faq/dobotmagicianに接続できない。.html)を参照して，ファームウェアを書き込む.

#5. 本体と制御ソフトの接続
まず，本体を起動（緑LEDの確認）後に，制御プログラムを起動．Resetボタンを押し，制御ソフトの接続ボタンを押す．（私はこれで成功しました）

#6. Play-Back Modeで動作確認
　アーム正面の鍵マークのボタンを押しながらアームを動かし，鍵マークのボタンを離すとそのポジションを記憶する．それを数箇所繰り返して，再生を押すと記憶されたポジションを再生する．

- [私の購入元のTechShareさんのDobot関係の情報サイト](https://physical-computing-lab.net/dobot)


#悪戦苦闘の記録

- [最新版マニュアルのURL](https://www.dobot.cc/downloadcenter.html?sub_cat=73#sub-download)
- [インストールするファイルのURL](https://www.dobot.cc/downloadcenter.html?sub_cat=70#sub-download)

初日は，直感的にインストールして，うまく行かなかった（デスクトップ：Win7にインストール，Macにインストール）．

- Win版はハード的につながるがNetworkエラーで本体を認識できず断念（学内のProxyのためか，，，と思ったが，原因不明）．
- Min版をインストールしてみたが，そもそもMac OS13は対応していないみたい（ソフトウェアは起動したが，本体との接続は不可）．

初日の結論は，本体のFirmwearを更新する必要がありそう，という結論に達した．
二日目は，初日と異なるノートPC：Win7にインストール

- Magician Studio v1.4.15を[前述のサイト](https://www.dobot.cc/downloadcenter.html?sub_cat=70#sub-download)からDL

制御ソフトのインストールがすすみ，最後にシリアル通信のためのドライバーがインストールされた．しかし，制御ソフトがクラッシュして落ち，起動せず．ノートPCがフルすぎるのか．．．OSとの相性が悪いのか．．．諦め　昨日のデスクトップPCにて再チャレンジ

その結果，冒頭の手順で　なんとか初期動作の確認ができた．

##Keywords
DOBOT 接続 できない Magician
自分がFirst issueを作るときのテンプレート

備忘録に過ぎないけど、
こういうノウハウの需要もあるかもしれないので公開します。

最初に準備しないといけないもの（プロジェクトの下準備）はだいたい定型作業です。

つまり、issueとして回すことができるようにするための一歩目はテンプレート作業で、
手順と内容をissueのテンプレートとして用意することで、
仕事(頭を使う)から作業(頭を使わない)に落とした状態で回せるようにします。

以下をコピペして、このメッセージでコミットできたら初期状態は終わりと。


*****
``` 
# The first issue
- [ ] Add place holder and test frame
- [ ] Update test frame as minimum use case
- [ ] Update implements in minimum build
```

```  
ex)
# The first issue
- [x] Add place holder and test frame -> #14  
- [ ] Update test frame as minimum use case
- [ ] Update implements in minimum build
```



*****
``` 
# 最初に解決すべき問題
- [ ] 解決に必要なファイル、クラス、インタフェース、テストのプレースホルダを用意しました
- [ ] 最小限のユースケースにおける、テストの準備を行いました
- [ ] ビルドができる最小限の実装ができました
```

上記における最小限や準備とは、

> テストの中身は失敗状態が返るだけ
> 実装の中身もpublicの呼び出しが行われるインタフェースがあるだけ

という状態を意味します。
sshで接続したくないけどSFTPは使いたい時の設定

# なんでそんなことするの？
面倒だけど、そんな需要もあるところにはあるのです。
OSはCentOS6です。

vsftpdを介した通信(FTPやFTPS)を廃止して、sshで完結するSCPやSFTPを使いたい。でもFTPのように使いたいのでシェルにログインできなくしたい。
そんなときに/sbin/nologinで制限すると、シェルログインできなくなりますが、勢い余ってSFTPも使えなくなってしまいます……
# 「でもあきらめたくない！sshは制限してSFTPだけ使いたい！あ、面倒な方法以外でね＾＾ｖ」
そんなクッソワガママなあなたにピッタリの方法がこちら↓

```bash
useradd -s /usr/libexec/openssh/sftp-server hogehoge
```
通常は「/sbin/nologin」と書くところに、sftp-serverを突っ込みます。ユーザーの名前(hogehoge)は適宜書き換えてください。
sftp-serverの場所は違うかもしれないので、そのときはfindコマンドで見つけるなりしてください。
ちゃんとこれで動きます。かなり乱暴な気がしないでもないですが……

# 参考ページ
sshを制限してsftpだけ許可する - GeekFactory
http://int128.hatenablog.com/entry/20100126/1264511908

上記記事の設定方法を端折っただけです。
元記事のほうが丁寧な設定だと思いますが、ワンライナーで済むというのもいいのかな？
【React Native】Facebookログインで使用してるFacebookアプリ切り替え時にする管理画面の操作とソース変更箇所 for iOS

## やりたいこと
iOSでFacebookログイ認証を使用しています。
Facebookの管理画面で別のアプリ(スマホアプリではなく、Facebook管理画面上のアプリ)に
向き先を変更したいです。

## 前提
すでにFacebookログインの実装が完了している前提のため、
Facebookログインを導入っする方法は記載していません。

## 管理画面
https://developers.facebook.com/apps/

## 変更箇所
### 管理画面
バンドルIDを新しいアプリ(Facebook管理画面上のアプリ)


### info.plist
```
<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleURLSchemes</key>
  <array>
    <string>fb{アプリID}</string>
  </array>
  </dict>
</array>
<key>FacebookAppID</key>
<string>{アプリID}</string>
<key>FacebookDisplayName</key>
<string>{表示名}</string>
```
Powershell で読み取り専用属性を変更する

# 環境

* Powershell v5.1
* Windows 10

# 読み取り専用かどうかを調べる

`Get-ChildItem`（または`dir`）コマンドでModeが`r`になっているものが読み取り専用です。

```
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---       2018/03/09     12:34              2 memo.txt
```

# 読み取り専用にする

読み取り専用にするには`IsReadOnly`を`true`にします。

```powershell
Set-ItemProperty memo.txt -Name IsReadOnly -Value $true
```

読み取り専用を解除するには`$true`を`$false`にします。

# 複数のファイルを変更

ワイルドカードを使ってディレクトリ配下のファイルを一括で変更できます。

```powershell
Set-ItemProperty .\* -Name IsReadOnly -Value $true
```

ただし、ディレクトリには読み取り専用属性が存在しません。変更対象にディレクトリが含まれている場合は下記のエラーメッセージが表示されます。

```
Set-ItemProperty : プロパティ bool IsReadOnly=False が存在しないか、見つかりませんでした。
```

このような場合は、ファイルだけをリストして変更します。

```powershell
Get-ChildItem -File | Set-ItemProperty -Name IsReadOnly -Value $true
```

サブディレクトリに含まれるファイルすべてを対象にしたい場合は`-Recurse`をつけます。

```powershell
Get-ChildItem -File -Recurse | Set-ItemProperty -Name IsReadOnly -Value $true
```
gitのpre-commitを使ってbuildに失敗するコミットを防ぐ

## 問題だったこと

私はgoでコード書いていてしばしばコミットした後にbuildしてエラー。
修正してコミットみたいな生産性の低いことをやっていました。

これをどうにかするためにgitのpre-commitを使ってみることとしました。

## 手順

```
$ vi .git/hooks/pre-commit
```

```bash:pre-commit
#!/bin/sh

# build project
build_result=$(make)
build_rc=$?
if [ $build_rc -ne 0 ] ; then
	echo "git pre-commit check failed: build failed."
	exit 1
fi
```

```
$ chmod +x .git/hooks/pre-commit
```

これでcommit時にmakeコマンド(build命令していると思ってください)が走って
失敗した場合はcommitが作られないようになります

## サンプル

```
$ vi main.go
```

```go:main.go
package main

func main() {
	a := 1
}
```


```bash
$ git add .
$ git commit -m "init"
github.com/smith-30/sample-git
# github.com/smith-30/sample-git
./main.go:4:2: a declared and not used
make: *** [build] Error 2
git pre-commit check failed: build failed.
```

修正

```go:main.go
package main

import "fmt"

func main() {
	a := 1
	fmt.Println(a)
}
```

```
$ git add .
$ git commit -m "init"
[master d34bde1] init
 1 file changed, 8 insertions(+)
 create mode 100644 main.go

# yatta
```

## 参考

https://gist.github.com/tamas-molnar/b76f7cc64902dbcf10f2
RDSのSnapshotのリストをCLIから確認したい

# AWS CLI
```
aws rds describe-db-snapshots
```
リストで取得される。


https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-snapshots.html

```
  describe-db-snapshots
[--db-instance-identifier <value>]
[--db-snapshot-identifier <value>]
[--snapshot-type <value>]
[--filters <value>]
[--include-shared | --no-include-shared]
[--include-public | --no-include-public]
[--cli-input-json <value>]
[--starting-token <value>]
[--page-size <value>]
[--max-items <value>]
[--generate-cli-skeleton <value>]
```
Python matplotlib 使えるフォント一覧の作成

# はじめに
matplotlib でフォントを指定したい場合，フォント名とそのパスが必要となります．

[例えばこれ：https://qiita.com/damyarou/items/98ba9a3c4dbfd5c71ab0](https://qiita.com/damyarou/items/98ba9a3c4dbfd5c71ab0)

その時，フォントの一覧表を参照したいわけですが，私は ImageMagick をインストールしているので，ターミナルで

```
convert -list font
```

を実行し，パスをコピーして使っています．この方法のいいところは，既にフォント名がABC順でソートされており，使いたいものを探しやすいところです．

でもせっかく Jupyter notebook を使っているので，Jupyter notebook 上の Python
 で，使えるフォント一覧を出してみることにしました．

### 参考サイト
+ [python matplotlib 内で日本語を利用する(使用できるフォントを探す)](http://paper.hatenadiary.jp/entry/2016/11/06/222223)
+ [pandasで表示が省略されるのを防ぐ](http://uyamazak.hatenablog.com/entry/2016/09/29/163534)


# やっていることの説明
matplotlibのフォントマネージャーと，データをソートするためpandasをインポート．

```python:
import matplotlib.font_manager as fm
import pandas as pd
```

フォントパスの取得とリストへの格納．これだとフォントファイル名がパス付きで出てくるため，使いたいフォントを探すのに不便です．

```python:
fonts = fm.findSystemFonts()
```

フォントファイル名とフォントファイルパスを分離する作業．
フォントファイル名のみは，リスト ```fna``` に格納しています．
また，pandas で表示が省略されないようにするため，フォントファイル名とパス名の文字数をリスト ```l1``` と ```l2``` に格納していきます．

for文を回し終わったところで数字の確認出力．

```python:
fna=[]
l1=[]
l2=[]
for font in fonts:
    text=font.strip()
    text=font.split('/')
    fna=fna+[text[-1]]
    l1=l1+[len(text[-1])]
    l2=l2+[len(font)]
print('length of list-fna       =',len(fna))
print('length of list-fonts     =',len(fonts))
print('character length of fna  =',max(l1))
print('character length of fonts=',max(l2))
cl=max(l1)+max(l2)
```

pandasのデータフレームにリストをセット．

```python:
df=pd.DataFrame({
    'fname': fna,
    'path' : fonts
})
```

pandasでの表示が省略されないよう，行数と列の文字数を変更します．
行数は，フォントファイル名のリストの長さ，列の文字数はフォントファイル名とパス名の文字数の最大値の和としています．

```python:
pd.set_option('display.max_rows',len(fna))
pd.set_option('display.max_colwidth',cl)
```

フォントを探しやすいように昇順（ABC順）でソートして表示．

```python:
df=df.sort_values(by='fname')
df
```


# プログラム全文

```python:
import matplotlib.font_manager as fm
import pandas as pd

fonts = fm.findSystemFonts()
fna=[]
l1=[]
l2=[]
for font in fonts:
    text=font.strip()
    text=font.split('/')
    fna=fna+[text[-1]]
    l1=l1+[len(text[-1])]
    l2=l2+[len(font)]
print('length of list-fna       =',len(fna))
print('length of list-fonts     =',len(fonts))
print('character length of fna  =',max(l1))
print('character length of fonts=',max(l2))
cl=max(l1)+max(l2)
df=pd.DataFrame({
    'fname': fna,
    'path' : fonts
})
pd.set_option('display.max_rows',len(fna))
pd.set_option('display.max_colwidth',cl)
df=df.sort_values(by='fname')
df
```
上記を実行すると，pandasの表が表示されます．
フォントファイル名をABC順に並べたので，使いたいフォントパスを探しやすいです．


以　上
ACMのInternational Conference Proceedings Seriesの利用手順

# ACMのInternational Conference Proceedings Series(ICPS)とは??
学術目的の国際会議のオーガナイザーが，プロシーディングスを出版するときに使える有料のサービスです（個別の論文の出版ではありません）．2018.3現在，下記の料金で利用が可能です．小規模の会議に有利になるかも．
https://www.acm.org/publications/icps-series

参考までに私が担当した[CEA2017はこんな感じ](http://dl.acm.org/citation.cfm?id=3106668)で公開されています．

2018年7月以降に出版予定のものは下記の料金になるようです（２０１８年３月現在の情報）．

> Incidental charges include the following:
> a) Non-refundable application fee: US $50
> b) DOI registration fee: US $1 per article published
> c) iThenticate plagiarism detection fee: US $0.55 per accepted article
> d) Library of Congress Proceedings Registration fee: US $80 per proceedings volume
> e) ISBN acquisition and registration Fee US $1.50 per proceedings volume

ざっとですが，日本語にすると下記のような感じでしょうか?
a. 応募費用（返却されない） $50
b. DOI番号(論文毎に割り当ててくれる）の登録費: 出版される論文1篇あたり $1
c. 盗作・剽窃のチェックソフト(iThenticate plagiarism)による検出費用: 採録論文1篇あたり $0.55 
d. "Library of Congress Proceedings"への登録費用: volumeあたり $80
e. ISBNの獲得・登録費用: volumeあたり $1.50

2017年度までは，確か20篇以下の場合でも一律$500という料金設定だったので，かなり安くなったような印象です．

# 利用するモチベーション
国際会議などで，プロシーディングスを出版する場合，ISBNがつくかどうかなどによって投稿の価値が大きく変わります．また，ACMから出版されているということで，怪しい営利目的のものではなく，学術目的だとある意味で権威付けを受けることができます．このことは投稿件数に顕著に影響するでしょう．

また，そもそも自分で公開し，管理するのはかなり難しいので，その点でも最初に一度お金を払ってしまえば，あとは未来永劫管理してくれるという点でも非常に有用なサービスだと思います．

それから，これも重要だと思いますが，ACMのtex templateを利用できます．下記はCEA2017におけるAuthor Instructionからの抜粋です．

>
The proceedings of CEA2017 will be published in the ACM Digital Library within its International Conference Proceedings Series. All papers must be written in English and should be formatted using [the ACM proceedings templates](http://www.acm.org/publications/article-templates/proceedings-template.html/).
>
NOTE: Authors of CEA2017 must use the "sigconf" proceedings template.
NOTE: CCS code generation support tool is available [here](http://dl.acm.org/ccs.cfm)

# 作業のハマりどころ
利用手順の詳細については[ICPSのinstraction](https://www.acm.org/publications/icps-instructions)を参照して下さい．ちょくちょく更新されるようです．

非常に大まかに出版までの流れを書くと，以下の作業があります．
1. Web formから申し込んで審査を受ける
2. 原稿を集める(easychairとかmicrosoft cmsとかを利用する)
3. プロシーディングスのメタ情報を作成し，公開準備をする (csvファイルを作る)
4. 支払を行う(国際送金が面倒であれば，クレジットカード払いもメールベースで対応してもらえる）
(支払のタイミングについて，CEA2017のときは投稿件数確定後に支払でしたが，新しく出来たapplication feeについては支払タイミングは不明です．)


また，注意することは下記の2点です．
A. 2に関して，カメラレディ原稿において，著者自身にISBNやDOIの情報を入れてもらうことを忘れると，オーガナイザがtexをコンパイルする，という作業をする羽目になります(私はなりました)．
（いずれにしても，カメラレディのlatex sourceは提出を求めるべきでしょう．)

B. 全著者に対して，ACMのcopyrightsポリシの確認が完了しないと出版してくれません．なので，CfPの段階で，それの対応をしない場合は出版がされない（当日の発表ができるかどうかは敢えて明記せず)などの文言を入れる必要があります．
下記はCEA2017において著者に連絡した内容です．
> #After Acceptance
> All accepted authors must submit the "ACM rights management form", which will be sent to the authors after the acceptance notification. An accepted paper will not be published in the proceedings if the authors do not submit this form by July 10th.

気づいたこと，情報の誤り，改善案などWelcomeです．
GASからhangout chatにPostする

#準備
##WebhookのURLを取得する
チャットルームでWebhookを設定しWebhookURLを取得します。

![chat1.png](https://qiita-image-store.s3.amazonaws.com/0/7695/b3aecb87-3583-96fa-5885-9ffdd9b2a321.png)
![chat2.png](https://qiita-image-store.s3.amazonaws.com/0/7695/dfd90a3a-6988-b52d-d361-c4c050d53c8c.png)

#投稿する

リファレンスのサンプルはPythonで書かれていますがこれをGASで書きます。
https://developers.google.com/hangouts/chat/quickstart/incoming-bot-python#step_2_create_the_python_script

```gs
function myFunction() {
  var url = 'WebhookのURL';
  var botMessage = { 'text' : 'Hello from GoogleAppsScript!'}
  
  var options = {
    'method': 'POST',
    'headers' : {
      'Content-Type': 'application/json; charset=UTF-8'
    },
    'payload':JSON.stringify(botMessage)
  };

  var result = UrlFetchApp.fetch(url, options);
  Logger.log(result);
}
```



あとは実行するだけでwebhookを設定したチャットルームに投稿されます。
![chat3.png](https://qiita-image-store.s3.amazonaws.com/0/7695/e781137c-3a06-440e-a743-8c33744a998d.png)


ちなみにwebhookはURLを知っていればG Suiteドメイン外からでも投稿できるので注意。

#リファレンス
https://developers.google.com/hangouts/chat/how-tos/webhooks
https://developers.google.com/hangouts/chat/quickstart/incoming-bot-python