OmniAICreator/Qiita-1.07M huggingface dataset:
dockerでmongodb環境を構築してテストをする話

# dockerでmongodb構築

```
docker run -d --name dev-mongo -p 27017:27017 mvertes/alpine-mongo
```

-d：バックグラウンドで起動する
--name dev-mongo：dev-mongoという名前をつける
-p：ホストの27017ポートでアクセスしたら、コンテナの27017に転送する
mvertes/alpine-mongo：alpineを利用したmongoのイメージ

## 起動確認
この記事中は、起動させたままにします。

```sh
$ docker ps
CONTAINER ID        IMAGE                  COMMAND                 CREATED             STATUS              PORTS                                 NAMES
a3d250b5c18b        mvertes/alpine-mongo   "/root/run.sh mongod"   2 seconds ago       Up 3 seconds        0.0.0.0:27017->27017/tcp, 28017/tcp   dev-mongo
```

先ほどの設定が生きています。
IMAGEにはmvertes/alpine-mongo
PORTSでホストの27017からコンテナの27017に転送指定
NAMESにはdev-mongo

補足として、停止と削除は以下のコマンドから。

```sh
$ docker stop dev-mongo
$ docker rm dev-mongo
```

## アクセス

dev-mongo内部のアクセス

```
docker exec -it dev-mongo /bin/sh
```

dev-mongo内でmongoコマンド

```
mongo
```

mongo関連のコマンドの抜粋

```
// 終了
quit()

// adminで操作
use admin

// コレクションの一覧
show collections
```

それらを実行した時のコード

```sh
$ docker exec -it dev-mongo /bin/sh
bash-4.3# psql -U postgres
psql (10.1)
> use admin
switched to db admin
> quit()
/ # exit
```

# テスト準備

npmでmongodbをインストールします。
typescriptを使いたいので、@types/mongodbもインストールします。

```
npm install mongodb @types/mongodb --save
```

## テストコード

```test.ts
import * as mongodb from "mongodb";
import { Db } from "mongodb";

const MongoClient = new mongodb.MongoClient();
let mongoDb: Db;

// db名
const dbName = "TEST";

// allTest()メソッドを実行
allTest()
	.then( () => {
		// 成功した場合
		console.log( "Complete" );
	} )
	.catch( ( e ) => {
		// 失敗した場合
		console.warn( e );
	} );

/**
* 全テスト実行
**/
async function allTest() {
	await before();

	// 1000件インサート
	await insertTest();

	// todo 必要ならここに他のテストのメソッドを追加したり
}

/**
* 事前実行
**/
async function before(): Promise<any> {
	const db = await MongoClient.connect( "mongodb://localhost:27017/" );
	try {
		// テストで使用したいdb名と同名のdbがあったらdrop
		await db.dropCollection( dbName );
	} catch ( err ) {
		// 存在しない場合は無視
	}
	// 新しくdbを作る
	await db.createCollection( dbName );
	mongoDb = db;
}

/**
* 挿入テスト
**/
async function insertTest() {
	const coll = mongoDb.collection( dbName );

	const timeName = "1000件インサート";
	console.time( timeName );

	const len = 1000 | 0;
	let i = 0 | 0;
	while ( i < len ) {
		i = (i + 1) | 0;

		await coll.insertOne( {
			id: i,
			name: `username${i}`
		} );
	}
	console.timeEnd( timeName );

	const count = await coll.count( {} );
	if ( count === len ) {
		console.log( "SUCCESS" );
	} else {
		console.log( "FAILURE" );
	}
}
```

ちょっと訳あって普通にコード書いてますが、テストは普通にmocha使ってpower-assertで判定した方がいいと思います。
（というか実際はそうしているのであとで書き直すかも）
wip:Tabulator

# リンク（固定）

```javascript
$("#example").tabulator({
    height: "311px",
    columns: [
        {title: "", headerSort: false, formatter: "link", formatterParams: {label: "リンク", url: "/"}},
    ]
});
```

<img width="174" alt="スクリーンショット 2018-03-18 9.16.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/37624/37ca6ff8-e95d-8835-590a-8773476632c6.png">

# リンク（カスタマイズ）

```javascript
$("#example").tabulator({
    height: "311px",
    columns: [
        {title: "", field: "name", headerSort: false, formatter: "link",
         formatterParams: {label: "リンク", url:
                        function(cell){
                            return "link?v=" + cell.getValue()}}},
    ],
});
```

テーブルにセットされた値(name）を取得してリンク先のパラメータ(v)に設定している
（TODO：リンク先は安全な値になるように気をつけて・・・）

# フィルター（カスタム）

テーブルに表示する値をフィルタリング

```javascript
function customFilter(data, filterParams){
    //data - the data for the row being filtered
    //filterParams - params object passed to the filter

    return data.name == "bob" && data.height < filterParams.height; //must return a boolean, true if it passes the filter.
}

$("#example-table").tabulator("setFilter", customFilter, {height:3});
```

（公式ドキュメントの例をそのまま引用）


# 読み込み中のメッセージを書き換える

```js
$("#example").tabulator({
ajaxLoaderLoading: "読み込み中",
....
})
```
ローカルのRStudioの設定をDockerコンテナ上のRStudio Serverに反映する

新しくDockerコンテナを作成してRStudio Serverを起動すると、外観だとかキーバインドの設定は当然だけど既定値になっている。コンテナ作成の度にこれらをいちいち設定するのは面倒なので、RStudio Desktopの設定を反映させるようにしたい。

## そもそもRStudioの設定はどこにあるのか?

Global Optionsから設定できる項目は以下のディレクトリ内に保存されている。DesktopとServerで若干パスが異なる（注:以下はmacOSの場合）。

- RStudio Desktop: `~/.rstudio-desktop/monitored/user-settings`
- RStudio Server: `~/.rstudio/monitored/user-settings`

キーバインドだけは別で、DesktopもServerも以下の場所に.jsonで保存されている。

- `~/.R/rstudio/keybindings`

ということは、`docker run`の際に`-v`で上記ディレクトリをリンクさせてやれば設定が反映される…と思いきや、コンテナを一度起動しないと`~/.rstudio`が作成されないらしく、上手くいかない。

## `~/.rstudio/monitored/user-settings`入りのDockerイメージを作成する

無いのであれば作ってしまおう。`rocker/rstudio`をベースにするとして、以下の様な内容で`Dockerfile`を作成する。もちろん、既存のものがあれば下部の2行を追記してもいい。

```Dockerfile:Dockerfile
FROM rocker/rstudio

RUN mkdir -p /home/rstudio/.rstudio/monitored/user-settings/
RUN chown -R rstudio:rstudio /home/rstudio/.rstudio
```

作ったら`docker build`する。`Dockerfile`のあるディレクトリで

```bash
docker build -t my-rstudio .
```

ビルドが終わったら、設定ファイルのディレクトリをリンクさせてコンテナを起動する。

```bash
docker run \
  -v ~/.rstudio-desktop/monitored/user-settings:/home/rstudio/.rstudio/monitored/user-settings \
  -v ~/.R/rstudio/keybindings:/home/rstudio/.R/rstudio/keybindings \
  -p 8787:8787 my-rstudio
```


## 参考

- [Rから離れたくない人向けのDocker環境の操作: RStudio Serverを分析・開発の基盤にするために - まだ厨二病](http://uribo.hatenablog.com/entry/2017/12/21/212941)
- [Conducting reproducible research with Docker (Part 3 of 3) - Derek Powell](http://www.derekmpowell.com/posts/2018/02/docker-tutorial-3/)
簡単なTCPサーバー

TCPサーバーを書く必要があったので復習で書いてみた。

とりあえず、対話式の通信ではなく、一歩的にデータを送信してくる相手の通信をログに残している。

>Wiresharkみたいなパケットキャプチャツールをログは良いかもしれない

同期型であまり役に立たないかな…

次は、非同期とか、複数のクライアントの管理なんかをやりたいけど。思いっきり忘れているので、Qiitaあさりをしたいと思います。いい例があったらコメントに書いて下さい。

>でも、ライブラリのインポートをみると始めにいろいろとやろうとした意志だけは感じる

```cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;


namespace SampleTCPServer
{
    class Program
    {
        readonly static string IP_ADDRESS = "192.168.0.1";
        readonly static int OPEN_PORT = 60000;

        static void Main(string[] args)
        {
            IPEndPoint ipaddress = new IPEndPoint(IPAddress.Parse(IP_ADDRESS), OPEN_PORT);
            TcpListener listener = new TcpListener(ipaddress);

            listener.Start();
            TcpClient client = listener.AcceptTcpClient();

            if (client.Connected)
            {
                listener.Stop();
                NetworkStream net_stream = client.GetStream();

                string file_name = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString() + "_" + DateTime.Now.ToString() + ".log";

                StreamWriter writer = new StreamWriter(file_name);

                do
                {
                    if (net_stream.CanRead)
                    {
                        byte[] recive_byte = new byte[client.ReceiveBufferSize];
                        net_stream.Read(recive_byte, 0, (int)client.ReceiveBufferSize);

                        writer.WriteLine(recive_byte);
                    }
                } while (client.Connected);
                client.Close();
                writer.Close();
            }

            Console.WriteLine("何かのキーを押すと終了");
            Console.Read();
        }
    }
}
```
react-native環境の構築

やらないといけなさそうなので、
勉強はじめました。
まずは環境セットアップから。

#前提

* インストール済みソフトウェア
  * xcode
  * brew
* PC
  * Macbook pro 2016 late
  * mac OS High Sierra

# node,npmのインストール


以下のコマンドでインストールします

```bash
$ brew install node
$ brew install npm
```
     
# watchmanのインストール

Facebookが作ったファイルシステムの監視ツールらしく
React-nativeでは必須なんだそうです。
以下のコマンドでインストールします

```bash
$ brew install watchman
```

# react-nativeのインストール

npmでインストールします。

```bash
$ npm isntall -g react-native-cli
```

# Hello worldの実行
さっそくreact-nativeでhello worldしてみます。
特定のディレクトリに移動して、初期化してみます。

```bash
$ react-native init hello_world
```

いろいろと関連モジュールのダウンロードのため、
ちょっと時間がかかるかもしれません。
自分の環境では、npmがsudoじゃないと動かなかったのですが、きっと昔にsudoでインストールしていたのかもしれません。。。切ない。

```bash
:
:
:
To run your app on iOS:
   cd /Users/user_name/hello_world
   react-native run-ios
   - or -
   Open ios/hello_world.xcodeproj in Xcode
   Hit the Run button
To run your app on Android:
   cd /Users/user_name/hello_world
   Have an Android emulator running (quickest way to get started), or a device connected
   react-native run-android

```
iOS上で実行したかったら、
`react-native run-ios`を実行しろと言っているので実行してみましょう。

```
$ cd hello_world
$ react-native run-ios
```

動きました！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/63125/cc3f2cca-f920-c21b-b831-bbdbdf2c9b53.png)
TypeScript の Object.assign 型定義がガバガバだった

TypeScript 2.8.0rc でも駄目でした。

## 事象

```typescript
const x = {
    a: 1
}

const y = {
    a: "two"
}

const c = Object.assign({}, x, y);
c.a = ???; // a: number & string
```

[Playground](https://www.typescriptlang.org/play/index.html#src=const%20x%20%3D%20%7B%0D%0A%20%20%20%20a%3A%201%0D%0A%7D%0D%0A%0D%0Aconst%20y%20%3D%20%7B%0D%0A%20%20%20%20a%3A%20%22two%22%0D%0A%7D%0D%0A%0D%0Aconst%20c%20%3D%20Object.assign(%7B%7D%2C%20x%2C%20y)%3B%0D%0Ac.a%20%3D%20%3F%3F%3F%3B%0D%0A)

本来なら `c.a` は `string` となって欲しいが、 Object.assign の型定義が `assign<T, U>(target: T, source: U): T & U;` となっているせいで `c.a` は `number & string` となってしまう。

ネストしたオブジェクトでも `&` されるとそのプロパティがユニオンされてしまうので駄目

```typescript
const x = {
    a: {
        b: 1
    }
}

const y = {
    a: {
        b: "two"
    }
}

const c = Object.assign({}, x, y);
c.a.b = ???; // b: number & string
```

[Playground](https://www.typescriptlang.org/play/index.html#src=const%20x%20%3D%20%7B%0D%0A%20%20%20%20a%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20b%3A%201%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20y%20%3D%20%7B%0D%0A%20%20%20%20a%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20b%3A%20%22two%22%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20c%20%3D%20Object.assign(%7B%7D%2C%20x%2C%20y)%3B%0D%0Ac.a.b%20%3D%20%3F%3F%3F%3B%0D%0A)

## 解決方法

本家は issue は立っているが type spread の機能で解決しようとしているためまだ掛かりそう。
とりあえずは [utility-types の Assign](https://github.com/piotrwitek/utility-types#assign) にキャストしてしまえば問題はない。

`Object.assign({}, a, b) as Assign<typeof a, typeof b>`
jupyter notebookのdefault設定で%matplotlib inlineを省略とline numberを表示 on Mac

# 以下のファイルを編集する

osによって設定は異なるのでmacの人以外は参考にならない

## line numberをdefaultで表示

以下を作成

```~/.jupyter/custom/custom.js
IPython.Cell.options_default.cm_config.lineNumbers = true;
```

## %matplotlib inlineを省略する設定

以下を実行

```sh
ipython profile create
```

以下のように編集

```~/.ipython/profile_default/ipython_config.py
# lines of code to run at IPython startup.
# c.InteractiveShellApp.exec_lines = traitlets.Undefined
c.InteractiveShellApp.exec_lines = ['%matplotlib inline']
```


参考
- https://qiita.com/noguchi0123/items/2c83e30e274e5a51cb41
PHP　＊　mysqli　チートシート

自分用のチートシート(基本)

#よくある定番の流れ
```php

<?php
//エラーと警告を表示する設定
ini_set( 'display_errors', 1 );
ini_set( 'error_reporting', E_ALL );

//DBへ接続
$db = new mysqli('DBのアドレスまたはlocalhost', 'ユーザ名', 'パスワード', '使うDB名');

if( mysqli_connect_errno($db) ) {  //接続失敗
	mysqli_close($db);
}
else{  //接続成功
    //入力したいSQL文の作成
    $sql = 'select * from article'
        
    //SQL文を実行
    $res = $db->query($sql);
        
    //結果のすべての行を連想配列・数値添字配列で取得
    $row = $res->fetch_all();
        
    //欲しい情報を上手に取り出すために配列を表示させて確認
	//echo var_dump($row);

	$title1 = $row[0][0];
	$year1  = $row[0][1];

	$title2 = $row[1][0];
    $year2  = $row[1][1];

    //リソースの開放
	$sql->free();
	$res->free();
	$row->free();
	mysqli_close($db);
}
?>
```

#fetch_all()で取り出した情報の見方

```
//SQL文に対する結果の例

+-----------------------+
| tag_name              |
+-----------------------+
| 音楽                  |
| 食事                  |
| 日常                  |
+-----------------------+

//これを$res->fetch_all()で取り出して
//var_dump()で見ると次のように表示される
//(インデントは僕がつけました)

array(3) { 
　　　　[0]=> array(1) { [0]=> string(6) "音楽" } 
　　　　[1]=> array(1) { [0]=> string(6) "食事" } 
　　　　[2]=> array(1) { [0]=> string(6) "日常" } 
}

//二重の配列になっているとわかる
//この3つを取り出すのは次の通り

$tag1 = $res->fetch_all()[0][0]; //音楽
$tag2 = $res->fetch_all()[1][0]; //食事
$tag3 = $res->fetch_all()[2][0]; //日常

```

#コメント
正直僕は初心者なので、変なとことかあるかも。。。
連想行列好きじゃないから添字行列だけで取れれば良いんだけど、
どうやるか分かんないです誰か教えてください。

この処理を表示用のページに書くのはナンセンスなので、関数化して別のファイルに分けるのが妥当だと思う。
元メルカリCSが仕事でQAとしてプログラムを書くまでにやったこと

## 初めに

僕のキャリアについてご紹介します。

18歳の時にメルカリへ入社しました。
インターン生より若いという現象が起きたり、何より初めてちゃんと働いたので色々と勉強になりました。

当時はプログラミングなんてしたことなかったのですが、やれる幅を広げたいと思い独学でpythonを勉強してました。

当時地方に住んでいたので、僕の周りには誰もおしえてくれる人がいなかったのですが、当時の僕が知っていればよかっただろうなと思うことを書いていきます！

## 技術書を読んで勉強するのはしんどい

僕は最初に技術書から読み始めたのですが、すごい苦労しました。

何より、環境構築ですらままならない状態だからです。
(systemにある言語が使えるのすら知らなかったので、一人で苦労してました。笑)

# **お勧めしない勉強方法**

###・**最初から技術書を見ること**
中には実践的な、何かを作りながら勉強する本もありますが、ほとんどが文法を紹介する本です。

実際には何かを作ることが目標なので、困った時に本を読む感覚でいい思います。

###・**メンターをつける**

オンラインで受講できる有料講座を何個かやっていたのですが、サービスによっては返答が遅かったりします。

何より、担当の方の技術力やコミュ力が無いと聞く側のもやもやは解消しないので、僕の場合結局はメンターに聞かずググって講座を進める結果になりました。

###・**勉強会に出る**

メリットもたくさんありますが、勉強した気になって何も進まないことが多い気がします。

聞ける人を作りたいところですが、そういう目的で行っても誰一人としてレビューしてくれる人はいませんでした笑

# **お勧めの勉強方法**

###・**[Udemy](https://www.udemy.com/)等の動画講座**

動画はわかりやすく、時間が決まっているのですごい捗ります。

ただ、ある程度評価のある講座をご受講することをおすすめします！

###・**[paizaのスキルチェック問題](ttps://paiza.jp/challenges/info)を解く**

複数のランキングがあり、初心者向けから難しいアルゴリズムを書くまで無料で出来ます！

自分が書いているプログラムがちゃんと動いて、ランキングが上っていくのは見ていてモチベーションの維持になりました。

面接官にスキルレベルを伝える時にある程度の指針にもなるので、とても伝えやすいです。

### **・[rails tutorial](https://railstutorial.jp/)を一通りやってみる**

短期間で高いアウトプットを出したいのであれば、rails tutorialは一番いい選択だとおもいます。早く出会えていればもっとうまく勉強できたんじゃないかなと思います。

これをやり終えて、プログラミングに関する理解が広がりました。

### **・インターンとして働く**

僕はインターンしたこと無いのですが、面接され通れば、レビューしてくれる人がいて、お給料もいただける最高の体験だと思います。

## **とにかく書く**

わからなくてもいいので、とにかく書いてみてください。

僕は当時本しか読まないで書ける気になっていたのですが、どれだけ最初の方に書いたかによってプログラミングに関する考えは変わります。

このプロセスがないと、プログラムを書く楽しさには気づけないです。

## 最後に

いろんな勉強方法がありますが、とにかく、自分に合う方法で試してみてくださいm(^^)！

相談にも乗りますので、ぜひコメントくださいませ!;))
CarrierWaveでのさまざまなファイル名取得方法

担当しているプロジェクトではファイルのアップロードに[CarrierWave](https://github.com/carrierwaveuploader/carrierwave)を使っているのですが、ファイル名の取得ってどうやるんだろう？と思ってCarrierWaveをマウントしたカラムを見たところ

```
model_with_file.file_column
=> #<FileUploader:0x007ff886cdc388
 @file=
  #<CarrierWave::SanitizedFile:0x007ff886cd7c98
   @content_type=nil,
   @file=
    "/path/to/filename.pdf",
   @original_filename=nil>,
 @model=
  #<ModelWithFile:0x007ff886cdc748
   id: 39,
   file: "filename.pdf",
   created_at: Fri, 26 Jan 2018 19:12:17 JST +09:00,
   updated_at: Fri, 26 Jan 2018 19:12:17 JST +09:00>,
 @mounted_as=:file_column,
 @storage=
  #<CarrierWave::Storage::File:0x007ff886cdc2e8
   @uploader=#<FileUploader:0x007ff886cdc388 ...>>,
 @versions={}>
```

よく分からないけど@file=の中の@file=にファイルパスらしきものが見えるので

```
model_with_file.file_column.file
=> #<CarrierWave::SanitizedFile:0x007ff87dea58d0
 @content_type=nil,
 @file=
  "/path/to/filename.pdf",
 @original_filename=nil>
```

```
model_with_file.file_column.file.file
=> "/Users/iwatsuki.rei/Documents/donuts/roumu-server/public/uploads/uploaded_file/file/39/
```

```
File.basename(model_with_file.file_column.file.file)
=> "filename.pdf"
```

なんとかファイル名が取得できましたが、かなり冗長で気持ち悪いです。またアップロード先にローカルを指定している場合これでも取得できるのですが、S3の場合オブジェクトの構成が違うのかうまく取得できませんでしたので他の方法を模索します。

filenameメソッドを使えばFile.basenameを使う必要がありません。

```
File.basename(model_with_file.file_column.file.file.filename)
=> "filename.pdf"
```

file_column.pathでパスが取れるのでそのbasenameを取る方法もあります。

```
File.basename(model_with_file.file_column.path)
=> "filename.pdf"
```

model_with_file.file_columnでは上記のようなオブジェクトしか取れませんでしたが、file_columnにハッシュでアクセスするとファイル名を取得できます。

```
model_with_file[:file_column]
=> "filename.pdf"
```

これが一番シンプルそうです。
Railsで環境変数の変更が反映されないときはspring stopを試す

### 不具合

[dotenv](https://github.com/bkeepers/dotenv)という、プロジェクトディレクトリの.envファイルに設定した内容を環境変数として読み込んでくれるgemを使っているのですが、.envの設定を変更しても想定した通りに挙動が変わらなかったためENV変数の中身を見てみると、.envを書き換えたにも関わらず何故か環境変数は元のまま書き換わっていない！ということがありました。

.envで

```
HOGE=0
```

HOGEを1に書き換えたのに

```
HOGE=1
```

なぜかHOGEは0のまま

```
[1] pry(main)> ENV['HOGE']
=> "0"
```

railsのサーバーは再起動させているはずだし、なんでだろうなんでだろう（古い）と隣の席の方に指示を仰いだところ、```spring stop```すると反映されるかもしれないとのことでしたので、試してみたところ無事環境変数が書き換わりました。よかったよかった。

### 環境変数の変更が反映されないときはspring stopを試す

[Spring](https://github.com/rails/spring)とはRails4.1から標準で付属するようになったアプリケーションプリローダーで、Railsアプリケーションをバックグラウンドでプリロードしておくことによりrailsコマンドの起動時間が短縮されるというものです。```rails server```や```rails console```などのコマンドを実行すると同時に起動します。

このSpring、どうやらうまくリロードされていないのか、環境変数をキャッシュしてしまっているのか、環境変数の書き換えが反映されない原因となることが稀によくある（やや古い）ようです。

https://twitter.com/search?q=spring%20dotenv&src=typd
https://twitter.com/search?q=spring%20%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0&src=typd

また今回のケースとは異なりますが、Springのロード処理の失敗が原因でrailsコマンドが動かなくなってしまうこともあるようです。

[Rail4で困ったらSpringを停止せよ](http://itexp.hateblo.jp/entry/rails4-stop-spring-on-trouble)
[Rails コマンドが動かなくなった場合の対処](https://books.google.co.jp/books?id=VCFHDwAAQBAJ&pg=PA40#v=onepage&q&f=false)
[railsコマンドが固まったんでspringをstopしたら動くようになった](http://b0npu.hatenablog.com/entry/2016/04/11/032826)
[railsのコマンドが動かない時はspringを(stop|kill)してみよう](https://qiita.com/yokozawa/items/7b92c260f8c3dfec8e28)

このようなケースに遭遇した時は、```spring stop```を試してみる、と覚えておくとよさそうです。
ネストしたトランザクション内でActiveRecord::RollbackしてもRollbackされない

### 不具合

```
def perform
  ApplicationRecord::Base.transaction do
    unless create_something
      raise ActiveRecord::Rollback
    end
  end
end

def create_something
  Hoge.create!(name: 'hoge')  
  ...
  return false if error
end
```

だいたい上記のような、モデルオブジェクトを作ったりするメソッド内でエラーがあった際にロールバックすることを意図した処理があったのですが、create_something内でエラーが起こり画面にエラーメッセージが出ているにもかかわらず、何故かHogeのレコードは作られてしまっているという不具合がありました。

create_somethingがfalseを返し```raise ActiveRecord::Rollback```の行を通っているのは確かなのに、ログを見たところなぜかROLLBACKされておらずCOMMITされてしまっていました。

なかなか原因の手掛かりが掴めなかったのですが、しばらくしてこのperformを呼んでいる箇所でもさらにトランザクションがかかっていることに気づきました。

```
def create
  ActiveRecord::Base.transaction do
    ...
    something_service.perform
    ...
  end
end
```

### ネストしたトランザクション内でraise ActiveRecord::RollbackしてもRollbackされない

ググってみたところ、どうやらネストしたトランザクション内で```raise ActiveRecord::Rollback```してもロールバックされない仕様のようです。

[ネストしたトランザクション内で ActiveRecord::Rollback を raise しても握りつぶされるだけだ](http://www.techscore.com/blog/2015/02/06/rails-nested-transactions/)

リンク先の例ではネストが1箇所にまとまっていて分かりやすいですが、今回の不具合のようにトランザクションの記述が別のファイルに分かれていてネストに気づけなくても同様の問題が発生してしまいますので、トランザクションをかけるレイヤーは揃えておくべきかと思いました。

なおネストしたトランザクション内で```ActiveRecord::Rollback```したい場合はドキュメントに記載されているように```requires_new: true```を指定するといいようです。
https://github.com/rails/rails/blob/v4.2.0/activerecord/lib/active_record/transactions.rb#L142
Riot.jsでの注意

# 概要
自分的なメモついでに注意点をメモしておきます。

# 内容
## class定義出来ない
### 課題
tag内でクラス定義しようとすると

```html
<test>
    <h1>{text}</h1>
  <script>
    var self=this;
    class Hello{
      constructor(v){
        this.v = v
      }
      get(){
        return v;
      }
    }
    var h = new Hello("world")
    self.text=h.get();
  </script>
</test>

```
こんな感じで怒られます。

```
Uncaught SyntaxError: Unexpected token .
    at jn (riot+compiler.min.js:2)
    at o (riot+compiler.min.js:2)
>      this.constructor = function(v){
```

初期化関数の```constructor```をriotの関数として処理している感
### 対策
定義を下記のように変更すると怒られません。

``` html
<test>
    <h1>{text}</h1>
  <script>
    var self=this;
    var Hello=(v)=>{
      
      var _v = v
      return {
        get:()=>{
          return _v;
        }
      }
    }
    var h = Hello("world")
    self.text=h.get();
  </script>
</test>

```

## 思ったように初期化されない(多分、javaScriptの仕様)
### 課題
下記のように変数定義すると、エラーも出ずに結果がこうなる。

```javascript
var t=[[[1,2][3,4]],[[5,6][7,8]]];
console.log(t);
// --下記表示結果--
// (2) [Array(1), Array(1)]
//  >0:[undefined]
//  >1:[undefined]
//  >length:2
//  >__proto__:Array(0)
```

個人的にはエラーが出てほしい…

### 対策
ご存知の通り、下記のように```,```を追加すれば望んだように…
そもそもエラーが出てほしいのだけど…

``` javascript
var t=[[[1,2],[3,4]],[[5,6],[7,8]]];
```

#### 実はエラーではないというお話
@karak　様からコメントが有ったので追記させていただきます。
実は、javascriptの`,`の仕様によりエラー文ではなかったようです。


```javascript
// この定義は
var t1=[[[1,2][3,4]],[[5,6][7,8]]];
// (2) [Array(1), Array(1)]
//  >0:[undefined]
//  >1:[undefined]
//  >length:2

// これと同じ
var a = [1, 2];
var b = [5, 6];
var t2 = [a[4], b[8]];
// (2) [Array(1), Array(1)]
//  >0:[undefined]
//  >1:[undefined]
//  >length:2 
```
つまり`,`で区切られた手前側が参照するindexの値として処理されてしまっていたようです…
ということで、下記のような内容だと`undefined`ではなくなる。

```javascript
var t=[[[1,2][3,0]],[[5,6][7,1]]];
// (2) [1,6]
```

非常に勉強になりました…
コメントありがとうございました！
AndroidのAudioRecordの基本を理解する

Android で音声処理をするために AudioRecord クラスを利用しました. これがちょっと曲者で, いくつかの日本語ページを参照したのですが, どうも仕様に曖昧な部分が多くもやもやします...

そもそも音声処理の基礎知識がないと理解しづらいのもあると思いますが, ```positionNotificationPeriod ``` とか ```notificationMarkerPosition``` などの何が違うのかよく分からないAPIも多いです.

ということで, 公式ドキュメントおよびローカルテストで調査した仕様をメモ(コメント付きのコード)に残します. 

* Android API:27
* Kotlin

```Kotlin:AudioRecordSample.kt

import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
import kotlin.math.max

/**
 * AudioRecord クラスのサンプルコード
 */
class AudioRecordSample {

    // サンプリングレート (Hz)
    // 全デバイスサポート保障は44100のみ
    private val samplingRate = 44100

    // フレームレート (fps)
    // 1秒間に何回音声データを処理したいか
    // 各自好きに決める
    private val frameRate = 10

    // 1フレームの音声データ(=Short値)の数
    private val oneFrameDataCount = samplingRate / frameRate

    // 1フレームの音声データのバイト数 (byte)
    // Byte = 8 bit, Short = 16 bit なので, Shortの倍になる
    private val oneFrameSizeInByte = oneFrameDataCount * 2

    // 音声データのバッファサイズ (byte)
    // 要件1:oneFrameSizeInByte より大きくする必要がある
    // 要件2:デバイスの要求する最小値より大きくする必要がある
    private val audioBufferSizeInByte =
            max(oneFrameSizeInByte * 10, // 適当に10フレーム分のバッファを持たせた
                    android.media.AudioRecord.getMinBufferSize(samplingRate,
                            AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT))

    fun startRecording() {

        // インスタンスの作成
        val audioRecord = AudioRecord(
                MediaRecorder.AudioSource.MIC, // 音声のソース
                samplingRate, // サンプリングレート
                AudioFormat.CHANNEL_IN_MONO, // チャネル設定. MONO and STEREO が全デバイスサポート保障
                AudioFormat.ENCODING_PCM_16BIT, // PCM16が全デバイスサポート保障
                audioBufferSizeInByte) // バッファ

        // 音声データを幾つずつ処理するか( = 1フレームのデータの数)
        audioRecord.positionNotificationPeriod = oneFrameDataCount

        // ここで指定した数になったタイミングで, 後続の onMarkerReached が呼び出される
        // 通常のストリーミング処理では必要なさそう？
        audioRecord.notificationMarkerPosition = 40000 // 使わないなら設定しない.

        // 音声データを格納する配列
        val audioDataArray = ShortArray(oneFrameDataCount)

        // コールバックを指定
        audioRecord.setRecordPositionUpdateListener(object : AudioRecord.OnRecordPositionUpdateListener {

            // フレームごとの処理
            override fun onPeriodicNotification(recorder: AudioRecord) {
                recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
                Log.v("AudioRecord", "onPeriodicNotification size=${audioDataArray.size}")
                // 好きに処理する
            }

            // マーカータイミングの処理.
            // notificationMarkerPosition に到達した際に呼ばれる
            override fun onMarkerReached(recorder: AudioRecord) {
                recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
                Log.v("AudioRecord", "onMarkerReached size=${audioDataArray.size}")
                // 好きに処理する
            }
        })

        audioRecord.startRecording()
    }
}
``` 

あくまで基本です. パフォーマンス等のより高度な見識が得られればまた記します.
ファイル作成時のテンプレート


いちいち調べるのが面倒くさいのでテンプレートをまとめるページ．

### python

```python:main.py
# -*- coding: utf-8 -*-

# use arguments #
import sys
cmd, *args = sys.argv

# use standard input #
stdin = input()

def main():
    # processing

if __name__ == '__main__':
    main()
```

### html(+Vue.js)
```html:main.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <Title>Title</Title>
  <link href="css/main.css" rel="stylesheet">
</head>
<body>
  <div id="app">

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="js/main.js"></script>
</body>
</html>
```
```js:main.js
var app = new Vue({
  el: '#app'
})
```
ブラウザを透明にしてスタイルコーディングをしよう

Macを対象としています

## tl;dr

* 後ろにデザインを置いてスタイルレイアウトすると捗る
![opacity.gif](https://qiita-image-store.s3.amazonaws.com/0/5472/378827d7-35a8-f224-6be8-741ff843cf32.gif "opacity.gif")


## やりかた

### 1. mySIMBLをインストール

1. [mySIMBL](https://github.com/w0lfschild/mySIMBL) から Download the latest release をクリック
2. zipを解凍してmySIMBL.appをapplicationフォルダにコピーする


### 2. SIPを無効にする
1. macを電源を切る
2. 電源を入れるときに command + R を同時押ししながら電源ボタンを押してリカバリモードを起動する
3. メニュー ＞ ユーティリティ ＞ ターミナル をクリック
4. コマンドラインが開いたら csrutil disable を入力して Enter
5. ターミナルを終了して、アップルアイコンから再起動する

### 3. ブラウザを透明化する Afloatをインストール
1. ターミナルを起動する 右上の虫眼鏡アイコンから ターミナルと入力
2. コマンドラインから↓を入力して Enter
3. パスワードを求められたらログイン時に入力しているパスワードを入力

```
curl https://raw.githubusercontent.com/rwu823/afloat/sierra/install.sh | sh
```

### 4. SIPを有効に戻す

1. macを電源を切る
2. 電源を入れるときに command + R を同時押ししながら電源ボタンを押してリカバリモードを起動する
3. メニュー ＞ ユーティリティ ＞ ターミナル をクリック
4. コマンドラインが開いたら csrutil enable を入力して Enter
5. ターミナルを終了して、アップルアイコンから再起動する


### 5. インストールの確認
1. Finderを開く
2. メニュー > ウィンドウを開くと↓のメニューが追加されてれば設定OK
![スクリーンショット 2018-03-18 1.58.48.png](https://qiita-image-store.s3.amazonaws.com/0/5472/62f19308-0d30-7e79-6749-10dfbc802585.png "スクリーンショット 2018-03-18 1.58.48.png")
3. Finderにカーソルを当てる
4. command + control + 上下スクロールで透明度を変更
![finder_opacity.gif](https://qiita-image-store.s3.amazonaws.com/0/5472/63ef6536-eddb-bc72-f534-3e8c18404959.gif "finder_opacity.gif")
ミライアカリの公式サイトを読む

ミライアカリさんが登録者数50万人突破記念ということで公式サイトがリリースされました。
サイトを見ていただければわかると思うのですが、アニメーションを多用したグラフィカルな構成で、彼女のかわいらしくセクシーな魅力が十二分に発揮されています。

告知動画：https://www.youtube.com/watch?v=YAJ2h7_uQoc
サイト：https://akari-mir.ai/

ドメインハックを使っているあたり、好き者が作っている感じがします。

### ドメイン

whoisを見てみるとCreation Dateは2017-12-16となっているので、前々から進んでいたプロジェクトのようですね。
ちなみに.aiはアンギラのドメインだそうです。アンギラってどこなんでしょう？
https://www.whois.com/whois/akari-mir.ai

ちなみにホワイトハッカーであるCheenaさんは2018-01-12の時点ですでにドメインの存在に気づいていたようで、さすがという感じですね。
https://twitter.com/CheenaBlog/status/951757416395403264

### サーバー

digってみるとサーバーはxserverを利用しているようです。
個人的にはxserverはレンタルサーバーの中でも一段落ちるイメージだったのですが、最近はちょっとしたサイトを公開するのに使われているのをたまに見ます。

Let's Encryptを使っているのはxserver提供のものだからですかね。
![スクリーンショット 2018-03-18 1.13.08.png](https://qiita-image-store.s3.amazonaws.com/0/16060/c8b181d7-4a71-8f31-e49e-e0c8bc6bc7f9.png)

### 構成

Weppalyzerで構成を見てみます。

WordPress を中心に
- Nginx
- Twitter Widget
- Google Analytics
- jQuery2.2.4
- jQuery Migrate1.4.1
- YouTube
- Google Font API
を利用しているようで無難な感じですね。jQueryが少し古い気もしますがプラグインの関係か流用したソースの関係なのでしょうか。

WordPressは最新のバージョン4.9.4を利用していて良い感じですね。

### HTML

ソースを見ると懐かしげなこんな記述が…
![スクリーンショット 2018-03-18 1.24.49.png](https://qiita-image-store.s3.amazonaws.com/0/16060/6f985d9b-d65b-6e43-3a40-1c7599615508.png)

現時点で動画（公式サイト）の公開から6時間くらいしか経ってないのですが、そのURLにアクセスするとすでに2000回以上の再生がされているようです。
動画中で軽く言及されているとはいえこの数字は、どこかでリークされてるんでしょうか。
![スクリーンショット 2018-03-18 1.04.17.png](https://qiita-image-store.s3.amazonaws.com/0/16060/2da5e276-61ae-a3a0-768b-e3c491998cb7.png)

Validityにかけるとちょいちょいエラーが見つかるのでそこまでstrictにHTMLは書いていないようですね。
![スクリーンショット 2018-03-18 1.16.30.png](https://qiita-image-store.s3.amazonaws.com/0/16060/de720e0f-d40a-362d-3297-9ac460d24932.png)

OGPタグも多く設定されていますがtwitter:domainあたりの指定が怪しいです。
![スクリーンショット 2018-03-18 1.42.29.png](https://qiita-image-store.s3.amazonaws.com/0/16060/a2f509ec-8661-36bb-d016-8720257ef792.png)

サイトはレスポンシブではありませんが、ペライチとはいえPC・モバイルともにナビゲーションの収まりはきれいで好きです。
贅沢を言えば振り分けはUAではなく横幅でやってほしいという感じも…
【GAS】Googleドライブ上のスプレッドシートを追記するWeb API

今さらながらGASの便利さに気付き色々試しております。

本頁は、Google Apps Script をWebAPIとして利用して、Googleドライブ上のスプレッドシートに追記するメモです。

---

Googleドライブ上にスプレッドシートを用意します。
![01.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/7e6aeb05-e364-2746-101c-d74995249ca2.jpeg)


GASからアクセスできるように共有可能なリンクを取得します。
![02.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/c5aba486-6bea-d9f2-828e-aa2fb01fe816.jpeg)

「?id=」以降がGAS側で利用するIDです。
![03.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/77887ad4-9a77-0bea-3ee6-78623eefcf93.jpeg)


たいしたコードでも無いので、ソースコードにそのままIDを埋め込んでも良いですが、
一応GASのプロジェクトプロパティにIDを入れておきます。
![04.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/ee729346-b555-325e-35d0-132fc3435882.jpeg)
![05.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/fa96a593-0be9-d3d7-6e74-e04c883674d8.jpeg)



GAS上のソースコードは以下です。
リクエストパラメータは手抜きしてactionをそのまま使用。。。

```javascript:コード.gs
function doGet(e) {
  // action未指定の場合
  if(!e.parameter.action) { 
    return ContentService.createTextOutput(JSON.stringify({'status': 'NG'}))
           .setMimeType(ContentService.MimeType.JSON);
  }
  
  // スプレッドシートに記録
  // プロジェクトプロパティからスプレッドシートのIDを取得
  var PROPERTIES = PropertiesService.getScriptProperties();
  var SPREAD_SHEET = PROPERTIES.getProperty('SPREAD_SHEET')
  var sheet = SpreadsheetApp.openById(SPREAD_SHEET);
  // スプレッドシートに追記するCSVデータを生成
  var appendData = new Array();
  var cells = e.parameter.action.split(",")
  for(var i = 0; i<cells.length;i++){
    appendData.push(cells[i])
  }
  // スプレッドシートの最終行に追記
  sheet.appendRow(appendData);

  return ContentService.createTextOutput(JSON.stringify({'status': 'OK'}))
         .setMimeType(ContentService.MimeType.JSON);
}
```
「ウェブアプリケーションとして導入」を実施します。
![06.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/9ee51470-4007-e445-8cc4-9355b2c3c82f.jpeg)

アプリケーションにアクセスできるユーザーは「全員（匿名ユーザーを含む）」に設定し「更新」を実施します。
初回はGoogleドライブ上へのアクセス許可を求められるはず。。。
スクリーンショット取り忘れました。。。
![07.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/6c4cdbf6-eba6-c3c9-3f61-52e05816d7b1.jpeg)


テストとしてブラウザから「1,2,3, ,abcde」を指定して呼び出してみます。
![08.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/5f3f7456-05f6-556c-0821-00ba4c7c6cd4.jpeg)

スプレッドシートに追記されました。
![09.jpg](https://qiita-image-store.s3.amazonaws.com/0/140207/b09ae4b0-ae88-b5aa-2f55-210d601590ed.jpeg)


以上。
Microsoft flow 使い方

会社でMicrosoft Office365 を使い始めて、アプリの連携でflowを使っての作業の効率ができたかをメモ

# Microsoft flow とは
公式のコメントはこう書いてある。
> 生産性の向上。
> Microsoft Flow で自動ワークフローを作成します。

簡単に言えば自動でワークフロー（アプリの連携**など**）ができる

- [ifttt](https://ifttt.com/)を使っていればつかみやすい
  - 例えば、twitterにツイートした内容をfacebookに自動で投稿できるワークフローをUIで分かりやすく連携ができる
- ただ**など**を強調したようにMicrosoft flowはiftttに比べ、複雑に連携ができる
  - if構文やfor構文が使用できるが、ただ使い方が独特な関数がある

# Microsoft flow 登録
Microsoftに登録していればフリープランが使える

- 月ごとの実行数 750 回
- 無制限のフロー作成
- 15 分ごとにチェック

らしいがこの**実行数**が何かは調査中
各フローには、所有者欄がありそこのほかのメンバーを登録することで共有ができる

# Microsoft flow 使用方法
今回やったことMicrosoft TeamsのwikiをSharePointに自動登録をする
Microsoft TeamsのwikiをSharePointは、Office 365アプリなのでどちらもこれは有料

- Microsoft Teamsは、slackに近いチャットアプリ
  - もっとほかにもできると思うが、何ができるかを模索中
  - Microsoftは、結構力を入れているらしい（いずれはSkype for Businessをこっちに移行したいみたい）
  - https://japan.cnet.com/article/35116052/
- SharePointとは、形容しがたい…

> コンテンツ、知識、アプリケーションを共有および管理してチームワークを強化し、情報をすばやく検出して、組織全体でシームレスに共同作業できます。

公式のコメントにはこう書いてあり、メンバー管理にリストを使っているが正直重く使いやすいとは言えない

# 今回のフロー
1. Sharepoint の新規登録
2. ある数値に対して、if構文をつかいtrueとfalseの条件をわける
3. trueの数値に対して、Microsoft Teamsのwikiを記載する

## 1. Sharepoint の新規登録

![flow1.jpg](https://qiita-image-store.s3.amazonaws.com/0/178856/6c9ed61a-9e16-bac0-ebda-a0ffad964930.jpeg)
これは、サイトアドレスにSharepointのURL、リスト名に新規登録したいリストを指定

## 2. ある数値に対して、if構文をつかいtrueとfalseの条件をわける

![flow2.jpg](https://qiita-image-store.s3.amazonaws.com/0/178856/860f6048-5801-f4a9-0478-69b255a049e5.jpeg)
**ここがはまった**

```python
if 0 ==0:
#この条件分岐にしたら、0==0でもtrueへ分岐がしなかった。
#数字に関しては、関数をしないといけないみたい。
if init(0) == init(0):
#こうするとtrueへ分岐した
#このへんは、pythonに似ている気がする
```

## 3. trueの数値に対して、Microsoft Teamsのwikiを記載する

![flow3.jpg](https://qiita-image-store.s3.amazonaws.com/0/178856/16a74381-fbe0-c713-a0fa-ae5b2a2e7158.jpeg)


1. ファイルコンテンツの取得からTeamsアプリを選ぶ
2. サイトアドレスで対象のTeamsのチームを選ぶ
3. ファイル識別子から対象のwikiを選択
4. 新しいアクションにSharePointのアクションから項目の更新を選択
5. サイトアドレスとリストにwikiを追加したいSharePointのURLとリストを記入
6. その下の項目に追加したい項目に、ファイルコンテンツを選択する
App Service の Azure Active Directory 認証でユーザ情報をサーバーサイドで取得する

# 方法
* App Service の 認証, Token Storeをオンにする
* サーバサイドの以下のリクエストヘッダにAAD関連の情報が入っている。さらに詳細情報が必要な場合はトークンを使用して認証APIにアクセスする。
  * `X-Ms-Client-Principal-Name` : ログイン名 
  * `X-Ms-Client-Principal-Id` : ID
  * `X-MS-TOKEN-AAD-ACCESS-TOKEN` : 認証APIアクセス用のトークン

# 参照
* [Azure App Service の Authentication 徹底解説 – Tsmatz](https://tsmatz.wordpress.com/2016/06/23/azure-app-service-authentication-authorization-deep-dive/)
* [App Services アプリケーションに Azure Active Directory 認証を構成する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-mobile-how-to-configure-active-directory-authentication#span-data-ttu-idf180e-121a-nameadvanced-a%E4%BB%A3%E6%9B%BF%E6%96%B9%E6%B3%95-%E8%A9%B3%E7%B4%B0%E8%A8%AD%E5%AE%9A%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6-azure-active-directory-%E3%82%92%E6%89%8B%E5%8B%95%E3%81%A7%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8Bspanspan-classsxs-lookupspan-data-stu-idf180e-121a-nameadvanced-aalternative-method-manually-configure-azure-active-directory-with-advanced-settingsspanspan)
* [Setting up Application Gateway with an App Service that uses Azure Active Directory Authentication – Microsoft Azure App Service](https://blogs.msdn.microsoft.com/waws/2017/11/21/setting-up-application-gateway-with-an-app-service-that-uses-azure-active-directory-authentication/)
PKCS#12形式のpfxファイルから必要な秘密鍵・サーバー証明書を取り出そう


# 今回のお題
SSL更新の際にPKCS#12形式の*.pfxファイルとパスワードのみをいただいたので
そこから更新作業に進んでみましょう。というお話です。

この話題も結構書かれていますが、いつも通り備忘録として。

## 確認
SSL更新作業では、まずcsrと秘密鍵を作成してサーバー証明書の申請を行います。
発行された証明書(crt)と秘密鍵、中間証明書の3点をサーバーに設定します。

上記の3点セットをいただくと反映するだけなので非常に作業は早いのですが
今回は*.pfxファイルのみポンとある状態。。。
なんぞこれは。。。？

## PKCS#12って
SSLサーバ証明書のバックアップ・エクスポート等に用いられる
秘密鍵と証明書を 1つのファイルに格納する形式。
OpenSSLからそれぞれを取り出すことができる。

というので早速やってみましょう。
(hogehoge.pfxファイルからoutputというファイル名を取り出すという体で)

## opensslのインストールを確認
`openssl version`
バージョンが表示されたらこのまま進めましょう。
そうでなければインストールしましょう。

## 秘密鍵を取り出す
`openssl pkcs12 -in hogehoge.pfx -nocerts -nodes -out output.key`
(この後パスワードを入力)

## サーバー証明書を取り出す
`openssl pkcs12 -in hogehoge.pfx -clcerts -nokeys -out output.crt`
(この後パスワードを入力)

## 中間証明書を取り出す
`openssl pkcs12 -in hogehoge.pfx -cacerts -nokeys -out output.cer`
(この後パスワードを入力)

pfxファイルがあっても、パスワードがなければ無用の産物になってしまいますね。
今回はこれまで。
FireFoxで開いているページをChromeで開く

1. FireFoxとChrome、双方に「Pushbullet」のアドオンをインストールする
2. FireFoxにて右クリックメニューから「Pushbullet - Chrome」を選択する
3. Chromeが起動中であればChromeで対象ページが開かれる（Chromeを起動していない場合は、次回起動時に対象ページが開かれる）

Firefox Quantum にアップデートしてから「Chromeで開くアドオン」が使えなくて困ってたので書きました。
Pythonによる二分探索法

初めまして。python初学者の初投稿です。

###コードを書いてみた、、が
```python:binary_research.py
def binary_search(numbers, target):
    #中央値（切り捨て）＝center
    center = len(numbers)//2
    #長さが変わった後のリストの１番目が本来の何番目の数か−１＝index
    index = 0
    while numbers[center-1] != target:
        #中央値よりターゲットが大きいとき中央値以下をリストから消しindexを更新
        if numbers[center-1] < target:
            numbers = numbers[center:]
            index = index + center
        #中央値よりターゲットが小さいとき中央値より大きい部分をリストから消す
        else:
            numbers = numbers[:center]
        #次の中央値計算
        center = len(numbers)//2
        #centerが切り捨てにの影響で0になってしまうことを防ぐ
        if center == 0:
            center = 1
    print(str(target)+"は"+str(index+center)+"番目にあります")

#実行例
numbers = [1, 2, 4, 8, 9, 11, 12, 15, 17, 20, 21, 24, 30]
target = 9
binary_search(numbers, target)
```
と拙い頭で「中央値の判定により、listから半分削除して探索していく」という方針でコードを書いてみましたが、先人のコードを検索するとどうやら「中央値判定により、探索する必要のない側の半分から端の値を削っていく」というのが主流（というか正解？）らしくて肩を落としてます。
いずれのコードでもn個の数字に対する計算量のオーダーはlognだと思いますが、どうでしょうか。皆様のご意見を伺いたいです。
MacでGo言語の環境構築

# 環境情報
事前に[Homebrew](https://brew.sh/index_ja)をインストール

# 手順

```cmd
# goのインストール
$ brew install go

# バージョン確認
$ go version
```

# VSCodeで移動できない

```
# go　のバージョンが古いので更新する（本当はasdfとか使うのがいいですが）
brew remove go
brew uninstall --force go
brew install go@1.21
echo 'export GOPATH="/usr/local/opt/go@1.21/bin:"' >> ~/.zshrc
echo 'export PATH="$GOPATH:$PATH"' >> ~/.zshrc
```
React+Reduxの開発をFlowで行う ~React編~

会社製品の開発環境にFlowを導入したので、コーディング規約おさらいついでに書きます。

# コンポーネント

コンポーネントクラスは `React.Component<Props, State>` を継承するようにします。 `State` は省略可能ですが、 `Props` は省略できません。

```jsx
type Props = {
  someValue: number,
};

class Component extends React.Component<Props> {}
```

`children` など、Reactが描画可能なものは `Node` で定義しましょう。

```jsx
import { type Node as ReactNode } from 'react';

type Props = {
  children: ReactNode,
};
```

`render` など、Reactが定義しているメソッドの型定義を書く必要はありません。なぜなら親クラス側で定義しているからです。

```jsx
class Component extends React.Component<Props> {
  render() {
    // ...
  }
}
```

`propTypes` はもう不要です。サーバーからのレスポンスなど一部ランタイムでしか判明しないものがありますが、そこさえ型定義してキャストしてしまえば型に守られた世界が待ってます。

```jsx
type ResponseBody = {
  isSuccess: boolean,
  results: {
    employeeName: string,
  }
};
```

ESLintを使っているのであれば、 `propTypes` の警告はオフにしてしまいましょう。

```json:.eslintrc
{
  "react/prop-types": "off"
}
```

Reduxを使った開発では、よくコンテナから親コンポーネントを介して子コンポーネントにPropsを伝搬します。

```jsx
<ChildComponent
  {...this.props}
  childOwnProp=""
/>
```

のように、面倒がって親のPropsをまるごと伝搬しがちですが、Flow導入にあたってこれをやめます。(汚いし...)
子コンポーネントからPropsの型を受け取り、それを親へと伝搬することで、伝搬漏れに気付けるようにしましょう。

```jsx
export type Props = {
  // childOwnProp: PropTypes.string.isRequired,
  childOwnProp: string,
  // childOwnOptionalProp: PropTypes.string,
  childOwnOptionalProp: ?string,
}

const ChildComponent = (props: Props) => <div>...</div>;

export default ChildComponent;
```

親のコンポーネントの型定義はこう書くことができます。

```jsx
import ChildComponent, { type Props as ChildComponentProps } from './ChildComponent';

export type Props = ChildComponentProps & {
  parentProp: string,
};

const Component = (props: Props) => <div>
  <ChildComponent childOwnProp={props.childOwnProp} />
  ...
</div>;
```

子コンポーネントにPropを追加したいときなどは、小コンポーネントのPropsの型定義を先に編集します。
あとは **Flowのエラーが伝搬漏れを警告してくれますので、それに従えば簡単にリファクタできます。** 超便利!

# イベント

`SyntheticEvent<*>` を使いましょう。 `*` はイベントを発火するエレメントの型にします。( `HTMLButtonElement` など )
ただし、これを指定してもイベントを監視するエレメントを縛っているだけなので、　`SyntheticEvent<HTMLElement>` でも十分です。

Reduxで開発しているとよくある、イベントが発火されたらコンポーネントのPropを渡しつつPropから伝搬されたアクションを発火、みたいなやつが一番面倒くさいです。
アクションをラップしてコンポーネントのPropを渡す関数をレンダリングの外部で定義しなければならず、外部で定義するとコンポーネントのインスタンスにアクセスできなくなります。

冗長さはどうにもなっていませんが、こうします。

```jsx
import React, { type SyntheticMouseEvent } from 'react';

// ...

class Component extends React.Component<Props> {
  onClickButton: (SyntheticMouseEvent<HTMLButtonElement>) => void;

  constructor() {
    super();
    // ここでバインドしてしまいます。
    // 2つ目の this.onClickButton は this.__proto__.onClickButton の意味合いです。
    this.onClickButton = this.onClickButton.bind(this);
  }

  onClickButton(event: SyntheticMouseEvent<HTMLButtonElement>) {
    // if (event.currentTarget.disabled) { ... }
    this.props.onClickButton(this.props.inputValue);
  }

  render() {
    return (<button type="button" onClick={this.onClickButton}>...</button>);
  }
}
```
Chrome + Markdown Viewer + LiveReloadでリアルタイムにMarkdownをプレビューする

自分はatomでMarkdownを書いているのですが、atomでもSublime Textの[OmniMarkupPreviewer](https://github.com/timonwong/OmniMarkupPreviewer)のようにブラウザでリアルタイムプレビューができないか試したところChromeと以下の拡張機能を使えば（一応）できました。
ちなみに、atomのプレビューでもいいんですがマルチモニターの場合、他のモニターにプレビュー画面を出して見た方が個人的に見やすかったのでやってみました。

# 試した環境

| 項目         | バージョン |
|:-------------|:-----------|
| MacOS Sierra | 10.12.6    |

# Markdown Viewer

[Markdown Viewer](https://chrome.google.com/webstore/detail/markdown-viewer/ckkdlimhmcjmikdlpkmbgfkaikojcbjk)

ChromeでMarkdownをプレビューするための拡張機能です。
他だとMarkdown Preview Plusなどもありますが、こっちのスタイルの方が個人的に好きだったので使っていきたいと思いました。

**表示例**

![Markdown Viewer例](https://qiita-image-store.s3.amazonaws.com/0/180118/4c12fde0-cd3e-1731-a37d-6224f961c592.png)

ただし、自動更新の機能は標準でありませんでした。

# LiveReload(App Store)

[LiveReload](http://livereload.com/)

ファイルを更新したらブラウザをリロードしてくれるツールです。
ツールの構成は、ファイルの変更をモニタリングするサーバとファイルが変更されたらブラウザを更新するjavascriptです。
今回は、1,200円払ってApp StoreからLiveReloadを購入しました。

# 最初に試した環境

## Chrome/LiveReload/Chrome Markdown Viewer,LiveReload

最初に試したのは

* Chrome
* LiveReload(App Store)
* Chrome拡張機能のMarkdown Viewer
* Chrome拡張機能のLiveReload

です。
ただ、このやり方でやった時にうまくブラウザが更新されなかったり表示が崩れたりと安定しませんでした。
Chromeのデベロッパーツールで確認すると、どうもChrome拡張のLiveReloadがMarkdown PreviewでHTMLコードを生成する時に更新するためのjavascriptが入ったり入らなかったりしていました。
そのため、最初は更新されていても途中から更新されないという事象が頻発して使い物にならず...
それで思いついたのが拡張機能を直接修正して更新用javascriptを埋め込むようにすればいいのでは？ということでやってみました。

# 一先ず動くようになった環境

* Chrome
* LiveReload(App Store)
* Chrome拡張機能のMarkdown Viewer(ソース改修)

Markdown Viewerの拡張ツールは以下に保存されています。

```
/Users/$USER/Library/Application Support/Google/Chrome/Default/Extensions/xxxxxxxxxxxxx/$VERSION/content/content.js
```

Markdown Viewerのソースを以下のように改修しました。

```
--- before/content.js	2018-03-17 23:15:33.000000000 +0900
+++ after/content.js	2018-03-17 23:15:23.000000000 +0900
@@ -75,6 +75,7 @@
     },
     view: () => {
       var dom = []
+      dom.push(m('script', { src: 'http://127.0.0.1:35729/livereload.js?snipver=1' }))

       if (state.raw) {
         dom.push(m('pre#_markdown', {oncreate: oncreate.markdown}, state.markdown))
```

これで、ファイルを更新すれば自動でブラウザが更新してくれるようになりました :-)
このやり方は拡張機能をバージョンアップすると変更した部分が消えてしまいます。

# 課題

## tocについて

toc機能が見やすくて好きなのですが、日本語の場合クリックしてもうまく動作してくれません。
頭の文字が英字だと動いてくれます。

## 時々プレビューが失敗

時々、レンダリングがうまくいかず生のmdフィアルが表示されます。
原因はちょっとわからないですが、ブラウザの更新をして回避しています。。。
nginxでサブパスに複数のWordPressを配置する方法

基本的にWordPressは複数のテーマを同時に設定することができない。複数テーマを使用可能にするプラグインは存在するが、本体バージョンによるのか、投稿名でのパーマリンクを使用した場合は指定したテーマが採用されない。
そこで複数のWordPressをサブパスに分けて配置したが、実現するのに苦労したのでみんなに共有しておく。

以下の例では2つのWordPressを次のように配置する。

|        URL        |       ディレクトリ       |
|:-----------------:|:-----------------------:|
|http\://host/wpone/|/var/www/wponeroot/wpone/|
|http\://host/wptwo/|/var/www/wptworoot/wptwo/|

http\://host/にはWordPress以外が存在していると仮定して、default.confに以下のようにincludeディレクティブを追記する。
なお、nginxの設定フォルダが/etc/nginxであることを前提としている。

```/etc/nginx/conf.d/default.conf
server {
    :
    :

    include conf.d/sub/wpone.conf
    include conf.d/sub/wptwo.conf

    :
    :
}
```

以下は2つのWordPressのそれぞれの設定だが、aliasディレクティブでWordPressの配置先ディレクトリを直接指定するのではなく、rootディレクティブで指定したディレクトリの下にURLのサブパスと同名のサブディレクトリにWordPressを配置するのがコツである。

```/etc/nginx/conf.d/sub/wpone.conf
location /wpone {
    root /var/www/wponeroot;

    access_log /var/log/nginx/wpone.access.log  main;
    error_log /var/log/nginx/wpone.error.log;

    # wordpress パーマリンク設定
    try_files $uri $uri/ /wpone/index.php?q=$uri&$args;

    include conf.d/sub/wordpress-common;
}
```

```/etc/nginx/conf.d/sub/wptwo.conf
location /wptwo {
    root /var/www/wptworoot;

    access_log /var/log/nginx/wptwo.access.log  main;
    error_log /var/log/nginx/wptwo.error.log;

    # wordpress パーマリンク設定
    try_files $uri $uri/ /wptwo/index.php?q=$uri&$args;

    include conf.d/sub/wordpress-common;
}
```

以下は2つのWordPress向けの共通設定である。
複数のロケーション設定に共通点が多い場合は、1つのファイルにまとめてincludeディレクティブで取り込んだ方がメンテナンス性が高くなる。

```/etc/nginx/conf.d/sub/wordpress-common
index index.php;
charset utf-8;

# アクセス拒否設定
location ~* /(wp-config|xmlrpc)\.php {
    deny all;
}

# アクセス制限設定
location ~* /wp-login\.php|/wp-admin/((?!admin-ajax\.php).)*$ {
    index index.php;

    # 外部からのアクセス許可
    allow 87.65.43.21;

    # 自身からのアクセス許可
    allow 12.34.56.78;
    allow 127.0.0.1;

    # 上記以外はアクセス拒否
    deny all;

    include conf.d/sub/fastcgi-for-wordpress;
}

include conf.d/sub/fastcgi-for-wordpress;
```

同じ階層にあるlocationディレクティブはいずれか1つしか採用されないので、上記のようにアクセス制御を行いたい場合は、アクセス制御対象外のPHPファイルに対するphp-fpm用設定を以下のように別ファイルに定義し、それを上記のように2箇所でincludeディレクティブにより取り込むと良い。

```/etc/nginx/conf.d/sub/fastcgi-for-wordpress
# php-fpm用設定
location ~\.php$ {
    fastcgi_split_path_info ^(.+\.php)(.+)$;
    fastcgi_pass phpfpm;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    include fastcgi_params;
}
```

## wpone/hogeにwptwoを配置する方法

ちょっとしたTIPSだが、http\://host/wpone/hogeにwptwoを配置したい場合は以下のようにリバースプロキシを設定する。

```/etc/nginx/conf.d/sub/wpone.conf
location /wpone {
    location /wpone/hoge/ {
        proxy_pass http://localhost/wptwo/;
    }

    :
    :
}
Pythonでヒストグラムをさくっと描画

グラフの描画にはmatplotlibモジュールを使用します。

```python:histgram.py
import numpy as np
import matplotlib.pyplot as plt

#np.random.normal(平均, 標準偏差, 正規乱数の個数)
x = np.random.normal(50, 10, 1000)

plt.hist(x, bins=50)
plt.title("Histgram")
plt.xlabel("x")
plt.ylabel("y")
plt.show()
```

hist関数で```bins```引数では、ヒストグラムで表示される棒の数を指定できます。デフォルトでは10が自動的に指定されます。

#他の表示テクニック
範囲を指定する
plt.hist(x, range=(50, 100))

正規化
plt.hist(x, normed=True)

累積値を出力
plt.hist(x, cumulative=True)

ヒストグラムの下に余白を入れる
plt.hist(x, bottom=30)

縦軸を対数で表示
plt.hist(x, log=True)

棒の幅を設定
plt.hist(x, rwidth=0.8)

棒の色を設定（デフォルトだと青です）
plt.hist(x, color="red")

ぬりつぶしなし
plt.hist(x, histtype="step")

ぬりつぶしあり
plt.hist(x, histtype="stepfilled")

各棒の位置を目盛りの左側に設定
plt.hist(x, align="left")

今度は右側に設定
plt.hist(x, align="right")

縦軸と横軸を入れ替えて表示
plt.hist(x, orientation="horizontal")
prototypeってなんだっけ？

##はじめに
JSの基本で使用する言葉の定義をまとめています。
目次は[こちら](https://qiita.com/nabe_kurage/items/373adae38c0b6073b304)

## prototypeとは
コンストラクタだけが持つ特殊なプロパティで、コンストラクタからオブジェクトを生成する際に、不要なメモリ消費を押させるためのもの。
コンストラクタってなんだっけ？と言う人は[こちら](https://qiita.com/nabe_kurage/items/9af27b7b14e70d443a45)

コンストラクタからオブジェクトを生成する時に、全てのインスタンス変数とメソッドをコピーして生成する。
インスタンス変数は、それぞれが値を持つ必要があるが、メソッドは全オブジェクト共通であるためオブジェクトごとにコピーする必要はない。しかも、インスタンス変数より多くのメモリを消費するため、できたら、いくつもコピーしたくない。。。。
そこで活躍するのが、このprototypeだ。

```javascript
//コンストラクタの定義
var Constructor = function(arg1){
  this.$trigger = arg1;
}
///コンストラクタに入れていたメソッドをprototypeに登録
Constructor.prototype = {
  method1: function(){
    ...
  },
  method2: function(){
    ...
  }
}
//オブジェクトの生成
var clickCounter1 = new ClickCounter('#jsi-count-trigger1');
```
作成したオブジェクトにはインスタンス変数のみがコピーされ、メソッドは共通のものを参照することになる。

## 特徴
- prototypeに登録されている情報は、オブジェクト生成時にコピーされない。
- コンストラクタから作られたオブジェクトは、その時点でコンストラクタのprototypeに登録されている情報を参照できる。
- メソッドをprototypeに登録することにより、不必要なメモリ消費を抑えることができる。
gitでコミット時に自動的にPHP CodeSnifferを実行するhookスクリプト

# 動機

コーディングルールチェックのために[PHP Codesniffer] (https://github.com/squizlabs/PHP_CodeSniffer)を使っているが、
phpcsかけ忘れることが多々あったので、コミットしたタイミングで強制的にphpcsかけてくれるhookスクリプトを作ってみた。

Pull Requestを作った時にphpcsの指摘見つけたら自動的に指摘をpostするWebhook作ったけど、実際にプロジェクトで使ってみたら、PR作成直後に大量に指摘されて「あちゃー」ってなる事態が結構あったので、それを防ぐためになんかできないかなーと思ったのが動機。

# 作った機能

- git commit時に自動で *変更されたファイル単位で* PHPCSを自動実行する
- phpcs実行の結果、問題がない場合にはgit commitが正常終了する
- phpcs実行の結果、指摘が残っている場合には commitがキャンセルされる
- コミットメッセージに `PHPCS_SKIP` のキーワードを含めればスキップされる

## 実行イメージ

- phpcsをかけてエラーが発生した時の表示例

```
$ git commit -m "テストコミット"
[PHPCS:CakePHP] cakephp/src/Lib/Sample.php <ERROR>
----------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
----------------------------------------------------------------------
 19 | WARNING | Doc comment for parameter "$apiKey" missing
----------------------------------------------------------------------

[PHPCS:CakePHP] cakephp/src/Shell/SampleShell.php <ERROR>
----------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
----------------------------------------------------------------------
 30 | WARNING | Comment refers to a TODO task
----------------------------------------------------------------------

Oops, PHPCS has not passed.
This commit is CANCELED.
```

- スキップしたい時のコミット例

```
git commit -m "[PHPCS_SKIP] テストコミット"
```

# ソースコードと設定方法

自分のGithubアカウントにプロジェクト作ってpushしておいた。
READMEに設定方法などを軽くまとめていますのでそちらをご覧ください。

https://github.com/sameyasu/commit-msg

# その他

- phpcbfも自動で実行してもいいかもしれない
- 自前ルールを定義している場合にもgit configで対応できるようにしたつもり
- 当然ながらphpcsの出力仕様が変わるとスクリプトいじらないといけない
- ちなみにPHP7.1 CakePHP3.5でしか動作確認していないけれども、他の環境でもある程度は動くんじゃないかなと思っている
- 導入タイミングが限られる（実プロジェクトではまだ本格導入できてない）
- gulpとかで自動化すればいい話ってもわからなくもない
Amazon Inspectorの結果をいい感じにレポートしたい

# 前置き
Amazon Inspector 使っていますか？
EC2インスタンスにインストールするエージェント→AWSのエンドポイントへの通信が可能な環境であればホストベースの脆弱性診断ができるサービスです。なかなか注目されづらいサービスですが、数回に分けて深掘りしてみます。

# 課題
Inspectorを実行するのは簡単ですが、問題はその後。「診断結果をもとにどうアクションするか」がなかなかの悩みどころです。
Inspectorの実行結果はPDFまたはHTML形式でレポート出力することができます。この機能が初めてリリースされたときは「すごい！便利！」と思ったものですが、英語の長大なレポートを毎回見るかと言われると・・・次第に見なくなります。

### （事例）[How to Remediate Amazon Inspector Security Findings Automatically](https://aws.amazon.com/jp/blogs/security/how-to-remediate-amazon-inspector-security-findings-automatically/)

AWS Security Blog で紹介されていますが、Inspectorが検出した個々の脆弱性の内容を分析して、セキュリティパッチが当たっていない系の検出だった場合は該当するパッチを自動的にインストールするフローです。
[パッチマネージャ](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-patch.html)とかでパッチ状態を管理/適用しているのであれば、場当たり的にパッチ適用するこのフローはちょっとやりたくない気がします。それに、Inspectorが検出するのはセキュリティパッチの適用だけではないです（セキュリティパッチの管理だけをやりたいならパッチマネージャでも代替可能だし）。
なので、やはり人間による何らかの評価/検証プロセスが必要。でもPDFは見たくない。

# 目指すゴール
- その１　Inspectorの実行結果を、再処理しやすいCSVファイルとして出力する
- その２　Inspectorの最新の実行結果と前回の実行結果の差分（＝解消された脆弱性、新たに検出された脆弱性）をレポートする

結局のところ、PDFのレポートを見ていたときも、やりたいことは「ゴールその２」だった気がします。なので、その「判断材料」を自動でサクッと提供してくれるようにするのが最終的なゴールとここでは設定します。

# 実装の方針
## ゴールその１　Inspectorの実行結果を再処理しやすいCSVファイルとして出力する
1. Inspectorが検出した脆弱性（findings）を取得する
2. findingsをCSVへ出力し、S3へアップロードする
3. アップロードしたファイルのPresigned URLを作成し、SNSを介して関係者へ通知する

Inspectorの実行完了をトリガーにLambdaファンクションを実行し、上記の処理を行います。CSVファイルが再処理しやすいか？という指摘があるかもしれませんが、少なくともPDFの英語レポートよりかは…。DynamoDBにつっこむ案もアリですが、後述する分析処理を考慮すると CSVファイル + Athena の組み合わせのほうがやりやすいかと思いました。

## ゴールその２　Inspectorの最新の実行結果と前回の実行結果の差分をレポートする
1. あらかじめCSVファイルのレイアウトをAthenaに認識させておく
2. Athenaのクエリを実行して、今回と前回のInspector実行結果の差分を抽出する
3. 抽出した結果をCSVファイルへ出力し、S3へアップロードする
4. アップロードしたファイルのPresigned URLを作成し、SNSを介して関係者へ通知する

CSVファイルのdiffを取るだけでもいいんですが、ここではAthenaを使ってみます。
Lambdaファンクションの中でAthenaのクエリ処理を実行します。

### *（具体的な実装については次回以降の記事でアップ予定。。）*
[Inspectorの実行結果をCSVファイルとして出力する](https://qiita.com/onooooo/items/dcd59f060267ba4d44be)