OmniAICreator/Qiita-1.07M huggingface dataset:
mobxで、非同期処理を扱う

mobxにasyncComputedがないので作ってみた。

```js

const wait = delay => {
  return new Promise(resolved => {
    setTimeout(() => {
      resolved();
    }, delay);
  });
};

class AsyncCommitter {
  requestId = 0;
  commitId = 0;
  async resolve(promise) {
    this.requestId += 1;
    const currentRequestId = this.requestId;
    const value = await promise;
    if (currentRequestId <= this.commitId) {
      return { successed: false };
    }
    this.commitId = currentRequestId;
    return { successed: true, value };
  }
  async run(asyncFunction) {
    return this.resolve(asyncFunction());
  }
}

const asyncComputed = (target, resolvedFieldName, descriptor) => {
  const promiseFieldName = resolvedFieldName + "Promise";
  target.initHandlers = target.initHandlers || [];
  target.initHandlers.push(function() {
    const asyncCommiter = new AsyncCommitter();
    observe(
      this,
      promiseFieldName,
      async ({ newValue }) => {
        const { successed, value } = await asyncCommiter.resolve(newValue);
        if (successed) {
          runInAction(() => {
            this[resolvedFieldName] = value;
          });
        }
      },
      true
    );
  });
  Object.defineProperty(target, promiseFieldName, descriptor);
  delete target[resolvedFieldName];
  computed(target, promiseFieldName, descriptor);
  observable(target, resolvedFieldName, {
    configurable: true,
    writable: true,
    value: null,
  });
};
class Sample {
  constructor() {
    for (const handler of this.initHandlers || []) {
      handler.apply(this);
    }
  }
  someValue = 1000;
  @asyncComputed
  get someValuePlus1() {
    return (async () => {
      await wait(100);
      return this.someValue + 1;
    })();
  }
}
```
Sidekiqを使い始める [翻訳]

この記事は、[Getting Started - github.com/mperham/sidekiq](https://github.com/mperham/sidekiq/wiki/Getting-Started)の翻訳です。

----


# Sidekiqを使い始める

最新バージョン 2019-07-17 編集者 taki

Sidekiqは、最新のRailsアプリケーションでできるだけ簡単に使用できるよう、あらゆる努力を払っています。SidekiqをActive Jobで使用する場合は、[Active Jobのページ](https://github.com/mperham/sidekiq/wiki/Active+Job)をご覧になってください。

## Rails

1. Gemfileにsidekiqを追加する。

```ruby
gem ‘sidekiq'
```

2. ワーカークラスを `app/workers` に追加する。

```shell
rails g sidekiq:worker Hard # will create app/workers/hard_worker.rb
```

```ruby
class HardWorker
  include Sidekiq::Worker
  def perform(name, count)
    # do something
  end
end
```

3. ジョブを作成する。

```ruby
HardWorker.perform_async('bob', 5)
```

`perform` はインスタンスメソッドであるのに対し、`perform_async`はクラスメソッドであることに注意してください。

決められた時刻に実行を開始するジョブを作成することもできます。

```ruby
HardWorker.perform_in(5.minutes, 'bob', 5)
HardWorker.perform_at(5.minutes.from_now, 'bob', 5)
```
Railsコンソールで試している場合は、Springを停止する必要があるかもしれません。

4. SidekiqをRailsアプリケーションのルートディレクトリから実行する。

```shell
bundle exec sidekiq
```

これで完了です。もしワーカー内でActive Recordを利用する場合は、Active Recordのプールサイズを調整する必要があるかもしれません。詳細は[高度なオプション](https://github.com/mperham/sidekiq/wiki/Advanced-Options)をご覧になってください。


## Plain Ruby

[examplesフォルダ](https://github.com/mperham/sidekiq/tree/master/examples) にRails以外からSidekiqを利用するためのいくつかのサンプルコードがあります。 `por.rb` は "Plain Old Ruby" のためのサンプルです。そして、 `sinkiq.rb` SinatraからSidekiqを利用するためのサンプルです。

Sidekiqの概要を動画でもご覧になってください。

[![Getting Started](http://img.youtube.com/vi/bfPb1zD91Rg/0.jpg)](https://www.youtube.com/watch?v=bfPb1zD91Rg&index=1&list=PLjeHh2LSCFrWGT5uVjUuFKAcrcj5kSai1 "Getting Started")
Tech Expert (事前学習) day 1

【学習アウトプット】

初心者のため事足りないものが多々あるかと思いますが、悪しからず…

30歳専業主婦 Tech Expert(プログラミングschool) に挑む。初日のリアルな感想。

でも記載したように、まだまだ試行錯誤です。。。

明日からは目標も定めつつ、勉強内容も分析しながらしっかりアウトプット出来るように取り組んでいきたい。(学習時間もまとめていったほうがいいのかな？)
(この調子だと、事前学習抜けて本コースに差し掛かる頃にようやく慣れてくる？)

今日は「学習に入る前に」と「HTML/CSS」を少しかじっただけになってしまったので、明日はもっと本格的に学習に没頭出来るように頑張ろう！

そのためにも、早く寝よう！w
[CS入門] 講義 #4 テーマ１（計算を知る）：計算の基本要素（計算の原子に当たるものとは）

# やること

[東工大 コンピュータサイエンス入門 講義 #4 テーマ１（計算を知る）：計算の基本要素（計算の原子に当たるものとは）](https://www.youtube.com/watch?v=i_m3uyhvOiM&list=PLqX1hzBNwl2oMJqjuPylcf8aAQFSGCWQr&index=4)

# 基本演算とは？
計算の「原子」に相当するもので、下記の3つをさす。
これさえあれば、コンピュータの計算は十分である。

・繰り返し
・＋1
・ー1

* 「基本演算」（繰り返し、±）を組み合わせると、足し算と引き算ができる。
* 足し算と引き算をさらに組み合わせると、掛け算と割り算ができる（つまり、四則演算）。
* 四則演算を組み合わせれば、「√」「sin」「経路探索」「囲碁、将棋」プログラムの計算もできる。
* つまり、基本演算をうまく組み合わせて、計算を作るのがコンピュータの計算である。
* 基本演算の組み合わせを指示するのが「プログラム」（＝計算の指示書）。
* なお、プログラム（データ）は、メモリに格納されている。


# テーマ1（計算を知る）、まとめ

* コンピュータサイエンスとは、世の中を計算を通して見ること（＝計算世界観）
  「この計算世界観をいかに実現するか？」を追求する学問である。
* すべてを計算化するためには、計算に載せることが必要である。
　そのためには、あらゆる情報を”データ”（自然数）として表し、”計算”（繰り返し、±）として処理しなければならない。
【mysql】データベースを文字コードと照合順序を指定して作成する

mysqlでデータベースを作成する際に文字コードと照合順序をあらかじめ指定して作成するときのメモ



~~~
CREATE DATABASE database_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
~~~


小文字の部分は適宜変更すればOK
[CS入門] #講義03 東工大テーマ（計算を知る）：データは数（データの原子に当たるものとは）

# やること
[コンピュータサイエンス入門 #講義03 東工テーマ１（計算を知る）：データは数（データの原子に当たるものとは）](https://www.youtube.com/watch?v=YfPSa9PCWo4&list=PLqX1hzBNwl2oMJqjuPylcf8aAQFSGCWQr&index=3)

# 1.データは数である
「データ」 = 計算の対象
コンピュータの中ではすべての情報が二進列（０と１の列）で表される。

* 数
* 文字
* 画像
* 音
* 映像
…

### 例で考える

【数】
18 ← 00010010

【文字】
A ← 01100001（=97）
B ← 01100010（=98）
C ← …
      ASCIIという符号法

【画像】
「デジタル化とは、（画像に）方眼紙をあてることである」

* 画像を拡大し、方眼紙を当てると、色の違うマス(ピクセル）が見えてくる。
* 画素1つあたりを「ピクセル」と呼ぶ（30 × 30 = 900ピクセル）PCでは1280 × 800など。

***RGBの発光の粒***
[強さの度合い]
 R：０ 〜 255
 G：０ 〜 255
 B：０ 〜 255

【音】

* 音は「空気密度」の波である。波が伝わっていくのが音。
* 空気密度を時間で区切り、時刻ごとの波の強さを数で表す。
* 例：デジタルサウンドでは、
  1/44100秒刻み（つまり44.1kHz)で、音の量子化をする（秒にする）のが標準的。
[コンピュータサイエンス入門] 東京工業大学 講義 #2 テーマ１（計算を知る）

# やること
東京工業大学 渡辺治教授 コンピュータサイエンス入門の自分用まとめ

[参照：講義 #2 テーマ1（計算を知る）:導入「コンピュータサイエンス入門」](https://www.youtube.com/watch?v=YKFVPBGPLsg&list=PLqX1hzBNwl2oMJqjuPylcf8aAQFSGCWQr&index=2)

# 1. コンピュータサイエンスのこころ
『すべては計算である』

* （１ + 4 ）× 5 = 
* 12と16の最大公約数
* x² + 2xy + y² の因数分解
* 大型旅客機の設計図を作成する
* 遺伝子を解析する
* 銀行のATMの制御
これらはすべて計算とみなす。

さらに言えば、

* 木の成長
* 脳の形成

こういう過程もすべて計算で表すことができる。
というのがコンピュータサイエンスの考え方である。

# 次回予告：

では、そもそも計算とはなんだろう？

* データ（＝計算の対象）の話
* 計算の基本要素の話
[CS入門] 東工大 講義 #1 コンピュータサイエンス入門概要

# 東京工業大学 講義 #1 コンピュータサイエンス入門概要

# はじめに
コンピュータサイエンスの自分用まとめです。

[東京工業大学 講義 #1 コンピュータサイエンス入門概要](https://www.youtube.com/watch?v=sz9r80i3VzA&list=PLqX1hzBNwl2oMJqjuPylcf8aAQFSGCWQr)

# 0. 講義の目標

* コンピュータって何？

* なぜ、どこでも使われているの？
を知ること。

### コンピュータの活用例

1. 台風の動き
2. シミュレーション
3. 各種分析
4. 情報クラウド
5. 各種制御

# 1. 「計算世界観」 〜計算を通して世界を見る〜

コンピュータが上記のように色々な使われ方をするようになったのは、
自然界や人間界を、コンピュータ・計算を通して観ることができてきたからである。
こうした計算を通して世の中を見ることを”計算世界観”と呼ぶことにすれば、
コンピュータサイエンスというのはこの「計算世界観をいかにうまく実現するか？」
これを追求している学問分野である。

# 2. コンピュータに「載せる」とは？
コンピュータサイエンスの人間は、”コンピュータに載せる”という言葉をよく使う。
この意味、コンピュータに載せるとはどういうことか？それを知ることによって、
コンピュータがどういう風に動いているか？どうしてどこでも使われているのか？がわかってくる。
これをただ知識だけではなく、実感をしながら知る。これが講義の目標である。
これを知ることは現代人にとっての常識でもある。

# 3. コンピュータに「載せる」とは？ （続）
コンピュータに載せるとは、
やりたい仕事や表したいことを”計算”を用いて表現し、
コンピュータで処理できるようにすること

### 具体的には
* テーマ1. 計算とは何か？を知る
* テーマ2. コンピュータで処理するとは何か？を学ぶ
これらを講義を通して、学んでいく。

# 4. コンピュータサイエンスの参考書
『思考する機械コンピュータ』Daniel Hillis
『コンピュータサイエンス』渡辺治
ONNXRuntime の Ruby バインディングを動かしてみた

# はじめに

　今となってはそこまで珍しくないかもしれませんが、RubyからDeep Learningの推論エンジンを動してみたので記事にします。
　[ONNX Runtime](https://github.com/microsoft/onnxruntime)とは、Microsoftが中心となって開発しているOpen Neural Network Exchange (ONNX) 用の推論エンジンです。つい先日、Chartkickなどの開発で有名なAndrew Kane氏が、ONNXRuntimeのRuby向けバインディングを作成されました。今日はこれを使ってみます。Ankane氏は、最近[Xgb](https://github.com/ankane/xgb)、[LightGBM](https://github.com/ankane/lightgbm)と相次いでRuby向け機械学習バインディングを制作・公開されており、ONNXRuntimeはその最新作です。

* [ONNX Runtime - the high performance scoring engine for ML models - for Ruby](https://github.com/ankane/onnxruntime)

Ankane氏公式ブログより
> I’m happy to announce it’s now possible to build advanced models in TensorFlow, Scikit-learn, PyTorch, and a number of other tools, and score them in Ruby with minimal friction.

ONNXに変換すれば、だいたいのDeepLearningのモデルはRubyから簡単に呼び出せるようになりそうですね。

# 使ってみた

せっかくなのでVGGとかではなくResNetを動かしてみましょう。ここからmodelをダウンロードできます。

* https://github.com/onnx/models/tree/master/vision/classification/resnet

GUIツールキットにFlammarionを使います。numpyの代わりにNArrayを使います。画像のリサイズ・ピクセル取得は、いろいろやり方があると思うのですが、今回は筆者のブログの通りmini_magickを使用してみました。

```ruby
require 'mini_magick'
require 'numo/narray'
require 'onnxruntime'
require 'flammarion'

SFloat = Numo::SFloat

Flam = Flammarion::Engraving.new

model = OnnxRuntime::Model.new('resnet152v2.onnx')

path = File.expand_path(ARGV[0])
img = MiniMagick::Image.open(path)

def preprocess(img)
  img.resize '224x224!'
  img_data = SFloat.cast(img.get_pixels)
  img_data = img_data.transpose(2, 0, 1)
  img_data = img_data.expand_dims(0)
  mean_vec = SFloat[0.485, 0.456, 0.406]
  stddev_vec = SFloat[0.229, 0.224, 0.225]
  norm_img_data = SFloat.zeros(1, 3, 224, 224)
  norm_img_data.shape[1].times do |i|
    norm_img_data[true, i, true, true] =
      (img_data[true, i, true, true] / 255 - mean_vec[i]) / stddev_vec[i]
  end
  norm_img_data.to_a
end


labels = File.readlines("synset.txt")

input = preprocess(img)
result = model.predict(data: input)

score = result['resnetv27_dense0_fwd'][0]

lab2, sco2 = labels.zip(score).sort_by{|i| -i[1]}[0..9].reverse.transpose

Flam.orientation = :horizontal
Flam.image("#{path}\" height=400") # HTMLに埋め込まれるため変則的な方法で画像サイズ指定
Flam.pane("graph").plot(y: lab2, x: sco2,
          type: :bar, orientation: 'h',
          height: 400, margin: {l: 400})

Flam.wait_until_closed
```

こんな風に表示されました。ちゃんと猫であると判定してくれていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/fd5881c8-4ea0-0842-602e-7e76a4936333.png)

# 感想
```ruby
model.inputs
model.outputs
```
で、何をインプットしたらいいか、何をアウトプットすれば良いかがすぐわかるのが便利です。とても使いやすいです。

# そのほか
ONNXRuntime以外の推論エンジンでMenohというのがありまして、こちらもRuby向けのバインディングがあります。しかし、ONNXRuntimeの登場で、あまり使われなくなるんじゃないかなという気がします。

* https://github.com/pfnet-research/menoh-ruby
* [RubyでONNXフォーマットのDNNの推論を可能にするExtensionを開発](https://qiita.com/colspan/items/36b2e7cf25c6c6a9e534)
* [Menohを使ってRubyでDeepLearningしてみた](https://qiita.com/7rpn/items/eec83e60fa4f695ffa5a)

# 参考資料
* [Score Almost Any Machine Learning Model in Ruby](https://ankane.org/onnx-runtime-ruby)
* [TensorFlow Object Detection in Ruby](https://ankane.org/tensorflow-ruby)
30歳専業主婦 Tech Expert(プログラミングschool) に挑む。初日のリアルな感想。

事前学習初日！ハラハラ緊張しながらいざ出動。モバイルSuicaが非対応なエリアの為、初PASMO定期購入IC。不便…しかもJR定期と比べてとっても割高（悲）だか、JRは極力避けたかったから仕方ない。。これから毎日だからね、少しでもストレスレスな方を優先。

11時15分ごろ渋谷校着
朝礼中
端にある休憩スペースにて簡単な案内を受けて朝礼後空いてる席へ移動して開始
(いゃぁー、私だけだろうか…事前学習だからなんだろうか…大して案内事項自体がないのだろうか…
え？！案内それだけ？！と思った汗　渡された書類を読み上げるだけなら一人でできたぞ？女性はそれよりトイレの場所を伝えてくれた方が安心するぞ？一人キョロキョロ、初日ですアピールせずに済むから。(行きたかった笑)お昼とかみんなどうしているのかききたかったぞ？カリキュラムの進行具合に関する時間配分に関してとか、もうちょっと案内欲しかったぞ？)

電車でメールを読み直していた為、とにかくそこからログインしてそそくさとカリキュラムを潰していけばいいんだな！と自己判断し、気合を入れてみたらどっこい。
事前学習用からスタートしたのだが、、ご親切にも勉強に入る前に

勉強方法

からの案内(・_・)！

推定学習時間合わせて2時間だったが、飲み込みが悪い私は3時間半かかってしまった汗(この先マスマス心配汗)


目標の立て方や学習上で使用するツールのダウンロード方法やマックのショートカットキーの案内だったりがあった（マインドマップ作成ツールで推奨していたサイトは何回試しても起動せず。。辞めました。。）が、個人的に時間を割いてしまったのは多分これ、

“アウトプット”

slackやらツイッターやらブログ（hatena）やらこちらのQiitaを使用してアウトプットすることを推奨している。。

だよなぁー…

アウトプットは大事なのはわかるのだが…

SNSの類全く使用してこなかったため用語がわからなさすぎて、勉強本番前から愕然。。。（こんなことなら事前学習前からならしておいたのに涙）

だがもうはじまってしまったからには仕方ない。完璧を求めず、わかる範囲から着々と頑張ろう。。。
（このページも見出しやら画像やら使うべきなんだろうが。。。ま、今日はいいや。）
使い分け方もいまいちだなぁ。。。

勉強方法や事前準備の案内に推定時間2時間のところ3時間半くらいかけ(しかも“アウトプット”面は毎日使うべきらしいが、全く使いこなせていない)、HTML/CSSも推定時間4時間となっていたが、4時間で3/4くらいやって、夕礼がどんなものなのか体験して、18時半頃に切り上げ。
居候先の生活も安定するまで2−3日は時短でもともと切り上げようと思っていたのだが…
推奨時間にペース全くが追いついてない！！ヤバイ(-_-)（汗）
HTMLは事前学習前に自己流に少しかじって予習していたつもり。なのに遅れが。。。という事実でなおショック。。。全く触れていないカリキュラムがすごく不安です。。。
期間中4日ほど休みをはさみたいと思っているため事前学習で前倒しにして頑張ろうと思っていたのに、唖然…

But！！まだ初日だ！

こんな私でも最後までやりきった！！

と、誰かの励みになるよう、死物狂いで、(けど身体も労りながらw)頑張って達成します！！


他に気付いた点としては、
カリキュラム内に動画があったので、イヤホンあったほうが良いっぽい。(私持参してなかった（汗）)てか、メンターじゃなくてイヤホンマイクで何やら問い合わせしてた人がチラホラいたなぁー？
それと、テーブルにチョコとかおいている人いて、「私も明日からもってこよ。」と決意。(飲食OK)帰り買って帰りました。

それと、まだ勝手がわからないけど、勉強しながらチョクチョク要点を自分なりに書き出しながら復習をしたほうがいいのかも。(気がするわけじゃなくて、推奨されてたのかも？笑)
夕礼で学んだことを2分でまとめて1分でシェアをするっていう時間が設けられていますが、そこで初めて一日の復習をしようとしたら、まっっっったく何も思い浮かばず、テンパりました苦笑　記憶力全く鍛えられていません（汗）
それに合間合間でまとめながら勧めたほうが、一日のまとめブログも作成しやすいんだろう。。
明日やってみようと思う。
【Kotlin】日付文字列をUnixtimeに変換する方法

APIにパラメーターとして送るときなど、Unixtimeに変換したい場合があると思います。
今回は文字列の日付をUnixtimeに変換する方法を紹介します。

# 手順
画面表示に使うなどした、日付の文字列があるとします。

```kotlin
val formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日")
val str = LocalDate.now().format(formatter) //"2019年9月1日"

binding.textView.text = str // 画面に表示する
```

##1.  `String` → `LocalDate`の変換
`2019年9月1日`から`2019-09-01`に変換します。

```kotlin
val localDate = LocalDate.parse(str, formatter) // 2019-09-01
```

##2. `LocalDate` → `ZonedDateTime`の変換
`2019-09-01`から`2019-09-01T00:00+09:00`に変換します。

```kotlin
val zonedDateTime = localDate.atStartOfDay(ZoneOffset.ofHours(+9)) // 2019-09-01T00:00+09:00
```

* `ZonedDateTime`はタイムゾーンごとの時間付きの日付を扱うクラス
* JST（日本標準時）にしたいので、引数に`ZoneOffset.ofHours(+9)`を渡す
* UTC（協定世界時）にしたい場合は、引数に`ZoneOffset.UTC`を渡す

##3. `ZonedDateTime` → `Unixtime`の変換
`2019-09-01T00:00+09:00`から`1567263600`に変換します。

```kotlin
val unixTime = zonedDateTime.toEpochSecond() // 1567263600
```

* 上記`unixTime`の型は`Long`なので、必要に応じて`Int`に変換する
* 無事Unixtimeを取得できました🎉

# まとめ
文字列の日付をUnixtimeに変換するには
`String` → `LocalDate` → `ZonedDateTime` → `Unixtime(Long)`
と何度も変換をおこなう必要があり、ちょっと面倒でした。（もっと簡単なやり方があれば教えて下さい:pray:）

最後にコードをまとめておきます。

```kotlin
private fun getUnixTime(): Int {
    val formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日")
    val str = LocalDate.now().format(formatter)
    val localDate = LocalDate.parse(str, formatter)
    val zonedDateTime = localDate.atStartOfDay(ZoneOffset.ofHours(+9))
    return zonedDateTime.toEpochSecond().toInt()
}
```

こんな感じで拡張関数にしておくと便利です。

```kotlin
fun String.toUnixTime(formatter: DateTimeFormatter): Int {
    val localDate = LocalDate.parse(this, formatter)
    val zonedDateTime = localDate.atStartOfDay(ZoneOffset.ofHours(+9))
    return zonedDateTime.toEpochSecond().toInt()
}
```

# 参考
[【LocalDate/LocalDateTime】Java8以降で秒単位またはミリ秒単位のUnixTimeを取得する方法まとめ【EpochSecond/EpochMilli】 | Blogenist – ブロゲニスト](https://blogenist.jp/2019/01/30/7571/#UnixTime-2)
ARで空間を共有するには……

# 自己紹介
sadaと申します
# はじめに
HoloLens複数台とか、スマホ複数台とかで同じ場所で同じものを見れるようにしたいですよね？
でもどうするの？
というのを解決するお話です。
# まずそもそも
空間の共有を実装する前に知っておかなければならないことがあります。
**座標系**のお話です。
## Unityにおける座標
~~多分知ってる人多いと思うけど~~
### ワールド座標
空間のどこかを原点にして**その世界のたった一つの原点**を決めます。
その座標を元に全てのオブジェクトの位置が決まります。
この座標を元にオブジェクトを配置していくことになります。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/0a0d155b-dc6c-9d79-b0e2-419dd986cae3.png)
### ローカル座標
ローカル座標はオブジェクトの位置と向きを基準とした座標系です。
オブジェクトごとに座標があるので一つとは限りません。
原点は親のオブジェクトのワールド座標の位置が原点となります。
また、UnityのインスペクターのTransformは**ローカル座標系**であるので注意！![図10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/d2e8243c-f50b-cf7d-93f6-6b2f615407eb.png)
![図２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/9b848e1b-e681-31ab-517c-069dfacb2f57.png)

## ARにおける座標
ARKitやHoloLens等の自分が動ける、マーカーレスのAR全般で共通の座標系になっています。
それは**アプリを起動した時**にワールド座標系が決まります。
まずワールド座標の原点は**アプリを起動した時の端末の場所**
が原点になります。
また、	
Y軸の正の方向は起動時のジャイロで計測した天井の方向
	X軸の正の方向はYの正の方向に頭があると仮定したときの右手の方向
	Z軸の正の方向はYの正の方向に頭があり、Xの正の方向に右手があると仮定した時の正面の方向


が何も設定を変えない場合の軸の方向となります。

普通にスマホを構えるとこうなります。
![図３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/28c88682-3bb3-97e1-a7d9-ad30fe78da17.png)


下に向けて起動をした場合、ひっくり返して起動した場合は少し違いますが、
おおよそほとんどの場合自分の体を基準に右がX軸、上がY軸、前がZ軸となります。

### ここで大事なのは
起動した場所が原点となるので、原点が端末ごとに違うと言う事です。
空間を共有する際に原点が違うと言うのは致命的な問題です。
例えば次のようにに現実の場所が違うにも関わらずアプリの中のWorld座標が同じになっています。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/e0652e72-b739-0562-ee10-6ed1d8531ad2.png)
このような事を解決するためには**原点を合わせる**必要があります。
どうにかして原点を現実空間上の同じ場所に設定ができればAR空間を共有できます。
# 原点を合わせるには
おおよそ３つくらい方法がります
## その１ 起動位置をあわせる 
ある意味一番簡単な事です。アプリを起動する位置が原点になるので起動する場所を同じ場所にすれば原点が同じになります。
しかし、わざわざ同じ場所で起動をする必要がある上に起動直後は空間がまだ不安定であるためズレが起こる事が多いです。
## その２ マーカートラッキングで行う
ARKit1.5で画像のマーカーを検出してその画像がある場所にオブジェクトを生成ができるようになりました。
![図10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/a298f1d7-533e-2ec3-29da-bbd4a47f4704.png)
また、任意のTransformを与えることによりその場所を原点にすることができるようになりました。
この２つを組み合わせて現実世界のとある場所にあるマーカーを検出すると
その場所をWorld座標の原点にするということができます。
こうすることにより同じアプリを起動して少し離れた場所で起動してもマーカーを検出さえすれば現実空間の同じ場所にオブジェクトが配置できます。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/a88fceec-7efd-b4ec-dd77-99f4852e2045.png)
### ARKit以外での方法
ある座標を空間の原点にするという機能はARKitでしか使えないのでARCore,HoloLens等ではマーカーから生成されたオブジェクトをすべてのオブジェクトの親オブジェクトにするという方法を使います。
こうすることによってすべてのオブジェクトがマーカーの座標からの相対座標となるので実質的にマーカーの座標がワールド座標の原点となります。
## その３ ARWorldMapを使う（ARKit以外にも類似機能あり)
ARkit2.0から追加されたARWorldMapという機能を使うとARKitで取得した空間情報をもとにして位置の共有ができるようになりました。
他の人とだいたい同じような場所で起動すればマーカーも必要なくて楽だと思いますよね？
これを使うためには

-  一度取得した空間情報をサーバ等からもってきてそれを使う
- 空間情報を複数人で送り合う

といったようなことが必要であったりして~~結構めんどくさい~~。
CloudWatch Eventについての整理・備忘録

# 目的

CloudWatch Eventのついての自分向け備忘録


# 用語・概念の整理

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40692/b2edab62-6cbf-fe73-9676-8269f2fca3d7.png)


- イベント
  - AWS環境の状態変化
  - AWSリソースは状態が変化した際にイベントを生成する
  - リソースの変更だけでなく、Cronのように特定の時刻などを指定してイベントをトリガーすることもできる
- ルール
  - イベント振り分けるためのルール
  - 発生したイベントがルールに合致した場合はルールにしたがい、イベントをターゲットに振り分ける
- ターゲット
  - ターゲットは振り分けられたイベントを処理する。

# イベントパターン

イベントパターンがいわゆるルールの実態。
下図のようなイベントパターンの場合を考えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40692/a88f473f-c291-ec5e-532a-b2b9e00eb9f4.png)


このようなイベントパターンの場合、
イベントパターンのプレビューに書いてあるように、

1. イベントの発生元が`CodeBuild`
2. イベントの種類が`CodeBuildのステート変更`
3. ステートとしては変更後の状態が成功または失敗

の場合にのみ、ターゲットに対するイベントの振り分けを行います。


配列で記述されている場合は原則としてORで扱われます（そりゃそうだ）。

サンプルイベントは、イベントが通知される場合のメッセージの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40692/26fd5085-d1ff-a458-a41e-40cb78d844e8.png)


Lambdaをターゲットとして用いる場合はこのメッセージがそのまま`event`に入ってきます。

```python
def lambda_handler(event, context): # 個々のeventに上図の内容がdist形式で含まれる。
    処理内容
```

どうやらサンプルイベントに含まれる属性はイベントパターンとして指定できる内容の模様です。

たとえば、イベントパターンとして**CodeBuildのhogeプロジェクトのみを指定したい**場合は、以下のようにカスタムイベントパターンを指定します。

```json
{
  "source": [
    "aws.codebuild"
  ],
  "detail-type": [
    "CodeBuild Build State Change"
  ],
  "detail": {
    "build-status": [
      "SUCCEEDED",
      "FAILED"
    ],
    "project-name": [
        "hoge"
    ]
  }
}
```

`detail`の下に`project-name`キーをおいては配列の中で、対象となるCodeBuildのプロジェクトとなるhogeプロジェクトを指定しています。

# イベントのソースとして使用できるAWSサービス

[サポートされている各サービスからの CloudWatch イベント イベントの例](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/EventTypes.html)

# ルールのターケットとして使用できるAWSサービス

ほとんどの場合はLambdaやSNS、SQSになりそうですが…

2019年8月末時点では以下のようなものがターゲットとして利用できるようです。
最新のリストは、[Amazon CloudWatch Events とは](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html)にあるようです。

- Amazon EC2 インスタンス
- AWS Lambda 関数
- Amazon Kinesis Data Streams のストリーム
- Amazon Kinesis Data Firehose の配信ストリーム
- Amazon CloudWatch Logs のロググループ
- Amazon ECS タスク
- Systems Manager Run Command
- Systems Manager オートメーション
- AWS Batch ジョブ
- Step Functions ステートマシン
- CodePipeline のパイプライン
- CodeBuild プロジェクト
- Amazon Inspector の評価テンプレート
- Amazon SNS のトピック
- Amazon SQS キュー
- 組み込みターゲット: EC2 CreateSnapshot API callEC2 RebootInstances API call、EC2 StopInstances API call、および EC2 TerminateInstances API call。
- 別の AWS アカウントのデフォルトのイベントバス



# まとめ

このように、CloudWatch Eventを活用することでさまざまなイベントを利用して後続処理へのつなぎとできます。
git-svnでリポジトリを移行しつつgit-lfsを使用する方法について

Subversionで開発中のUnityプロジェクトをGitHub管理に移行するにあたり、git-svnを使っての移行でハマったので、今後のためにも書き残しておこうと思います。

#参考にさせていただいたサイト
git-svnとgit-lfsについての情報がなかなか見当たらなかったので、下記のページにはとても助けられました。多謝。

###Qiita内
- [SVN から Git(GitHub) へ移行した話と手順まとめ](https://qiita.com/hidekuro/items/4727715fbda8f10b6b11)
- [Git LFSの導入方法](https://qiita.com/takish/items/4b397caa5549a39a8194)
- [itHubに多数のファイル群をpushする際、RPC failed; curl 55 SSL_write() returned SYSCALL, errno = 32 が発生しエラー終了](https://qiita.com/coldsleep6666/items/423286d8d157a835a971)
- [【Git LFS】OpenCV for Unityをpushしようとして怒られた人が見るページ](https://qiita.com/nkjzm/items/89ede8aa10fad30937b4)

###Qiita外
- [Gitでpull or pushしようとしたらfatal: The remote end hung up unexpectedlyってエラーが出た話【エラーで学ぶ英語】](https://ynwa0826.com/2019/02/01/git%E3%81%A7pull-or-push%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89fatal-the-remote-end-hung-up-unexpectedly%E3%81%A3%E3%81%A6%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E5%87%BA/)
- [GitHub リポジトリに大量のファイルを一括登録する方法](https://sekika.github.io/2016/06/03/github-many-files/)

#発生した問題
以下ハマりポイント。

- いくつかのファイルが100MBオーバー → LFS使おう！
- バイナリファイルが比較的多め → LFS使おう！
- 全体としては2.5GBほどのプロジェクト
- 手順通りに「git svn clone」でコミットしようとすると、転送量が大きすぎるために接続エラー（error: RPC failed）が発生。

#解決までの手順
今回の作業環境はMacですが、理屈としてはWindowsでも通用するかと。

###1. とりあえずリポジトリ作る
GIT側のリポジトリは空っぽのものを作ります。そうしないと競合起こすので。

```
mkdir HOGEHOGE
cd HOGEHOGE
git svn init --prefix=svn/ SVN_REPO_URL
git svn fetch
#"git clone --prefix=svn SVN_REPO_URL" でもOKです。
#fetchした後にローカルリポジトリを操作すると、その後のデータが展開されないという挙動だったので、エラーが出ない状態ならcloneでも良いかと。

git remote add origin GIT_REPO_URL
git lfs install --force
git lfs track *.jpg *.tga *.fbx *.assetbundle *.psd *.hdr *.ttf *.mdb *.mp3 *.ogg *.png *.pdf *.zip *.bundle *.otf *.wav *.bmp *.pdb *.a *.acb *.awb *.dll *.exr
```
trackはLFSに置きたいものを適当に設定。

###2.LFSに置きたいファイルについて、管理履歴から除外

trackを行った際に .gitattributes が生成されているので、LFS管理にするファイルリストを生成します。面倒なのでファイルにまとめて自動作業化。
→ migrate コマンドあんじゃん！！！！


###3.コミットログごとにリモートリポジトリにコミット
この部分の情報がなかなか見つかりませんでした。
ローカルリポジトリに記録されたコミットIDを指定して順番にコミットしていくことで、転送量エラーが置きないようにします。
（ただしSVN時代に大きいコミットをしていた場合はどうしようもないので諦めるしか無い？）

```
for i in $(git log | grep ^commit | cut -b 8- | tail -r); do
  git push -u origin ${i}:refs/heads/master ;
done 
```
#実は

ここまで書いておきながら、Gitの管理履歴から除外するところまでしか処理が終わっていないので、無事に移行されたのかは、まだわかりません！
Docker + PostgreSQLでSSL対応

# 目的
自分用のメモとして記事に残す。

# 検証環境
```:VPS

$ cat /proc/version
Linux version 3.10.0-957.1.3.el7.x86_64 
$ docker -v
Docker version 18.03.1-ce, build 9ee9f40
$ docker-compose -v
docker-compose version 1.11.1, build 7c5d5e4
$ psql -V
psql (PostgreSQL) 11.4 (Debian 11.4-1.pgdg90+1)
```

# ツール
* PgAdmin 4.2
* WireShark 2.4.0

# docker-compose.ymlの設定
```
version: '2'
services:
    postgres:
        image: postgres:11.4
        container_name: postgres11.4
        ports:
            - 5432:5432
        volumes:
            - ./docker/postgres/init.d:/docker-entrypoint-initdb.d
            - ./docker/postgres/pgdata:/var/lib/postgresql/data
        environment:
            POSTGRES_USER: test
            POSTGRES_PASSWORD: test
            POSTGRES_INITDB_ARGS: "--encoding=UTF-8
```

# SSL接続前(Digest認証)
SSL接続前後のパケットの違いを比較するため、
WireSharkでパケットを確認する。
![Digest認証(加工後).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222289/28f1eb3a-1dd2-4e04-f3ca-e6ad63c8517d.png)

# SSL接続
## 証明書作成
１．Dockerのコンテナにアクセスし、証明書を作成するディレクトリに移動

```
$ docker exec -it [コンテナID] bash
$ cd /var/lib/postgresql/data
``` 

２．秘密鍵、証明書発行要求、証明書を作成

```
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 36500 -req -signkey server.key < server.csr > server.crt 
```

３．作成したファイルの権限を変更

```
$ chown postgres:postgres server.*
$ chmod 600 server.key
```

## PostgreSQLの設定ファイルを変更
１．SSL接続の設定を追加

```:pg_hba.conf
# TYPE  DATABASE   USER       ADDRESS            METHOD
# IPv4 local connections:
host    all        all        127.0.0.1/32       md5
hostssl all        all        0.0.0.0/0          md5 ←追加
```

２．SSLを有効化

```:postgresql.conf
# - SSL -

ssl = on ←コメント解除
```

## 設定を有効化
Dockerのコンテナから抜けて、再度コンテナを立ち上げる。

```
$ docker-compose down
$ docker-compose up -d
```

## パケット確認
WireSharkでパケットを確認し、SSL(TLS)接続していることを確認する。
![SSL認証(加工後).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222289/be72ecef-e6b3-6057-8b1e-7bc41d107bec.png)

# 参考サイト
以下の記事を参考にさせて頂きました。
[PostgreSQLを自己証明書でSSLに対応する](http://shinsuke789.hatenablog.jp/entry/2017/10/17/100000)
home brewを使ってインストールしたdocker-syncにfishでpathを通す

## パスの通し方

今まで`Ruby`のインストールには`rbenv`を使ってたんですが、最近は`Docker`を使ってるので、MacBookの新調をきっかけに`rbenv`をやめて、`homebrew`でシステムインストールしました。`homebrew`でインストールした`Ruby`を使うには、`Ruby`と`gem`それぞれに対してパスを通してあげないといけないみたいです。
僕は`fish`を使ってるのでこんな感じです。

```fish:~/.config/fish/config.fish
set PATH /usr/local/lib/ruby/gems/2.6.0/bin /usr/local/opt/ruby/bin $PATH
```

`bash`の人はこんな感じでしょうか。

```sh:~/.bashrc
export PATH=$PATH:/usr/local/lib/ruby/gems/2.6.0/bin:/usr/local/opt/ruby/bin 
```

- `/usr/local/opt/ruby/bin`
  - `Ruby`のパス
- `/usr/local/lib/ruby/gems/2.6.0/bin`
  - `gem`のパス

です。

## 詳細

`homebrew`でシステムインストールすると言っても、`homebrew`をインストールするとMacデフォルトの`Ruby`とは別に`Ruby`がインストールされるみたいです。

```fish:Terminal
><((("> brew install ruby
Warning: ruby 2.6.3 is already installed and up-to-date
```

まずハマったのがここなんですが、`Ruby`のバージョンを確認すると`homebrew`でインストールしたものとは異なりました。

```fish:Terminal
><((("> ruby --version
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
><((("> which ruby
/usr/bin/ruby
```

このままではデフォルトの`Ruby` を参照しているのでパスを通してあげないといけないみたいです。

```fish:~/.config/fish/config.fish
set PATH /usr/local/opt/ruby/bin
```

```fish:Terminal
><((("> source ~/.config/fish/config.fish
><((("> ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
```

一件落着かと思いきや、確かにインストールしたはずの`docker-sync`に対してもパスが通ってません。

```fish:Terminal
><((("> gem install docker-sync
Successfully installed docker-sync-0.5.11
Parsing documentation for docker-sync-0.5.11
Done installing documentation for docker-sync after 0 seconds
1 gem installed
><((("> docker-sync start
fish: Unknown command docker-sync
```

`gem`は`gem`でパスを通してあげないといけないみたいですね。

```fish:~/.config/fish/config.fish
set PATH /usr/local/lib/ruby/gems/2.6.0/bin /usr/local/opt/ruby/bin
```

これで本当に解決です。

## 余談

なんとなく、ほんの1年前まで「パスを通す」の意味もわからなかったことを思い出しました。
こんな記事でも誰かの参考になればいいなと思います。
もしわからないことあったらコメントとかで聞いてください。
間違いとかも指摘してもらえたらと思います。

それにしてもカスタマイズに時間が取られすぎてやりたいことに手がつけられません。。。

## 参考

[StackOverflow](https://stackoverflow.com/questions/6482738/installing-ruby-gems-not-working-with-home-brew)
ネットワーク入門

#ネットワークレイヤー理解
![スクリーンショット 2019-09-01 0.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/a8b9565c-8b97-a87c-3719-999c93540741.png)

##OSI参照モデル
・第7層｜アプリケーション層｜利用者間のデータの形式や内容の取り決め
・第6層｜プレゼンテーション層｜送受信するデータの文字やコード形式、暗号化、圧縮などによるデータ表現形式の取り決め
・第5層｜セッション層｜通信開始や終了など、利用者間で会話を正しく行うための、回線の接続、切断などの制御方式の取り決め
・第4層｜トランスポート層｜通信網の違いを九州し、高信頼性で経済的な通信機能を実現。伝送路の天気誤りの検出や訂正の制御を規定
・第3層｜ネットワーク層｜通信網に置いて中継や経路の選択を行い、端末間にネットワークサービスを提供
・第2層｜データリンク層｜データが正しく伝送されるように、伝送誤りの検出、同期の取り方、再送の制御方法を規定
・第1層｜物理層｜端末を通信回線へ接続するためのコネクタ形状や、ビット伝送のための電気的条件、物理的性質を規定

##TCP/IPモデル
・アプリケーション層
・トランスポート層
・インターネット層
・ネットワークインターフェイス層

#中継装置理解
電子信号を中継する装置
・ブリッジ、L2スイッチ
　・MACアドレスを参照して、データを中継する
　・スイッチがついた延長コードのようにON/OFFで宛先のPCだけにデータを中継する
・ルーター
　・LANを接続するための機器で、宛先IPアドレスを参照して、経路を決定する。
　・IPアドレスと宛先の対応表をもつ
・L3スイッチ
　・LANを接続するための通信機器でL2スイッチから派生したもの
　・ルーターとL3スイッチの違い
　　　　｜ルーター｜L3スイッチ
　　制御｜ソフトフェアまたはハードウェア｜ハードウェア
　　速度｜低速〜高速｜高速
　　ネットワークの規模｜小規模〜大規模｜大規模
・ゲートウェイ
　・LANとインターネットなど異なるネットワークの通信を可能にするためのデータ返還などを行う。

■端末情報
　MACアドレス｜NIC(network interface card)の番号
　IPアドレス｜通信相手の住所
　ポート番号｜通信相手のPC上のアプリケーション番号

#各種プロトコル理解
##アプリケーション層のプロトコル
　HTTP(Hyper Text Transfer Protocol)｜インターネット閲覧のためのプロトコル
　HTTPS(SSL(Secure Sockets Layer/ TLS(Transport Layer Secure)
　FTP(制御用とデータ用でポート番号が異なる)
　SMTP(Simple Mail Transfer Protocol)｜メールを送信するためのプロトコル
　POP3(Post Office Protocol version3)｜メールを受診するためのプロトコル。サーバーにあるメールをパソコン等の端末にダウンロードして、端末上でメールを管理する仕組み
　IMAP4(Internet Message Access Protocol 4)｜メールを受信するためのプロトコル。サーバーにあるメールをパソコン等の端末にはダウンロードせず、サーバー上でメールを管理する仕組み。
　MIME(Multipurpose Internet Mail Extensions)｜メールで画像や音声なども扱うためのプロトコル

　DHCP(Dynamic Host Configuration Protocol)
　　IPアドレス自動設定してくれるサーバーをDHCPサーバー
　DNS(Domain Name System)
　　ホスト名(ドメイン名)とIPアドレスを対応させる
　　DNSとは？ドメイン名とIPアドレスの対応表を持っており、外部からの問い合わせに答える。
　クライアント側は1024以降のポートが利用される。

##トランスポート層のプロトコル
　TCP(Transmission Control Protcol)｜信頼性の高いデータ転送を行うためのプロトコル。転送エラーの場合、データを再送する。
　UDP(User Datagram Protocol)｜信頼性を保証しない代わりに負荷が軽く高速に動作する。1対多の通信で使用される

##インターネット層のプロトコル
　IPv4(Internet Protocol)｜IPアドレス、サブネットマスク(ホストアドレス)｜
　　特別なホストアドレス｜ネットワークアドレス(ホストアドレスが全て0)、ブロードキャストアドレス(ホストアドレスが全て1)
　IPv6｜IPアドレス32ビット→128ビットに拡大
　　　　16進数を利用している
　IPアドレスを効率よく使う仕組み
　　・グローバルIPアドレス｜インターネット上で一意なIPアドレス
　　・プライベートIPアドレス｜LAN内で一意なIPアドレス
　　・NAT(Network Address Translator)｜グローバルアドレスとプライベートアドレスを変換する技術のこと
　　・NAPT(Network Address Port Translator)｜ポートを追加することでグローバルアドレスが1つでも複数のホストがインターネットに接続できる→IPマスカレード
　ARP｜IPアドレスからMACアドレスを導き出すためのプロトコル
　　　　IPアドレスは知っていても最終的にデータを転送する先はMACアドレスで判定している
　　　　ARPテーブルをマシンが持っていることが多い

##ネットワークインターフェイス層のプロトコル
　イーサネット｜有線LAN
　　CSMA/CD｜伝送路の空きを見つけてデータを送信する
　　複数の端末が同時に送信してデータが衝突した場合、データ通信を中断し、ランダムな時間を待ってから通信を再開する。　　　　　　　　

#安全に通信を行う仕組み
　FW｜ファイアウォール｜外部からの不正な通信を遮断
　DMZ(DataMilitarized Zone)｜社内のネットワークとインターネット間に設置する公開エリア
　プロキシサーバー｜社内のPCの代わりにインターネット接続を代理で行うサーバー。インターネットから社内のPCを隠してくれる。
HTML/CSS関連の参考URL

# HTML/CSSについて参考にしたWebサイトのメモ
個人用のメモです。
僕が初学者なので、初学者の人が読んでわかるリンクを載せています。
日々更新します。
世の中に発信してくれている人達のおかげで僕もコツコツ作品作れます。
ありがとうございます。

- *タグについて*

[https://html-coding.co.jp/annex/dictionary/html/](https://html-coding.co.jp/annex/dictionary/html/)

- *CSSで要素を横に並べる*


[https://qiita.com/plum_shiga/items/40271059497488d21495](https://qiita.com/plum_shiga/items/40271059497488d21495)

- *クリックで要素を増やしたい*

[https://joyplot.com/documents/2016/11/21/add-tag-dom/](https://joyplot.com/documents/2016/11/21/add-tag-dom/)

- *クリックでinput typeの要素を増やしたい*

[https://pgmemo.tokyo/data/archives/540.html](https://pgmemo.tokyo/data/archives/540.html)

- *innerHTMLで要素を増やしたい*

[https://www.sejuku.net/blog/26442](https://www.sejuku.net/blog/26442)

- *JavaScriptで特定のタグが存在するかをtrue/falseで確認したい*

[https://qiita.com/mitsuhiro_K/items/7d5cef1f4316c2080fa7](https://qiita.com/mitsuhiro_K/items/7d5cef1f4316c2080fa7)

- *特定のタグにclassを追加したい*

[https://connect-solution.net/jp/2018/05/22/divタグをjavascriptにて追加クラス指定あり/](https://connect-solution.net/jp/2018/05/22/divタグをjavascriptにて追加クラス指定あり/)
PHPのmail関数でメールを送信する。


# PHPのmail関数を用いて任意の文字コードで送受信を行う方法。

***メール送信を行う際、特定の情報は7bitの文字列にエンコードする必要がある。***

(1)メールタイトル
(2)差出人の名前

***まずは、メールタイトルが全メールプラットフォームで文字化けしないようにエンコーディングする。***

```php

<?php
$to = "sample@sample.bz";

// メールのタイトルは7bitでの送信が必要になる。
$title = "これはめーるたいとるです。これはメールタイトルです。";
// 7bitとして扱えるようにbase64エンコードする
$title = base64_encode($title);
// メーラーに7bitで転送していること、しかし元の文字列は
// UTF-8で既にbase64エンコしていることを教えてやる必要があるので
// 以下のようなフォーマットにする
$title = "=?UTF-8?B?{$title}?=";
// "=?[文字エンコーディング]?[B(base64)あるいはQ(Quoted-Printable)]?

$senderName = "株式会社 メールを文字化けなしに送信する会社";
// 送信元の名前を7bitとして扱えるように修正
$senderName = base64_encode($senderName);
$senderName = "=?UTF-8?B?{$senderName}?=";
// "=?[文字エンコーディング]?[B(base64)あるいはQ(Quoted-Printable)]?

// メール本文は、メールヘッダーの項目によってエンコーディングを調整する必要がある
// Content-Type: text/plain; charset=(UTF-8|SHIFT-JIS|EUC-JP)など
// Content-Transfer-Encoding: (7bit|8bit|base64|quoted-printable)など
$body = "UTF-8で記述したメール本文を送信";
// 今回は、メール本文をbase64_encodeして送信してみる。
$body = base64_encode($body);

// 以上の設定から下記のメールヘッダーが想定される。
$mailHeaders = <<< EOF
From: {$senderName}<test@dummy.com>
Reply-To: test@dumy.com
Return-Path: test@dummy.com
X-Mailer: X-Mailer
MIME-Version: 1.0
Content-Type: text/plain;charset=UTF-8
Content-Transfer-Encoding: base64 

EOF;
// Content-Type: メール本文はUTF-8でエンコードされる
// Content-Transfer-Encoding: ただし、送信時はbase64化する


$res = mail($to, $title, $body, $mailHeaders);

var_dump($res);

```



以上で送信処理を行ってみる。

すると無事に送信及び受信できているのがわかる。


## メールヘッダーのFromおよびメールタイトルについて

***https://secure.php.net/manual/ja/function.mail.php#Hcom108669***
phpの上記ページのマニュアルに詳しい。

以前は、メール本文も7bitで送ることがあらゆる環境にたいして望ましい
エンコーディングだったかもしれないが、現在はUTF-8で送信しても全く問題ないため
メールヘッダおよびタイトルのみに注意すれば、メール本文に致命的な不具合は発生しないと思われる。
コードレビュー時に気をつけていること

最近、物忘れが激しくなってきて、具体的なことを思い出すのに時間がかかる（笑）

なので、具体的なことをメモっておく。

コードレビュー時に気を付けるポイント。

# コードレビュー時に気を付けるポイント。
## 必須でみること
### 言語のバージョンに適した書き方をしているか？
Java7以降なら、try with resourceを使って書いているか？
Streamを使って書いているか？
など。

新しい書き方って、従来の問題点を改善するため生み出されているから、使ったほうが便利だと思っています。
学習コストとの兼ね合いはありますが。

### コメントが適切か？
リーダブルコードの受け売りですが、パッとソースを見てわかることは、コメントで書く必要は無いと思っています。
ソースで表現しづらい、部分を補足としてコメントで書いたほうが、より分かり易いソースと思っています。

### 例外が握りつぶされていないか？
発生した例外が、ログを出さず、呼び元にも返さず、握りつぶされていないか？は確認します。

### 同じ処理が点在していないか？
共通化ですね、同じ処理が2回以上出てきたら、共通化したほうが良いと思ったりします。

### 無駄な処理をしていないか？
呼び元で、マスタを参照して、呼び先で、またマスタ参照したりしてたら、1回でいいじゃん！って指摘します。

### ぱっと見、分かり易いか？
抽象的な言いかたですが、直感的に何をしているか？が分かり易いか？を見ます。
どういうのが分かり易いかというと、全体を見通しやすいソースだと思っています。
何かを理解する時に、
１．全体を把握
２．更にブレイクダウンして、把握
の順番で把握するので、１の全体を把握しやすいソースを心掛けます。

### SQLのWHERE句、JOIN句にINDEXが張られているか？
RDMSに限った話ですが、SQLのWHERE句、JOIN句にINDEXが張られているか？も一応みます。

## 状況次第で見ること
### 仕様通り作られているか？
これは基本、テストで担保することだから、あまり見ませんが、テストがしっかりできない状況の場合、コードレビューで拾うようにします。

### ログが適切に出力されているか？
これは、設計フェーズだと思うので、コードレビューで拾うことではないと思っています。
が、設計フェーズで適切にレビューされていないことが多々あったので、状況次第で拾うようにしています。
ただ、指摘はあくまでも、設計者宛にします（設計者と実装者が異なる場合もありますので）
よく使うDockerコマンド集

## 概要
よく使用するDockerコマンドのまとめ

## 公式ドキュメント

[https://docs.docker.com/engine/reference/commandline/docker/](https://docs.docker.com/engine/reference/commandline/docker/)
[http://docs.docker.jp/engine/reference/commandline/index.html](http://docs.docker.jp/engine/reference/commandline/index.html)


## イメージ作成系

Dockerイメージをリポジトリから取得

```
docker pull REPOSITORY[:TAG]
```

Dockerfileからイメージを作成

```
docker build . -t REPOSITORY[:TAG]
```

## 一覧表示系
イメージの一覧を表示

```
docker images
docker image list
```
起動中のコンテナの一覧を表示

```
docker container list
docker ps
```
コンテナ一覧を表示（停止中のコンテナ含む）

```
docker container list -a
docker ps -a
```

## コンテナ起動系

コンテナ起動 & コンソール上で操作(bashを起動)

```
docker run -it [IMAGE] /bin/bash
```

コンテナをバックグラウンドで起動

```
docker run -d [IMAGE]
```

--nameオプションで NAMESを指定することも可能

```
docker run -d --name [NAMES] [IMAGE]
```
起動中のコンテナをコンソール上で操作

```
docker exec -it [CONTAINER] /bin/bash
```
コンテナを停止

```
docker container stop [CONTAINER]
```

停止したコンテナを起動

```
docker container start [CONTAINER]
```

## 削除系

使用していない image・container・networkを削除

```
docker system prune 
```
使用していないイメージを削除

```
docker image prune
```
使用していないコンテナを削除

```
docker container prune
```
imageを指定して削除

```
docker rmi [IMAGE]
docker image rm [IMAGE]
```
コンテナを指定して削除

```
docker rm [CONTAINER]
docker container rm [CONTAINER]
```

## ログ・ステータス確認系

dockerコンテナのログを表示（更新あり）

```
docker logs -f [CONTAINER]
```
dockerのリソース使用状況を表示

```
docker stats
```
[VBA]PDFファイルをエクスポートするコード


ラジオボタンのリンクしているセルの値をGetSpecialFolders(Sheet2.Range("A1"))のように引数にしてます。

![PDFエクスポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361605/6f5c233c-4a3b-db98-36f5-ea12d834fa06.png)

シート[見積書]をPDF出力する感じで。


```vb
Sub export_PDF()

Dim kyaku As String
Dim savePath As String
Dim sheet As Worksheet
Dim Sheet2 As Worksheet
'On Error GoTo err

Set sheet = ThisWorkbook.Worksheets("見積書")
Set Sheet2 = ThisWorkbook.Worksheets("設定")

kyaku = sheet.Range("A3")

savePath = GetSpecialFolders(Sheet2.Range("A1"))

Dim fileName As String '保存先フォルダパス＆ファイル名
fileName = savePath & "\" & Format(Now, "yyyymmddhhmm") & "見積書_" & kyaku & "御中.pdf"


With sheet.PageSetup
 
    .Zoom = False
    .FitToPagesWide = 1
    .FitToPagesTall = 1
 
End With
 
sheet.ExportAsFixedFormat Type:=xlTypePDF, fileName:=fileName
MsgBox "PDFを出力しました", vbInformation

Exit Sub
'err:
'MsgBox "エラーが発生しました。", vbCritical
End Sub

Function GetSpecialFolders(sel As Integer)
    Dim wScriptHost As Object, strInitDir As String
    Set wScriptHost = CreateObject("WScript.Shell")
    Select Case sel
    Case 1
        GetSpecialFolders = ThisWorkbook.Path
    Case 2
        GetSpecialFolders = wScriptHost.SpecialFolders("Desktop")
    Case 3
        GetSpecialFolders = wScriptHost.SpecialFolders("MyDocuments")
    Case 4
        
        If Dir(ThisWorkbook.Worksheets("設定").Range("E7"), vbDirectory) = "" Then
            ans = MsgBox("指定のフォルダが存在しません。" & vbclrf & "フォルダを作成しますか？", _
            vbInformation + vbYesNoCancel)
            
            If ans = 6 Then
                MkDir (ThisWorkbook.Worksheets("設定").Range("E7"))
            Else
                End
            End If
            
        End If
        GetSpecialFolders = ThisWorkbook.Worksheets("設定").Range("E7")
    End Select
End Function
LeetCode / Number of 1 Bits

ビット表現祭りその2。

[https://leetcode.com/problems/number-of-1-bits/]

Write a function that takes an unsigned integer and return the number of '1' bits it has (also known as the Hamming weight).

Example 1:
Input: 00000000000000000000000000001011
Output: 3
Explanation: The input binary string 00000000000000000000000000001011 has a total of three '1' bits.

Example 2:
Input: 00000000000000000000000010000000
Output: 1
Explanation: The input binary string 00000000000000000000000010000000 has a total of one '1' bit.

Example 3:
Input: 11111111111111111111111111111101
Output: 31
Explanation: The input binary string 11111111111111111111111111111101 has a total of thirty one '1' bits.


Note:

Note that in some languages such as Java, there is no unsigned integer type. In this case, the input will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 3 above the input represents the signed integer -3.

#### 解答・解説

##### 解法1
下1桁が1であれば1を足すビット演算を32桁繰り返せば良いので、以下のように処理できます。

```python
class Solution(object):
    def hammingWeight(self, n):
        """
        :type n: int
        :rtype: int
        """
        res = 0
        for _ in range(32):
            res += n&1
            n>>=1
        return res
```

時間計算量・空間計算量ともに$O(1)$なのでここで満足しても良いのですが、若干改善の余地があります。

#### 解法2
32桁走査せずとも処理を完了できる可能性がある解法がこちら。

```python
class Solution(object):
    def hammingWeight(self, n):
        res = 0
        while n != 0:
            res += 1
            n &= n-1
        return res
```

n&(n-1)のビット演算を行う手法です。
どういうことかというと、n = n&(n-1)のビット演算を行なうごとに'1'のbitの数が1つずつ消えていくので、nが0となるまでの処理の回数をカウントしてやれば良いんです。
具体例を示します。

n          : 00000000000000000000000000001011

n          : 00000000000000000000000000001011
n-1       : 00000000000000000000000000001010
n&(n-1): 00000000000000000000000000001010

n          : 00000000000000000000000000001010
n-1       : 00000000000000000000000000001001
n&(n-1): 00000000000000000000000000001000

n          : 00000000000000000000000000001000
n-1       : 00000000000000000000000000000111
n&(n-1): 00000000000000000000000000000000

という形ですね。
[VBA]テキストファイルを取り込む

ばい。
備忘録っす。
textファイルを取り込むコードです。

コメント無し不親切コード炸裂してます。

・・・これVBAでやる必要あるんですかね。

```vb

Sub oneLine_txt()

    Dim myFile As String
On Error GoTo err
    myFile = Application.GetOpenFilename(" TXTファイル(*.txt),*.txt, CSVファイル(*.csv),*.csv,Excelブック,*.xls*,")
    
    Dim buf As String, n As Long
    Dim allLine As Variant
    
    Open myFile For Input As #1
        Line Input #1, buf
            allLine = Split(buf, ",")
            Do Until EOF(1)
                
            Loop
            Debug.Print UBound(allLine, 2)
    Close #1
    
Exit Sub
err:
    MsgBox "インポートに失敗しました", vbCritical
End Sub

Sub AllLine_txt()

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(1)
On eroor GoTo err
    Dim strPath As String
    strPath = Application.GetOpenFilename(" TXTファイル(*.txt),*.txt, CSVファイル(*.csv),*.csv,Excelブック,*.xls*,")
     
    Dim i As Long, j As Long
    Dim strLine As String
    Dim arrLine As Variant
    
    Dim V1 As Variant
    Dim RR As Range
    
    Dim maxRow As Long, maxCol As Long
    maxRow = count_txt_Row(strPath)
    maxCol = count_txt_Col(strPath)

    ReDim V1(1 To maxRow, 1 To maxCol)
    Set RR = Range(Cells(1, 1), Cells(maxRow, maxCol))

Open strPath For Input As #1 'csvファイルをオープン
    Dim T As Single
    T = Timer
    i = 1
    Do Until EOF(1)
       
        Line Input #1, strLine
        arrLine = Split(strLine, ",")
        
        For j = 1 To UBound(arrLine)
        
            V1(i, j) = arrLine(j)
            
        Next j
        i = i + 1
    Loop
 
Close #1
    RR.Value = V1
    Debug.Print Round(Timer - T, 2)
Exit Sub
err:
MsgBox "ファイルのインポートに失敗しました", vbCritical
End Sub

Function count_txt_Row(TargetFile As String)

    Dim FSO As Object
    
    Set FSO = CreateObject("Scripting.FileSystemObject")
    With FSO.OpenTextFile(TargetFile, 8)
        count_txt_Row = .Line
        .Close
    End With
    Set FSO = Nothing
    
End Function

Function count_txt_Col(strPath As String)

Open strPath For Input As #1

        Line Input #1, strLine
        arrLine = Split(strLine, ",")
        count_txt_Col = UBound(arrLine)
 
Close #1
End Function
バイナリサーチ　二分検索法

##バイナリサーチ　二分検索法
範囲を半分に絞りながら探していく検索法
###メリット
検索速度が速い
###デメリット
データをあらかじめ整列しておく必要がある

```java:BinarySerch.java

class BinarySerch{
  public static void main(String[] args){
   //検索するソート済の配列
   int a[] = {1,3,6,8,10};
   //検索する値
   int serchValue = 3;
   //見つかったデータの配列番号　初期値はエラー値（-1）
   int find = -1;

   //検索する左端、右端の番号
   int left = 0;
   int right = a.length-1;
   //調べる左端と右端にデータがある時は繰り返す
   while(left <= right){
     //左右の真ん中の番号を調べる位置に指定
     int middle = (int)((left + right)/2);
     //調べる位置の値と、探す位置を比較して
     if(a[middle] == serchValue){
        //同じなら、その番号を保存して繰り返しの終了
        find = middle;
        break;
    }else if (a[middle] < serchValue){
    //探す値より小さければ左端を移動
     left = middle + 1;
    }else {
    //探す値より大きければ右端を移動
    right = middle - 1;
    }
  }
  //検索結果の表示
  System.out.println("検索結果：" + find);
 }
}
```

参考書籍
[楽しく学ぶアルゴリズムとプログラミングの図鑑](https://www.amazon.co.jp/%E6%A5%BD%E3%81%97%E3%81%8F%E5%AD%A6%E3%81%B6-%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9B%B3%E9%91%91-%E6%A3%AE-%E5%B7%A7%E5%B0%9A-ebook/dp/B01N56TW48)
【laravel】404 not found のアレンジ

##1.やること
laravelのデフォルトの404 not foundが味気ないので変更します。
こっちに変えます。
![スクリーンショット 2019-08-31 23.14.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244070/fe3f27bf-44ef-61b4-568c-6c0cc4055b06.png)


##2.バージョン
laravel 5.7

##3.流れ

以下のコードをうちます。このコードによってエラー関係のファイルが生成されます。

```
 $ php artisan vendor:publish --tag=laravel-errors
Copied Directory [/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views] To [/resources/views/errors]
Publishing complete.
```

view/errors/404.blade.phpのファイルができるのでレイアウトを
　extends('errors::illustrated-layout')に変更します。

変更後

```php5:404.blade.php
@extends('errors::illustrated-layout')

@section('title', __('Not Found'))
@section('code', '404')
@section('message', __('Not Found'))

```

適当なURLで叩いてみると出てきました！

![スクリーンショット 2019-08-31 23.14.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244070/24f495d9-622e-472e-b157-2036469258d7.png)
オートシェイプ操作で自動ガントチャート作成[完全自分用]

はい。
コメントもほとんど無し。スーパー不親切なコード乗っけます。

まあ自分用だし細かいことはいいんじゃん？


```vb

Sub Main_macro()

    Call change_Day
    Call clear_Arrow
    Call timeArrow
    
End Sub

Sub change_Day()

    Dim TargetSheet As Worksheet, PasteSheet As Worksheet
    Dim day As Integer
    
    Dim RR As Range, RR2 As Range
    Dim rRow As Integer, cCol As Integer
    Dim VV As Variant
    
    Set TargetSheet = ThisWorkbook.Worksheets("月間シフト表")
    Set PasteSheet = ThisWorkbook.Worksheets("タイムチャート")
    
    day = PasteSheet.Range("D2")
    
    ReDim VV(1 To 15, 1 To 2)
    
    TargetSheet.Select
    
    For j = 6 To 101 Step 19
        For i = 3 To 15 Step 2
        
            If TargetSheet.Cells(j, i) = day Then
            
                For Each RR In TargetSheet.Range(Cells(j + 2, i), Cells(j + 16, i + 1))
    
                    VV(RR.Row - j - 1, RR.Column - i + 1) = RR
                    'Debug.Print RR.Row - j - 1, RR.Column - i + 1
                Next
                
            End If
            
        Next
    Next
    
    PasteSheet.Select
    Set RR2 = PasteSheet.Range(Cells(5, 3), Cells(19, 4))
    RR2 = VV

End Sub

Sub clear_Arrow()

    Dim s_Str As String
    
    For Each i In ActiveSheet.Shapes
        s_Str = i.Name
        
        If s_Str Like "*Right Arrow*" Then
            i.Delete
        End If
        
    Next
    
End Sub



Sub timeArrow()

    Dim minRow As Integer, minCol As Integer
    Dim maxRow As Long, maxCol As Long
    Dim CC2 As Variant
    
    minRow = 5: minCol = 6
    maxRow = 19: maxCol = 26
    
    For j = minRow To maxRow
        For i = minCol To maxCol
            If Cells(j, i) = 1 Then
                
                CC2 = WorksheetFunction.RoundUp((Range("E" & j) / 0.5), 3)
                CC2 = Int(CC2) + i
                
                'Debug.Print j, i, CC2
                
                Call autoShape(j, i, CC2)
                
                
            End If
        Next
    Next
    
    Cells(1, 1).Select
    
End Sub

Sub autoShape(RR As Variant, CC As Variant, CC2 As Variant)

    Dim T As Double, L As Double, H As Double, W As Double, allW As Double
    Dim R As Range, R2 As Range
    
On Error GoTo err
    Set R = Cells(RR, CC)
    Set R2 = Cells(RR, CC2)
    
    With R
        T = .Top
        L = .Left
        H = .Height
        W = .Width
    End With
        
        allW = R2.Left - L + W
        
        ActiveSheet.Shapes.AddShape(msoShapeRightArrow, L, T, allW, H).Select
        
        With Selection.ShapeRange.Fill
            .Visible = msoTrue
            .ForeColor.RGB = RGB(255, 255, 0)
            .Transparency = 0
            .Solid
        End With
Exit Sub
err:
MsgBox "時間の登録に異常があります。", vbCritical
  Call clear_Arrow
  End
  
End Sub

```
Electron の終了イベントまわりの整理

Electron は終了イベントがいくつかあり、さらに終了の仕方によって発火するイベントの種類や順序が微妙に変わるのが非常にややこしいのでまとめてみることにした。

## 検証方法
以下の検証スクリプトで Electron アプリを起動して、様々な終了方法を試みたときにどのような出力が出るかを見る。

環境は macOS v10.14.6, Node.js v12.9.1, Electron v6.0.5 で行った。

``` js:検証スクリプト
const electron = require('electron');

electron.app.on('ready', () => {
  const window = new electron.BrowserWindow();
  window.on('close', () => console.log('BrowserWindow.close'));
  window.on('closed', () => console.log('BrowserWindow.closed'));
});

electron.app.on('window-all-closed', () => {
  console.log('app.window-all-closed');
  electron.app.quit();
});
electron.app.on('before-quit', () => console.log('app.before-quit'));
electron.app.on('will-quit', () => console.log('app.will-quit'));
electron.app.on('quit', () => console.log('app.quit'));
```

`window-all-closed` のイベントハンドラで `app.quit()` を呼んでいるのは、 `window-all-closed` イベントを subscribe してない場合はそのまま quit が実行されるが subscribe している場合は quit が実行されないという仕様になっているため。

## 検証結果
終了方法をいくつか試したが、結果は2パターンに分かれた。

### パターン 1
- `Cmd + Q` で終了した場合
- `SIGTERM` を送った場合
- `SIGINT` を送った場合

```
app.before-quit
BrowserWindow.close
app.will-quit
app.quit
BrowserWindow.closed
```

「アプリが終了するからウィンドウを閉じますね」という流れ。

### パターン 2
- `Cmd + W` で終了した場合
- ウィンドウの閉じるボタンを押した場合

```
BrowserWindow.close
app.window-all-closed
app.before-quit
app.will-quit
app.quit
BrowserWindow.closed
```

「ウィンドウがすべて閉じたからアプリを終了しますね」という流れ。

パターン 1 と比べると、`app.window-all-closed` が発火している点と `app.before-quit` が発火するタイミングが遅い点が異なっている。

## 参考
各イベントの詳細は公式ドキュメントを参照されたい。

`app.will-quit` は `event.preventDefault()` でキャンセルできるけど `app.quit` はできないとか、そういう違いなどが書かれている。

- [app | Electron](https://electronjs.org/docs/api/app)
- [BrowserWindow | Electron](https://electronjs.org/docs/api/browser-window)
[VBA]お天気情報を取得するスクレイピング

私長野県長野市に住んでまして、webスクレイピングの学習を始めたころにお試しで作った物です。

長野県に住んでいる方はどうでしょうか？　

VBAでweb操作をしたかったら四角で囲まれた部分にチェックを入れてね
![webスクレイピング参照設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361605/790b4e64-ff01-d203-6926-80cfdd34cb91.png)



```vb


Sub wertherGet()

    Dim ie As InternetExplorer
    Dim tagTD As HTMLDocument
    
    Set ie = CreateObject("Internetexplorer.Application")
    
    ie.Visible = True
    ie.navigate "https://weather.yahoo.co.jp/weather/jp/20/4810/20201.html"
    
    Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
    
    Dim Row As Long, Col As Long
    
    Row = 1
    
    For Each i In ie.document.getElementsByTagName("td")
        c = c + 1
        Col = Col + 1
        Cells(Row, Col) = i.innerText
        
        If Col = 9 Then
            Row = Row + 1
            Col = 0
        End If
        
        If c = 54 Then
            Exit For
        End If
    Next
    
    ie.Visible = False
    ie.Quit

End Sub