OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsスクリプトでAWSアクセスキーの誤コミットを防ぐ


## はじめに

この記事は、Node.jsのスクリプトを使用し、gitのpre-commitフックの段階でAWSアクセスキーの混入を検出し、コミットを強制的に停止する手法を検証するためのものです。

## 問題

AWSのアクセスキーの検出とコミット防止の手段は[git-secrets](https://github.com/awslabs/git-secrets)があります。このソフトは高速にコードをスキャンしアクセスキーの検出と流出防止をしてくれます。AWS-Labsで開発されていることもあり、信頼性も高いです。

### 導入が難しい

git-secretsはシェルスクリプトで構成されています。macの場合Homebrewで一括インストールできますが、構成はpackage.jsonに残りません。各メンバーがセットアップを行う必要があります。

git-secretsをGUIアプリケーションから操作する場合、アプリ内蔵のgitに対してシンボリックリンクを通すか、使用するgitをシステムのものに切り替える操作が必要になります。

+ [git-secretsをSourceTree (Macintosh)で使えるようにする手順](https://qiita.com/yamaryu0508/items/d959dc32442b08b8a0a4)
+ [GitHub Desktopでもgit-secretsが使いたい](https://qiita.com/kadoyau/items/a0469f051fc4cb760329)

また、グローバルにインストールした場合、アンインストールの際に注意が必要です。

+ [[git] git secretsを削除する時の注意](https://piruty.com/?p=521)


リポジトリからクローンを行い`yarn`を実行してくださいという一言で説明が終わる環境と比べると、導入の手間は大きいです。

### huskyとバッディングする

[husky](https://github.com/typicode/husky)は、gitのpre-commitフックを手軽にpackage.json上で定義できるパッケージです。

*▼package.json*

```json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "...": "..."
    }
  }
}
```

このようにgitの各種hookを定義することでpackage.json内のスクリプトを呼び出すことができます。
たとえば[pretty-quick](https://www.npmjs.com/package/pretty-quick)と併用することで、コミット前にstage上のファイルを[Prettier](https://prettier.io/)で整形したあとコミットするというような使い方ができます。

しかし、このパッケージはgit-secretsとバッティングします。gitの[hook](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)ファイルをインストール時に書き換えてしまうため

```bash
git secrets --install
```

で生成したファイルを上書きしてしまいます。この問題はhuskyに限らずhookファイルを書き換えるパッケージ全般で発生します。
もちろんhookファイルを手作業でマージすれば両方の機能を併用することはできますが、パッケージの再インストール時には破壊されてしまうため運用が難しくなります。

## 対策の提案

上記の問題の対策として

* node.jsで稼働するスクリプトにする（huskyとの共存）
* pre-commitフック段階でAWSのアクセスキーを検出する
* キーが存在した場合コミットの処理を強制停止する

の条件が満たせれば問題を解決できるのではないかと考えました。

## 検証

というわけでスクリプトを組んでみました。

[![ReadMe Card](https://github-readme-stats.vercel.app/api/pin/?username=masatomakino&repo=node-secrets)](https://github.com/masatomakino/node-secrets)


### 動作検証の手順

* リポジトリをローカルにクローン
* ```npm install```か```yarn```して依存パッケージを取得
* AWSのキーを含むテキストファイルをaddする
* コミットするとpre-commitフックで蹴られる
* pretty-quickと共存して動作する

という一連の動作が確認できると思います。

### CLIモジュールとしての導入方法

**2018/09/12追記**

こちらの記事を参考に検証スクリプトをCLIモジュールに修正、更新しました。ありがとうございます。

+ [3分でできるnpmモジュール](https://qiita.com/fnobi/items/f6b1574fb9f4518ed520)
+ [コマンドラインで動作する npm ライブラリを作る](https://qiita.com/star__hoshi/items/51c6cc719793abfb337d)

GitHubのURLを指定して、npmかyarnでモジュールを読み込みます。

```bash
yarn add https://github.com/MasatoMakino/node-secrets -D
```

`node-secrets`コマンドで、npm-scriptsやhuskyから呼び出しができます。

*▼package.json*

```json
"scripts": {
  "secrets": "node-secrets"
},
"husky": {
  "hooks": {
    "pre-commit": "pretty-quick --staged && node-secrets"
  }
}
```

### テストの際の注意

**テストに本物のキーを使用するのは絶対に避けてください。**

[クラウド破産しないように git-secrets を使う](https://qiita.com/pottava/items/4c602c97aacf10c058f1#3-%E6%8B%92%E5%90%A6%E6%9D%A1%E4%BB%B6%E3%82%92%E8%A8%AD%E5%AE%9A)

こちらの記事にあるように、git-secretsがテスト用のダミーキーを用意してくれているのでそれが引っかかるかどうかを試してください。

## 未検証の部分

このスクリプトでは以下の点は未検証です。

* 誤検出 / 検出すり抜けの可能性
* 大規模なリポジトリでのパフォーマンスの問題
* バイナリを正常に切り分け可能か否か

あくまで提案の検証用ですのでご注意ください。
React Native (0.56.0) を Windows でビルドするとエラーが発生する

※ 2018/08/08 現在の情報です。
今更かもしれませんが、自分用にメモ

初投稿です。文章の不備はお許しください。

### 使用している端末
- Essential Phone (PH-1)
- Android バージョンは 8.1 ( 今は、Android 9 Pie にバージョンアップをしてしまいましたが… )

### React Native のバージョン
- 0.56.0

自分の環境で、`react-native init <ProjectName>` を行ったあと
`react-native run-android` を行うとエラーが発生する問題がありました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/276546/e035c2c8-abb3-735a-8bf2-3f5a9051dc1c.png" alt="エラー画面のスクリーンショット" width=300px>

## やったこと
以前のバージョンを指定してプロジェクトを作成します。
`react-native init <ProjectName> --version 0.55.4`

原因を調べたら、windows (10のみ？) の環境で起こるエラーみたいですね。
とりあえず、バージョンを落としてプロジェクトを作成すれば問題ないと思われます。

## 参考URL
https://github.com/facebook/react-native/issues/20015
Navigation Resource Fileが表示されないときの対処

## 環境
Android Studio 3.2 Beta4

Google I/O 2018で登場したNavigation Architecture Component。

試そうと思い、ナビゲーショングラフ用のリソースファイルを追加しようとしたらNavigation Resource Fileが表示されなかったのでその解決法を残しておきます。

参考: https://stackoverflow.com/questions/50271002/navigation-architecture-component-new-resource-dialog-doesnt-have-navigation

## Navigation Editorの設定
Android Studio > Preferences > Experimental から"Enable Navigation Editor"にチェックを入れます。
![スクリーンショット 2018-08-08 13.59.19.png](https://qiita-image-store.s3.amazonaws.com/0/220801/51395320-f301-4f7e-265a-b9894d598155.png)

## リソース追加
Android Studioを再起動し、res/navigationディレクトリを作成して右クリックするとNewの項目にNavigation Resource Fileが増えています。

<img width="693" alt="スクリーンショット 2018-08-08 13.52.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/220801/101f74b0-1162-721e-a84a-d2be7c622549.png">
mysqldumpでGot error: 1044: Access deniedが出た

備忘録っす

#何をしたら出たの？
```MySQL:
# mysqldump -u ユーザ名 -p データベース名 > dump-data.sql
```

#どんなエラーログ？
```MySQL:
mysqldump: Got error: 1044: Access denied for user 'ユーザ名'@'localhost' to database データベース名 when using LOCK TABLES
```

かなしいなあ

#原因は？
テーブルロック権限(LOCK TABLES)がないから。

#解決
--single-transactionをつける

```MySQL:
# mysqldump --single-transaction -u ユーザ名 -p データベース名 > dump-data.sql
```

別にルートユーザーでやっても一般ユーザーでもいい。
自動計測システムについての調査メモ（調査中）




## 自動計測システム

[記録計測 | RUNNET FOR ORGANIZER](https://owner.runnet.jp/support/date/)


[ランナーズチップ（Runners Chip） － RUNNET － 日本最大級！走る仲間のランニングポータル](https://runnet.jp/runtes/chip/)


## なぜ足だと問題なのか、なぜ胸なのか？
[ランディノート: ランナーズチップの罠](http://rundynote.blogspot.com/2015/11/blog-post_16.html)
たかがランナーズタグ、されどランナーズタグ



## 歴史
[RFタグの開発技術 - Google ブックス](https://books.google.co.jp/books?id=dZNWLFUBFckC&pg=PA285&lpg=PA285&dq=%E3%83%88%E3%83%AB%E3%82%BD%E3%83%BC%E3%82%BF%E3%82%B0&source=bl&ots=ULyCobolth&sig=0z1CYfOs71ujbzuIsoSfKbBub9s&hl=ja&sa=X&ved=2ahUKEwjV6unbytzcAhUCAogKHVPXDHU4ChDoATACegQICBAB#v=onepage&q=%E3%83%88%E3%83%AB%E3%82%BD%E3%83%BC%E3%82%BF%E3%82%B0&f=false)


[計測システム（特にマラソン計測について）](http://www.keisoku-kobo.co.jp/article/13190011.html)


[ランナーズチップを切り開いて中を見てみた – Techforlearning's Blog](https://techforlearning.wordpress.com/2015/03/29/%E3%83%A9%E3%83%B3%E3%83%8A%E3%83%BC%E3%82%BA%E3%83%81%E3%83%83%E3%83%97%E3%82%92%E5%88%87%E3%82%8A%E9%96%8B%E3%81%84%E3%81%A6%E4%B8%AD%E3%82%92%E8%A6%8B%E3%81%A6%E3%81%BF%E3%81%9F/)
VMをESXi2.1から6に移動してみた

オンプレの保守切れ縮退節約対応のようなものの備忘録です。

移動元のESXiが古すぎてちょいちょい落ちる感じでしたがまあ何とかはなってよかったです。
最近のやつはアカウントがいる、VCenterでやるっぽいしssh有効だとはかどる、Ansibleでつついてる、など見聞きしますがそういうんじゃない感じで大変申し訳ない。
ちなみに移動先が社内のサーバルームの物理でした。クラウドでもよかったけど。

１．vsphereでつないで移動元のVMの電源をパワーオフする
　ここだいじ。落とさないでデータコピーしても移動先で認識してくれなかったです。
２．移動元ESXiのホストの構成＞ストレージ＞データストア照会＞該当VMのデータをローカルにダウンロード
　このときログとスナップショットは不要ですのでそれ以外を。
　vmdkが複数あるやつはlvmかなんかでパーティション切られてるだけなので両方要ります。
３．移動先のESXiのホストの構成＞ネットワーク＞ネットワークの追加＞VMkernelで仮想スイッチ追加
　元のセグメントのネットワーク情報を入れて作成＞ポートグループが勝手に追加されるので名前を編集
　この時同じとこにつながれてるアダプタに複数のスイッチを追加してしまうとデフォルトゲートウェイの設定が変えたほうに合わせて勝手に変えられる現象を確認しましたので要注意（GWは実際に外に出られる口だけしか設定できない）
４．ストレージ＞データストア照会＞VM名のディレクトリを作成＞ローカルのVMデータをアップロード
５．vmxファイルを右クリックしてインベントリへの追加する
６．追加された仮想マシンの設定から追加したネットワークアダプタにつなぎつつ既存の外部につながるネットワークアダプタを追加、パワーオン時にNW接続はチェック外したまま適宜CPUやメモリなどのリソース割り当てて起動する（ディスクの統合しろというエラーがでるときは移行前に停止してるのであれば素直に統合すると起動してくる）
７．コンソールからログインしてネットワークの設定をいじる
　resolv.confとかifcfg-eth0,1,networkなどのファイルを修正しnetwork再起動する
　このときvsphereの画面から確認できるMACアドレスをHWADDRとするかHWADDR設定を消すのと
　元のセグメントのサブネットマスクを/32にして同一セグに居るのは自分だけと認識さす(ことで元居たセグメントのまだ稼働中のサーバと通信ができる)のと、
　外部に出られるようにデフォルトゲートウェイを追加したアダプタの社内のセグメント側のやつに設定する
８．仮想マシン設定からネットワークアダプタの、接続中とパワーオン時に接続にチェック入れて再起動する
　ログインして明らかに外部のドメインにping打つなどで動確する
　もとの機能が使えているかテスト、ドメイン更新などをする

なんかこんな古くても移動できて普通に動いて後方互換ありがとうございます、と思いました。


ちなみにFWの設定収集してる子でFW側のmanager-ip(接続元管理IP)設定変えないとだったり、
（グローバルIPが社内NWのゲートウェイ使う関係で会社の外部のやつになるせい）
ドメイン変えるときに行数が800超のspf入りのzoneファイルでnamed-checkzoneが4分くらい返ってこなかったりしました。

参考：
http://vm.study234.com/archives/267
https://qiita.com/tsukamoto/items/d0245570399fa88aebad
https://www.softantenna.com/wp/tips/vmware-fix-disconnected-network/
https://go-journey.club/archives/6324
https://blogs.vmware.com/jp-cim/2014/01/vsphere-basic-network01.html
http://blog.nabe.jp/archives/000110.html

スペシャルサンクス：職場の先輩。ネットワーク周りの設定一人じゃたぶん無理でした。
Cognos BI のマイフォルダのレポートにURLアクセス

#マイフォルダレポートへのURLアクセス

半分自分へのメモも兼ねて投稿しておきます。

マイフォルダ上のレポートにURLアクセスする際のURL指定です。

cogadminというユーザーのマイフォルダの下にFolder1というフォルダを作成し、その配下のReport1レポートを呼び出しています。

```html
http://CognosHostname/ibmcognos/cgi-bin/cognos.cgi?CAMNamespace=ApacheDS&CAMUsername=cogadmin&CAMPassword=password&b_action=cognosViewer&ui.action=run&ui.object=CAMID("ApacheDS:u:uid=cogadmin")/folder[@name='My Folders']/folder[@name='Folder1']/report[@name='Report1']&run.outputFormat=&run.prompt=true
```

**以下の箇所を環境ごとに書き換えて下さい**
CognosHostname という名前のCognosサーバー
cognos.cgi → cognosisapi.dllかmod2_2_cognos.soなど環境に応じて変更
ApacheDS という名前のネームスペースで認証
cogadmin という名前のユーザーのマイフォルダ
password というcogadminユーザーのパスワードでアクセス
My Folder上のFolder1というフォルダ配下のReport1というレポートを呼び出し

レポートのパスは、レポートのプロパティから「View the search path, ID and URL」を選択し、赤枠の「Search path」をコピーして使って下さい。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/6ba58088-5988-8145-66df-1a7c4ef7dbfb.jpeg)

ちなみに、レポート呼び出し元でヘッダーの変数にSSOのためのユーザーID組み込みが可能な場合、以下のURLでCAMUsernameとCAMPasswordの指定を省く事が可能です。
パスワードをURLに入れるなんて・・・、という場合はご検討下さい。

```html
http://CognosHostname/ibmcognos/cgi-bin/cognos.cgi?CAMNamespace=ApacheDS&b_action=cognosViewer&ui.action=run&ui.object=CAMID("ApacheDS:u:uid=cogadmin")/folder[@name='My Folders']/folder[@name='Folder1']/report[@name='Report1']&run.outputFormat=&run.prompt=true
```
ヘッダー変数にユーザーIDを組み込んだテストはこちらも参考にして下さい。
**Cognos でシングルサインオン(SSO)を実装する際のModify Headers使用の勧め**
https://qiita.com/shinyama/items/9a6df3a0fd781187eba5

レポートのURL実行の一般的な話はこちらから。
**Performing Tasks using Parameterized URLs in IBM Cognos 8**
https://www.ibm.com/developerworks/data/library/cognos/page123.html

これ系の情報は「cognos parameterized url」くらいの検索ワードで、Googleで色々ヒットしますので困った時は検索してみてください。

**マイ・フォルダそのものの呼び出しURLはこちら**

・ユーザID、パスワード埋め込み版

```html
http://CognosHostname/ibmcognos/cgi-bin/cognos.cgi?CAMNamespace=ApacheDS&CAMUsername=cogadmin&CAMPassword=password&b_action=xts.run&m=portal/cc.xts&m_path=CAMID("ApacheDS:u:uid=cogadmin")/folder[@name='My Folders']
```

・Modify Headers使用版

```html
http://CognosHostname/ibmcognos/cgi-bin/cognosi.cgi?CAMNamespace=ApacheDS&b_action=xts.run&m=portal/cc.xts&m_path=CAMID("ApacheDS:u:uid=cogadmin")/folder[@name='My Folders']
```
djangoアプリ開発時dbマイグレーション関連コマンド

開発時modelを変更する時にdjangoのコマンドを使ってdbを再構築することがあります
## スキーマを反映したmigrationsファイルの作成
```python
python manage.py makemigrations app_name
```

## マイグレーション
最新のマイグレーションファイルまで適用します

```python
python manage.py migrate app_name
```
特定のマイグレーションファイルまで適用します

```python
python manage.py migrate app_name migration_file_A
```

## 特定のdbにマイグレーションをかけます
シャーディンぐをした時など

```python 
python manage.py migrate app_name --database=daba_name
```

## dbを初期状態に戻します
これが一番便利

```python 
python manage.py migrate app_name 'zero'
```
これで特定のappのdbを初期状態に戻せます。ややこしいのが最後のパラメーターが'zero'であること
Python 3 (v3.4.8) > JSONファイル読込み > 3セットのimageごとの各項目を標準出力する

```txt:動作環境
CentOS release 6.9 (Final)
GNU Bash-4.1
ImageMagick Version: ImageMagick 6.7.2-7 2017-03-22 Q16
Python 3.4.8
```

### 関連

- [Python 3 (v3.4.8) + ImageMagick > 複数画像を切出して合成する v0.1](https://qiita.com/7of9/items/245de7dfee4841593524)


### 処理概要

- JSONファイルに画像切出しの設定が用意されている
- 設定はimage1, image2, image3のように用意されている
- 各imageXにおいて以下の設定がある
    - srcPath
    - cropSize
    - srcLeftTop
    - dstLeftTop
- image1, .. image3の名前を知らなくても、それぞれに対して各項目を取得したい

### code v0.1

```printPropJSONFile_180808.py
import json

# v0.1 Aug. 08, 2018
#   - read from JSON FILE to print properties for each imageX

JSONFILE = 'config.json'

with open(JSONFILE) as reader:
    json_data = json.load(reader)
    # type(json_data)

for images in json_data:
    # print(images)
    for akey in images.keys():
        print('---')
        print('key=%s' % akey)
        adict = dict(images[akey])
        print(adict['srcPath'])
        print(adict['cropSize'])
        print(adict['srcLeftTop'])
        print(adict['dstLeftTop'])

```

### JSONファイル

```config.json
[
	{
		"image1": {
			"srcPath": "DIR1/out.png",
			"cropSize": "100x100",
			"srcLeftTop": "+10+10",
			"dstLeftTop": "+50+10"
		},
		"image2": {
			"srcPath": "DIR2/out.png",
			"cropSize": "80x80",
			"srcLeftTop": "+10+10",
			"dstLeftTop": "+50+120"
		},
		"image3": {
			"srcPath": "DIR3/out.png",
			"cropSize": "110x110",
			"srcLeftTop": "+30+30",
			"dstLeftTop": "+140+120"
		}
	}
]
```

### 実行

```txt:run
$ python3 printPropJSONFile_180808.py 
---
key=image1
DIR1/out.png
100x100
+10+10
+50+10
---
key=image3
DIR3/out.png
110x110
+30+30
+140+120
---
key=image2
DIR2/out.png
80x80
+10+10
+50+120
```
Firebase Admin Python SDK で AttributeError: 'HTTPResponse' object has no attribute 'chunked' になった時

# 現象
requests の大量の***嫌がらせワーニング***に根負けして update したところ、案の定、***Firebase Admin Python SDK が動かなく*** なってしまいまい、***台風も来ている***というのに ***idToken の確認ができなくなる***というかなりひどい目に

こんな感じ

```

  File "/usr/local/lib/python2.7/dist-packages/cachecontrol/adapter.py", line 107, in build_response
    if response.chunked:
AttributeError: 'HTTPResponse' object has no attribute 'chunked'
```

# 対応
エラーメッセージから ***cachecontrol が古いのかな？***と思って update を試みるも***「最新ですよ」***との事

ならばと、***エラーメッセージでググる***と***[fixは自明](https://github.com/ionrock/cachecontrol/issues/137#issuecomment-293356223)***との事なので、指摘の通り、```/usr/local/lib/python2.7/dist-packages/cachecontrol/adapter.py``` の 107行目をいわれるとおり以下のように修正

```python:
#                if response.chunked: #fixed 2018.08.08 UEDA
                if hasattr(response, 'chunked'):
```

これで***治りました***、ああよかった

# 感想
風が弱いうちにコロッケ買いに行ってこよっと
Watson Studioで自動運転に必要な画像処理技術を学ぶ（２）

[前回](https://qiita.com/schiyoda/items/04ff94ca04d9f97b7d46)に引き続き自動運転に必要な画像処理技術シリーズ。今回は車両の検出をやってみます。今回も参照先は以下になります。

https://github.com/aruizga7/Self-Driving-Car-in-DSX

# 車両の検出
車両の検出は画像認識の技術では「物体検出」の問題になります。「物体検出」は画像上に写っている物体の位置とそのカテゴリー（クラス）を検出することを指します。物体検出のアルゴリズムはさまざまなものが提案されており、Web上でも詳しい記事を参照することができます。今回は比較的高速で使うのも簡単な YOLO v1 を使用して、車上のカメラで撮影した画像から車両の検出を行ってみます。


# 手順
Watson Studioでプロジェクトを作成して、以下リンク先から Notebook を作成します。
https://github.com/schiyoda/Self-Driving-Car/blob/master/2.Vehicle-Detection.ipynb

Notebookを順に実行すると、以下のようにNotebook上で車両検出結果の静止画および動画が生成されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/a0d76747-77ae-f090-0c3b-937ff3ac051d.png)



![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/c1a5a43b-13a7-3363-1d5c-967fe1d543d0.png)

![vehicle_detection.gif](https://qiita-image-store.s3.amazonaws.com/0/235649/4ad02849-8048-50a9-5a25-8039098b761b.gif)

動画は以下リンクで参照可能です。
https://raw.githubusercontent.com/schiyoda/Self-Driving-Car/master/vehicle_detection.mp4
Google Cloud Next '18 Day1 ノート

Day1 のメモ。

## Keynote [Building a Cloud for Everyone](https://www.youtube.com/watch?v=vJ9OaAqfxo4)
- Istio 1.0
- Cloud Services Platform
- GKE on prem
- G Suite
- Auto ML
- Contact Center AI

## [CI/CD in a Serverless World](https://www.youtube.com/watch?v=iyGHW4UQ_Ts)

### Serverless CI/CD

1. git push で unit and integration tests が実行される
2. テストが通り staging へ deploy される
3. 人が承認して production へ

### CI/CI spectrum
Manual, 一人で ./deploy.sh を実行するようなステージ
Baked-in automation, チームで CI/CD 処理を作あげり実行するステージ
Dev Centric CI/CD, レポジトリが source of truth であるだけ （このセッションでやる）
Ops Centric CI/CD, 単一コンソールで複数のサービス ( [Spinnaker](https://www.spinnaker.io/) とか)

### Demo
[Cloud Build](https://cloud.google.com/cloud-build/docs/overview) ソースコードの変更をトリガーに yaml で steps を定義して任意の Serverless への反映。
Serverless で全てが完結する。

## [Bringing You the Future of Cloud](https://www.youtube.com/watch?v=RBBCbCuimcc)

Hybrid Cloud におけるトレードオフを克服。

- Consistent experience
    - [GKE on prem](https://cloud.google.com/gke-on-prem/)
- Centralized control
    - GKE policy manager
- Agility with reliability
    - [istio](https://istio.io/)
- Flexibility
    - [Marketplace](https://cloud.google.com/marketplace/)

## [Serverless on Google Cloud](https://www.youtube.com/watch?v=iPQUdb0kssE)

see also [Serverless Compute on Google Cloud: What's New](https://www.youtube.com/watch?v=Y1sRy0Q2qig)

- [Cloud Functions](https://cloud.google.com/functions/)
    - Serverless containers
- [App Engine](https://cloud.google.com/appengine/docs/whatisgoogleappengine)
- [gVisor](https://github.com/google/gvisor)
- GKE serverless add-on
    - consistency
- [Knative](https://github.com/knative/)

## [Optimizing and Troubleshooting Your Application, the Google Way](https://www.youtube.com/watch?v=808eBF5tZ1g)

### Scenarios

- Scenario: Reducing latency
  - Getting Notified
     - alerts when SLOs are not met
  - Triage
     - analyzer? latency metrics for all RPCs
     - cause? distributed tracing
- Scenario: Resolving errors in production
  - Getting Notified
      - alerts when error budget is not met
  - Triage
      - metrics
      - logs
      - distributed tracing
- Scenario: Reducing cost, optimizing code
  - Deciding Where to Focus
      - distributed tracing



### Core concepts

- SLOs, Metrics
- Traces, Log Correlation
- Profiling, Debugging

### Observability for everyone (instrumentation)
- Metrics
    - OpenCensus, Prom
- Traces
    - OpenCensus, Zipkin
- Profiles
    - pprof
- Code
    - Debugger
- Logs
    - FluentD
CentOS7 SSL化（Apache、Let's Encrypt 使用）

Let's Encryptを使ったCentOS7のSSL化予忘録です。「設定するドメイン」を設定するドメイン名（例：hoge.jp）に変更してください。

rootユーザーで作業します。間違えていたらごめんなさい。

#Apacheのモジュールインストール
ApacheでSSL化を行うには、mod_sslが必要見たいです。すでにインストールされているかもしれませんが、インストールしましょう。

```
yum install -y mod_ssl
```

#ファイアウォール確認
ファイアウォールを確認して、httpsのポートに穴をあけましょう。

```
#ファイアウォールに穴をあける
firewall-cmd --zone=public --add-service=https --permanent
firewall-cmd --reload

#穴が開いたかもう一度確認
firewall-cmd --list-all
```

ポート番号を指定して、これであけることもできます。

```
firewall-cmd --zone=public --add-port=443/tcp --permanent
```

#Let’s Encryptのcertbotをインストール

```
yum install -y epel-release
yum install -y certbot python2-certbot-apache
```

#仮想ホストポート80を追加
/etc/httpd/conf/httpd.conf に下記を追記します。

```
vim /etc/httpd/conf/httpd.conf
```


```/etc/httpd/conf/httpd.conf
NameVirtualHost *:80

<VirtualHost *:80>
ServerAdmin root@設定するドメイン名
DocumentRoot /var/www/html
ServerName 設定するドメイン名
</VirtualHost>
```



#証明書発行
メールアドレスなどをいろいろ聞かれるので、答えていきましょう。

```
certbot --apache -d 設定するドメイン
```

#httpdの再起動

```
systemctl restart httpd
```

https://設定したドメイン
にアクセスして、うまくできたかを試してみましょう。

#証明書の更新
```
certbot renew   #残り30日未満の場合のみ更新
certbot renew --force-renew      #残り期間に関係なく更新
certbot renew --webroot-path /var/www/html/ --post-hook "systemctl reload httpd" --force-renew　#Apache 再起動も実行
```

#参考にしたサイト
https://knowledge.sakura.ad.jp/10534/
https://dacelo.space/linux/entry-979.html
https://freepc.jp/encrypt
http://www.sassy-blog.com/entry/20180511/1526031971
Case条件分岐使用時に出力データが暗黙的に変換される

##状態
Case文を使用したデータ抽出を行ったときなぜか抽出データがint型になって詰まってしまった。

###当時のCode(多少加工あり)

```sql
Select 
T.NO,
Case when T.区分 = '1' Then  T.コード Else 0 END As A

From T
Where T.NO= 00

```

###出てきたエラー

`nvarchar の値 '9999999999999999999999' の変換が int 型の列でオーバーフローしました。`
とか
`nvarchar の値 'aa11aa11a1a1' をデータ型 int に変換できませんでした。
`

##原因

ELSEの0が文字ではなく数字の0だったことが原因
どうやら出力型はあわせないといけないようだ。

##対策

以下のコードにして完成

```sql
Select 
T.NO,
Case when T.区分 = '1' Then  T.コード Else '0' END As A

From T
Where T.NO= 00

```

##余談
上記のことをアーキテクトの上司に言うとあー、よくあるよくあるといわれましたとさ。
Longのときはどうするんだろうか？Convert?
React Nativeでアプリやストアへのリンクを行う「react-native-app-link」

# react-native-app-link
https://github.com/FiberJW/react-native-app-link

レビューしてもらうときなどにストアに飛ばすと思いますが、iOSであれば面倒なので、react-native-app-linkを使っています。

Linkingの拡張みたいな感じのパッケージです。

```javascript
import AppLink from 'react-native-app-link';

// 別アプリを開く、もしアプリがなければダウンロードのためにストアへ行く
AppLink.maybeOpenURL(url, { appName, appStoreId, playStoreId }).then(() => {
  // 開いた後の処理
})
.catch((err) => {
  // エラー処理
});


// ストアで開く
AppLink.openInStore(appStoreId, playStoreId).then(() => {
  // 開いた後の処理
})
.catch((err) => {
  // エラー処理
});
```

appStoreId（例）: 'id529379082'
playStoreId（例）: 'me.lyft.android'

とても便利です。
swiftを読めるようになろう！！１（classの概念編）

![classの概念.png](https://qiita-image-store.s3.amazonaws.com/0/279308/800460dc-913e-4e1e-1ece-909ebbc1878c.png)
#継承とは？？　
15行目のclass SuperRobot : Robot のコードのことで、SuperRobotがRobotを継承しますよって宣言すること。
#継承を使うと・・・
* *継承により打ち間違いが少なくなり、コードが短くなる！*  
(共通の部分をまとめられるから、単純に見やすい)
 * ということは、新しい機能を追加する際にベースのclassを定義すれば一回一回定義する必要がなくなる！
 * ということは、メンテナンスしやすい！
* *ただ、機能が多いアプリは継承が深くなる為、逆にわかりずらくなる*

記事作成時間　約１５分
LESSの使い方-概要-


CSSをわかりやすい形で記述できるというLESS。
CSSで丁寧に書いていたところをHTMLのような階層に分けて記述することもできます。
より感覚的に記述できるということが特徴ですね！
また、変数を指定できることやHTMLを塊で修飾できる組を作ることもできます。

例えば

```css

div{
   width:40px;
   margin:0 auto;
}

div h2{
    font-size:27px;
    color:red;
}

div a{
    font-size:15px;
    background:url("")
}
```
以下はlessのコードになります。

```css

div{
  width:40px;
  margin:0 auto;

   h2{
    font-size:27px;
    color:red;

    a{
     font-size:15px;
     background:url("")
  }
 }
}
```
といったところです。
HTMLと対応させやすく、視覚的にわかりやすいです。
RailsでスマホとPCヘッダーを分ける方法

画面幅に応じて、2種類の画像が変わっています。
[なろう廃人のすすめ](https://narou-osusume.com/)
![8月-08-2018 12-30-34.gif](https://qiita-image-store.s3.amazonaws.com/0/145707/357fd73c-53c4-03e3-4eae-ec21c77ab13a.gif)


#方法
cssで画面のピクセル数に応じて
スマホヘッダー、PCヘッダーのdisplay:block, display:noneを切り替える。

#scss
```scss
 /* パソコンで見たとき*/
 .pc-header { display: block !important; }
 .sma-header { display: none !important; }
 /* スマートフォンで見たとき*/
 @media only screen and (max-width: 750px) {
 .pc-header { display: none !important; }
 .sma-header { display: block !important; }
 }
```

#haml
bootstra4使ってます。

```haml
    .container.p-0
      = link_to image_tag("/assets/images/sma-header.png", width: 'auto', alt: "なろう廃人のすすめ", class: "sma-header header-image container-fluid p-0"), root_path
      = link_to image_tag("/assets/images/pc-header.png", width: 'auto', alt: "なろう廃人のすすめ", class: "pc-header d-block container-fluid mx-auto p-0"), root_path
```

#画像の場所

画像はpublicの中に入れる。

```
/public/assets/images/sma-header.png
/public/assets/images/pc-header.png
```

##ベストプラクティスが知りたい
この方法ならスマホを横にした時とかも
きちんと画像表示されるけど、
イマドキのベストな方法ってなんだろう。
현재 페이지에 class 추가하기

# 개념
```javascript
var str = 'Mozilla';

console.log(str.substring(1, 3));
// expected output: "oz"

console.log(str.substring(2));
// expected output: "zilla"
```
##현재 페이지에 클래스 추가하기
javascript, jquery を勉強したけどいつも難しい。:frowning2:

```javascript
    // http://127.0.0.1/06_menu/feature/index.html //"/"[2]기준으로 feture 를 가져온다.
    var activeUrl = location.pathname.split("/")[2];
    
    // 문자열의 앞 20번째 인덱스까지 자른후 다음 문자열 추출, 20이후의 문자열 추출
    var activeSub = location.href.substring(20);

      navList = $(".menu-list > li").find("> a");
      subMenu = $('.sub-menu > li').find(">a");
      
      navList.each(function(){
        if( $(this).attr("href").split("/")[2] == activeUrl ) {
          console.log($(this).attr("href").split("/")[2],activeUrl);
         $(this).addClass("active");
        };
      });

      subMenu.each(function() {
        if ($(this).attr("href") == activeSub) {
          $(this).addClass("active");
        }
      });
    }
```
nginxでGETパラメータの値を使用してリダイレクト先のURLを作成する方法

## GETパラメータの値を使用してリダイレクト先のURLを作成する方法
### 旧サイトから新サイトへ移行する際に、新サイトのパッケージの都合でカテゴリーページ、個別ページのURLが変更になった時に行なったnginxの設定メモ

・ECサイトにおける商品カテゴリーページ、商品個別ページの旧サイト→新サイト設定例

```nginx:nginx.conf
server {
#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~

    #商品カテゴリーページ例
    # 旧サイトURL： https://xxxxxxx.jp/products/list.php?category_id=1
    # ↓
    # 新サイトURL： https://xxxxxxx.jp/products/cat1/
    #
    if ($args ~ "category_id=(.*)") {
        set $category_id $1;
        rewrite ^/products/list.php.*$ /products/cat$category_id/? permanent;
    }

    #商品個別ページ例
    # 旧サイトURL： https://xxxxxxx.jp/products/detail.php?product_id=1
    # ↓
    # 新サイトURL： https://xxxxxxx.jp/product/1/
    #
    if ($args ~ "product_id=(.*)") {
        set $product_id $1;
        rewrite ^/products/detail.php.*$ /product/$product_id/? permanent;
    }

#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
}
nginxの設定の一部を複数ファイルに分ける方法

## nginxの設定を複数ファイルに分ける方法
### 記述が長すぎたり、役割によってファイルを分けたい場合、includeを使用すれば実現できる。
confファイルとして読ませたくない場合も.txtなどのファイルとして読ませる事が出来る。

例：rewriteの設定だけ別ファイル(.txt)に持たせる場合
・conf本体の設定

```nginx:nginx.conf
server {
#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
    include /etc/nginx/conf.d/nginx_rewrite.txt;
#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
}

```


・includeされたrewrite用ファイル

```nginx:nginx_rewrite.txt
server {
#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
    rewrite ^/sample/from.php /to/ permanent;
    rewrite ^/sample/from2.php /to2/ permanent;
#~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
}

```
WindowsOSへのRubyインストール方法

最近仕事でRubyについて聞かれることが多くなり、今後増えた時に伝えるのを楽にするため、備忘録も兼ねての投稿です。
筆者は開発環境として仮想マシンの**ubuntu(16.04.4)**を主に使っています。

LinuxやMac以外のPCしか持っていなくて、**WindowsOS**のPCしかない上に仮想環境を作りたくない人向け。
#1.ダウンロードとインストール
まずはインストーラーを下記のサイトよりダウンロード。
https://rubyinstaller.org/downloads/
![Rubyインストール.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/4776ec55-5544-03d1-934c-b3d8afc6f5d7.png)

色々と出てくるが慌てないで、最新版をダウンロード。
32bit版OSであればx86
64bit版OSであればx64をそれぞれ選択。
バージョンの確認方法は
スタートボタン>設定>システム>バージョン情報>システムの種類を参照してください。

![OS.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/fb38c12d-e7f2-ea2c-9c78-59cbd1bc361d.png)

#2.インストーラーの実行
インストールを実行すると、色々聞かれますが慌てずNextを押します。

![rubyinst1.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/9979dcbc-ce1b-c311-875a-882f8c90b12b.png)
各チェック項目について上から順に日本語に訳すと、
1.PATHにRubyの実行ファイルを追加する
2.拡張子が「.rb」「.rbw」のファイルはRubyと関連づける
3.デフォルトのエンコードをUTF-8にする

3はデフォルトでチェックが入っていません。お好みです。

Nextを押せばインストールが開始される。
終了するとコマンドプロンプトの画面が出てくる。

![rubyinst2.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/cc5c6c06-4af1-4e4e-51e1-022467b09d52.png)

![rubyinst3.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/4a66345e-aac9-cf27-231c-f6e534ec9296.png)
Enterキーを押して自動でインストールされるので待機。

![rubyinst4.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/58b4c16e-d736-0852-d510-beafebf6607c.png)
この画面が表示されたら、Enterキーを押して終了。

#3.インストールできたかの確認
コマンドプロンプトを開いて「ruby -v」と入力。
-vは実行オプションで、バージョン情報の確認ができます。
これで以下のような表示がでればインストール成功です。
![rubyinst6.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/48bd580f-f029-4f15-58af-9d95848a1839.png)

#4.Rubyの実行
定番のHello Worldをルビーで作ります。
コマンドプロンプトのディレクトリにでも「hello.rb」を作ります。

```ruby:hello.rb
puts "Hello Ruby"
```
コマンドプロンプトで「Ruby 実行ファイル」と入力します。
以下のようなが表示がされれば成功。
![rubyinst7.PNG](https://qiita-image-store.s3.amazonaws.com/0/246001/52ccc5d8-d73d-6d5d-723b-70a8fa61bda4.png)

以上です。
Rubyはスクリプト言語なので、繰り返し作業をさせたりできます。ぜひともご活用ください。
Stackdriver Monitoring(v3)の概念/用語を整理した

※2018/08/06現在、日本語版Stackdriver Monitoringのドキュメントは2016年に書かれたものが多いため2018年に更新されている英語版を読んだ。

![stackdriver_monitoring_terms.png](https://qiita-image-store.s3.amazonaws.com/0/97191/2b729336-bb4b-037f-d374-03ae8f0f3840.png)

## 概念/用語
Stackdriver Monitoring(v3)のドキュメントを読むにあたって、頻出するけどよくわからない基本用語/概念があったのでまとめた。
https://cloud.google.com/monitoring/api/v3/metrics

### Metrics(指標)
Metricsはシステムやリソースのパフォーマンスを把握するための測定値。
`Metric Types(指標タイプ)`はMetricsと同義。
#### 標準メトリクスとカスタムメトリクス
GCPによって最初から用意されている各GCPのリソースに関する`Built-in Metrics(標準メトリクス)`もあれば、
ユーザーが定義する`Custom Metrics(カスタムメトリクス)`もある。
標準メトリクス例:　`storage.googleapis.com/api/request_count` (GCSのリクエスト数に関するメトリクス)

#### Label(ラベル)
メトリクスには`ラベル`が定義でき、標準メトリクスには最初からラベルがついているものがある。
ラベルはメトリクスの集計に利用できる。
例えば `storage.googleapis.com/api/request_count` には `response code` というラベルがあり、
リクエストの成否を元に集計することができる。

#### Monitored Resource(監視対象リソース)
前述のラベルの中にはGCSのバケット名やGCEのインスタンスIDなどは含まれておらず、
それらは`Monitored Resource`が保持する。
Monitored Resourceはメトリクスのデータポイントを送信してきた具体的なインスタンスやバケットなどを表す。
各リソースでどのような値が保持されているかについては`Monitored Resource Type(監視対象リソースタイプ)`で定義されている。
https://cloud.google.com/monitoring/api/resources
例えば `gcs_bucket`には`project_id`, `bucket_name`, `location`が含まれている。

#### Data Point(データポイント)
メトリクスの各測定値のこと。
`Metric Data`、`Metric Data Point`と同義。

### Time Series(時系列)
`Time Series`は一連のタイムスタンプ付きのデータポイントを表す。
例:タイムスタンプ:2018/01/01 09:00:00 + データポイント: CPU使用率50%
それぞれのTime Seriesは以下の4つを保持している。
- メトリクスの名前
- メトリクスのラベル
- Monitored Resource
- タイムスタンプとデータポイント

なのでTime Seriesは以下3つの値の組み合わせで一意になり、組み合わせの数分Time Seriesが存在することになる。
- メトリクスの名前
- メトリクスのラベルそれぞれの値
- Monitored Resource

注1:
`compute.googleapis.com/instance/cpu/utilization` メトリクスのように、
Monitored Resource Typeが常に`gce_instance`(単一)のメトリクスもあれば。
`agent.googleapis.com/cpu/utilization` メトリクスのように、
Monitored Resource Typeが`gce_instance`と`aws_ec2_instance`(複数)から指定できるものもある。

注2:
Time Seriesはデータがなければ存在しない。
対象のデータが存在した場合のみ生成される。


## Reference
Stackdriver Monitoringで使われる概念/用語説明
https://cloud.google.com/monitoring/api/v3/metrics

Monitored Resource Type(監視対象リソースタイプ)一覧
https://cloud.google.com/monitoring/api/resources
pyenvをiTerm2で使う際にハマったこと

## 前提
iTerm2を使用しており、.bashrc, .zshrcの両方を使用している。

## やりたかったこと
python2系と3系の切り替えが面倒になってきたので、pyenvを入れたかった。

## やったこと
pyenvのインストール、使い方、pythonのバージョン切り替えできない時の対処法（https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b ）を参考に入れてみる。
PATHは/usr/local/bin/pythonを向いているが、pyenvで設定したpythonのバージョンになっていない。
pyenvでPythonがSystemバージョンから切り替わらない時の対処（https://qiita.com/ta_ta_ta_miya/items/e24394c6b0022405a126） などもみるがよくわからず。
調べると、.bash_profileに書き込んだ「eval "$(pyenv init -)"」の実行が失敗している
.bash_profileを.zshrcでsourceコマンドで読み込んでいるのでここら辺があやしいことに気づく。

## 結果
.zshrcに「eval "$(pyenv init -)"」を書き込むと解決

## 原因
「eval "$(pyenv init -)"」の実行内容を把握していないため、調査中
Crystal言語で小さなバイナリが作れるようになっていた

# 概要

Crystal言語でのHelloWorldは以下のようなプログラムになる。

```ruby:greet.cr
puts "Hello, World!"
```

```
crystal build --release greet.cr
```

これを、普通にリリースビルドすると、現在約192kbのバイナリが生成される。

先程知ったのだが、この記事にある方法でソースコードを書きビルドすると、同じ機能にもかかわらず約8.5kbのバイナリが出力される。
https://perens.com/2018/07/06/tiny-crystal-language-programs/

```ruby:minimal.cr
require "lib_c"
require "lib_c/i686-linux-gnu/c/stdlib"
require "lib_c/i686-linux-gnu/c/stdio"

def free(object)
  LibC.free(pointerof(object))
end

class String
  def to_unsafe
    pointerof(@c)
  end
end

class Foo
  def bar
    LibC.printf "Hello, World!\n"
  end
end

f = Foo.new
f.bar
free(f)
```

```
crystal build minimal.cr --prelude="empty" -p --release --no-debug
```


# 解説

Crystalはコンパイル時に自動的に [`src/prelude.cr`](https://github.com/crystal-lang/crystal/blob/master/src/prelude.cr) を読み込む。
このファイルの中で標準ライブラリを読み込んでいるため、CrystalではRubyのようにスラスラとコードがかけるようになっている。

一方、このファイル内で大量の標準ライブラリを読みこんでいるせいで、Crystalのバイナリは実際には使ってない機能もバイナリに含めてしまっている。
正確に言えば、コンパイラが使わないと分かっているコードは含まれないのだが、シグナルやスレッド等、使うかわからないコードはバイナリに含まれてしまう。

例にあるように、ビルドオプションに `--prelude="empty"` を加えると `src/prelude.cr` を読み込む代わりに [`src/empty.cr`](https://github.com/crystal-lang/crystal/blob/master/src/empty.cr) を読み込むようになる。このファイルではごくわずかなライブラリのみを読み込んでいるため、生成されるバイナリサイズが小さくなる。
ただしこのファイルは本当に最小なため、何かしたければ上のサンプルのようにいろいろ自作しなくてはいけない。

# 確認

Crystal生成結果はLLVM中間コードを通して確認できる。

```
$ crystal build minimal.cr --prelude="empty" --release --no-debug --emit llvm-ir

$ cat minimal.ll
; ModuleID = 'main_module'
source_filename = "main_module"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"

@ARGV_UNSAFE = internal unnamed_addr global i8** null
@"'Hello, World!\0A'" = private constant { i32, i32, i32, [15 x i8] } { i32 1, i32 14, i32 14, [15 x i8] c"Hello, World!\0A\00" }

; Function Attrs: nounwind
define void @__crystal_main(i32 %argc, i8** %argv) local_unnamed_addr #0 {
alloca:
  store i8** %argv, i8*** @ARGV_UNSAFE, align 8
  %0 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({ i32, i32, i32, [15 x i8] }, { i32, i32, i32, [15 x i8] }* @"'Hello, World!\0A'", i64 0, i32 3, i64 0)) #0
  ret void
}

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #0

; Function Attrs: nounwind uwtable
define i32 @main(i32 %argc, i8** %argv) local_unnamed_addr #1 {
entry:
  store i8** %argv, i8*** @ARGV_UNSAFE, align 8
  %0 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({ i32, i32, i32, [15 x i8] }, { i32, i32, i32, [15 x i8] }* @"'Hello, World!\0A'", i64 0, i32 3, i64 0)) #0
  ret i32 0
}

; Function Attrs: nounwind
declare void @llvm.stackprotector(i8*, i8**) #0

attributes #0 = { nounwind }
attributes #1 = { nounwind uwtable "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" }
```

（インライン化した関数が残っているため、もう少し小さくなりそうだけど）ほぼ最小構成であることが確認できる。
コンパイラのデフォルトC++バージョン

メモを供養

# GCC

バージョン6からC++14（+GNU拡張）がデフォルトになっており、それ以前はC++98（+GNU拡張）だった。

https://gcc.gnu.org/gcc-6/changes.html

> Caveats
> - The default mode for C++ is now -std=gnu++14 instead of -std=gnu++98.

# Clang

バージョン6からC++14（+GNU拡張）がデフォルトになっており、それ以前はC++98（+GNU拡張）だった。

http://releases.llvm.org/6.0.1/tools/clang/docs/ReleaseNotes.html

> C++ Language Changes in Clang
> - Clang’s default C++ dialect is now gnu++14 instead of gnu++98. This means Clang will by default accept code using features from C++14 and conforming GNU extensions. Projects incompatible with C++14 can add -std=gnu++98 to their build settings to restore the previous behaviour.

# まとめ

どちらもバージョン6から`-std=gnu++14`がデフォルト、それ以前は`-std=gnu++98`がデフォルト。
覚えやすい。
シェルスクリプトでシンプルにurlエンコードする話

訳あってシェルスクリプト上で文字列を符号化したかったのですが、結構色んな所で詰まったのでまとめました。

やってること自体はシンプルですが、簡単ではないです。

# tl;dr 
↓の関数のような処理を行えばOKです。

```sh
function urlencode {
  echo "$1" | nkf -WwMQ | sed 's/=$//g' | tr = % | tr -d '\n'
}
```

## 使用例
```sh
% urlencode "記号入りの文字列<>&abc"
%E8%A8%98%E5%8F%B7%E5%85%A5%E3%82%8A%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%3C%3E%26abc
 ```

# 各処理の説明
１つずつ処理の流れを説明していきます。

## `nkf -WwMQ`

Googleで「シェルスクリプト URLエンコード」などで調べるとnkfを使うという方法がいくつか紹介されています。
- [urlエンコード（コマンドライン／シェルスクリプト） \- Qiita](https://qiita.com/kkdd/items/d5a32b5981ed4b41d384)
- [逆引きUNIXコマンド/URLエンコード・URLデコード方法・nkf \- Linuxと過ごす](http://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/URL%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%83%BBURL%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89%E6%96%B9%E6%B3%95%E3%83%BBnkf#u9980cdc)

このnkfのオプションはそれぞれ以下の指定となっています。

```
OPTIONS
       -J -S -E -W -W16 -W32 -j -s -e -w -w16 -w32
           Specify input and output encodings. Upper case is input.  cf. --ic and --oc.
           -W  UTF-8N.


       -M  MIME encode. Header style. All ASCII code and control characters are intact.

           -MQ Perform quoted encoding.
```

すなわち、nkfの入力出力の文字コードを、共にUTF-8を指定、[quoted encoding](https://ja.wikipedia.org/wiki/Quoted-printable)した上で出力するという指定になります。

quoted encodingは主に電子メールで非ASCII文字を表現するために使用するエンコード方式です。 任意の8ビットバイト値を `=[16進数2桁]` の表記にすることでASCII範囲内の文字列で表現しています。

ただ、本来のquoted encodingではASCII印字可能文字は`=` 以外符号化不要のはずなのですが、このnkf オプションではアルファベット・数字以外のASCII印字可能文字も符号化されます。(そのおかげでurlエンコードできるのですが)

これでアルファベット・数字以外の文字をすべて符号化出来ます。

## `sed 's/=$//g'`
> Quoted-printable で符号化したデータの行は、76文字を超えてはならない。

このような成約があるため、nkfに長い文字列を渡した場合、以下のように改行されて出力されます。

```shell
% echo "とても長い文章ああ" |nkf -WwMQ
=E3=81=A8=E3=81=A6=E3=82=82=E9=95=B7=E3=81=84=E6=96=87=E7=AB=A0=E3=81=82=
=E3=81=82
```

URLエンコード目的では改行は不要のため、改行を無視して扱う必要があります。(それ自体は後のステップで行います)

さらにここで注意しなければならないのは、その挿入された改行を明記するために行末に`=`が追加されます。
単純に改行を削除してしまうだけだと、この=が次の行とつながり `==` のような仕様上正しくない文字順が生まれてしまいます。

なので、各行の末尾に存在する `=`をこのsedで削除します。

## `tr = %`
Quoted-printableは `=??` という表記で符号化していますが、URLエンコーディングでは `%??` という表記で符号化しています。

そのため、出力結果の`=` を `%` に置換します。

## `tr -d '\n'`
前述のように、Quoted-printableでは76文字を超える文字列は禁止のため、主力結果が76文字を超える場合、nkfで改行が挿入されています。

しかし、基本的にURLエンコーディングではそういった制約はなく、改行は不要のため、trを用いて改行を削除しています。
MySQL へ大量のCSVファイルをbashでインポートする

大量のCSVファイルをインポートするためにシェル組んだので残しておく

MySQL8.0 で実行

```bash
$ mysql --version
mysql  Ver 8.0.11 for Linux on x86_64 (MySQL Community Server - GPL)
```

---


設定ファイルに以下を記述する必要があった
記述しないと 「 The used command is not allowed with this MySQL version 」って怒られる

```bash:/etc/my.cnf
[client]
loose-local-infile=1
```

もしかしたら以下も実行しとく必要があったかも

```sql

mysql> SET PERSIST local_infile= 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@local_infile;
+----------------+
| @@local_infile |
+----------------+
|              1 |
+----------------+
1 row in set (0.00 sec)

mysql>
```
[MySQL 8.0でLOAD DATA LOCAL INFILEが "ERROR 1148 (42000): The used command is not allowed with this MySQL version" で失敗する時](https://yoku0825.blogspot.com/2018/07/mysql-80load-data-local-infile-error.html)
（参考にさせていただきました）


---


#大量のCSVをインポートするシェル
実行ディレクトリにある ～.csv ファイルを全部読み込んでインポートします

```bash:
#!/bin/bash

## INIT
PWD="PasSw0rd"
TOTAL=`ls *.csv | wc -l`

## テーブルクリア
echo 'TRUNCATE TABLE csv_table;' | MYSQL_PWD=$PWD mysql -u UserName DBName -s -N

## ディレクトリ内の CSV ファイルを対象にループ
ls `pwd`/*.csv | while read line
do
  ## CSV の行数取得
  L=`cat "$line" | wc -l`

  ## カウンタ
  cnt=`echo $(($cnt + 1))`

  ## 処理ファイル表示
  echo "$line" | awk -v"cnt=$cnt" -v"total=$TOTAL" -v"line=$L" '{ printf("%3d/%3d %\0477d %s\n", cnt, total, line, $0);}'

  ## インポート処理
  MYSQL_PWD=$PWD mysql -u UserName DBName << EOT
  LOAD DATA LOCAL INFILE '$line'
  INTO TABLE csv_table
  FIELDS
    TERMINATED BY ','
    ENCLOSED BY '"'
  LINES
    TERMINATED BY '\r\n'
  IGNORE 1 LINES;
EOT
done

## 結果行数表示
echo 'select count(*) from csv_table;' |
MYSQL_PWD=$PWD mysql -u UserName DBName -s -N |
awk '{printf("\nIMPORT %\047d  Record\n", $0);}'

```

CSVファイルの先頭１行を読み飛ばしてます（ IGNORE 1 LINES ）
CSVはカンマ区切り（ TERMINATED BY ',' ）
CSVはダブルクォーテーションで囲まれてる（ ENCLOSED BY '"' ）
CSVの行の終わりは改行 （ TERMINATED BY '\r\n' ）
CSV ファイルはUTF8 で作ってありました


実行時には以下のような表示を行います

```
  1/128      56 /path/file1.csv
・・・・・
128/128   9,440 /path/file128.csv

IMPORT 201,289  Record
```


---

### インポートしたデータのカラム毎のデータバリエーション数とレコード数確認

CSVにデータがあったのか、カラム毎にとりあえず確認してみる

```bash

#!/bin/bash

## INIT
PWD="PasSw0rd"

echo "desc csv_table;" |
MYSQL_PWD=$PWD mysql -u UserName DBName -s -N |
awk '{print $1;}' |
while read line
do

  col=$(echo $line | sed -e 's/\//_/g')
  echo "$line" | awk '{printf("SELECT `%s`, count(*) FROM csv_table GROUP BY `%s` ORDER BY 2 DESC, 1\n", $1, $1);}' |
  MYSQL_PWD=$PWD mysql -u UserName DBName -s -N >  "lst.$col"

  cnt=`cat "lst.$col" | wc -l`

  if [ $cnt -ne 1 ]
  then
    echo "$line" | awk -v"cnt=$cnt" '{printf("%\0477d %s\n", cnt, $0);}'
    if [ $cnt -lt 10 ]
    then
      cat "lst.$col" | awk '{printf("          : %s\n", $0);}'
    fi
  fi

done

```

カラム内のデータバリエーションがない場合は表示対象外にして（ if [ \$cnt -ne 1 ] ）
バリエーションが少ない場合はデータ内容毎のレコード数を表示してみる（ if [ \$cnt -lt 10 ] ）

実行結果はこんな感じ

```
109,790 ｘｘキー
 40,927 ｘｘ番号
 46,699 ｘｘ名
 21,118 ｘｘｘｘ
     14 ｘｘｘｘｘｘ
    223 ｘｘｘ
      2 ｘｘ種別
          :     201051
          : 001 238
  4,862 ｘｘｘｘｘｘｘｘｘ
　・・・・・
```
　ｘｘキー は 109,790のバリエーションがあり
　ｘｘ種別 は 2 バリエーションあり、内容は 空白が 201,051レコード、種別 001 が 238レコード
のような表示になります
「-2147467259：このログインで要求されたデータベース"xxx"を開けません。ログインに失敗しました。」解決手順

#起こったこと。
テスト環境構築のため、データベース（以下DB)をテスト版として設けた。
ExcelVBAからテスト版のDBへ接続しようとすると、「-2147467259：このログインで要求されたデータベース"xxx"を開けません。ログインに失敗しました。」と表示されて、処理が出来なかったため、対応開始。
![キャプチャ_Excel_ログイン失敗メッセージ.PNG](https://qiita-image-store.s3.amazonaws.com/0/63307/408e05e5-8122-34e6-15a8-1004866ed69b.png)

#環境
- SQL Server 2014
- Management Studio 2014（以下SSMS）
- Excel 2010
- ExcelとSQL ServerはADOを使用して接続。Windows認証を使用。

#行なったこと。
##1. DBのプロパティを比較
SSMSで、本番環境、テスト環境のDBのプロパティを比較してみた。
その結果、テスト環境のDBにはguestユーザーの権限がなかった。

##2. 権限を追加
SSMSで、テスト環境のDBに、guestユーザーの権限を追加。
そして、権限を許可する項目は本番環境DBのそれと同じにした。
以下の8項目。

- 更新
- 削除
- 参照
- 実行
- 接続
- 選択
- 挿入
- 変更

許可をチェック→[OK]の後に再度プロパティを確認したところ、権限の許可者が「dbo」になっていた。
これは本番環境のDBも同様なのでOKと見なした。

#結果。
ExcelVBAから該当処理が問題なく行なえるか実行したところ、全て処理出来るようになった。

#疑問点
今回テスト環境のDBを作成した時、sa権限で実行した。その時にguestユーザーの権限付与も合わせて行なえるように出来たら、追加で権限付与する必要がなくなって良いなと思った。
静的メソッドの呼び出し（class構文）

ESlintの`class-methods-use-this`ルールを有効にしている場合、
thisを使用しないメソッドに関しては静的メソッドを定義する必要がありまして、
`static MyMethod()`としていないと、次のようなエラーになります。

```shell:terminal
error  Expected 'this' to be used by class method 'MyMethod'  class-methods-use-this
```

```js:js
class MyClass {
    constructor(alpha) {
        this.alpha = alpha
    }

    MyMethod () {
        console.log('This is bad')
    }
}
```

`MyClass.callStaticMethod()` と記述することで、
補助メソッド的に他のメソッドで呼び出すことが可能です。

```js:js
class MyClass {
    constructor(alpha) {
        this.alpha = alpha
    }

    PrimaryMethod () {
        MyClass.StaticMethod()
        console.log(this.alpha)
    }

    StaticMethod() {
        console.log('This is good')
    }
}
```
replace a column name in dataframe 

```
 df.columns.foreach { case col =>
      col.toLowerCase match {
        case "a_cookie_id" =>
          df = df.withColumnRenamed(col, "cookie_id")
        case "a_member_id" =>
          df = df.withColumnRenamed(col, "member_id")
        case "collect_set(concat(item_cd, -, color_cd))" =>
          df = df.withColumnRenamed(col, "item_ids")
        case _ =>
          df = df.withColumnRenamed(col, col.toLowerCase())
      }
    }
```
DirectX12 事始め スワップチェインの生成

今回は、スワップチェインの作成をしていきます。
スワップチェインとは裏画面と表画面の切り替え役みたいなものです。
それではやっていきます。

```c++:Swap.h
#include "Obj.h
class Window;
class Queue;
class Swap : 
   public Obj
{
   public:
      // コンストラクタ
      Swap(Window* win, Queue* queue);
      // デストラクタ
      ~Swap();

      // スワップチェインの取得
      IDXGISwapChain3* Get(void) const {
         return swap;
      }
      // バックバッファの数取得
      UINT GetBack(void) const {
         return bufferCnt;
      }
   private:
      // ファクトリーの生成
      HRESULT CreateFactory(void);
      // スワップチェインの生成
      HRESULT CreateSwap(void);

      // ウィンドウ
      Window* win;
      // コマンドキュー
      Queue* queue;
      // ファクトリー
      IDXGIFactory4* factory;
      // スワップチェイン
      IDXGISwapChain3* swap;
      // バックバッファ数
      UINT bufferCnt;
};
```

```c++:Swap.cpp
#include "Swap.h"
#include "Window.h"
#include "Queue.h"

// コンストラクタ
Swap::Swap(Window* win, Queue* queue) : 
   win(win), queue(queue)
{
   CreateFactory();
   CreateSwap();
}
// デストラクタ
Swap::~Swap()
{
   Release(swap);
   Release(Factory);
   delete win;
   delete queue;
}
// スワップチェインファクトリーの生成
HRESULT Swap::CreateFactory(void)
{
   result = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
   return result;
}
// スワップチェインの生成
HRESULT Swap::CreateSwap(void)
{
   //スワップチェイン設定用構造体
   DXGI_SWAP_CHAIN_DESC1 desc = {};
   desc.AlphaMode   = DXGI_ALPHA_MODE_UNSPECIFIED;
   desc.BufferCount = 2;
   desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   desc.Flags       = 0;
   desc.Format      = DXGI_FORMAT_R8G8B8A8_UNORM;
   desc.Height      = win->GetY();
   desc.SampleDesc  = { 1, 0 };
   desc.Scaling     = DXGI_SCALING_STRETCH;
   desc.Stereo      = false;
   desc.SwapEffect  = DXGI_SWAP_EFFECT_FLIP_DISCARD;
   desc.Width       = win->GetX();

   //スワップチェイン生成
   result = factory->CreateSwapChainForHwnd(queue->Get(), win->GetHandle(), 
   &desc, nullptr, nullptr, (IDXGISwapChain1**)(&swap));
   //バックバッファ数保存
   bufferCnt = desc.BufferCount;

   return result;
}
```

```c++:Main.cpp
//これで表・裏の入れ替え
swap->Get()->Present(1, 0);
```

今回は、ウィンドウハンドルからスワップチェインを作成してみました。
これで裏画面と表画面の入れ替えができるようになりました。
次回はレンダーターゲットを作成し、画面に影響を与える準備しよかな。
通信管理で出てくる　TX　と　RX　は？

# 通信系で出てくるTX/RXってなんだ？
- Tx　は送信結果、送信機
- Rx　は受信結果、受信機
- Txは　Transmitter
- Rxは　Receiver
- の頭文字からきているようです
- xは単純に省略を示す文字　X　そうです。
- Transmit eXchang
- Received eXchange
- の eXchange　の略という説もある
Rails Jbuilder の部分テンプレートに任意のファイルを使いたい

# きっかけ
親子関係のあるデータについて、親のエンドポイントにアクセスした時には親のデータとその親に紐づく子のデータを含めたい、そして子のデータだけにもアクセスできるようにしたい、ただ jbuilder を親と子で同じ内容を書くのが DRY じゃなくてダサい。`json.partial!` が使えそうだけど、他のディレクトリにあるテンプテートはどうやって呼び出すのかがググり力不足でわからず。

# めっちゃ簡単なモデル
```parent.rb
class Parent < ApplicationRecord
  has_many :children
end
```

```child.rb
class Child < ApplicationRecord
  belongs_to :parent
end
```

# ディレクトリ構成
```
views/
|-parents/
|  |-show.jbuilder
|-children/
   |-_detail.jbuilder
   |-show.jbuilder
```

# `parents/show.jbuilder` で `children/_detail.jbuilder` を呼び出したい
10分ググり続けてもマニュアルが見当たらなかったのでソースコードを読んだ。
https://github.com/rails/jbuilder/blob/ad01e8496e1b4c537314a2b74a76dfb4594f67bf/lib/jbuilder/jbuilder_template.rb

上記クラスの `_render_explicit_partial` メソッドに、テンプレートのviewから見たパスと、渡したい変数を locals で渡せれば良さそう。

```jbuilder_template.rb
def partial!(*args)
  if args.one? && _is_active_model?(args.first)
    _render_active_model_partial args.first
  else
    _render_explicit_partial(*args)
  end
end

# 中略

private

# 中略

def _render_explicit_partial(name_or_options, locals = {})
  case name_or_options
  when ::Hash
    # partial! partial: 'name', foo: 'bar'
    options = name_or_options

# 以下略
```

コメントにあるように `json.partial! partial: 'name', foo: 'bar'` の形で使ってあげれば良さそう。

# 結論
こう書きました。

```parents/show.jbuilder
json.id(@parent.id)
json.set! :children do
  json.array!(@parent.children) do |child|
    json.partial! partial: 'children/detail', locals: { child: child }
  end
end
```

```children/_detail.jbuilder
json.id(child.id)
```

んでAPI叩く。

```
curl -X GET http://localhost:3000/parent/1
```

```json
{
  "id": 1,
  "children": [
    { "id": 1 },
    { "id": 2 }
  ]
}
```

動きました:)

# 追記
普通にreadme.md に書いてありました…ググり力が足りなすぎる…
[備忘録]Rust個人用メモ

# インストール方法

```
curl https://sh.rustup.rs -sSf | sh
```

# IDE

[IntelliJ Rust](https://intellij-rust.github.io/)が良い？

# Rust自体のバージョン管理いる？

本家にもVerupの仕組みはあるけども[rsvm](https://github.com/sdepold/rsvm)とか使った方が良い？

# Package Manage

デフォで入っているcargo使えばおっけー？

# Web framework

[Iron](https://github.com/iron/iron) or [Rocket](https://github.com/SergioBenitez/Rocket)？その他に有力なものある？

# DB関連

## OR mapper

[diesel](http://diesel.rs/) 一択の世界観に見える

## Connection Pool

[r2d2](https://github.com/sfackler/r2d2) 一択の世界観に見える



# クライアント系黒魔術

iOS,androidの[黒魔術](https://github.com/kennytm/rust-ios-android)って使ってる話って聞く？
GO VSCodeで「シンボルの名前を変更」が出来ない

## 実行環境
Code 1.25.1
go version go1.10.3 darwin/amd64

## 経緯
goで型名をまとめて変更しようと「シンボルの名前を変更 F2」を行ったら、

```
Rename failed: gorename: can't find package containing /Users/****/workspace/test/main.go
名前の変更を実行できませんでした。
```
と出てしまいました。

## 解決方法
ソースを$GOPATH以外の場所に置いていかららしい。
ソースのディレクトリを$GOPATH下のsrcの中に移動すればすんなり動いた。

## 解決のきっかけ
[Gorename not working: Rename failed: gorename: can't find package containing #1641](https://github.com/Microsoft/vscode-go/issues/1641)
> I get it now : my code wasn't in the GOPATH ! It works now :)
Qiita(22)今朝、Qiitaで起きた奇異な現象を聞いてください。

2018年8月8日、早朝。
### 今朝、Qiitaで起きた奇異な現象を聞いてください。
## 今朝、Qiitaで起きた奇異な現象１）10しか保存できない下書きが11になった。
下書きが10になったため、一つを編集して空にして、編集して保存しようとしたら、移動しますかと聞いてきて保存できなかった。

下書きの一覧を表示させたら、11/10になっていた。

この状態では、Qiitaに登録がうまく機能せず、
下書きの空になっている記事を削除して、１１番目になっていた記事を登録した。

## ２）投稿済みの記事と同じ記事が下書きに保存されていた。
これは今朝に限らず、複数の計算機でqiitaの記事を編集すると遭遇する現象。

ある窓で編集していて、別の窓で同じ内容を編集していて、保存がうまくできずにいると起きることがある。

## ３）投稿したら同じ記事が２つ投稿された。
今朝初めて。
全く同じ記事が、２度投稿された。

１つはすぐに削除した。

これは操作誤りの可能性がある。

いずれも再現試験をしようとしているが、まだ再現できていない。
２）、３）は複数の窓を開いている状態の操作間違いによって起きる可能性がある。１）はシステム側ができないようにしているはずなのに、、、。

# 参考資料
Qiita最近反応遅くないですか
https://qiita.com/kaizen_nagoya/items/6e4b15a777f8fb6043e6

Qiita(0)Qiita関連記事一覧（自分）
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.10 初稿　20180808
ver. 0.11 文書履歴追記 20180810
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
cssを３倍楽に　lessに関する基本のき

lessはcss記述を簡略化してくれる便利なやつ。
lessに関する基本情報まとめ

##lessをインストール
　mode.jsをインストール後、コマンドプロンプトなどでnpm install less -gと打つ
これで完了。

##　lessファイルをcssに反映
 lessc＋lessファイルの名前＋cssファイルの名前を打ち込む

##less最大の特徴「変数」
　lessでは自分で変数を設定できる
例）@mycolor: red;

また、変数はpやh1などプロパティにも使える

例）@dir: "./img";
h1{
   background:url("@{dir}/bg.png");
}
こうすれば、
h1{
  background: url("./img/bg.png");
}
　と表示される

## ミックスイン機能
　lessではミックスインという機能を使うことができる
変数のでっかいバージョンってかんじ？

例）

```less:quiita.rb
my-mixin{border: 5px, solid red;

padding: 7px;

margin: 7px;}


h1{
my-mixin()
font-size: 20px;


```

また、paddingだけは適宜サイズを変えたい…なんて時は

```less:quiita.rb
my-mixin[@border]{
border 5px; solid: red;
padding: padding;

margin: 7px;}


h1{

my-mixin(5px);}


と書くことが出来る。
この場合、borderは5px。
もちろん、複数設定することも可。
自分のデスクトップにリモート接続

## 参考

* 今までvinoを使ってきたが、 /usr/bin/vino-preferences が xubuntu 18.04 から含まれていない様子。
    * [Bug #1775999 “Cannot set vino preferences in Lubuntu 18.04” : Bugs : vino package : Ubuntu](https://bugs.launchpad.net/ubuntu/+source/vino/+bug/1775999)
* [VNC/Servers - Community Help Wiki](https://help.ubuntu.com/community/VNC/Servers)

## 方法


```
apt install -y x11vnc

x11vnc -display :0
```

5901 ポート でLISTENされる。
あとはvncviewerで接続すればよい。