OmniAICreator/Qiita-1.07M huggingface dataset:
aws cli が profileを読み取ってくれなくてハマった

# やりたかったこと
aws cliでプロファイルを複数指定したかった。
仕事用のプロファイルをdefaultにして、プライベート環境をprivateというプロファイルにしようとしたらregionを読み込んでくれなくて困った。

# 最初にやったこと
以下のように~/.aws/credentialsと~/.aws/configを指定した。

```~/.aws/credentials
[default]
aws_access_key_id=AKIAXXXXXXXXXXXXXXXXXX
aws_secret_access_key=Q+SaNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

[private]
aws_access_key_id=AKIAYYYYYYYYYYYYYYYYYY
aws_secret_access_key=nxO0CYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
```

```~/.aws/config
[default]
region=ap-northeast-1

[private]
region=ap-northeast-1
```

# 試してみる
```
## dynamoにsample-table-1というテーブルを作る

$ aws --profile=private dynamodb create-table \
        --table-name sample-table-1 \
        --attribute-definitions AttributeName=LockID,AttributeType=S \
        --key-schema AttributeName=LockID,KeyType=HASH \
        --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
You must specify a region. You can also configure your region by running "aws configure".
```
aws configureを実行しろと怒られる。

# 正しくは
```~/.aws/config
[default]
region=ap-northeast-1
[profile private]      ## ←　"profile private"と指定しなければいけない
region=ap-northeast-1
```

# もう一度試してみる
```
$ aws --profile=private dynamodb create-table \
        --table-name sample-table-1 \
        --attribute-definitions AttributeName=LockID,AttributeType=S \
        --key-schema AttributeName=LockID,KeyType=HASH \
        --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
TABLEDESCRIPTION	1526629948.28	0	arn:aws:dynamodb:ap-northeast-1:929250186533:table/sample-table-1	814a448b-4fd8-40cb-8d02-4be323a17927	sample-table-1	0	CREATING
ATTRIBUTEDEFINITIONS	LockID	S
KEYSCHEMA	LockID	HASH
PROVISIONEDTHROUGHPUT	0	1	1
```

作れた。どうでもいいことに10分ぐらいハマってしまったのでメモ。

# 参考
[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html)
BitbucketからGitHubに移行するのに四苦八苦したので記憶記事

※先に伝えますが私はコミットとプッシュとプルしか行わないようなただの大学生です。

##経緯
今までBitbucketを使っていたのですがGitHubの緑のあれが気に入ってしまって、気づいたら課金をしていました。そこでBitbucketからGitHubへ移行することにしました。

##通常の移し方
GitHubの機能によりURLを乗っけるだけで簡単に移せます。
参考サイトURL : https://qiita.com/tackeyy/items/74e87a0300fc091ef259



通常はこれでいけるのですが、今回プッシュ及びリポジトリの容量制限によりBitbucketでは管理出来たのにGitHubでは管理できないものがありました。最初は分からず何度も試してました。
そのせいでメールボックスには"failed"が沢山届いています。つらいです。


##対策(Git LFS)
それを直すために、まずは容量を減らすことを考え、Git LFSを使いました。
いろいろと調べたのですが、私がよく使っているSourcetreeでは少しやり方が違っていました。
参考サイトURL : http://blog.techlab-xe.net/archives/4390

SourcetreeではGiとGit LFSを入れなくてもSourcetreeに入っているので大丈夫なはずです。
(私はこんなものがあることは知っていたのですがGit Bashに該当するとはつゆも知らずGitとGit LFSを入れました。)


![無題3.png](https://qiita-image-store.s3.amazonaws.com/0/252485/3280e28d-9097-fbff-ac09-a4dba8556565.png)
これがGit Bashに該当するものです。

![無題4.png](https://qiita-image-store.s3.amazonaws.com/0/252485/4263e9c9-1286-b703-9300-598c3a1d8917.png)
これがそれを開いた直後のものです。このときのGit LFSのバージョンは2.4.0です。


そしてgit LFSに管理するものを指定します。

```
$ git lfs track "*.png"
```


指定したら確認します。

```
$ git lfs track
Listing tracked patterns
    *.png (.gitattributes)
```




上のようになっていたら[.gitattributes]が自動生成され、コミットするよう指示されます。


ですが、これだけでは最新のコミットのみに適応されるだけで過去のコミットには適応されません。
一回のプッシュ容量的にGitHubの移行は失敗すると思われます。


##対策２
そのため過去のコミットも軽量化します。
これについてはこのサイトを参考にしました。私では理解がまだ足りていないので、細かい説明は割愛します。
参照サイトURL : https://qiita.com/ikmski/items/0faf9eae808ff29f6358


##嬉しい
そうすることで以下のようになります。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3235323438352f35336364366336652d333861392d393731322d623562612d3037623264333566333566312e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/252485/135d028e-6ee6-e792-a643-c2b8e78eecb3.png)
このようにBitbucketのリポジトリ詳細に[Git Large File Storage]に容量が記載されます。サイズはなんとなく隠しました。(LFSでバレるけど…)

このあとで一番上のようにGitHubにコミットすれば移行が成功します。
途中でLFSをどう扱うかの確認が出ますが適宜対応してください。
googleのクラウドでAngularを使う方法

googleのクラウドは、慣れると使いやすい感じがしました。

##説明
この記事は、googleのアカウントを既に持っていると想定して書いてます。
また、既にgoogleのクラウドのアカウントを持っていることを想定して書いています。
まだ、googleのクラウドのアカウントを作っていない場合は、作ってください。
https://cloud.google.com/?hl=ja

##仮想マシンを作る
私は、AmazonやMicrosoftのクラウドも使ったことがあります。
また、paizaのクラウドを使ったことがあります。
paizaの無料クラウドは、２４時間で使えなくなるので、今回googleのクラウドで、開発環境を作ることを試しました。

VMインスタンスを選択すると、仮想マシンを作ることができます。
一年間無料で使える仮想マシンは、かなりCPUパワーが少ないので、標準で選択されている状態で進んで良いか迷うと思います。
私も迷いましたが、デフォルトでチェックされている仮想マシンの状態で作りました。

![スクリーンショット 2018-05-18 15.44.41.png](https://qiita-image-store.s3.amazonaws.com/0/20977/96a7afcd-f19e-fbc5-6b00-64f5dec7ec05.png)

私は、ブートディスクは、画像とは違いUbuntu１６.4を選択しました。

仮想マシンのインスタンスは、画面の右に出るチュートリアルを読んでください。

##npmとNodeのインストール
私は、後で説明するApp Engineのことを知らなかったので、このVMマシンのシェルのコンソールで、
下記のページを参考にして、npmやNodeのインストールをしました。
Ubuntuとnの項目を参考にしました。
http://www.tohoho-web.com/ex/nodejs.html

##App Engineのセット
App Engineを選択します。
![スクリーンショット 2018-05-18 15.49.30.png](https://qiita-image-store.s3.amazonaws.com/0/20977/81e57e2d-c12b-cdc0-b960-18e07b125cc2.png)



この赤い丸の部分を選択して進みます。
私は、既にプロジェクトを作っているので、初期画面を案内できません。
新しくプロジェクトを作った場合は、次のページが表示されると思います。
![スクリーンショット 2018-05-18 15.55.45.png](https://qiita-image-store.s3.amazonaws.com/0/20977/4829d2a8-9045-6e8e-be50-6b91a020bf03.png)

選択できるプログラミング言語が、表示されます。
私は。PHPを選択して作りました。

##App Engineのサンプルアプリについて
App Engineの設定を済ませると画面の右に、チュートリアルが表示されます。
その内容に従って、shellの使い方などを学びます。

##App Engineのシェルのコンソール
App Engineのシェルのコンソールで、Angular CLIのインストールを行います。
```
npm install -g @angular/cli
```

https://angular.jp/guide/quickstart
のページにあるクイックスタートの順番で進めると、サンプルアプリの起動ができます。

なお、ポート番号の変更は、次の画像のように、shellのコンソールの右上のアイコンを選択して行います。![スクリーンショット 2018-05-18 16.05.09.png](https://qiita-image-store.s3.amazonaws.com/0/20977/0f443b27-f1ff-0a84-343a-06b1c9f5ffee.png)

他人のアプリをインストールして動作確認する時は。インストールしたアプリのディレクトリに移動して、下記のコマンドを実行すると、必要なものをインストールしてくれます。

```
npm install
```

googleのクラウドは、使いやすいと思いました。

##加筆訂正します
Compute Engineで仮想マシンを作らなくても、App Engineで開発できることを知りました。
対応している言語などは、下記のリンク先のページで確認できます。
https://cloud.google.com/shell/docs/features#language_support

npmは、最初からインストールされています。
PHPでfopenとかcURLとかでSSL関連のエラーが発生して困ってます

# はじめに
PHP（NGINX + PHP-FPM）から外のサーバにHTTPS通信をしたときにエラーが出るようになりました。

* 相手方の証明書に問題はない
* 複数のサーバ（クラウドサーバ、VPS)で発生

という状況でした。


# 事例1
WordPressのJetpackからTwitterへの自動投稿でエラーが出るようになっていました。

<img width="579" alt="Screen_Shot_2018-05-18_at_15_32_02.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/47327/d75372a1-81c3-4c69-1e51-477adc78116a.jpeg">

# 事例2
こちらもJetpackですが、HTTPSの通信でエラーが発生していました。

<img width="988" alt="Screen Shot 2018-05-18 at 15.34.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/dd6bb8c5-7564-88df-a5c8-3c5bc5511269.png">

# 事例3
PHPのcURL系（この場合はSimpleXML）でエラー。

```
Warning: simplexml_load_file(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mnt/example.com/wp/wp-content/themes/example/functions.php on line 506

Warning: simplexml_load_file(): Failed to enable crypto in /mnt/example.com/wp/DocumentRoot/wp-content/themes/example/functions.php on line 506
```

# 事例4
file_get_contents（fopen）で外部を開いた時にエラー。

```
2018/05/09 15:41:47 [error] 9268#0: *1641694 FastCGI sent in stderr: "PHP message: PHP Warning:  file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mnt/example.com/wp-content/themes/example/functions.php on line 468
```

```php:test.php
var_dump('hoge');
ini_set('display_errors', true);
echo file_get_contents('https://example.com/hoge.jpg');
```

```
Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mnt/example.com/test.php on line 4

Warning: file_get_contents(): Failed to enable crypto in /mnt/example.com/test.php on line 4

Warning: file_get_contents(https://example.com/test.jpg): failed to open stream: operation failed in /mnt/example/test.php on line 4
```
# 経過
同じテストコードを使ってPHP7.2系で発生していて、PHP7.0だと発生していません。
バージョンによるデフォルトのコンフィグが原因かも…。

PHP7.0系のOpenSSL
<img width="964" alt="Screen Shot 2018-05-18 at 16.36.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/1deebab2-e653-11bf-1b53-c36fb7017821.png">


PHP7.2.5のOpenSSL
<img width="971" alt="Screen Shot 2018-05-18 at 16.36.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/3462c058-5046-2587-c6c5-a71eac667bb1.png">
【Windows】Dockerでmysqlのデータ領域をローカルにバックアップする際の注意点


## 結論
Windows上でdocoker-machineを使ってmysqlのデータ領域をローカルにバックアップするときは、トップレベルに定義したvolumesを使わないといけない（ただし無理やり回避することは可能）。
※docker for Mac の場合は問題なし

#### ダメな例
```yaml

version: "3"
services:
    db:
        image: mysql:latest
        volumes:
            - ./.data/db:/var/lib/mysql
            - ./db-data/mysql.dump.sql:/docker-entrypoint-initdb.d/install_wordpress.sql
        ・・・
```

#### OKな例
```yaml
version: "3"
services:
    db:
        image: mysql:latest
        volumes:
            - db-data:/var/lib/mysql
            - ./db-data/mysql.dump.sql:/docker-entrypoint-initdb.d/install_wordpress.sql
        ・・・
volumes:
    db-data:
```

## 問題
以下の記事を参考にdockerでwordpress開発環境の構築をしました。
[docker-compose を使って WordPress テーマ開発環境を構築しよう – PSYENCE:MEDIA](https://tech.recruit-mp.co.jp/infrastructure/post-11266/)
上記の記事ではトップレベルのvolumes内で定義したvolumesを使う方法が紹介されていました
[Docker の Data Volume まわりを整理する](https://qiita.com/lciel/items/e21a4ede3bac7fb3ec5a)

この方法だと、ローカルの中で永続化されているので`dokcer-compose down -v`などでvolumeごと削除すると永続化したデータが消えます。
なので、更新するごとに`docker exec -it dbコンテナ名 sh -c 'mysqldump データベース名 -u データベースユーザ名 -pデータベースパスワード 2> /dev/null' > db-data/mysql.dump.sql`として、データを保存しないといけません。

手元にデータを置いておきたかったのでトップレベルのvolumesを使わずに、ホスト側のディレクトリに保存することに。
公式のやり方もこっちだったので以下を参考に。
[クイックスタート・ガイド：Docker Compose と Wordpress — Docker-docs-ja 17.06.Beta ドキュメント](http://docs.docker.jp/compose/wordpress.html)

しかし、このやり方だとWindowsでdocker-toolboxを使っている場合（Windowsは大体そうだと思いますが）上手くいきません。
（なお、手元のdocker for macでは上手く動きました）
以下の記事に詳しくまとまっています。無理やり回避する方法も載っているので、どうしてもhost側に置きたい場合はどうぞ。
[docker composeでMySQLのデータ領域をローカルにマウントする | WEB EGG](https://blog.leko.jp/post/how-to-mount-data-volume-to-local-with-docker-compose/)

## まとめ
||volumesトップレベル定義|host側のディレクトリにマウント（通常の方法）|
|:--:|:--:|:--:|
|Windows docker-toolbox|〇|×|
|docker fot mac|〇|〇|
Ubuntuでセキュリティアップデートのみ実行する

- `unattended-upgrades`を使用するのが筋
    - https://qiita.com/key/items/60c43e3f97828b219436

なぜか`unattended-upgrades`でセキュリティアップデートできない場合は以下の手順でアップデートできます。

### セキュリティアップデートのあるパッケージを特定

```bash
ubuntu@ip-10-1-0-7:~$ sudo apt upgrade -s |grep security
Inst libxslt1.1 (1.1.28-2.1ubuntu0.1 Ubuntu:16.04/xenial-updates, Ubuntu:16.04/xenial-security [amd64])
Conf libxslt1.1 (1.1.28-2.1ubuntu0.1 Ubuntu:16.04/xenial-updates, Ubuntu:16.04/xenial-security [amd64])
```

### 特定したパッケージのみアップデート
`apt-get install`を使う。

```bash
ubuntu@ip-10-1-0-7:~$ sudo apt-get install libxslt1.1
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  libxslt1.1
0 upgraded, 1 newly installed, 0 to remove and 6 not upgraded.
Need to get 145 kB of archives.
After this operation, 478 kB of additional disk space will be used.
Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu xenial-updates/main amd64 libxslt1.1 amd64 1.1.28-2.1ubuntu0.1 [145 kB]
Fetched 145 kB in 0s (899 kB/s)
Selecting previously unselected package libxslt1.1:amd64.
(Reading database ... 52139 files and directories currently installed.)
Preparing to unpack .../libxslt1.1_1.1.28-2.1ubuntu0.1_amd64.deb ...
Unpacking libxslt1.1:amd64 (1.1.28-2.1ubuntu0.1) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
Setting up libxslt1.1:amd64 (1.1.28-2.1ubuntu0.1) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
ubuntu@ip-10-1-0-7:~$
```

### セキュリティアップデートが完了したことを確認

```bash
ubuntu@ip-10-1-0-7:~$ sudo apt upgrade -s |grep security
ubuntu@ip-10-1-0-7:~$
```

### おまけ:yumの場合
環境によりますがだいたい↓これでいけます。

```bash
 yum --security update
```
Qiitaの目次は見出しが長い場合にどのように表示されるのか？

# H1 私は時間けっしてその評らとしてのの中にあるたた。同時に以後に鑑定らはもしわが話たなくらいになるがいんがは買収来なありけれども、とてもには落ちありでたでしょ。人格が行きたのはいったい九月にすでにうないた。最も岡田さんを教育中学それほどまごまごがあるで人その封建彼らか自失をについておお尋ねないなですたて、その前はそこか自分手になくなっから、嘉納さんののに学校のあなたで同時にお建設とよしが私主義に小料簡がきまらようにまあお講演を起らなたて、よくもし病気で考えませているん事が着るませ。

## H2 だからまた同国家に上る事はなるべく丁寧となるですで、どんな鉱脈をは云っですてという他人で云っているでた。ある所中の後その根柢は私中のするたかと大森さんをなっませなら、絵の事実たというお濫用うませなと、時代のために防を以後までの人を場合載せていから、これからの十月を命じけれどもどんな後を何だか弱らですなとしうのないて、好いたうてたったご理由得なのましょですです。及び人か自由か観念の暮らしましけれども、昔上評語へ見合せて来るでしょうちをお講演の絶対に取り消せなた。たくさんにはとうてい畳んからするですないんないて、はなはだけっしてありて内約は全く若いですものない。またはお品評が握るてもならあるものますと、人がは、もしそれか来が進んれるですたされなけれなと知れが、断りはさで来るずた。

### H3 けっしてようやくもまして繰り返しというしまっあって、私にも先刻上なり私の肝排斥はやむをえなかっ考えいるないた。あなたはもう観念のものがご自覚は考えているでたううて、一三の国家をはっきり踏みましとかいう立脚ないて、またその最後の自分をしれるが、これかをこれの先生にお話しをいっているですのんなと唱道云えて尊敬いうありないた。

テキスト：夏目漱石『私の個人主義』
Speech API のトラブル

Long-running operation had neither response nor error set

音声データ12分程度をグーグルストレージにアップ　＞　python で API に投げるってことをしたら、上のエラーが発生。
google 翻訳によると下の通り

"長時間実行される操作では、応答もエラーも設定されませんでした"

？
API のセッション維持時間を超えた、、、とか、そんな理由なのかな？
下のgit でも同じエラーに遭遇した方がいるようだが、解決は出来ていない模様。。。
https://github.com/GoogleCloudPlatform/google-cloud-python/issues/4928

ソースが間違ってないか、別の音声ファイルを投げてトライしてみるよ。

いくらかソースを修正して、無事に投げれた。

発生の理由は、恐らく、音声ファイルから言葉を認識できないほど、音質が悪かったかもしれない。
投げた音声データは、m4p 形式だった。
google のオススメはflac 形式で、これで投げたら無事に文字を返してくれた。
JavaScript複雑度の閾値チェック

# 背景
   JavaScriptコードのメトリクス測定がしたい。

   JSでコードメトリクスといえば、Platoという優秀なビジュアライズツールがある。

https://github.com/es-analysis/plato

   しかし、それすら見に行かなくてもいいようにしたい。

   具体的には、複雑度が閾値を超えるコードがpushされてきたら、CIが警告してくれるようにしたい。

# 使用するパッケージ

   complexity-report

## complexity-reportとは

   CLIで複雑度計測。オプションで閾値チェックが可能。

https://github.com/escomplex/complexity-report

### インストール

```
npm install complexity-report --save-dev
```
   
### 実行
   
```
node ./node_modules/complexity-report/src/index.js <JSディレクトリまでのパス>
```

### Platoとの併用
結論から言うと問題ない。

レポート生成と閾値チェックは異なるパッケージを用いることになってしまう。

とはいえ、Platoとcomplexity-reportはどちらも複雑度の計算にexcomplexというモジュールを利用しており、結果の整合性は問題ないはず。

   依存関係をざっくり描くと以下の通り。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79697/c3daa1c3-488d-7bb7-1054-acbd33987da7.png)

バージョンは以下のようになっている。

```
$ npm list --depth=0
...
├── complexity-report@2.0.0-alpha
...
├── plato@1.7.0
...
```

# 監視する複雑度
## Cyclomatic Complexity（循環的複雑度）
### 概要
   if, forなど条件分岐がどれだけあるかによって計算される

###    参考リンク
   https://en.wikipedia.org/wiki/Cyclomatic_complexity

###    下限
   0

###    上限
   なし


###    閾値

   こちらを参考に、メソッド毎に10を超えないようにした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79697/b9d33078-1518-520d-f379-2f07ba67ce25.png)

   https://jp.mathworks.com/discovery/cyclomatic-complexity.html

## Maintainability Index

### 参考リンク

   http://www.projectcodemeter.com/cost_estimation/help/GL_maintainability.htm

### 下限
   0

###    上限
   100

※ただし、この値はマイクロソフトが0から100に正規化した計算式を利用した場合のレンジであり、元の計算式はマイナス無限大から171までの数値で表される。
※Platoは正規化した式でMaintainabilityを算出している。complexity-reportはどちらの式を使用するかオプションで選択できる。


### 概要

保守性。

   SLOC（ステップ数）、Cyclomatic Complexity、Halstead Volume（後述）から算出される総合的な保守性。

   Visual Studioではこれを利用して保守性を判断してくれる。その際の基準値は以下の通り。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79697/e4e18441-e83d-bc34-5f5d-df417f41f009.png)

   あるいは http://www.ecs.csun.edu/~rlingard/comp589/ColemanPaper.pdf の論文では38〜49(原著では正規化前の値で65から85)となっている。

###    閾値
   ファイル毎に50を超えないようにした。

# 監視しなかった複雑度
##  Halstead Difficulty

### 参考リンク

   https://en.wikipedia.org/wiki/Halstead_complexity_measures

### 下限
   0

### 上限
   なし

### 概要
難易度。

学習コストや実装コストの観点から算出される値。演算子や変数の種類と総数から計算される。

いくつ以上が何というものではなく、閾値の基準設定が難しかったので採用を見送った。

# 実際使用しているコマンド

```shell
$ node ./node_modules/complexity-report/src/index.js -n -C 10 -M 50 <JSディレクトリまでのパス>
```

## オプションの説明

```
-n, --newmi                           use the Microsoft-variant maintainability index (scale of 0 to 100)
-M, --minmi <maintainability index>   specify the per-module maintainability index threshold
-C, --maxcyc <cyclomatic complexity>  specify the per-function cyclomatic complexity threshold
```

Platoはnewmiを使っているので、数値を合わせたい場合はnオプションが必要。

# CI連携
今回の目的。

コードは省略。

CircleCIで上記のコマンドを叩いてやれば、閾値判定でジョブを成功させたり失敗させたりできる。

## 実際の運用

1. push時にCIのコンテナが上記のコマンドを叩く
2. 成功/失敗の判定をSlackやGitHubに通知
3. 失敗したら成功するようにリファクタリングする

# まとめ

## JSコードメトリクスの閾値チェック
* complexity-reportのインストール
* CIジョブ追加: push時に実行
* 失敗条件: Cyclomatic Complexityが11を超える関数またはMaintainability Indexが50を下回るファイルが検出された場合

## JSのコードメトリクスのビジュアライズ
* Platoを使用
* CIジョブ追加: masterマージ時にレポートを生成

今回は、ES5コードで使用しているけれど、全く同じ手順でES6でも使用できるはず。
～～にキレられないための～～メソッド：構文考察

# 序論

水銀構文[[1]](https://qiita.com/suigin/items/10960e516f2d44f6b6de)やイショティハドゥス構文[[2]](https://qiita.com/Ishotihadus/items/bbbb85f54e6a4e7aaac0)に見られるような「～～にキレられないための～～メソッド」という記事が話題に登っている。

有用な情報が独特の文体で読みやすくまとまっている点，「キレられないため」という題を冠しながら実際の記事内では閲覧者に対してキレたり皮肉を飛ばしているというコミカルな点などが人気を博している。

総じて，少々辛口ながらも意義のある事柄をきちんとまとめているので有用な記事になっており，（~~そういった意味でも本記事の存在意義が問われる。~~）読みやすく有用な情報を世に広める為に「キレヤクザメソッド構文」の研究開発が求められている。

# Disclaimer
非常に強い煽り言葉を用いるキレメソッドの都合上，発言の責任回避や緩衝材としてDisclaimerを書くことが多いです。
この項では
- あくまで有用な情報の共有を目的としていること
- 誤りの可能性やその際の意見を歓迎する旨
等を書いて議論するという姿勢を残しておきましょう。

本記事はあくまで一個人の考察ですので，意見や修正案などあれば随時受け付けます。
あと，文章の校正をしてないので日本語の体をなしてないところがあるかもしれません。ご容赦を。

# 対象読者
全方位爆撃を仕掛けることのないようにきちんと対象読者を定める。
誤解による無用な争いを避けるだけでなく論点が明らかになる効果もある。
私の場合は

- 暇な人
- キレヤクザメソッド研究者

以上。

# 考察

## タイトル
後半の～～には好きな題材を入れればよいが，前半の～～にはインパクトのある題名を入れたほうが良い。

✕ 先生にキレられないための輪講資料作成メソッド
◯ アカデミックギャングにキレられないための輪講資料作成メソッド

ヤクザやオタク，ギャングといったカタカナは見た目にも語感的にもインパクトが強い。

## 本文
文献[[1]](https://qiita.com/suigin/items/10960e516f2d44f6b6de),[[2]](https://qiita.com/Ishotihadus/items/bbbb85f54e6a4e7aaac0)のように有用な情報を並べつつ「してはいけないこと」や「ダメな例」をコミカルに貶めることでメリハリのある文章を書くことが推奨される。

本記事のテーマ的に有用な情報は期待できないので構文紹介でお茶を濁すこととする。
（全然練れていないので誰か言語化頼みます）

### キレ構文 A
1. 何らかの禁止事項について説明
1. 具体的なキレ事例を述べる
1. 煽る
1. 断定的な口調で締める

### キレ構文 B
1. 理想論や目的に関して説明
1. 理由を説明
1. だめな例
1. 諌める


# 例文集：調査輪講資料作成メソッド草案
## 資料は論文形式で
資料の書き方について，未熟な新入生がおぼつかないのもしょうがないかもしれない。
TexやWORDで数式が書けて満足している諸君もいることだろう。

しかしながら最低限読んだ論文にフォーマットを寄せようと努力をして欲しい。
きちんとした論文の体裁が保たれているというのはそれだけで発表者の印象を向上させてくれる。

文字間隔や余白，しょうもない図でスペースを埋めているそこのお前，お前の読んだ論文はそんなフォーマットだったか？

## Latexのすゝめ
上記の体裁に関して言うならLatexを使うのがオススメである。
テキストを打てば自動的に体裁が整うので使えるなら使わない理由がない。
それこそ文献[[1]](https://qiita.com/suigin/items/10960e516f2d44f6b6de)等の文書にある項をキチンと実行して欲しい。

### オンライン環境でのLatex
セットアップが面倒ならsharelatexがオススメ。
Overleafは無課金だと書いた文章が公開されてしまうためである。
[XeLatexを使う記事](https://qiita.com/ishigaki/items/55a0f42cdffd3fcdf4a2)が多く散見されるが個人的にはplatexを使うように[latexmkrcを使った手法が良い](http://ossyaritoori.hatenablog.com/entry/2018/05/09/%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%97%E3%81%AA%E3%81%84%E3%81%A7Tex%E3%82%92%E4%BD%BF%E3%81%86_%EF%BC%88sharelatex_VS_Overleaf%EF%BC%89)と思っている。

イショティハドゥス氏には悪いがplatexをまだ使っており，移行するモチベもあんまりないのでその程度の意見と思ってもらって結構である。

## 新しい内容を調査せよ
調査輪講は当然発表者が新しい内容や知見について調査し報告する場である。
然るになるべく「最新」の文献を調査して紹介することが望ましい。

例えば，先輩などに有力なConferenceやトップジャーナルの名前を聞いて，そこから興味深そうな内容を選べば芋づる式に関連論文が出てくることもあるだろう。


## 参考文献はきちんと埋めたか？
参考文献を埋めればよいというわけではないが，埋まっていないのは論外である。
調査輪講で参考文献が10個切ってるやつは取り組みがどう見ても足りない。
調査輪講はポエムでも小説でもない。
調べた内容があるならその原典をきちんと引用するべきである。
WikipediaやQiitaの記事で各自勉強するのは結構だが論文には載せないでほしい。

## ちゃんとした輪講テーマを選ぶ
本来は一番最初に来るべき内容だが，以上のことを把握した上であえて最後に記述した。
調査輪講をきちんとやるためには適切なテーマ設定が必要であり，適切なテーマ設定には事前調査が欠かせないためである。

これは運営側にも問題があり，何もわからないペーペーを集めて合同で輪講テーマを決めさせる某ネオ千葉工業大学の先XXXXXX工学の輪講等の形式は発表者に負担を掛ける以外に特に何も寄与していない。

お題目が「仲良く協調して一つのテーマ」となっているので学芸会になるのはある程度避けられないだろうし，「興味や研究テーマ基づいて最新の内容について調査せよ」と圧をかければもう少しマシなものになるはずである。
うん，これは言いすぎた気がします。

# 終わりに
質の高い記事を書いた場合はたくさん言うことがあるが，本記事にそんなものはない。

皆さんの良きキレメソッド執筆ライフを願って本記事を終了とします。
ご意見などあればコメントください。
一歩先のDBやserverへ接続する

# データベースサーバへ踏み台サーバを経由してsshトンネリング接続

# やりたいこと
各自端末から踏み台サーバより先のデータベースへ接続する

![スクリーンショット 2018-05-18 15.21.11.png](https://qiita-image-store.s3.amazonaws.com/0/75761/6cb1afd5-a72f-b96e-c4af-88b6d1b4c2b3.png)

# 設定
というか、ワンライナーでトンネリングを張る

```
ssh -f -N -L 13306:dbserver:3306 gatewayユーザー名@bastion
```

自分の端末で13306ポートに接続すると、
dbserver:3306にコネクションが張られる。


# DBへの繋げ方
```
mysql -udbuser -h 127.0.0.1 -P 13306 -p
```

|接続先|Port |
|---  |--- |
|127.0.0.1|13306|

へ設定すると、接続が可能。
ただし、トンネリングを張ったコンソールを閉じると接続は切れてしまうので要注意。

もちろん大前提として、DBサーバへユーザーの作成は必要。
以下、参考手順
https://qiita.com/S-T/items/f454c2668c6805e690e4#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%A8%A9


# 踏み台を意識せずdbserverへssh

 ~/.ssh/config に以下のような設定を追記

```
Host dbserver
        ProxyCommand ssh bastion -i ~/.ssh/key.pem -W %h:%p
        
```

その後
```
ssh dbserver
```
を実施すると、まずは踏み台サーバ(bastion)のPWが聞かれ、その後
dbserverのログインパスワードが聞かれる
MacのQuick Lookの拡張プラグイン

## Quick Lookとは

MacのFinderでファイル上でスペースを押すと、アプリを使わずに内容が表示されるやつ。
拡張プラグインを入れると例えば

* Markdown(README.mdなど)が見られる
* 無拡張子ファイル(Makefileなど)が見られる
* CSVやJSONが綺麗に表示される

## インストール
Homebrewでインストールできる。使うやつだけインストールすれば良いと思う。
選択肢は、

* 無拡張子ファイル
* .mdファイル
* .JSONファイル
* .CSVファイル
* zipファイル
* ソースコードのカラーシンタックス・コードの折り畳み

```bash
$ brew cask install qlstephen
$ brew cask install qlmarkdown
$ brew cask install quicklook-json
$ brew cask install quicklook-csv
$ brew cask install betterzipql
$ brew cask install qlcolorcode
```

それと、QuickLookからコピペできるようにするコマンド。これもあると便利らしいが、僕のPCだと実行しても変わらなかった。

```bash
$ defaults write com.apple.finder QLEnableTextSelection -bool true && killall Finder
```

## 参考
<a href="https://ottan.xyz/quick-look-plugin-78/">OTTAN.XYZ -Macを購入したら最初に導入しておきたいQuick Lookのプラグイン</a>
C++ Builder 10.2 Tokyo > PageControl > タブの色の変更 > 2004年の情報:できない | 別の方法:違和感

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
```

### 希望動作

- PageControl内のタブの色を変更する

### 情報1. Delphi実装例 (2004年)

- [ページコントロールのタブの色の変更](https://www.papy.in/bbs/delphi/200402/04020023.html) @ Delphi Q & A 掲示板

上記を元に以下を実装してみた。

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PageControl1DrawTab(TCustomTabControl *Control, int TabIndex,
          const TRect &Rect, bool Active)
{
    switch(TabIndex) {
    case 0:
        Brush->Color = clAqua;
        break;
    case 1:
        Brush->Color = clLime;
        break;
    default:
        Brush->Color = clGray;
        break;
    }

    if (Active) {
        Brush->Color = clYellow;
    }

    Control->Canvas->FillRect(Rect);
    Control->Canvas->TextOutW(Rect.Left+4, Rect.Top+4, PageControl1->Pages[TabIndex]->Caption);
}
//---------------------------------------------------------------------------
```

タブの色の変更はできない。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/47a27967-1891-6077-2dcd-88a124f6ae5c.png)


### 情報2. STACK OVERFLOW (2011年)

[How can I change the background color of my TTabSheets?
](https://stackoverflow.com/questions/5904353/how-can-i-change-the-background-color-of-my-ttabsheets?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)

- A. styleプロパティを「tsFlatButtons」にする by Johan
- B. themes.pasを参考にしてFormの色を変える by Peter Turner
    - ThemsesEnabled時はclBtnHighlightにする

下図は方法A(tsFlatButtonsにした場合)の結果。
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/4ecd05f2-e59b-1d0e-74a1-1bbb9e7733bd.png)

下図は方法B(clBtnHighlightにした場合)の結果。
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/2572abdc-ce62-2fd2-640b-1e1256aa5117.png)



A,Bどちらの対応にも違和感を感じる。
プログラミングを勉強してWEB APIを使いたい

私はいわゆるウェブデザイナーをやっていて、HTMLやCSSはある程度わかる。
今はウェブディレクター的なことが多い。
これからはプログラムもできないといけないと強く思うので、プログラムを勉強しようと思っている。

プログラムはこれまでも何度も挑戦したが、挫折してきた。挑戦した回数は三桁になるんじゃないかと思う。
挫折した原因はちょっとわかる。
それは、プログラムで作りたいものがなかったから。
何もイメージがない状態で何かを習得できるほど、世界は甘くない。

今はある。
WEB APIを使えるようになりたい。
WEB APIがプログラムというのか？
違う気がする。

WEB APIを勉強したいというよりも、SpotifyのAPIを使っていろいろできるようになりたい、と書いたほうがわかりやすい。
Spotifyの情報を使って、分析とかリサーチをしてみたいと思っている。
もちろんSpotifyだけではなく、SoundCloudとか音楽系のものは全部使ってみたい。

プログラミングをがんばるぞ！という宣誓的な記事です。
計算の順序がわからんのやけど怒怒怒（演算子の優先順位と結合法則について）

# a = b = c = 1 + 2 * 3 - 4 / 5 て、どう読んだらええんや......

```math:
a = b = c = 1 + 2 * 3 - 4 / 5 \\
↓\\
a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))
```
どうやったら、複数の演算子がごちゃまぜになった式の計算順序がわかるんだろう

## 計算の順序を理解する手順
1. 演算子の**「優先順位」**を知る
2. 「同じ優先順位」の演算子の**「結合法則（結合性・結合規則）」**を知る

3. 優先順位と結合法則から、括弧をつけた式に変換する（=式が読めるになる!）
4. 1~3を逆順に行う（=式が書けるようになる!）


**-------以下は「優先順位」や「結合法則」が必要な理由なので、飛ばしてもOK------**
例えば $1 + 2 * 3$のような式は、$(1 + 2) * 3$とも$1 + (2 * 3)$ともとれ、括弧を使わなければ、計算の順序があいまいになってしまう。
でも、(((((((......と永遠にも思える括弧が続く式を読みたいとは、だれも思わない。
優先順位と結合法則があると、計算の順序が定まって、忌々しくも鬱陶しい括弧を使う必要がなくなって、うれしい。

### 1. 演算子の「優先順位」を知る
演算子には、式のどの部分から優先して計算するかの順位、である**「優先順位」**というものがある。
例：*の方が+より優先順位が高いため、$1 + 2 * 3$は$1 + (2 * 3)$と計算する

C言語では以下のような感じ。
[優先順位と評価順序](https://msdn.microsoft.com/ja-jp/library/2bxt6kc4.aspx)
上の表では上から順に優先順位が高い

### 2.「同じ優先順位」の演算子の「結合法則（結合性・結合規則）」を知る
「同じ優先順位」の演算子には、**「結合法則（結合性・結合規則）」**がある。

左から先に計算することを「左結合」という。
左結合の例：+と-は同じ優先順位、かつ左結合のため、$1 + 2 + 3 - 4$は$((1 + 2) + 3) - 4$と計算する

また、右から先に計算することを「右結合」という。
右結合の例：代入演算子=は右結合のため、$a = b = c = d$は$a = (b = (c = d))$と計算する

### 3. 優先順位と結合法則に従って、括弧をつけた式に変換する（=式が読めるようになる!）
括弧をつけた式への変換方法
a. 括弧の内側でないもので、優先順位の最も高い演算子を探し、結合法則を確認する
b. 結合法則に従って、括弧をつける
c. a.bを繰り返し、演算子が探せなくなったら終わり

例: $a = b = c = 1 + 2 * 3 - 4 / 5$
1. *と/が優先順位の最も高い演算子で左結合
2. $a = b = c = 1 + (2 * 3) - (4 / 5)$
3. +と-が優先順位の最も高い演算子で左結合
4. $a = b = c = (1 + (2 * 3)) - (4 / 5)$
5. $a = b = c = ((1 + (2 * 3)) - (4 / 5))$
6. =が優先順位の最も高い演算子で右結合
7. $a = b = (c = ((1 + (2 * 3)) - (4 / 5)))$
8. $a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))$

答え $a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))$

わーい(+0)

### 4. 1~3を逆順に行う（=式が書けるようになる!）
つかれたので後で書く（かかない）

# 怒りの雑記(タグのHaskell成分)
Haskell において、(f.g.h\$x)のような式も、上記の計算の順序と型さえわかればそれほど難しくない。

例：f.g.h\$x
1. (.)が最高で右結合
2. f.(g.h)\$x
3. (f.(g.h))\$x
先に関数同士を結合(.)していって、最後に値を適用($)する、みたいに読める

（以下さらなる怒りの雑記）
いくつかのC/C++に関するページでは、演算子の優先順位に番号を振るとき、優先順位の高い方から順に0,1,2,...としているが、
[BohYoh.com【C言語講座】演算子一覧表](http://www.bohyoh.com/CandCPP/C/operator.html)
[演算子の優先順位-Wikipedia](https://ja.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%AE%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D)
[C++の演算子の優先順位](http://ja.cppreference.com/w/cpp/language/operator_precedence)

Haskellでは、言語仕様で優先順位（precedence）の高い方から順に9,8,...と振られており、混乱する原因なので、気を付けてほしい。てか実際、混乱した。（怒怒怒）
[4.4.2  結合性宣言](http://www.sampou.org/haskell/report-revised-j/decls.html)

あ、あと関数適用(f xの空白部分)はどの演算子よりも優先順位が高いけど、関数適用演算子($)はどの演算子よりも優先順位が低い(infixr 0)だから気を付けてね。（怒怒怒）
Djangoで初期のmigrateが出来ない。(`disk I/O error`)

「teratail」にも質問投げたんですが、文字数制限のせいで、追加情報が載せれなかったので、こっちにも書いておきます。
そもそも何で文字数制限あるんや...

[Djangoで初期のmigrateが出来ない。(`disk I/O error`)](https://teratail.com/questions/126752)

# 追記: 2018/05/18 14:55
原因っぽいもの見つけました。(まだ対処法までは見つかってませんが...)

「②makemigrationsしてから、migrate」でエラーとなっている以下の行から、`contenttypes`のSQLが怪しいと見ました。

```sh
Running migrations:
  Applying contenttypes.0001_initial...Traceback (most recent call last):
  File "/root/.virtualenvs/env1/lib/python3.6/site-packages/django/db/backends/base/base.py", line 239, in _commit
    return self.connection.commit()
sqlite3.OperationalError: disk I/O error
```

そこで、`python manage.py sqlmigarte`にて、実行される各SQLを表示してみました。

```sh
$ python manage.py sqlmigrate contenttypes 0001
BEGIN;
--
-- Create model ContentType
--
CREATE TABLE "django_content_type" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL, "app_label" varchar(100) NOT NULL, "model" varchar(100) NOT NULL);
--
-- Alter unique_together for contenttype (1 constraint(s))
--
CREATE UNIQUE INDEX django_content_type_app_label_model_76bd3d3b_uniq ON "django_content_type" ("app_label", "model");
COMMIT;
```

以下のオペレーションを行ったところ、`COMMIT;`にて`disk I/O error`が発生しました。

```sh
# db.sqlite3を削除
$ rm db.sqlite3

# makemigrations
$ python manage.py makemigrations
No changes detected

# SQLite3に接続し、「contenttypes.0001_initial」で実行されるはずのSQLを手動で実行
$ sqlite3 db.sqlite3 
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> --- tables内に何も無いことを確認
sqlite> .tables
sqlite> --- contenttypes.0001_initialで実行されるはずのSQLを手動で実行
sqlite> BEGIN;
sqlite> CREATE TABLE "django_content_type" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL, "app_label" varchar(100) NOT NULL, "model" varchar(100) NOT NULL);
sqlite> CREATE UNIQUE INDEX django_content_type_app_label_model_76bd3d3b_uniq ON "django_content_type" ("app_label", "model");
sqlite> COMMIT;
Error: disk I/O error
```

ちなみに、BEGINとCOMMITを付けなかったらエラーなく実行できます。

何で`SQLite3`でcommitするだけで、`disk I/O error`になるんでしょう...

# 追記：SQLiteのBegin~Commit/Rollback


```sqlite
sqlite> -- テーブル作ってみる
sqlite> begin;
sqlite> create table dummy (id, name);
sqlite> commit;
Error: disk I/O error
sqlite> -- disk IO error発生した....
sqlite> 
sqlite> -- しかも何故か、生成は成功してる...
sqlite> .tables
dummy
sqlite> -- ロールバックはうまくいく
sqlite> begin;
sqlite> drop table dummy;
sqlite> rollback;
sqlite> .tables
dummy
sqlite> -- コミットは例のごとくerrorになるのに、処理自体は成功する....
sqlite> begin;
sqlite> drop table dummy;
sqlite> commit;
Error: disk I/O error
sqlite> .tables
sqlite> 
```

何なんだ、お前は.....

# 追記：解決！！！
SELinuxが影響してました。
`disabled`じゃないとダメみたいです。

`getenforce`で確認したら`disabled`だったから安心しきってたけど、
再起動してなかったのかな...分からんち。
（**SELinuxは再起動しないと反映されないので注意しよう！！！**）
Python3 で Google Datastore のデータを削除 (Delete)

Google Datastore にある次のデータを削除する方法です。
![datastore_may1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/044507d4-2a18-d8ea-50af-62224fca5531.png)

```py:datastore_delete.py
#! /usr/bin/python
#
#	datastore_delete.py
#						May/18/2018
# ------------------------------------------------------------------
from gcloud import datastore
import sys
# ------------------------------------------------------------------
def datastore_delete_proc(client,name):
	kind = 'Cities'
	key = client.key(kind,name)
	client.delete(key)
#
# ------------------------------------------------------------------
sys.stderr.write("*** start ***\n")
key_in = sys.argv[1]
#
print(key_in)
#
try:
	project_id = "my-project-aug-29-2016"
	client = datastore.Client(project_id)
except Exception as ee:
	sys.stderr.write("*** error *** in datastore.Client ***\n")
	sys.stderr.write(str(ee) + "\n")
#
datastore_delete_proc(client,key_in)
#
sys.stderr.write("*** end ***\n")
#
# ------------------------------------------------------------------
```

実行コマンド

```bash
export GOOGLE_APPLICATION_CREDENTIALS="/home/uchida/my_project_Aug-29-2016-7313bb6c3526.json"
#
./datastore_delete.py t0922
```
Python3 で Google Datastore のデータを更新 (Update)

Google Datastore にある次のデータを更新する方法です。
![datastore_may1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/df9b8b76-07e5-7c89-dde2-1dd2f16a8188.png)

```py:datastore_update.py
#! /usr/bin/python
#
#	datastore_update.py
#						May/18/2018
# ------------------------------------------------------------------
from gcloud import datastore
import sys
import datetime
# ------------------------------------------------------------------
def add_data_proc(client,name,name_city,population):
	sys.stderr.write("name = " + name + "\n")
	kind = 'Cities'
	key = client.key(kind,name)

	task = datastore.Entity(key)

	task.update({
		'population': population,
		'name_city': name_city,
		'date_mod': datetime.datetime.utcnow()
		})

	client.put(task)

	return task.key

# ------------------------------------------------------------------
def name_city_read_proc(client,name):
	kind = 'Cities'
	key = client.key(kind,name)
	results = client.get(key)
#
	return results['name_city']
# ------------------------------------------------------------------
sys.stderr.write("*** start ***\n")
key_in = sys.argv[1]
population_in = int(sys.argv[2])
#
print("%s\t%d" % (key_in, population_in))

try:
	project_id = "my-project-aug-29-2016"
	client = datastore.Client(project_id)
except Exception as ee:
	sys.stderr.write("*** error *** in datastore.Client ***\n")
	sys.stderr.write(str(ee) + "\n")
#
name_city = name_city_read_proc(client,key_in)
add_data_proc(client,key_in,name_city,population_in)
#
sys.stderr.write("*** end ***\n")
#
# ------------------------------------------------------------------
```

実行コマンド

```bash
export GOOGLE_APPLICATION_CREDENTIALS="/home/uchida/my_project_Aug-29-2016-7313bb6c3526.json"
#
./datastore_update.py t0922 98912355
```
Java コンパイルエラー　エンコーディングwindows-31jにマップできません

#とにかくJavaに触れてみる①

続くか分からないけど続きものっぽいタイトルにしてみました。

今まで経験出来なかったJava。
ちょっと憧れのあるJava。
今回やっとチャレンジ出来ると思ったら、目の前で別の人に持っていかれちゃいました。
なので、悔しいから自発的にJavaのお勉強を開始。

#参考サイト
[一番かんたんなJava入門](https://nobuo-create.net/)
[DAY5:エラー: この文字は、エンコーディングMS932にマップできません](https://qiita.com/Mocacamo/items/74d8bbd019b3e139bc02)

#いざ開始

とにかく簡単に始めようと思って、まずは参考サイト様「一番かんたんなJava入門」の
手順通りに環境を整えて、いざ「Hello World」へと思ったらエラー発生。
原因は、JDKとJREのバージョンの差異でした。
こちらは、環境変数の順位を変えてあげることで対応できました。
（私のPC内にはJREがバージョン違いで複数存在していました）

続いて、日本語が入ったプログラムをコンパイルをしようと思ったら
またもやエラー発生。

原因は、文字コードの違いらしく、こちらも参考サイト様「DAY5:エラー: この文字は、エンコーディングMS932にマップできません」を参考に、コンパイル時に文字コードを指定して解決できました。

エラー：この文字(0xEF)は、エンコーディングwindows-31jにマップできません
原因：文字コードの違い
対応方法：「-encoding UTF-8」を付けてコンパイル

```bat
javac -encoding UTF-8 Scores.java
```

#感想
今まで手が出せずにいたJava。
遠くの方で「Javaのバージョンが違うからさぁ～」とか言っていた意味がようやく分かりました。
なかなか業務では経験できないけど、細々と続けていけたらいいなと思っています。
有名なセキュリティ攻撃名おさらい

セキュリティ研修を受けたのでメモ。

内容としては超有名な攻撃とその対策なんだけど、
これを自分の口で説明しようとすると途端に難しい。


#SQLインジェクション
多分もっとも有名なやつ。SQL知っていれば説明不要なんだけど、
SQL知らない人に説明するのがちょっと難しい。

簡単に言うと、DBを操作するSQLって命令をいじる攻撃。
たとえばDBの個人情報盗んだり、データを壊したりできる。
攻撃者にとって自由にDB書けるのと同じ。

```:SQL
SELECT ID FROM USER
WHERE NAME = 'ここにフォーム入力値が入る'
```

とかだったら

```:SQL
SELECT ID FROM USER
WHERE NAME = '' OR 1=1 --'
```
とかやって全件出力させるとかできる。
UNIONとかで別テーブルの中身もごそっと見れるかもしれない。


'とか()とか--とかをエスケープしていないのが原因。

手動でエスケープする必要はなく
ParameterizedQueryとかで回避するのが一般的。
（いい感じにエスケープしてくれる）

うちのJDBCだとLIKEを使いたい時はちょっとめんどくさい。



#クロスサイトスクリプティング(XSS)
クソリプではない。

たとえば記事のコメント欄など、ユーザーが投稿できる部分に
たとえばJavascriptを仕込んだりする攻撃。
cookieを盗めたりできる。
攻撃者にとっては画面を実装できるのと同じ。

対策は、特殊文字をサニタイジング（無害化）すること。
入力するときHTMLの特殊文字<>とかをバリデーションし、
出力するときエスケープする。


#クロスサイトリクエストフォージェリ(CSRF)
早口言葉ではない。

攻撃者が作った別のサイトのリンクを踏ませ、
Web決済をさせたり、退会させたり。

攻撃者にとっては第三者をある程度好きに動かせるのと同じ。


第三者が絡むのがこの攻撃のめんどくさいところ。

対策
・ページトークンを発行・確認する
（最近はWebフレームワークがやってくれる）

----

多分この３つがWEBエンジニアが気を付けないといけない攻撃。
対策とセットで頭にいれておこう。

あとは今日はやらなかったけど、以下有名な攻撃名。


#ディレクトリトラバーサル
サーバルちゃんではない。

相対パス指定`../`とかで、見てほしくない、
権限のない親ディレクトリとかみれちゃう。


#DDos攻撃
田代砲やF5アタックの強化版・全方位版みたいな攻撃。
本質的な対策が難しい攻撃。

IoT経由のDDosが最近人気。一番有名なのがMiraiってマルウェア。
IoT持ち主はパスワードとかを工場出荷設定のままにしないのが大事。




#ゼロデイ攻撃
公式が「脆弱性発見したんでアプデよろ！」って告知だしてから
会社が本当にアプデするまでのタイムラグに攻撃する手法。


#ブルートフォースアタック（総当たり攻撃）
パスワードを本当にしらみつぶしで試行する。
4桁の暗証番号が0000～9999までなら、その1万回試そうという話。
コンピューターならわりと現実的な時間で終わってしまう。


#パスワードリスト攻撃
Twitterのレイバン乗っ取りはこの攻撃らしい。
他で盗んだパスワードを別のサービスでも同じパスワードを使ってるか
サービス横断的に試す攻撃。


#辞書攻撃
世の中で一番使われているパスワードは
123456とかpasswordとかqwertyとかそういうのらしい。
よく使われるパスワードや英単語をベースに
パスワードを手当たり次第試行する攻撃。


#ランサムウェア
ランサム(Ransom)は身代金という意味。
システムを暗号化したりロックしたりして
「このPCを使いたかったらビットコイン送ってね」
などという、実利的（？）なマルウェア。
Liberty for JavaでサーバーのIPアドレスを確認する方法

##Liberty for JavaでサーバーのIPアドレスを確認したい
IBM Cloud (PaaS)上で動作するLiberty for Javaから外部のリソースにアクセスする際に、そのリソース側でIPアドレスによるアクセス制御を行いたい場合があります。このようなケースでは通常StaticaのようなProxyサービスを利用しますが、サーバー側からのアウトバウンドのリクエストの際に使用されるIPアドレスを一時的に確認したいケースもあるでしょう。

##curlを用いて、IPアドレスを返すサービスを呼び出す
sshでcurlを用いて、IPドレスを返してくれるようなサービスを呼び出すことで、IPアドレスを確認することが可能です。
試しに以下の2つのサービスを呼んでみたところ正しいIPアドレスを取得できました。

http://ifconfig.io
http://ip.jsontest.com/

具体的には、以下のようなbxコマンドで確認可能です。
`bx cf ssh appname -c "curl http://ifconfig.io"`

Liberty for Javaのインスタンスが複数の場合には以下のように-iオプションでインスタンス番号を指定して確認します。
`bx cf ssh appname -i 0 -c "curl http://ifconfig.io"`
`bx cf ssh appname -i 1 -c "curl http://ifconfig.io"`

アウトバウンドのIPは固定で付与されているものではないことに注意する必要がありますが、一時的な動作確認などは上記方法を用いても問題ないでしょう。
[django-pyodbc-azure] DjangoのデータベースにSQLServerを使う

## SQLServerをデータベースに使うことは普通に可能

DjangoのデフォルトでサポートしているデータベースサーバはPostgres・MySQL・Oracleの３つです。Djangoを始めた当初SQL Serverに接続する方法を探していたのですが、Googleで「Django SQLServer」と検索しても古い情報しか出なかったり（django-mssql等、更新の止まった古いパッケージの情報は出る）、terataiにも「[できないので諦めろ](https://teratail.com/questions/75801)」という趣旨の回答があったりで、自分もできないもんだと思い込んでいましたが、最近になって現在も継続更新中の接続用パッケージの存在を知りました。

## django-pyodbc-azure について

DjangoからSQLServer への接続用ライブラリです。
Github : https://github.com/michiya/django-pyodbc-azure

Microsoftが公式にサポートしているPython用SQLServer接続ライブラリ「pyodbc」を使ってODBC経由で接続します。

Python SQL ドライバー - pyodbc: 
https://docs.microsoft.com/ja-jp/sql/connect/python/pyodbc/python-sql-driver-pyodbc?view=sql-server-2017

DjangoやMicrosoftの公式サポートではありませんが、[atmarkitの記事](http://www.atmarkit.co.jp/ait/articles/1612/13/news076.html)を見る限りでは準公式的な扱いのように思えます。過去にMicrosoftで公開されていたAzureへのDjangoのデプロイ方法の記事にもこのパッケージが使われています（現在は削除されてflaskの記事に置き換えられている）。

Githubに残っている記事がこれです。

- [Github : Python Tools 2.2 for Visual Studio を使用した Azure 上の Django と SQL Database](https://github.com/yuesan/azure-content-jajp/blob/master/articles/app-service-web/web-sites-python-ptvs-django-sql.md)


Qiitaにも利用している記事がありますね。

- [Azure App Serviceにpipを使用できないパッケージをインストールする]
(https://qiita.com/YuichiNukiyama/items/ad125213c44b4100764b)


Githubのスター数も多いので、今後の継続開発を信じて使ってみたいと思います。

## django-pyodbc-azure の使い方


`pip install django-pyodbc-azure`でインストール後、`settings.py`の`DATABASE`を編集します。


settings.py 例

```
DATABASES = {
    'default': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'mydb',
        'USER': 'user@myserver',
        'PASSWORD': 'password',
        'HOST': 'myserver.database.windows.net',
        'PORT': '',

        'OPTIONS': {
            'driver': 'ODBC Driver 13 for SQL Server',
        },
    },
}
```

driverはデフォルトで「ODBC Driver 13 for SQL Server」を使うので、無ければインストールします。諸事情でインストールできない場合でも既にインストールされている過去バージョンを文字列で指定すれば接続することができます。

参考：[ODBCダウンロードはこちら](https://www.microsoft.com/ja-JP/download/details.aspx?id=50420)


`HOST`はAzureなら`server_name.database.windows.net`、オンプレミスのインスタンスなら`server\instance`です。例えばローカルマシンのExpress Editionに接続するなら`localhost\SQLEXPRESS`となります。

※ただしExpress Editionに接続するには色々と設定が必要です。
参考：[SQL Server Express にリモート接続](https://creativeweb.jp/fc/remote/)

とりあえずローカルマシンとAzureのDBインスタンスに接続して試してみました。マイグレーションでエラーも出ず、問題なく動いています。

DjangoのフィールドとSQLServerのカラム型との対応はこちらのエントリにまとめまています。

- [Django モデルフィールド：データベースフィールド 型対応表](https://qiita.com/okoppe8/items/13ad7b7d52fd6a3fd3fc#sql-server)
一定時間待機する(sleep)

# sleep の代替

Windows には sleep コマンドがないので、WSH で代替。

いつも忘れるので書いておく

> sleep.vbs
>> Option Explicit
>> REM 5分(300秒=300000)待機
>> WScript.Sleep 300000

こんな感じの WSH を

> cscript.exe sleep.vbs

という感じで、bat などから呼び出せば良い
[Rails s]コマンドでエラー多発したけどなんとか起動できたよ

railsいれて、reils newでアプリ作成。
まだapacheいれてないから、
とりあえずPuma使って立ち上げてみようとしたらエラーエラーエラーの連続。
いろいろやったキロク。


## エラー内容

```cmd:エラー
There was an error while trying to load the gem 'uglifier'. (Bundler::GemRequireError)
```
ちなみに「uglifier」ってgemはinstallされてた。


## 対処法その１

とりあえずbundler install してみたらエラー発生。

```cmd:エラー
$ Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from https://rubygems.org/
```

切り分けしたらまさかの名前解決が出来てなかった模様。

```cmd:コマンド
# DNSアドレス変更
$ sudo vi /etc/resolv.conf
```

## 対処法その2

足りてないものある？ってことでいろいろ入れてみる。

```cmd:コマンド
$sudo yum install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel
```

## 対処法その3

node.jsをいれる。

[参考サイト](https://qiita.com/te2u/items/ee8391842397da381e23)

## rails起動

もう1度！

```cmd:コマンド
rails s
```

できたっぽい？

## アクセスしてみる

仮想サーバー内に作成してるので、
ホストOSからそちらさん宛てへ。

http://ゲストIP:3000/

DB作ってないので接続エラーは出てるけど、とりあえず起動成功？
ちゃんと初期画面を見るために、db作ってみる。

## DB作成

```cmd:コマンド
# DBのrootパスを記入。
$ vi config/database.yml
```

17行目の所に追記

```cmd:config/database.yml
     12 default: &default
     13   adapter: mysql2
     14   encoding: utf8
     15   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
     16   username: root
     17   password: ここ
     18   socket: /var/lib/mysql/mysql.sock
```

終わったら、

```cmd:コマンド
$ rake db:create
```

出来たみたいなので、確認。

```cmd:mysql
$ mysql -u root -p

# ログインしたら
>show databases;
```

- アプリ名_development
- アプリ名_test

が無事できた。

もう1度rails起動させてアクセス。

やっと
「Yay! You’re on Rails!」
に出会えた。


おしまい
generating nemesis block for catapult-server

[running catapult-server on ubuntu16.04](https://qiita.com/ryosasa/items/dec70696626c73437a9e)でcatapult-serverが動いたと思った。
しかし、よく考えたらデフォルトのmijin-test.propertiesでnemsis blockを生成してしまったら後でに何もできない気がした。
(最初にxemを持っている人の秘密鍵がわからないため)

ということで、以下、nemesis blockの再作成手順。
これでmijin-test用の409,090,909,000,000 xemゲット!

### address生成
```
cd catapult-server/_build/bin
./catapult.tools.address -g 1 -n mijin-test > ../nemesis.address.txt
cat ../nemesis.address.txt
--- generating 1 keys ---
           private key: E1...
            public key: 82...
  address (mijin-test): SCSBPEXYDODOFC4LHR27KDVKRELXMRERKO4ZPDYV
```

### mijin-test.propertiesに上記address(mijin-test)を設定
```
cp -p ../../tools/nemgen/resources/mijin-test.properties{,.bak} 
# 上記のaddressに変更
vi ../../tools/nemgen/resources/mijin-test.properties
diff -u ../../tools/nemgen/resources/mijin-test.properties{.bak,}
--- mijin-test.properties.bak      2018-05-18 01:37:23.290430662 -0400
+++ mijin-test.properties  2018-05-18 01:24:13.503868857 -0400
@@ -38,7 +38,7 @@

 [distribution>nem:xem]

-SAAA244WMCB2JXGNQTQHQOS45TGBFF4V2MJBVOUI = 409'090'909'000'000
+SCSBPEXYDODOFC4LHR27KDVKRELXMRERKO4ZPDYV = 409'090'909'000'000
 SAAA34PEDKJHKIHGVXV3BSKBSQPPQDDMO2ATWMY3 = 409'090'909'000'000
 SAAA467G4ZDNOEGLNXLGWUAXZKC6VAES74J7N34D = 409'090'909'000'000
 SAAA57DREOPYKUFX4OG7IQXKITMBWKD6KXTVBBQP = 409'090'909'000'000
```

### nemesis block生成
```
mkdir -p ../seed/mijin-test
./catapult.tools.nemgen -r ../../tools/nemgen/resources/mijin-test.properties
cp ../seed/mijin-test/00000/00001.dat ../data/00000

```
[個人的メモ]Atomのキーバインドを変更

# はじめに

最近、Atomに魂を売ったSublime教徒です
Atomにインストールしているpackageで`platformio-ide-terminal`と`atom-runner`の二つで、
それぞれよく使うキーバインドが

ctr-`でターミナルを開く
ctr-rでプログラムを実行

の二つとも`ctr`ではなく、`cmd`で使いためどうすればいいのかを調べたメモです

## やり方

```bash
$ atom ~/.atom/keymap.cson #atomでatomのキーバインドの設定ファイルを開く
```
```yml
'atom-text-editor': 
  'cmd-r': 'run:file' #cmd-rでプログラムの実行
  'cmd-`': 'platformio-ide-terminal:toggle' #cmd-`でターミナルを開く
```
Python3 で Google Datastore のデータを読む (Read)

Google Datastore にある次のデータを読む方法です。
![datastore_may1801.png](https://qiita-image-store.s3.amazonaws.com/0/179446/fd627124-a5a5-22f1-9547-b7fd27490dad.png)

```py:datastore_read.py
#! /usr/bin/python
#
#	datastore_read.py
#						May/18/2018
# ------------------------------------------------------------------
from gcloud import datastore
import sys
import datetime
# ------------------------------------------------------------------
def data_read_proc(client,name):
	kind = 'Cities'
	key = client.key(kind,name)
	results = client.get(key)
	str_out = name + '\t'
	str_out += results['name_city'] + '\t' + str(results['population'])
	str_out += '\t' + str(results['date_mod'])
	print(str_out)
# ------------------------------------------------------------------
sys.stderr.write("*** start ***\n")

try:
	project_id = "my-project-aug-29-2016"
	client = datastore.Client(project_id)
except Exception as ee:
	sys.stderr.write("*** error *** in datastore.Client ***\n")
	sys.stderr.write(str(ee) + "\n")
#
kind = 'Cities'
query = client.query(namespace='',kind=kind)
#
results = query.fetch()
keys = []
for unit in results:
	keys.append(unit.key.name)
#
for name in keys:
	data_read_proc(client,name)
#
sys.stderr.write("*** end ***\n")
#
# ------------------------------------------------------------------
```

実行結果

```text
$ export GOOGLE_APPLICATION_CREDENTIALS="/home/uchida/my_project_Aug29-2016-4363ff6a1234.json"
$ ./datastore_read.py
*** start ***
t0921	宇都宮	38921	2018-05-17 23:31:34.124883+00:00
t0922	小山	56413	2018-05-17 23:31:34.574463+00:00
t0923	佐野	92385	2018-05-17 23:31:34.787974+00:00
t0924	足利	39546	2018-05-17 23:31:34.994691+00:00
t0925	日光	18492	2018-05-17 23:31:35.296938+00:00
*** end ***
```
gitのコミットやタグがブランチとどう関連するか確認する

# gitのコミットやタグがブランチとどう関連するか確認する

## 問題
gitのタグが分るが、そのタグが打たれたブランチが分らないとき。
あるいは、あるコミットがどのブランチのものなのか不明なとき、などの作業記録。

## 解法
こちら[^1]の情報から次のようなことをして確認

追記:ローカルにチェックアウト済みでないとうまくいかない場合もあるかもしれないので、注意して利用のこと。

```shell-session
# その1
# タグ(ハッシュでもよい)が含まれるブランチ一覧
# リモートも含めて調査させるなら -a 
$> git branch --contains <TAG_ANY>

# その2
# タグのハッシュ確認
$> git show <TAG_ANY>
# ハッシュ指定版
$> git branch --contains <hash>

# その3
# あるハッシュがどのブランチ/タグにあるか、検出できるものを出す
$> git name-rev <hash>
# あるハッシュ/タグが指定ブランチのどの位置(最新の何個前)か (ex.ここではmaster)
$> git name-rev --refs master <hash>
```

## 参照
[^1]: [Git でコミットの親子関係を master からの相対距離で調べる方法](http://blog.kyanny.me/entry/2014/08/29/141019)および[git で指定したコミットがどのブランチに属するか知りたい](https://qa.atmarkit.co.jp/q/2318#answer_14777)を参考にした
Webスクレイピングにおける注意事項

#はじめに
Webスクレイピングする際に注意すべき事項を簡潔にまとめていきます。
※より詳細な情報についてはページ下部にある参考ページに詳しく載っています。

#注意事項
情報解析のためにデータを複製する事はOK。ただし以下事項に注意。

- 著作権
    - 情報解析の為のデータ複製はOK、ただしそのデータに関連した物を公開するのは×

- 動産不法侵入
    - Webページが提示している条件を守る
        - robot[s].txt の内容を守る
        - aタグのrel属性がnofollowの場合は除外
        - …など
    - サーバーに負荷をかけない
- スクレイピング対象サイトの利用規約に違反しない
    - 例えばTwitterであれば、規約内で明示的にスクレイピングを禁止している

#参考ページ
[Webスクレイピングする際のルールとPythonによる規約の読み込み](https://vaaaaaanquish.hatenablog.com/entry/2017/12/01/064227)
Google Drive File Streamがjupyterで開けない

Google Driveのときは普通に使ってたのにGoogle Drive File Streamになってからそこに保存しているpythonファイルがjupyterで開けなくなった。

# 追記 2018/06/14
結局"バックアップと同期"をインストールして並列して使用することにした。"バックアップと同期"は今までのgoogle driveのようにgoogle driveのフォルダをシステムのフォルダとして扱えるのでjupyterで開くことができる。
ペアレント購入(Ask-To-Buy)のテスト


##simulatesAskToBuyInSandbox

子供のアプリ購入を、親のデバイスで承認する機能でデバックするための、`simulatesAskToBuyInSandbox`に関して、ちょっとしたハマりどころをまとめました。

[simulatesAskToBuyInSandbox](
https://developer.apple.com/documentation/storekit/skmutablepayment/1620604-simulatesasktobuyinsandbox?language=objc)

お子様にスマートフォンを持たせている親御様にはピンとくる機能だとは思いますが、これは、アプリ購入時に、ペアレントコントロールされている端末で購入の認証をし、その上で購入フローに入るといった機能です。

UnityIAPでは、この機能をサポートしていて、Sandbox環境下で機能する状態になっています。
https://forum.unity.com/threads/solved-how-does-iappleextensions-simulateasktobuy-work.489759/

ただ、Sandbox環境下では、通知は行くものの、購入ボタンを押しても遅延購入のフローには入れない状態となっています。

## Apple側の仕様
Ask-To-Buyのサポートに関しては、APIではなくStoreKitを通じて、特定のアカウントとやり取りをするものなのですが、Sandbox環境で行おうとすると、いくつかの段取りが必要な状態になっているとの事ですが、その方法は詳細に明言されていません。
https://forums.developer.apple.com/thread/38561#117143

要望があるならばバグレポートが欲しいとの事ですので、現状では「Apple Sandbox」環境下ではサポートされていないという結論になっています。

## まとめ
* UnityIAPではAsk-To-Buyの機能はサポートされているが、Sanxbox環境下では一部機能のテストができない。
* テストができない内容は、通知後購入ボタンを押した後の遅延購入部分のテストが不可。(通知は飛ばせる)
RSpec で Rails の cookie をモック/スタブする

```ruby
# 取得
allow_any_instance_of(ActionDispatch::Cookies::CookieJar).to receive(:[]).with(cookie_name).and_return(cookie_value)

# 代入
expect_any_instance_of(ActionDispatch::Cookies::CookieJar).to receive(:[]=).with(cookie_name, cookie_value)
```

ただし`allow_any_instance_of`の使用は非推奨なので注意。 cf. [rspec/rspec-mocks](https://github.com/rspec/rspec-mocks#settings-mocks-or-stubs-on-any-instance-of-a-class),  [rspecでallow-any-instance-ofは使わない方がよい、が身に沁みたので別の方法で試してみる](https://suruseas.github.io/ruby/2017/01/19/donot-use-allow-any-instance-of.html)
RSpec で devise.gem の user_signed_in? をモックする

`Devise::Controllers::Helpers#user_signed_in?` をモックする。[コードはこのへん(plataformatec/devise)](https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/helpers.rb)。 `Devise` で使ってるモデルが `User` じゃない場合は適宜変更すればOK。

## 例

```ruby
before do
  allow_any_instance_of(Devise::Controllers::Helpers).to receive(:user_signed_in?).and_return(false)
end
```

ただし `allow_any_instance_of` の使用は非推奨なので注意。 cf. [rspec/rspec-mocks](https://github.com/rspec/rspec-mocks#settings-mocks-or-stubs-on-any-instance-of-a-class),  [rspecでallow-any-instance-ofは使わない方がよい、が身に沁みたので別の方法で試してみる](https://suruseas.github.io/ruby/2017/01/19/donot-use-allow-any-instance-of.html)

**追記**

`allow_any_instance_of` つかわずにテスト対象のモジュールに対してモックすれば十分なことが多い。

```ruby
# helper がテスト対象のインスタンスの場合
before do
  allow(helper).to receive(:user_signed_in?).and_return(false)
end
```