OmniAICreator/Qiita-1.07M huggingface dataset:
js例外エラーログを取得するjs作った

#経緯
サービスを利用してるエンドユーザーから「うまく動作しない」という連絡があったときに、
クライアント依存の問題だとフロントエンドのエラーログを見ないと推測が難しいケースがある。
なので、ログを集めるコードを作った。

#導入対象となったサイト
仕事で運用してるレガシーな環境。超レガシー。
７年ぐらい前に構築されたサイトなので、jqueryバリバリ。
もちろんパッケージ管理もされてない。

#方針
本当はSentryを使いたかったけど、前述の通りパッケージ管理もされておらず、
導入コストが大きそうなので自前で作成。
基本方針は、

* ライブラリに依存しないようにする
* nativeのjavascriptで処理するようにする
* エラーが発生したらhttp通信でサーバー側にエラー情報を送ってDB格納
* ハンドリングされてるエラーはとりあえず想定なし。例外エラーだけを対象

的な感じ。

#コード
```javascript:javascript
var gSendLog = function(log){
	//XMLHttpRequestオブジェクトの生成
	var request = new XMLHttpRequest();

	//イベントハンドラ設定
	request.onload = function (event) {
		if (request.readyState === 4) {
			if (request.status === 200) {
				console.log(request.statusText); // success
			} else {
				console.log(request.statusText); // error
			}
		}
	};
	request.onerror = function (event) {
		console.log(event.type); // error
	};

	//open("request method", URL, true or false))
	request.open("get", "/top/api/asp/get_jslog.asp?" + log, true);
	XMLHttpRequest.responseType = 'html';

	//Call
	request.send(null);
}
var gSetLogger = function(){
	window.onerror = function (msg, file, line, column, err) {
		/*
		msg: error message
		file: file path
		line: row number
		column: column number
		err: error object
		console.log(msg + ':' + file + ':' + line + ':' + column);
		*/
		var strLog = "msg=" + encodeURIComponent(msg)
		strLog += "&file=" + encodeURIComponent(file)
		strLog += "&line=" + encodeURIComponent(line)
		strLog += "&col=" + encodeURIComponent(column)
		strLog += "&stack=" + encodeURIComponent(err.stack)
		strLog += "&ua=" + encodeURIComponent(window.navigator.userAgent)
		strLog += "&platform=" + encodeURIComponent(navigator.platform)
		strLog += "&referrer=" + encodeURIComponent(document.referrer)
		gSendLog(strLog);
	};
}
//Call
gSetLogger();
```

gSetLogでonerrorをグローバルでキャッチしてエラー情報作成したら、
gSendLogで、ajaxでAPIコールしてサーバー側でDBに記録。
ちょっと手をぬいてGETで送っちゃってますが、jsonにしてNoSQLに
入れる方がログ管理的にはいい気がします。
あと、ここには書いてませんが、サーバー側でアクセス元IPを取得して、一緒に記録するようにしてます。

#備考
ハンドリングされてるエラーの箇所で「gSendLog」をコールすれば同じようにDB記録できます。
AWS Cloud9でコードをシェアする方法


# IAMグループを作る
1. マネジメントコンソール > IAM > グループ > 新しいグループの作成からCloud9用のグループを作る。
2. グループにCloud9のポリシーをアタッチする。後述のCloud9のIAMポリシーの違いを参照。

# IAMユーザを作る
1. マネジメントコンソール > IAM > ユーザー > ユーザーを追加からCloud9用のユーザーを作る。
2. ユーザーが所属するIAMグループを決める。


# Cloud9からIAMユーザを招待する
- Window > Shareをクリック
![menu_window_share.jpg](https://qiita-image-store.s3.amazonaws.com/0/33176/fbec3a48-318c-52ab-601e-124c1a813b39.jpeg "menu_window_share.jpg")

または

- 右上のShareボタンをクリック
![top_right_share_button.jpg](https://qiita-image-store.s3.amazonaws.com/0/33176/acd78cdd-3968-d287-dc5e-2473129800cc.jpeg "top_right_share_button.jpg")

そして

- IAMユーザ名を入力して、アクセス権限決めて、inviteをクリック
	- ダイアログが出ることもあるけど全部OKをクリックでよい(が、メッセージは読みましょうね)
![invite_iam_user.jpg](https://qiita-image-store.s3.amazonaws.com/0/33176/4707b77c-b300-2094-cff3-cbf4bdce5c8b.jpeg "invite_iam_user.jpg")
- 追加したらDone

## Cloud9のアクセス権限
### RW

- コードの編集ができる。
- コンソールも使える。なのでgitコマンドも使ったり、プログラムの実行ができる。
- コード上で相手のカーソル位置が見える。

### R

- コードを見れるだけ
- コンソール使えない。
- RWユーザがアプリケーション実行してくれれば、プレビューで動作確認できる。
- コード上でRWユーザのカーソル見えない。


# Cloud9のIAMポリシーの違い

調べてみたところ、できることの違いは多分こんな感じ。
詳しくは[こちら](https://docs.aws.amazon.com/cloud9/latest/user-guide/auth-and-access-control.html)

### AWSCloud9Administrator
- Cloud9に関して、ルートユーザとほぼ同じことができる。
- シェアされた環境にアクセスできる。
- Cloud9環境が新規に作れる。
- Account Environments(アカウントに紐づくCloud9環境の一覧)が見れる。
- シェアされた環境を削除することもできる。 :angel: 

### AWSCloud9User
- シェアされた環境にアクセスできる。
- Cloud9環境が新規に作れる。
- Account Environmentsが見れない。

### AWSCloud9EnvironmentMember
- シェアされた環境にアクセスすることしかできないみたい。
- Cloud9環境も新規に作れない。
- Account Environmentsが見れない。

# まとめ
- できることを最小限にしたいなら、AWSCloud9EnvironmentMember ポリシーのグループにIAMユーザを追加するのがよいのでしょうね。
WPのAll-in-One WP Migrationの上限を回避方法

#やりたいこと
表題の通り

#背景
- WPにて引っ越し作業をする際に、All-in-One WP Migrationというpluginを使用したが、移行したいサイトの情報が512Mを超えてしまった。
- All-in-One WP Migrationのファイルアップロード上限サイズは512Mなので、有料版を買えと言われた。
- 69$だとっ...？やだな。容量食う投稿部分のデータは裏から挿入すればいいか
- 本番環境に入ってdump取れないことを思い出す（権限がまだない）
- よし、改造だ

#そもそもWPのPluginってどこに情報があるのか
- /wp-content/plugins/All-in-One WP Migration ←いた

#思ったこと
- 絶対上限サイズ設定している処理の部分あるはず
- /wp-content/plugins/All-in-One WP Migration/constants.phpにいた

##ソースコード
```ruby:constants.php
// =================
// = Max File Size =
// =================
define( 'AI1WM_MAX_FILE_SIZE', 536870912 );
```
ここの第二引数が上限のサイズを定義しているとみた！

なのでこうした

```ruby:constants.php
// =================
// = Max File Size =
// =================
define( 'AI1WM_MAX_FILE_SIZE', 536870912 * 2);
```
※今回アップしたかったのは580Mのファイルだったので、まぁ今後のことも考えてこんくらいにしておくか
※テーマのアップデートで絶対この処理は上書きされるので、そん時はそん時

#結果
余裕でアップロード完了。
69$もとるなんて、ちょっと情報弱者を舐めすぎだ！！
（一回買おうか迷った）

#さいごに
pluginは人が作ったファイルにすぎないので、installするということはそのファイルを自分のproject内に追加するだけです。
てことは自分の管轄内に、いじりたいファイルはあるわけですので、購入前に少し考えたほうがいいですね。
でも、かなり便利なpluginなので、ありがとうの気持ちを込めて69$支払うのもかっこいいなと思ったでやんす。
Atomでlatexをコンパイルするときにlatexmk: Filure in some part of making files と出てpdfが出力できない

# 現象:AtomでTeXのコンパイルが途中で止まる
- latex0.50.0パッケージを使ってコンパイルする。
- dviファイルまでは更新した所が反映されるもdviがpdfに変換されないで下のようなエラーメッセージが出る。
- latexmk: Filure in some part of making files
- 何度やってもこのままで反映されない。
- .texファイル以外消してもう一度行うと反映されるけどいちいち消すのが面倒

# 原因と解決策
- 単純に他のソフト(Atom内部のpdfビュワーではないもの。自分の環境ではPDF-Viewer)で更新するpdfを開いてただけ
- 更新を反映させようとしたときにそこで引っかかってエラーが出ていた
- 実際にpdfビュワーを閉じたらなんなく更新できた。
- .tex以外消してコンパイルできたのは当然ビュワーもなにも見るpdfが無かったため

# 補足
- これは完全に自分用のメモでエラーメッセージの感じからこれ以外のエラーを示していることが十分考えられる
- 他の状況で発生したらまた追記
アート・オブ・アプリケーション　パフォーマンステスト

パフォーマンステストに関して初心者なので、「[アート・オブ・アプリケーション パフォーマンステスト (Theory in practice) | Ian Molyneaux, 田中 慎司 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E3%82%A2%E3%83%BC%E3%83%88%E3%83%BB%E3%82%AA%E3%83%96%E3%83%BB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%83%86%E3%82%B9%E3%83%88-Theory-practice-Molyneaux/dp/4873114241)」を読んでみました。パフォーマンステストってそもそも何をすると良いのか、一般的に気をつける点はどこなのかを勉強する目的で読みました。以下章立てですが、1,2,4章をしっかり、3,5章はざっくり目を通しました。（３章はプロジェクトの中でどのようなステップでパフォーマンステストをするかみたいな話で今知りたいことじゃない、５章は特定技術に対するパフォーマンステストへの影響の説明だったので一旦関係のある部分だけ読みました。）

```
1章　なぜパフォーマンステストをするのか？
２章　効率的なアプリケーションパフォーマンステストの基礎
３章　パフォーマンステストのプロセス
４章　結果の解釈：効果的な根本要因の分析
５章　アプリケーション技術とそのパフォーマンステストへの影響
```

# 所感
- ツールの使用方法レベルの具体的なやり方ではなく、パフォーマンステストについて概念的な部分を体系的に学べて良かった。
    - いままでやってきて身につけたバラバラとした知識を体系的に整理できた気がする。
- これからパフォーマンステストをやってみようという人にはオススメ。
    - パフォーマンステストの分類やどのように負荷をかける方法があるかはこういう本で最初に勉強しないとわかるわけない。
- 初心者としては、気にすべきポイントを知れた部分は大きい。
    - 例えば負荷挿入サーバが過負荷になっていないか確認すること。初心者の私は負荷掛け対象のことしか気にしていなかった。

# メモ
## 負荷挿入サーバが過負荷になっていないか確認する。
- 過負荷であるならば負荷生成サーバを増やす。
- 監視項目
    - CPU使用率
    - 空きメモリ量
    - ディスク使用率
    - ディスクアクセス情報(例えばiostat -x）
  
## 主要なパフォーマンス指標
- 可用性
   - サーバが過負荷時にタイムアウトでエラーを返すかもしれない。
- 同時接続数、スケーラビリティとスループット
- 応答時間
- ネットワーク使用率
   - データ量
   - データスループット 
   - データエラー率
- サーバ使用率
   - CPU使用率
   - メモリ使用料
   - ディスク入出力
   - ディスク容量

## ピーク時の利用を許容できるようにすることも考慮する。

## コード変更があるとそこまでの負荷テストはほとんど無意味になる。
  - テストプラン（スクリプト）が無意味になる場合がある。

## テスト環境は本番環境になるべく近くする。

## パフォーマンスが生きるか死ぬかは提供されたテストデータの質と量にかかっている。
- 入力データ
- 目標データ
   - データベースに現実的なサイズのテストデータを入れる。
   - データを書き換えるようなテストを行う場合はテストごとにロールバックを行いデータを同じ状態に戻す。
- 実行データ
   - アプリケーションから返されるデータ。セッションに関する情報など。

## 様々な種類のパフォーマンステスト
- ベースラインテスト
    - 将来のテスト実行と比較するために行う。
    - **一定** の仮想ユーザや**一定**の時間負荷をかけ「最良の場合」を計測する。
- 負荷テスト
    - 目標の値までアプリケーションに負荷をかけていく。
    - 実際の利用方法に沿った値を利用。
- ストレステスト
    - システムの上限を調べるテスト。
    - システムに無理させてみる。
- 浸透、安定性テスト
    - 長時間負荷掛けを行いメモリリークなどの問題を発見する。

## 負荷の掛け方
- ビックバン型
    - 全仮想ユーザが同時に開始する。
    - 同時にスタートすると極めて大きい負荷がかかるのでパフォーマンステストを正常に始める前にシステム障害になるかもしれないので注意する。
- 増加型
    - 目標数に到達するまで負荷を一定間隔で増やしていく。
- 増加型（ステップ付き）
    - 目標数に到達するまで負荷を一定間隔で増やしていく。
    - 途中で負荷をしばらく一定にして定常状態を確認する。

## パフォーマンステストのステップ
1. テスト環境を準備する
2. 負荷を挿入する環境を準備する
3. 業務トランザクションを特定し、スクリプト化する
4. 十分なテストデータを特定し作成する
5. テスト環境を確認する
6. パフォーマンステストを順次実行する
7. 特定された問題に対処する

## 統計学入門
- パフォーマンステストにおいて理解しておくべき統計ツール
    - 平均値
    - 中央値
    - 標準偏差
    - 正規分布
    - パーセンタイル値
    - ヒストグラム

## テスト前の準備
- 実行したテストの区別をできるようにする
    - テスト結果などのファイル名などでテストを識別できるようにする。
    - どのテストで何を測定したかったのかを文書化する。


# テスト後のタスク
- 必要な結果が全てでているか確認する。
- テストの全ての資産（スクリプト、入力データファイル、テスト結果など）は隔離した場所でバックアップをとっておく。
Ruby tryの記法

## try(:[], :name)ってどんな動き？


ActiveSupportで追加された非常に便利なメソッド

```
engineer = {name: 'aoki', age: 34}
engineer.try(:[], :name)
=> "aoki"
engineer.try(:[], :prefecture)
=> nil
```

上記のコードの例だと、
nameというキーは存在しているので、そのまま返す
prefectureというキーはないのでnilを返す


```
engineer = {name: 'aoki', age: 34}
engineer&.[] :name 
=> "aoki" 

```
Ruby2.3以降ではこのような書き方も可能

```

engineer = nil
engineer[:name]
=> NoMethodError: undefined method `[]' for nil:NilClass
engineer.try(:[], :name) 
=> nil
engineer&.[] :name
=> nil
```

NoMethodErrorを避けたい時に便利
Bundlerでgemライブラリをインストール・アンインストールする小さなメモ

# メモ

## 前提

- rbenv
- bundlerインストール済
- `mechanize` というライブラリを例にメモ

## ライブラリのインストール

```zsh
% bundle init ★初期設定：Gemfileが作成される
Writing new Gemfile to /home/kure/bundle1/Gemfile
% gem list mechanize ★ mechanize はまだ無い

*** LOCAL GEMS ***


% vim Gemfile ★ [gem "mechanize"] を追記
% bundle install ★ インストール。Gemfile.lockもこのタイミングで出来ると思われる
% gem list mechanize ★確認

*** LOCAL GEMS ***

mechanize (2.7.6)
```

## ライブラリのアンインストール

略。以下の通りでできた

Rubyが参照してるgemのパスやインストール済gemを確認する方法 - Qiita https://qiita.com/h5y1m141@github/items/74029cab9706971c8dbe
Webpack4でのビルドエラー「Chunk.entrypoints:」

# 問題と対処法
webpack4 環境で build 時に以下エラーが出た場合。

```
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
    at Chunk.get (/var/www/node_modules/webpack/lib/Chunk.js:750:9)
    at /var/www/node_modules/extract-text-webpack-plugin/dist/index.js:176:48
    at Array.forEach (<anonymous>)
    at /var/www/node_modules/extract-text-webpack-plugin/dist/index.js:171:18
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/var/www/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/var/www/node_modules/tapable/lib/Hook.js:35:21)
    at Compilation.seal (/var/www/node_modules/webpack/lib/Compilation.js:905:27)
    at hooks.make.callAsync.err (/var/www/node_modules/webpack/lib/Compiler.js:494:17)
    at _err0 (eval at create (/var/www/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:11:1)
    at _addModuleChain (/var/www/node_modules/webpack/lib/Compilation.js:771:12)
    at processModuleDependencies.err (/var/www/node_modules/webpack/lib/Compilation.js:710:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)

```

extract-text-webpack-plugin のver.問題らしい。

```
npm i -D extract-text-webpack-plugin@next
```

すると通るようになった。

## 参考
* [webpack-contrib/extract-text-webpack-plugin > issues > Webpack 4 compatibility #701](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701)
Ruby 配列に要素を出し入れ

## 配列の後ろに要素を追加 push
レシーバ自身を変更する。戻り値はレシーバ自身。

```
prefectures = ['Tokyo', 'Kanagawa', 'Fukuoka', 'Aichi']
prefectures.push('Okinawa')
=> ["Tokyo", "Kanagawa", "Fukuoka", "Aichi", "Okinawa"]
```

## 配列の後ろの要素を削除 pop
レシーバ自身を変更する。戻り値は削除した要素。

```
prefectures = ['Tokyo', 'Kanagawa', 'Fukuoka', 'Aichi']
prefectures.pop
=> "Aichi"
prefectures
=> ["Tokyo", "Kanagawa", "Fukuoka"]
```

## 配列の前に要素を追加
レシーバ自身を変更する。戻り値はレシーバ自身。

```
prefectures = ['Tokyo', 'Kanagawa', 'Fukuoka', 'Aichi']
prefectures.unshift('Aomori')
=> ["Aomori", "Kanagawa", "Fukuoka", "Aichi"]
```

## 配列の前の要素を削除 shift
レシーバ自身を変更する。戻り値は削除した要素。

```
prefectures = ['Tokyo', 'Kanagawa', 'Fukuoka', 'Aichi']
prefectures.shift
=> "Tokyo"
prefectures
=> ["Kanagawa", "Fukuoka", "Aichi"]
```
Swift 4でカジュアルにthread safeなハッシュを作る - How to create thread safe hash / array in Swift 4

以下、実装です。
なお、Swiftはハイレベルなものからローレベルなものまで様々なマルチスレッド・プログラミングのためのAPIがあり、これが筋の良いものかはまだ未検証。

容易に想像がつくが、`flags: .barrier`がないとクラッシュする（検証済み）

```swift

class ThreadSafeHash<T: Hashable, S> {
    private var raw: [T: S]
    private let concurrentQueue = DispatchQueue(label: "ThreadSafeHashQueue", attributes: .concurrent)

    init(_ raw: [T: S]) {
        self.raw = raw
    }

    subscript(i: T) -> S? {
        get {
            var value: S?
            concurrentQueue.sync {
                value = raw[i]
            }
            return value
        }
        set {
            concurrentQueue.async(flags: .barrier) {
                self.raw[i] = newValue
            }
        }
    }
}
```

# DispatchSemaphore, NSCache, objc_sync_enter, NSLock等との比較
- TODO

# 苦情・まさかりはコチラ
twitter: _kentrino
rubyにおける：：（ダブルコロン、コロンコロン）についてのメモ


rubyにおける：：（ダブルコロン、コロンコロン）について、調べました。


１番目、rubyでは、メソッドや定数を呼び出す場合に：：ダブルコロンが使われます。

```ruby
class Colon
  def method
    puts "Colon"
  end
end

c = Colon.new
c::method
# Colon
```
引用元）https://qiita.com/ktarow/items/772014a4f0d48905f3ef


２番目、Ruby では名前空間の（トップレベルからのパス）絶対パスで指定する場合に：：ダブルコロンが使われます。

```ruby
class Foo; end 

module MyNameSpace
class Foo; end

def foo1 
::Foo.new # 一番上のFoo
end

def foo2
Foo.new # MyNameSpace::Foo
end
end
```
引用元）https://teratail.com/questions/3382


３番目、スコープ演算子としての::（ダブルコロン）
C++でも、::(ダブルコロン)はスコープ演算子として使っている。

```config/initializers/constants.rb

module Constants
  AgeStart = 0
  AgeEnd   = 99
end
```
```app/modles/customer.rb
class Customer < ActiveRecord::Base
  age_start = Constants::AgeStart #=> 0
  age_end   = Constants::AgeEnd   #=> 99
  validates :age, :inclusion => { :in => age_start..age_end }
end
```
引用元）https://qiita.com/nashirox/items/0c885edf7d78fd5a83f1

```ruby
class Hoge
  FUGA = "piyo"
end

p Hoge::FUGA #=> "piyo"
```
引用元）https://qiita.com/mnuma/items/22338399a86064c61f24


４番目、ではこの、ActiveRecord::Baseの二重コロンはどれに該当するのか？

```ruby
class User < ActiveRecord::Base
  
end
```
参考記事
https://teratail.com/questions/20825
http://www.atmarkit.co.jp/ait/articles/1104/12/news135.html

参考記事では、BaseはActiveRecordの親クラスである、と教えてくれています。
４番のクラスの継承で::ダブルコロンが使われている場合は、何番の使われ方なのだろうか？

なお、deviseでも4番のように使われます。

```ruby
class RegistrationsController < Devise::RegistrationsController

end
```

理解が深まったら、追記します。
機械学習論文読みメモ_128

[Log-DenseNet: How to Sparsify a DenseNet](https://arxiv.org/abs/1711.00002)
Skip connectionはdeepnetの性能向上のために重要な要素となっている。
特にDenseNetがその例として挙げられる。
しかしこのモデルはネットワークの深さに関してscalabilityを保てず
また計算コストが膨大化しやすい。
本論ではまず、こうしたskip connectionの利点は、各特徴層へのパスが
短くなることでback propagationによる情報伝達がしやすくなることに
あることを示した。
この知見をもとに、本論ではDenseNetよりも少しだけback propagation
を行う際の距離が伸びるが、connectionの数を2乗オーダーからlogオーダー
に削減したLogDenseNetを提案する。

[HIERARCHICAL REPRESENTATIONS FOR EFFICIENT ARCHITECTURE SEARCH](https://arxiv.org/abs/1711.00436)
本論ではevolutionary algorithmに基づいてarchicecture searchの
手法を提案する。
この手法は人間のエキスパートが用いているmodularized design patternを
まねたhierarchical representation schemeと、
複雑なトポロジーに対応可能な探索空間を組み合わせる。
hierarchical representation schemeでは、
最小に小さく簡単なconvolutionやpoolingのみの組み合わせからはじめ、
そのあとその構造を単位とした組み合わせでblockを形成していくことで
より高位の複雑なネットワークを形成する手法である。
こうして実現される複雑な探索空間に対して、evolutionary algorithmと
（あるいは単純なrandom searchと）組み合わせて探索を行うことで
SOTAな性能のネットワークを見つける事が可能になる。

[The Implicit Bias of Gradient Descent on Separable Data](https://arxiv.org/abs/1710.10345)
本論ではunregularized logistic regressionを分離可能なデータに対して学習した場合、
max-margin solutionへ収束する事を示した。
この結果はさらに単調減少関数に関して一般化できることを示し、
また多クラス拡張としてcross entropy lossに関する一般化についても議論する。
さらにこの収束は遅く、logarithmic scaleである事を示す。
この事実より、訓練誤差がゼロになったり、訓練損失が限りなく小さくなったとしても、
学習を続けることに意味があることを示唆する。
VBAでサイト内の特定の場所を自動的にクリックする

前回、前々回はサイトへ自動的にログインする方法を調べて成功しました。
今度はサイト内の特定の場所を自動的にクリックする方法を調べていきます。


①

```vb
objIE.Navigate "クリックしたいURL"
    Call IEWait(objIE) 
    Call WaitFor(3) 
```

これでいけそうな感じがする。

②

```vb
Dim objtsugi As Object
    For Each objtsugi In objIE.Document.getElementsByTagName("a")
        If InStr(objtsugi.outerHTML, "次のページ") > 0 Then
            objtsugi.Click
            Call WaitFor(3)
            Exit For
        End If
    Next
```
これも近い気がしますね。


しかし、、、、
最初、①をログイン操作のプログラムの後に付け加えるとログインが出来なくなってしまった。

①の前にSet objIE = CreateObject("InternetExplorer.Application")
を追加し解決。
MastodonのVersionUp時に遭遇するErrorの対処法（脳筋編）

#### git pull 編

```
error: Your local changes to the following files would be overwritten by merge:
        Gemfile
Please, commit your changes or stash them before you can merge.
Aborting
```
```
git checkout Gemfile.lock
git reset --hard HEAD
```

#### rails db:migrate 編

```
rails aborted!
ActiveRecord::ConcurrentMigrationError:

Cannot run migrations because another migration process is currently running.
```
```
/etc/init.d/postgresql restart
[....] Restarting postgresql (via systemctl): postgresql.service==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'postgresql.service'.
Authenticating as: ,,, (mastodon)
Password:
==== AUTHENTICATION COMPLETE ===
. ok
```

※あくまでも備忘録なので、その点はご了承くださいませ。
java.util.stream.Stream の実装を手軽に作成する方法

## 動機
`java.regex.Matcher` を使って正規表現にマッチした部分文字列を処理する典型的なイディオムは以下である．

```java
Pattern pattern = Pattern.compile("(cola)+");
Matcher matcher = pattern.matcher("cola, cola, I love cola.");
while (mather.find()) {
  // do something with the current match.
  System.err.println(matcher.group());
}
```

マッチした箇所に対する read-only な処理をするだけなら，ストリーム処理として書けるべきであろう．こんなふうに．

```java
Matcher matcher = pattern.matcher("cola, cola, I love cola.");
matcher.forEach(h -> System.err.println(h.group()); // h はマッチした箇所を表す何か（定義する必要がある）
```

`Matcher`をラップする`java.util.stream.Stream`の実装を作れば実現できる，と思ったのは良かったが，このインタフェース，メソッドが多すぎて実装するのが大変である．
https://docs.oracle.com/javase/jp/9/docs/api/java/util/stream/Stream.html
`Stream` を簡単に実装する方法があるだろうか？
##追記: `Matcher`に対する解決方法
もとの記事では，下にある一般的な解決方法を挙げていたが，`Matcher`に関してはJava9から`Matcher#results()`を使うと完全な答えが得られる．このメソッドの実装が，まさに上で書いたやりたいことを実装してくれている．

```java
Pattern pattern = Pattern.compile("(cola)+");
pattern.matcher("cola, cola, I love cola.").results()
    .forEach(x -> System.err.println(x.group()));
```

NOTE: ご指摘下さった @saka1029 さん，ありがとうございました．
なお，`Matcher` 以外に何かを iterate したい一般的な場合の手法は以下を参照して下さい．



##一般的な解決方法

少し調べた結果，`StreamSupport#stream` と `Spliterators#spliteratorUnknownSize` を組み合わせることにより，以下のように書けることがわかった．
この方法は，すぐわかるように`Matcher`に限らず`java.util.Iterator`の実装に帰着すれば何でも適用可能である．
というわけで，汎用性が高いのでメモしておく次第である．
【追記: この例だけを見れば元のコードより長く複雑になっている，ということは理解しております :-)】

```java:RegExTest.java
import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 
 */
public class RegExTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		
		final Pattern pattern = Pattern.compile("(cola)+");

		final Stream<Matcher> s = StreamSupport.stream(
			Spliterators.spliteratorUnknownSize(
				new Iterator<Matcher>() {
					final Matcher matcher = pattern.matcher("cola, cola, I love cola.");
					@Override
					public boolean hasNext() {
						return matcher.find();
					}
					@Override
					public Matcher next() {
						return matcher;
					}
				},
				Spliterator.NONNULL | Spliterator.IMMUTABLE),
			false);
		
		// 冒頭の例と同じ使い方ができるようになった！
		s.forEach(m -> System.err.println(m.group()));
	}

}
```

##追記: `java.util.Iterator`を実装せずに済む方法
@saka1029 さんに再びご指摘頂き，`java.util.stream.Stream` の Java9 から提供されているメソッド [Stream#iterate] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/stream/Stream.html#iterate(T,java.util.function.Predicate,java.util.function.UnaryOperator)) を使うと，以下のように `Iterator` を実装せずとも綺麗に書けることを知りました．@saka1029 さん，ありがとうございます．Java9 で新しくこの書き方が提供されたということは，こんなふうに書けたらいいのになと思った人が私以外に大勢いたであろうということで，うれしいです．

```java
final Pattern pattern = Pattern.compile("(cola)+");
Stream.iterate(pattern.matcher("cola, cola, I love cola."), m -> m.find(), m -> m)
    .forEach(m -> System.out.println(m.group()));
```
「W杯 ポルトガルvsスペインの得点シーン」をOpenPoseで可視化してみた

サッカーW杯 ポルトガルvsスペインの得点シーンをOpenPoseで可視化してみました。
OpenPoseとは人の画像から、その関節位置を推定するディープラーニングのアルゴリズムです。


本投稿では
1. OpenPoseによるサッカー動画の可視化の結果
2. OpenPoseの使い方

を紹介します。


### 免責事項：OpenPose
- 本内容は筆者が個人的趣味の範囲で楽しんでいるものです
- OpenPoseの商用利用にはライセンスが必要です
- OpenPoseは商用利用でもスポーツ領域には使用できません
※ [OpenPoseライセンスの詳細](https://flintbox.com/public/project/47343/)

### 免責事項：画像・動画
- 画像・動画引用元：サッカーW杯 ポルトガル対スペイン, NHK, 2018年6月16日.
- 本投稿では「明瞭区別性」と「主従関係」が明らかな「引用」として画像・動画を使用しています。弁護士の見解では以下のように著作権法に対して問題ないようですが、注意は必要です。 

>[テレビの試合中継。写メってツイートするのは著作権侵害？？｜平林弁護士がアドバイス！SNS法律相談所](http://kakeru.me/twitter/hira-tv-tweet/)
>【結論】Tさんの画像付きツイートが著作物の「引用」（著作権法32条1項）と認められる場合、著作物侵害にはならない


# OpenPoseでの可視化の結果

![fig1.png](https://qiita-image-store.s3.amazonaws.com/0/191401/306e140c-2139-e9fe-b37a-42b6ce49fdca.png)


![fig2.png](https://qiita-image-store.s3.amazonaws.com/0/191401/0b7c77d4-1f26-dd1c-6c3f-2f44fe2c4b71.png)

![fig3.png](https://qiita-image-store.s3.amazonaws.com/0/191401/09a09122-fc23-dff6-3287-57030ff19e4a.png)




動画はこちら（約2分）
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">W杯 ポルトガルvsスペインの得点シーンをOpenPoseで可視化してみた。詳細や免責事項はこちら。<a href="https://t.co/lu41tbORik">https://t.co/lu41tbORik</a> <a href="https://t.co/bgjYwu1DBP">pic.twitter.com/bgjYwu1DBP</a></p>&mdash; すぐる (@Neuro_educator) <a href="https://twitter.com/Neuro_educator/status/1007855031201116164?ref_src=twsrc%5Etfw">2018年6月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# OpenPoseの使い方
[公式GitHubのインストール手順書](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md)の通りにやっていたのですが、うまくいかずに苦労しました。
最終的には以下の記事が非常に参考になりました。

[●GPU非搭載のPCだけどOpenPoseを試したい（その2）](http://kghr.blog.fc2.com/blog-entry-120.html)

### 1. マシンの用意
AWSのEC2インスタンスを用意します。設定は以下の通りです。
- マシンイメージ：Deep Learning Base AMI (Ubuntu)
- インスタンスタイプ：p2.Xlarge

OpenPoseを実行するためには、基本的にはGPUインスタンスを使用します。


### 2. 環境設定
以下の内容を順番に実行します。

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose
cd openpose

mkdir build
cd build

cmake ..
make -j`nproc`

```
最後のmakeは時間がかかります。20分くらいかかったような。

### 3. 実行方法
openposeのフォルダに戻り、データを置くフォルダinputを作成します。

```
cd ..
mkdir input
```

フォルダinputに画像や動画を置きます。画像はpng、動画はaviを試しました。

画像を解析する場合の実行方法は次の通りです。

```
./build/examples/openpose/openpose.bin --image_dir input/ --write_images output -display 0
```

-display 0に注意が必要です。--no_displayは通りませんでした。これでinputフォルダ内の画像が解析され、outputというフォルダに解析結果が格納されます。

動画を解析する場合の実行方法は次の通りです。

```
./build/examples/openpose/openpose.bin --video input/mv.avi --write_video mv_pose.avi -display 0
```

これでinputフォルダ内のmv.aviという動画ファイルが解析され、openposeフォルダ直下にmv_pose.aviという解析された動画が保存されます。


# まとめ
以上、OpenPoseで遊んでみたでした。

昨週は、Alexaとスマートウォッチで遊んだ記事を書きました。
お時間ありましたら、こちらもぜひご覧ください。

[「アレクサ、今の気分におすすめの音楽をかけて♪」を作ってみた（スマートウォッチ×Alexaスキル）](https://qiita.com/sugulu/items/f23a697507c9a93c81b2)
Concourse CI環境を5分で構築する

公式のDockerイメージを利用して、Concourse CIの環境を構築する。

#### **（事前）Dockerインストール**
Dockerは事前にインストールしておく。

```
# for Mac
brew cask install docker
```

```
# for Linux
yum install docker -y
```

#### **Concourse起動**

```sh:
# 公式リポジトリからclone
git clone https://github.com/concourse/concourse-docker.git
cd concourse-docker

# 秘密鍵生成
./generate-keys.sh

# docker-compose.ymlを編集
#  - CONCOURSE_EXTERNAL_URLを修正
#  - CONCOURSE_BASIC_AUTH_USERNAMEを追記
#  - CONCOURSE_BASIC_AUTH_PASSWORDを追記
vi docker-compose.yml
```

```yaml:docker-compose.yml
version: '3'

services:
  concourse-db:
    image: postgres
    environment:
    - POSTGRES_DB=concourse
    - POSTGRES_PASSWORD=concourse_pass
    - POSTGRES_USER=concourse_user
    - PGDATA=/database

  concourse-web:
    image: concourse/concourse
    command: web
    links: [concourse-db]
    depends_on: [concourse-db]
    ports: ["8080:8080"]
    volumes: ["./keys/web:/concourse-keys"]
    environment:
    - CONCOURSE_POSTGRES_HOST=concourse-db
    - CONCOURSE_POSTGRES_USER=concourse_user
    - CONCOURSE_POSTGRES_PASSWORD=concourse_pass
    - CONCOURSE_POSTGRES_DATABASE=concourse
    - CONCOURSE_EXTERNAL_URL=${CONCOURSE_EXTERNAL_URL}
    - CONCOURSE_BASIC_AUTH_USERNAME=concourse
    - CONCOURSE_BASIC_AUTH_PASSWORD=concourse
    - CONCOURSE_ADD_LOCAL_USER=test:$$2a$$10$$0W9/ilCpYXY/yCPpaOD.6eCrGda/fnH3D4lhsw1Mze0WTID5BuiTW
    - CONCOURSE_MAIN_TEAM_ALLOW_ALL_USERS=true

  concourse-worker:
    image: concourse/concourse
    command: worker
    privileged: true
    links: [concourse-web]
    depends_on: [concourse-web]
    volumes: ["./keys/worker:/concourse-keys"]
    environment:
    - CONCOURSE_TSA_HOST=concourse-web:2222
    - CONCOURSE_GARDEN_NETWORK
```

```sh:起動
export CONCOURSE_EXTERNAL_URL=http://$(ipconfig getifaddr en0):8080
docker-compose up -d
```

以上で構築完了。http://localhost:8080 で画面にアクセス可能。

#### **構築完了したら**
flyコマンドでパイプラインを作って実行してみよう。
[Concourse CIのよく使うコマンド集](https://qiita.com/cacarrot/items/8cb4a13b10d408a108c3)を参照。

#### **参考**
* https://concourse-ci.org/
Javaで接続時、IEで設定されたプロキシを使用方法まとめ

#java中如何设定，使程序可以自动使用IE设置好的代理访问HttpsUrlConnection 

**10几年前有人遇到和我一样的问题，而且解决了 
https://community.oracle.com/message/7326510#7326510**
### 尝试以下设置①
1. 在系统属性中设置 System.setProperty("proxySet", "true");
2. 在系统属性中设置 System.setProperty("java.net.UseSystemProxies", "true");
3. IE中设置好代理
4. 程序验证代理是否可用

### 如果设置①不可以，尝试改变注册表的值
1. 在CurrentUser项目下找到：Software\Microsoft\Windows\CurrentVersion\Internet Settings设置项，确认以下三个属性的设置是否启用。
2. ProxyEnable:0 ProxyHttp1.1:1 ProxyOverride:[127.0.0.1;<local>] （我PC上设置值）

### 在jre/lib/net.properties中修改配置
1. 修改文件中java.net.useSystemProxies=false 为true，默认使用系统代理
2. 问题是在我启动项目时，根本没有加载这个文件
 
### IE和eclipse上的代理设置都设置正确，java中仍然不使用这些代理的情况
1. **这个情况下，主要问题是解决如何使java去寻找我们配置的各种代理（关键点）**

（持续更新。。。。）

2018/06/16 update
- **jdk java.net.UseSystemProxies属性使用bug https://bugs.java.com/view_bug.do?bug_id=6912868**
-
- https://community.oracle.com/message/7326510#7326510 12年前同样问题
- https://community.oracle.com/message/4639742#4639742 9年前有人确认可行
VBAで自動的にサイトへログインをする

前回の方法だと上手くログインまで行けなかったので他の方法で試したら出来ました。


```vb
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Zoom\ZoomFactor",100000,"REG_DWORD"

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True

objIE.FullScreen = False
objIE.Top = 0
objIE.Left = 0
objIE.Width = 1280
objIE.Height = 964

objIE.Toolbar = True
objIE.MenuBar = True
objIE.AddressBar = True
objIE.StatusBar = True

objIE.Navigate2 "ログインしたいサイトのURL"

Do Until objIE.Busy = False
    WScript.sleep(250)
Loop

objIE.Document.Forms(0).Item(2).value = "自分のログインID"
objIE.Document.Forms(0).Item(3).value = "自分のパスワード"
objIE.Document.Forms(0).Submit

Set WSHShell = WScript.CreateObject("WScript.Shell")
WSHShell.AppActivate "Explorer"
```
サイトの入力部分を指示する下記の部分は、使用するサイトの構成で違ってくる。

```vb
objIE.Document.Forms(0).Item(2).value = "自分のログインID"
objIE.Document.Forms(0).Item(3).value = "自分のパスワード"
objIE.Document.Forms(0).Submit
```

構成の中のidやNameでやっても上手く行かない無い場合は、Fromで指示すると上手くいきました。


＝＝＝課題＝＝＝
サイト内で特定の場所を自動的にクリックするにはどうすれば良いのか。
JavaScript で可読性を残しつつタグを生成する方法

# 用途
* テンプレエンジンとかモダンなフレームワークを使わずに、標準のDOM APIだけでタグを生成したい場合。

# 実装
## 準備
* 以下のような関数を定義

```js
var createElement = function(tag, attr = null, ext = null){
    var element = document.createElement(tag);
    if(attr !== null){ 
        Object.keys(attr).forEach(function(e){
            element.setAttribute(e, attr[e]);
        });
    }
    if(ext !== null) ext(element);
    return element;
}

```

## 生成例
### シンプルな構成
* id と class を指定した単純なdiv要素

```js
var foo = createElement('div', {id: 'foo', class: 'foo'}, null);
```
↓

```html
<div id="foo" class="foo"></div>
```


### ネストさせる
```js
var bar = createElement('div', null, function(div){
    div.appendChild(createElement('p', {id: 'bar'}));
});
```
↓

```html
<div><p id="bar"></p></div>
```

### テーブルとか

```js
var baz = createElement('table', {style: 'border: 1'}, function(table){
    for(var i=1; i<10; i++){
        table.appendChild(createElement('tr', null, function(tr){
            for(var j=1; j<10; j++){
                tr.appendChild(createElement('td', null, function(td){
                    td.appendChild(document.createTextNode(i*j));
                }));
            }
        }));
    }
});
```
↓
<table><tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td></tr><tr><td>2</td><td>4</td><td>6</td><td>8</td><td>10</td><td>12</td><td>14</td><td>16</td><td>18</td></tr><tr><td>3</td><td>6</td><td>9</td><td>12</td><td>15</td><td>18</td><td>21</td><td>24</td><td>27</td></tr><tr><td>4</td><td>8</td><td>12</td><td>16</td><td>20</td><td>24</td><td>28</td><td>32</td><td>36</td></tr><tr><td>5</td><td>10</td><td>15</td><td>20</td><td>25</td><td>30</td><td>35</td><td>40</td><td>45</td></tr><tr><td>6</td><td>12</td><td>18</td><td>24</td><td>30</td><td>36</td><td>42</td><td>48</td><td>54</td></tr><tr><td>7</td><td>14</td><td>21</td><td>28</td><td>35</td><td>42</td><td>49</td><td>56</td><td>63</td></tr><tr><td>8</td><td>16</td><td>24</td><td>32</td><td>40</td><td>48</td><td>56</td><td>64</td><td>72</td></tr><tr><td>9</td><td>18</td><td>27</td><td>36</td><td>45</td><td>54</td><td>63</td><td>72</td><td>81</td></tr></table>

## 関数の説明
createElement（a, b, c)
a: タグ名 String ex. 'div'
b: 属性 Object ex. {id: 'foo', class: 'bar'}
c: 拡張 function(tag) このtag は生成されるHTMLElementなので
tag.appendChild(...) でネストしたり、 tag.addEventListener(...)とかでイベントリスナをつけたりする。
iOSカスタムキーボードでデバッガが落ちる

iOSでカスタムキーボードを作成しようとしたときにデバッガが'SIGQUIT'して落ちるという事象に出くわしました。

### 環境

|IDE|Version|
|---|-------|
|Xcode|9.4|
|iOS|11.4|
|動作環境| シミュレーター|

### 原因

原因は不明ですが、Xcode8ごろから同様の事象があるようです。

[debugging - Xcode 8 keyboard extension debugger - Stack Overflow](https://stackoverflow.com/questions/41881490/xcode-8-keyboard-extension-debugger)

### 対策

#### 対策1. detach / attachする

1. 'SIGQUIT'させる
2. Xcode > debug > detach
3. Xcode > debug > Attach to Process で目的のアプリにつなぐ

#### 対策2. 実機でやる

なぜかエラーが起きにくいような気がします。

## 参考

1. [iOSカスタムキーボードの作り方 - Qiita](https://qiita.com/Kyomesuke3/items/4257de4e33d3647085e6)
2. [debugging - Xcode 8 keyboard extension debugger - Stack Overflow](https://stackoverflow.com/questions/41881490/xcode-8-keyboard-extension-debugger)
3. [swift - Xcode 9.2 fails to debug custom keyboard extension strangely - Stack Overflow](https://stackoverflow.com/questions/48907285/xcode-9-2-fails-to-debug-custom-keyboard-extension-strangely)
C#のクラスにつけられるキーワード

|キーワード| 役割|
|:----|:----|
|`abstract`|抽象クラスであることの宣言|
|`sealed`|継承の禁止|
|`partial`| クラスの分割定義|

# abstract

抽象クラスになり、直接のインスタンス化の禁止。

```abstract_sample.cs
abstract class MyAb
{
    // Hanbetsuメソッドは抽象メソッド
    public abstract double Hanbetsu(double a, double b, double c);
}

class MyHanbetsu: MyAb
{
    // 基本クラスの抽象メソッドは必ずオーバーライドする
    public override double Hanbetsu(double a, double b, double c)
    {
        return Math.Pow(b, 2.0) - 4.0 * a * c;
    }
}
```

* abstractクラスにメソッドの実装は可能

# sealed

継承を禁止したい場合は、`sealed` キーワードを付ける

```sealed_sample.cs
sealed class MyClass
{
}
```

# partial

クラスの定義内容を機能毎に分割して、それぞれ別のファイルとして保存できる

```partial1.cs
using System;

partial class MyClass
{
    public int x;
}

class Partial01
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        mc.x = 10;
        mc.Show();
    }
}
```

```partial2.cs
using System;

partial class MyClass
{
    public void Show()
    {
        Console.WriteLine("x = {0}", x);
    }
}
```

以下でコンパイルする

```display:terminal
csc partial1.cs partial2.cs
```
駆け出しJava(3年)からNode.js（4年）。そしてJavaに戻ってきた感想


タイトルの通り、Javaに戻ってきました。

見える世界がまるで違う。強くなって初めて分かるぜ。Javaってこんな仕組みだったのか！？てきな。

[ウェブアプリケーション開発に新言語を採用したときにインフラで考えたこと](https://blog.yuuk.io/entry/infra-for-newlang)

仕組みというのは↑的な意味です。

### 駆け出し時と今の違い
---

僕の駆け出しのときの状況ですが、

- Java
- プロジェクトのプログラミングルールを覚える
- tomcat
- IDEの使い方
- DBとの接続ツールの使い方
- Gitの使い方
- SQL
- リリースなどのオペレーション
- 障害対応
- 社内用語
- 先輩との付き合い方
- チャットツールとの付き合い方
- HTTPとかWeb全般の知識
- クロスサイトスクリプティングとかセキュリティ関連の話
- HTML
- JavaScript
- Websocket
- 認証方式
- LinuxOS
- サーバーマシンのスペックによる上限値の意識

などなど、覚えることが多く正直深く理解せずに、コントローラとサービス書くしかない状況でした。
（今思えば、ペアプログラミングでベテランが引っ張ってくれたら、高速道路理論が使えて成長速度が違ったと思います。）

一応、昼休みに技術書読むなど頑張ってました。

しかし、今思えばずいぶんとレベルが低かったなぁと思います。
（駆け出しなので当たり前かと思いますが。。）

現状では、記述したものはだいたい分かっている状況となっています。

その状態で改めて見たJavaの良いとこ、悪いとこをNode.jsとの比較も交えて書いていきます。

### 環境
---

- Java8
- Nginx
- Tomcat7系
- Spring4系
- MongoDB3.0系
- MongoDB3.6系
- MariaDB5.5系
- RabbitMQ
- Redis3.0
- Redis4.0
- メインのインフラはDCにあるベアメタルサーバ
- Websocket(WSS)

### 良いところ
---

- Node.jsと違って非同期のイベント駆動では無いのでコードが追いやすい
- 型があるのでコンパイルさえ通れば割と動くという安心感がある
- Javaは使われているし、枯れてもいるので安心感がある
- やろうと思えば非同期処理も書ける
- ググれば色々と情報が出てくる（量が多すぎて逆にノイジーでもある）
- MongoDBがスキーマレスなので、Java側で型を使ってスキーマ定義できるのは非常に良い

### 悪いところ
---

- コンパイルに時間が掛かる
  - 回避方法はあると思うが、プロジェクトの現状では2分30秒掛かる
- IntelliJ IDEA（統合開発環境）が無いと開発できない（なんとかしたい。。）
  - Node.jsの場合、VimとかVisualStudioCodeとか自由だった
- テスト(JUnit)が、[Node.jsのMocha](https://mochajs.org/#getting-started)と比べて書きづらい
  - 事前処理とか事後処理を明示的に書きたいが、テスト内にごちゃっと書くしか無い。
- Springのせいで実装がしづらい（バッチ処理もまともに書けない状況）
  - SpringもDIがほしいだけなら、Google Guiceとかもある
  - [SparkJava](http://sparkjava.com/)とかシンプルだと思う
- 同期型のせいか？わからないが、全然パフォーマンスが出ていない
  - これに関しては、現在のプロジェクトの実装の仕方がまずい可能性も高い。
- 生存期間の短いオブジェクトでもクラスを作る
  - 1リクエストパスでしか使わないようなVOクラスは、ListとMapで良いと思う。
  - Node.jsではListとMapしか使ってないようなもので、それでも運用できていた。
  - コーディング速度優先のテスト駆動開発さえできれば、ListとMapでも行けると思う。
- Getter, Setter要らなくないですか？
- Mavenのせいかもしれないが、ディレクトリ構成が不格好
- アノテーションのせいで動作の仕組みがわからずに苦労することがある
  - メソッド前に動くのか？メソッド後に動くのか？とか実装見ないとわからん
  - アノテーションは仕組みがぱっと見でわからんのでダメだと思う
  - [Lombok](https://projectlombok.org/)程度なら良いと思います

### まとめ
---

なんか悪い点に書いたものって、実装次第で全然変えられると思う。

Javaの今までの慣習が邪魔なだけな気がする。

Node.js風のJava開発とかをやってみたら面白いのでは？と思う。
（そういえば、CyberAgentに居るときにPlayFrameworkを使ってNode.js風の開発をしていた人が居た気がする。）

僕としては早く帰るには、速く実装する必要があるので、それが出来る環境にしたいです。
Unity3DゲームエンジンをUbuntu16.04にインストール

Linux用のUnityが開発されていますのでそれのインストール方法について紹介します。
追記(2018/09/29): [Unity Hub beta版をUbuntu16.04で使ってみる](https://qiita.com/pollenjp/items/f18bae4b5c4ea00ea70c) 現在はUnityHub (Beta)というものもありますのでこちらのほうが管理が楽かもしれません。ただ、どちらのやり方も覚えておくと良いでしょう。

今回の環境

- Ubuntu 16.04

# ダウンロード
まずはインストーラをダウンロードします。
以下のサイトでリリース状況を確認できダウンロードできます。
ただ少し分かりづらかったので説明を加えます。

- https://forum.unity.com/threads/unity-on-linux-release-notes-and-known-issues.350256/

このサイトでは2018年6月17日現在、古い順にリリースが並べられています。そこで今回の場合Page２に移動します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/685652ed-553d-aac2-e67f-df6a114973f2.png)

最新版はベータ版であったりするので、そこそこ安定していそうなバージョンを選びます。
ここでは2017.4.4f1を選びました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/3f2a82e0-9044-8a7e-1f44-0f8d6a689cb7.png)

この写真にも写っているように「Official Installer」のリンクが貼ってありますのでリンク先に飛びます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/affdb325-4070-3a6c-b0ae-d5c11d550080.png)

「Linux Download Assistant」をクリックしてファイルをどこでもいいので保存します。

# インストール
インストーラを保存したディレクトリにTerminalで開き実行権限を与えます。

```
$ chmod +x UnitySetup-2017.4.4f1
```

あとはこれを実行すればInstallerが立ち上がります。

```
./UnitySetup-2017.4.4f1
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/57a13dcb-3d96-2a36-49b0-df52468968c1.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/efc7187e-c0c0-987a-c0f4-391f96b13674.png)

ほしいサポートを選択して進みます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/9ca8523a-5b7c-ddf2-b524-b67f535f0d72.png)

ダウンロード場所も特に変更する必要はなく進みます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/5fd20364-df9f-7e2c-4a06-c96620b90485.png)

するとダウンロードとインストールが始まります。

完了するとホームディレクトリに`Unity-2017.4.4f1/`の名前のディレクトリが作られますのでその中にあるファイルを実行します。

```
cd ~/Unity-2017.4.4f1/Editor
./Unity
```

Unityが起動してめでたしめでたしですね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/a08deb58-5f30-4bae-1e2c-58a7e34c1314.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/5271b444-2cf8-0d26-ccb8-51a0675e1a35.png)


## 追記 (2018/09/17)
　現時点ではファイルの編集等はできるのですがゲーム画面のプレイしようとすると謎のコンパイルエラーに見舞われます。これについてはいろんな質問系サイトを見ても明確な解決策は見つかっていない感じだったのでもしコンパイルエラーが出ない事例などあればコメントくださいorz

## 追記 (2018/09/19)
　なんか動いたという人もいるそうです。

## 追記 動作確認済みパージョン
- Unity 2018.2.7f1 Linux Editor downloads (2018/09/28現在)
- バージョン2017系が動かない模様 (2018/09/28現在)
M5Stackでマルチタスク処理を実行する

###目的
M5stackはCPU:ESP32を内臓しており、マルチタスク処理に対応している。
M5stackでマルチタスク処理を行う。


###方法
xTaskCreatePinnedToCore()関数を使うことで実装できる。

```
xTaskCreatePinnedToCore(タスクの関数名,"タスク名",スタックメモリサイズ,NULL,タスク優先順位,
タスクハンドルポインタ,Core ID);
```

###サンプルソース

```
#include <M5Stack.h>
void task0(void* arg) {
  int cnt = 0;
  while (1) {
    printf("task2 thread_cnt=%ld\n", cnt++);
    delay(1000);
  }
}
void task1(void* arg) {
  int cnt = 0;
  while (1) {
    printf("task1 thread_cnt=%ld\n", cnt++);
    delay(1500);
  }
}

void setup() {
  Serial.begin(115200);
  xTaskCreatePinnedToCore(task0, "Task0", 4096, NULL, 1, NULL, 0);
  xTaskCreatePinnedToCore(task1, "Task1", 4096, NULL, 1, NULL, 1);
}

void loop() {
  static int cnt = 0;
  printf("Maintask thread_cnt=%ld\n", cnt++);
  delay(1200);
}


```

実行画面
![Screenshot from 2018-06-16 13:08:13.png](https://qiita-image-store.s3.amazonaws.com/0/73020/a10a3f06-3169-9894-36fb-f3951fc23ee0.png)



###参考：
Docs » API Reference » System API » FreeRTOS
http://esp-idf.readthedocs.io/en/latest/api-reference/system/freertos.html

-ESP32でデュアルコアを使おう！
https://kerikeri.top/posts/2017-06-24-esp32-dual-core/

-マルチタスク・デュアルコアの実験(ESP-WROOM-32)
https://garretlab.web.fc2.com/arduino/lab/esp32_task/index.html
Railsでモデルのupdate_atのみを更新したい場合

 - touchメソッドを使います

```:ruby
user = User.last

user.updated_at
# => Sat, 16 Jun 2018 12:45:43 JST +09:00

user.touch
=> true

user.updated_at
# => Sat, 16 Jun 2018 12:47:03 JST +09:00
# updated_atが更新されている

```

他の値は変えたくないが、更新日時だけ更新したいときに便利!

ちなみに引数で指定すれば`updated_at`以外にも更新できるみたいです、試しに`created_at`を更新してみます。

```:ruby
user.created_at
# => Fri, 15 Jun 2018 17:36:48 JST +09:00

user.touch(:created_at)
# => true

user.created_at
# => Sat, 16 Jun 2018 12:51:04 JST +09:00
# created_atが更新されている
```

いろいろ応用が利きそうですね。

ただこのメソッドはバリデーションしてくれないので、更新する値にバリデーションが必要な場合は注意してください。

## 参考
- https://apidock.com/rails/ActiveRecord/Persistence/touch
VRChatのオンラインなフレンドをPythonで取得する

## 追記（2019/1/25）
VRChat APIを使うためのPythonパッケージ [vrchat-api-python](https://github.com/y23586/vrchat-api-python) を公開しました。
内部的に以下で書かれている処理を行っています。

## 注意 
この記事で使用しているVRChat APIの仕様は非公式なドキュメント (https://vrchatapi.github.io/) に基づくものです。
私が調べた限りではVRChat公式

- https://vrchat.net
- https://vrchat.com
- https://docs.vrchat.com/docs
- https://medium.com/@vrchat
- https://vrchat.groovehq.com/help_center 

では存在自体が言及されておらず、一般ユーザがVRChatクライアントやVRCSDK以外の手段でアクセスすることが容認されているかどうかは不明です。
一応、[APIの仕様について中の人が言及していることもある](https://vrchat.canny.io/bug-reports/p/friends-instances-are-still-not-secure-due-to-world-listing-api-endpoint)ので完全にブラックというわけではないようですが、**下記のコードを実行する際はアカウントの停止措置等のリスクを承知の上でサーバに無理をかけない範囲で行ってください。**

## 背景
VRChatでオンラインなフレンドを確認する場合は

- VRChatクライアント内でフレンド画面を開く
- [公式ページ](https://www.vrchat.net/home/worlds) にログインする

方法がありますが、この記事ではスクリプト的に確認する方法としてPythonでVRChatのAPI (以下VRChat API) を叩いてみます。
VRChat APIでは以下の手順を踏んでフレンドやインスタンス等の情報にアクセスします。

1. `https://api.vrchat.cloud/api/1/config`をGETして`apiKey`を取得 (以下すべてのアクセスに`apiKey`パラメータを使用)
2. `https://api.vrchat.cloud/api/1/auth/user`をGETして`authToken`を取得 (VRChatのユーザ名・パスワードでBasic認証を行う)
3. `apiKey`, `authToken`をパラメータとして目的のAPIにアクセス

---

201/7/8追記:
2.について、[ドキュメント](https://vrchatapi.github.io/#/UserAPI/Login)では`authToken`がレスポンスとして返ってくると書いてありますが、返り値に含まれなくなったようです。代わりに同じものをCookieから取り出すことができます（以下を参照）。

---

以下はこれらの実行例です。

## `apiKey`の取得
```python
import json
import requests

API_BASE = "https://api.vrchat.cloud/api/1"

url = "{}/config".format(API_BASE)
response = requests.get(url)
apiKey = json.loads(response.text)["clientApiKey"] # 2018/6/16時点で "JlE5..." みたいなのが返ってくる
```

## `authToken`の取得

```python
from requests.auth import HTTPBasicAuth

USER     = "your-user-name"
PASSWORD = "your-password"

url = "{}/auth/user".format(API_BASE)
response = requests.get(url, 
                        params={"apiKey": apiKey},
                        auth=HTTPBasicAuth(USER, PASSWORD))
# token = json.loads(response.text)["authToken"] # "authcookie_[UUID]" みたいなのが返ってくる
token = response.cookies["auth"] # (API変更のためCookieからauthTokenを取得、2018/7/8追記)
```

## フレンド一覧の取得
```python
url = "{}/auth/user/friends".format(API_BASE)
response = requests.get(url, 
                        params={"apiKey": apiKey, "authToken": token})
friends = json.loads(response.text)
for f in friends:
    print(f["displayName"]) # オンラインなフレンド一覧を表示
```

---

この他にもワールドやワールドインスタンスの情報も取得できるため、「多くのフレンドが集まっているワールドを一覧表示」といったことも可能です。
Raspberry pi 3 上で、SWITCH SCIENCE BME280 を動かしてみた

# はじめに
Raspberry pi 3の電子工作にハマり、部屋の温度、湿度、気圧を取って遊んでみようと言うことで、「SWITCH SCIENCE BME280」を購入してました。

今回は動かすことメインで！！！

# 構成

- Raspberry pi 3(OS:Raspbian)
- SWITCH SCIENCE BME280 温湿度・気圧センサーモジュール

接続図は以下の通り

![スクリーンショット 2018-06-13 22.22.43.png](https://qiita-image-store.s3.amazonaws.com/0/232494/46bd621b-0f76-9b17-15c7-774c0dac90d4.png)

# 手順

## I2C を有効にする

左上の アイコン　→ 設定　→ Raspberry Pi の設定　を選択すると、画面が起動。
インターフェースタブを選択し、　I2C を有効にし、OKボタンを押す

以下のコマンドで再起動することで、I2Cが有効化します。

```terminal:terminal
$ reboot
```

## I2C 接続できているか確認する

I2C接続のデバイスを以下のコマンドで確認する。

```terminal:terminal
$ sudo i2cdetect -y 1
```

以下の通り、76 と表示されていて、接続が確認できる。
![スクリーンショット 2018-05-27 22.37.35.png](https://qiita-image-store.s3.amazonaws.com/0/232494/f53b2895-2609-ca7e-cee1-558bef77de6a.png)

## サンプルソフトを動作

### ダウンロード方法

SWITCHSCIENCE の github からサンプルソースコードを取得

```terminal:terminal
$ cd (sampleファイルを置くディレクトリ)
$ wget https://raw.githubusercontent.com/SWITCHSCIENCE/samplecodes/master/BME280/Python27/bme280_sample.py
```

### 必要なソフトのインストール

bme280_sample.py 内で、smbus2 のライブラリを利用しているので、
以下のコマンドでインストール。

```terminal:terminal
$ pip install smbus2
```

### 動作確認

以下のコマンドを入力することで、温度、気圧、湿度　を表示する。
温度は少し高めに出ているような気がする。。。

```terminal:terminal
$ python bme280_sample.py 

temp : 27.56  ℃
pressure :  986.88 hPa
hum :  25.52 ％
```

# 今後について
温度、気圧、湿度を クラウドサーバー　に蓄えておき、それらのデータを分析してみたい。


# 参考URL

- [SWITCH SCIENCE社のレポジトリ](https://github.com/SWITCHSCIENCE/samplecodes/tree/master/BME280)
- [ラズベリーパイで温度・湿度・気圧をまとめて取得！AE-BME280でI2C通信](http://deviceplus.jp/hobby/raspberrypi_entry_039/)
gem install・bundle installなしでgemを使ったスクリプトを実行する方法

通常、gemを使うには主に以下の2つの方法を使います。

* `gem install foo`でgemをインストールしてから使う
* Gemfileにそのgemを記述し、`bundle install`でインストールしてから使う

どちらもせずに済ますには、`bundler/inline`を使います。

## `bundler/inline`の使い方

以下は[Timers gem](https://rubygems.org/gems/timers)を使うサンプルです。

```timers.rb
require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'timers'
end

timers = Timers::Group.new
every_five_seconds = timers.now_and_every(1) { puts "Hello!" }
loop { timers.wait }
```

このスクリプトは、Timersを使って1秒ごとに"Hello!"と表示するものです。実行前にgemコマンドもbundlerコマンドを使わず、いきなり、

```console
$ ruby timers.rb
```

と入力すれば実行できます。

このスクリプトのポイントは1行目の`require 'bundler/inline'`と、3行目からの`gemfile`のdo〜endブロックです。`require 'bundler/inline'` とすると、`gemfile`というメソッドが使えるようになります。この`gemfile`メソッドのブロックがGemfileの代わりになります。このブロックの2行でTimersが使えるようになります。

上記のサンプルでは`require 'timers'`を暗黙に実行しています。明示的にさせるようにするには以下のようにします。

```ruby
require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'timers', require: false
end

require 'timers'

timers = Timers::Group.new
every_five_seconds = timers.now_and_every(1) { puts "Hello!" }
loop { timers.wait }
```

5行目の`require: false`によって、暗黙の読み込みをしないようにしています。そのため、8行目の `require 'timers'`を削除して実行するとエラーになります。

## 参考

https://bundler.io/v1.16/guides/bundler_in_a_single_file_ruby_script.html
[AutoHotKey]#Includeに関する覚書

インクルード元：`#Include`って書いてある方
インクルード先：`#Include hoge.ahk`のhoge.ahk
とする。

## 基本
- [\#Include / \#IncludeAgain \- AutoHotkey Wiki](http://ahkwiki.net/-Include)

> \#Include / #IncludeAgainは、スクリプトが実行される前の解析の段階で実行される。
> スクリプトが実行されるときには、あたかも#Includeが書かれたところに指定されたスクリプトファイルの内容が書かれているかのようになる。

つまり、仮想的に単一のスクリプトファイルを生成した上で実行されるということ。

実行される段階では、インクルード先のファイルは存在していない。インクルード元のファイルしか存在しない。

## 組み込み変数`A_ScriptPath`が参照するパスはどこ？
よって、これはインクルード元のスクリプトファイルになる。`A_ScriptDir`とかも同じ。

しかしながら、特に`FileRead`とかで外部ファイルから何かを読み込みたい場合などは、対象ファイルをインクルード先からの相対パスで指定したい場合もあるはず。
そのような場合は、組み込み変数`A_LineFile`によって、**実行中の行が記述されたファイル**のパスを得ることができる。
これを`SplitPath`すれば、インクルード先ファイルが存在するディレクトリのパスも得ることができる。

## Auto-executeセクションとの関係
Auto-executeセクションについては下記を参照。

- [スクリプト仕様 \- AutoHotkey Wiki](http://ahkwiki.net/Scripts#.E3.82.B9.E3.82.AF.E3.83.AA.E3.83.97.E3.83.88.E3.81.AE.E8.B5.B7.E5.8B.95.E3.81.A8Auto-execute.E3.82.BB.E3.82.AF.E3.82.B7.E3.83.A7.E3.83.B3)

> スクリプトが読み込まれると、最初にReturnかExitあるいはホットキーラベルが現れるか、スクリプトの終わりに達するまでが実行される。
> この部分のことを、Auto-executeセクションと呼ぶ。
> 
> ホットキーラベルや#Persistent指令、Lock系キーの固定などで常駐状態にされない場合、Auto-executeセクションが終了したらスクリプトは終了する。

`#Include`を含むスクリプトにおいては、インクルード実行後にこれが判定される。

つまり、Auto-executeセクションにおいて、`#Include`の後に、まだAuto-executeセクションが続く（別の`#Include`も含む）場合、インクルード先ファイルの末尾に`Return`/`Exit`/`ExitApp`を書いてはならない。もちろんホットキーラベルも同様。
**最初の**Return/Exitないしはホットキーが現れた時点で、Auto-executeセクションが終了し、続く処理は行われなくなってしまうのだ。

言い換えれば、インクルード先のファイルにおいては、「Auto-executeセクションで実行されるべき処理」と「Auto-executeセクション以外で実行されるべき処理」を両方書くべきではない。
（唯一許容されるのは、「境目」に該当するファイルということになる。）

よって、望ましい`#Include`の書き方は以下のようになる。

```ahk
; ファイル先頭からAuto-executeセクションが開始

; Auto-executeセクションで実行したい処理を書く
SetTitleMatchMode, 2

; Auto-executeセクションで実行したいファイルをインクルードする
#Include AutoExec1.ahk
#Include AutoExec2.ahk

; Auto-executeセクションの終了（省略可）
Exit

; ホットキー等のファイルをインクルードする
#Include HotKey.ahk
#Include HotString.ahk
#Include SubRoutineLabel.ahk
```
Azure AD B2C with Twitter で Twitter の Callback仕様変更に対応する。

**つい廃** なので Azure AD B2C でもTwitterログインできるようになると嬉しいです！

先日、Twitter の仕様変更が行われ CallBackURL のホワイトリスト運用が開始されました。
具体的には、CallBackURL をちゃんと事前に登録してね！みたいなやつ。

## 情報元

https://twittercommunity.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342

## Azure AD B2C でこれに対応する

で、重要なのが Azure AD 側での対応。

とはいえども、Azure AD の公式ブログに対応するための記事が載っているので参考に実装すればおkでした。
https://blogs.msdn.microsoft.com/azureadb2c/2018/06/13/twitter-login-changes-to-signin-handshake-fix/

以下の内容を CallbackURL に設定してく感じの。

>Correct Format : 	https://login.microsoftonline.com/te/{tenant}/{policyId}/oauth1/authresp

>Example:  https://login.microsoftonline.com/te/myb2ctenant.onmicrosoft.com/b2c_1_policy/oauth1/authresp
一度コミットされてしまった多量のファイルを.gitignoreに追加後Gitから一括削除する方法

Gitレポジトリにすでコミットされてしまった多量のファイルを`.gitignore`に追加して、レポジトリから外した場合一般的に対象フィアルを以下のコマンドで対応します。

```
git rm --cached <file>
```

ただ、フロントエンドアセットやパッケージ依存ライブラリなどが多量にコミットされてしまったときは流石に一つひとつ削除したくないです。

以下の手順でまずすべてのファイルをGitから外して、そして`.gitignore`以外すべて追加し直して、コミットする流れで簡単に対応できます。

```
git rm -r --cached .
git add -A
git commit -am 'Removing ignored files'
```
パスを通す｜Linux（MacOSX,CentOSなど）

『コマンドが見つかりません』こんなエラーがでたら
それはパスが設定できていない（パスが通っていない）のかもしれません。
パスが通っていないとはコマンドを実行する準備ができていないとも言えます。

# 現状確認

以下のコマンドで現在のパスの設定が確認できます。

```shell

echo $PATH

```

# 現在の設定に新たなパスを追加します

以下の記述をホームディレクトリ（/home/ユーザー名/.bash_profile）に追記します。

```shell

export PATH=$PATH:/usr/local/scala/bin

```

もしexport PATH~という記述があったら
今回追加したい:以下の部分を追記してください。

※centosの全ユーザーに反映させたい場合は/etc/profileの最終行に追記するといいようです。

# パスを有効にする
.bash_profileに追記して保存しただけではパスが通りませんので
以下のコマンドで有効にします。

```source.sh

$ source ~/.bash_profile

```


# 余談
コマンドを打つといってもアプリケーションを実行するという意味では
exeファイル（アプリのアイコン）をダブルクリックするのと同じです。
exeファイルがディレクトリにない状態ではエイリアスを作成するのと同様で
コマンドも実体ファイルをどこにインストールするかで
実行できるかできないかが決まります。
よく「ローカルにインストールする」「グローバルにインストールする」と
言われたりしますが、グローバルというのはcentos内のどこからでも実行できる
というようなイメージで、ローカルというのはアプリケーションディレクトリだったり
実行ディレクトリを作ってそのディレクトリにインストールしたコマンドを実行するというイメージです。

# 注意事項
コマンド実行するshellには種類があります。
shellごとに使えるコマンドが違っていたり
インストールされていなかったりということが起こります。
これは1台のmac内にも複数のshellがインストールされているので確認してみましょう。
ターミナルを立ち上げて以下のコマンドを実行してみてください。

```echo.sh

#↓以下のコマンドでインストールされているshellがわかる
$cat /etc/shells

#↓実行した後の出力結果。/bin/の後ろがシェル名
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

```

そして以下のコマンドで現在どのshellを使用しているかということがわかります。

```echo.sh

$echo $SHELL
/bin/zsh

```

ちなみにmacOSの標準shellがmacOS 10.15 Catalinaから
zshに変更されています。（以前はbashだった。現在も切り替えればbash使えます。）

※上記は個人的見解になります。認識に誤りがありましたらご指摘いただければ幸いです。