OmniAICreator/Qiita-1.07M huggingface dataset:
Kindleでハイライトした内容をScrapboxに書き込むためのメモ

*  [Kindle Notebook](https://read.amazon.co.jp/notebook)を開く
*  ブックマークに追加して、編集のURLに以下のJavaScriptコードをコピペする
 *  **`your-project-name`**を自分のScrapboxのプロジェクト名に変更する

```javascript:ブックマークレット
 javascript:
Scrapbox="https://scrapbox.io/your-project-name/";
url="https://read.amazon.co.jp/kp/notebook";
if(location.href.indexOf(url) == 0) {
  var titleElement=document.getElementById("annotation-scroller").querySelectorAll("h3.kp-notebook-metadata");
  var title =titleElement[0].innerText;

  var authorElement=document.getElementById("annotation-scroller").querySelectorAll(".a-spacing-none");
  var authors = authorElement[0].innerText;  
  var content ="";

  var highlightNodes = document.getElementsByClassName("kp-notebook-highlight");
  var highlights = [];

  var quotationNodes = document.querySelectorAll("#annotationHighlightHeader");
  var quotationPages = [];
  
  for (var i = 0; i < highlightNodes.length; i++) {
    highlights.push(highlightNodes[i].innerText);
  }

  for (var i = 0; i < quotationNodes.length; i++) {
    quotationPages.push(quotationNodes[i].innerText);
  }
  
  var banner = "[" + document.querySelector(".kp-notebook-printable img").src + " " + document.querySelector(".kp-notebook-printable").href + "]";  
  content += banner;
  content += "\n";
  content += "By: " + authors;  
  content += "\n\n";

  for(var i = 0; i < quotationPages.length; i++) {
    content += quotationPages[i];
    content += "\n";
    content += ">" + highlights[i];
    content += "\n";
  }

  var links = "#readings" + " ";  
  authorList = authors.split('、');
  for (var i = 0; i < authorList.length; i++) {
    links += "#" + authorList[i] + " ";
  }
  content += links;

  url = Scrapbox + encodeURIComponent(title) + "?body=" + encodeURIComponent(content);
}

location = url;
```
Scrapboxに追加したい本を選択して、ブックマークをクリックすると自動的にScrapboxに追加される。

## 参考
[W&R : Jazzと読書の日々](http://d.hatena.ne.jp/wineroses/20180821/p1)
Windowsで、Chocolateyとnodistで、バージョン切り替え可能なNode.jsの環境を構築する


Windows10 に バージョン切り替え可能なNode.jsの環境を構築したときのメモ。


### パッケージマネージャ Chocolatey をいれる
Windowsにも [Homebrew](https://brew.sh/index_ja) みたいなパッケージマネージャのがあるっぽいですね。

https://chocolatey.org/install#installing-chocolatey

公式の指示通り、**管理者権限で起動したコマンドプロンプト**でサイトにあるコマンドを実行。
2019/01/26時点:

```bash
(管理者)T:\> @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" 
-NoProfile -InputFormat None -ExecutionPolicy Bypass 
-Command "iex ((New-Object System.Net.WebClient)
.DownloadString('https://chocolatey.org/install.ps1'))" && 
SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

(実際は一行で。というか公式サイトに正確なのがあります)
```

バージョン確認します

```bash
(管理者)T:\> choco -v
0.10.11
```

OKそうです。

### nodist のインストール
いわゆる[nodenv](https://github.com/nodenv/nodenv#homebrew-on-macos)など、バージョン切り替えツールのWindows版。

管理者権限で起動したコマンドプロンプトで、、

```bash
(管理者)T:\> choco install -y nodist
```

バージョン確認します

```bash
T:\> nodist -v
0.8.8
```
OKそうです。



### Node.jsのインストール
ようやくNode.jsのインストール。コマンドプロンプトで

```
T:\> nodist + 10.15.0
T:\> nodist global 10.15.0


T:\> node --version
v10.15.0
```

出来ました。

### 参考:バージョン切り替え

他のバージョンを入れて、切り替えてみます。

```bash
T:\>node --version
v10.15.0

T:\>nodist  +  11.8.0
 11.8.0 [===============] 25551/25551 KiB 100% 0.0s
11.8.0

T:\>node --version
v10.15.0    ← まだ切り替わってない

T:\>nodist global 11.8.0
11.8.0
Default global pacakge update dsuccessful.

T:\>node --version
v11.8.0  ← 切り替わりました

T:\>
```

おつかれさまでした。

### 蛇足

[Nodist を入れたら npx が使えなくなったので手動でインストール](https://tt-computing.com/npx-install) にも情報がありますが、コレでいれた Node.js は``npx``コマンドがインストールされないようなので

```console
$ npm i -g npx
```

で手動インストールしておきましょう。
App Store ConnectにAppプレビューを載せる

# Appプレビュー
App StoreにはAppプレビュー(動画)を載せることが出来ます。
実機操作を録画して載せるだけなので簡単だろう、と思ったら、守らなければならない点が幾つかありました。
備忘録も兼ねて作業行程を残します。

ちなみにAppプレビュー、スクリーンショットの概要はヘルプにあります

- [App Store アイコン、App プレビューとスクリーンショットの概要](https://help.apple.com/app-store-connect/#/dev910472ff2)

# 申請にあたり躓いた点

自分のアプリのAppプレビューを、QuickTime Playerの新規ムービー収録から操作動画を作成しました。
それをそのままアップロードできるはずもなく。
以下が躓いた点です。

- プレビューのサイズを変更しなければならなかった
    - iPhoneX実機でのプレビューサイズは「1126x2436」。<br>しかし、iPhoneX(5.8 インチ)のAppプレビューサイズは「886 x 1920」<br>[App プレビューの仕様](https://help.apple.com/app-store-connect/#/dev4e413fcb8)
- fps30にしなければならなかった
    - QuickTime Playerの新規ムービー収録では60fpsになってしまいアップロードの際にエラーで弾かれる
- 無音動画はNG
    - 操作動画撮影時の生活音を消すため、オーディオトラックを削除してアップロードしたところ、エラーで弾かれる

# 問題点の解消
iMovieなど動画編集ができる方は、上記問題は解決できると思います。
自分にはどうもうまく行かなかったので、ffmpegでコマンドを叩いて解決してみました
前準備として、ffmpegをインストールしておきます

```console
brew install ffmpeg
```

## プレビューサイズとFPSの変更

```sh
# ffmpeg -i {入力ファイル} -filter:v scale={サイズw:h} -r {フレームレート} {出力ファイル}
# iPhoneX(5.8インチ)指定
ffmpeg -i src.mov -filter:v scale=886:1920 -r 30 dst.mov
```

scaleでサイズ変更、-r 30でフレームレートの変更を指定

## 無音化

```sh
# ffmpeg -i {入力ファイル} -f lavfi -i aevalsrc=0 -c:v copy -map 0:0 -map 1:0 -shortest -ac 2 -strict -2 {出力ファイル}
ffmpeg -i src.mov -f lavfi -i aevalsrc=0 -c:v copy -map 0:0 -map 1:0 -shortest -ac 2 -strict -2 dst.mov
```

オーディオトラックを削除するのではなく、無音のオーディオトラックとしています（詳しくは参考サイト様をご覧ください）

# 最後に
これでアップロードできる状態になりました。
自分はこの後で字幕編集アプリを使って操作説明などを入れましたが、このままでもApp Store Connectにアップロードできます。

# 参考サイト様
- [FFmpegで動画の一部を無音にするときは音声を削除せずに無音データで埋めないとダメ](https://hori-ryota.com/blog/ffmpeg-mp4-part-to-silence-nosound-missing/)
Kotlinの==と===はどう違うの？

Kotlinには、オブジェクトを比較する場合に```1 == 1```と```1　===　1```の二種類があり、それぞれどう違うのかってのが話題に上がったので調べてみました。

# (=)イコールとは？
> 等号（とうごう）は「=」のかたちをした数学記号である。「イコール」と読むことが多い。等号の左右が等価であることを表し、等号で結ばれた数式を「等式」と呼ぶ。

引用：「等号」（2019年1月26 (土) 10:00　UTCの版）『ウィキペディア日本語版』。

Wikipediaで調べてみました。 ```=```の左辺と右辺が***"等価"***であるということを表すとのことです。

# Kotlinにおける等価とは？
Kotlinでは、```=```の記号は代入として扱われ、等価かどうか判断する記号は```==```や```===```が用いられます。

## ```===```は、参照の等価性による判定

``` a === b ```の場合、```a```と```b```が同じオブジェクトかどうかの判定になります。

```kotlin
    1 === 1 // 同じオブジェクトなのでtrue
    1 === 2 // 別のオブジェクトなのでfalse

    Hoge() === Hoge() // それぞれのオブジェクトとして生成されるのでfalse

    val hoge = Hoge()
    hoge === hoge // 同じオブジェクトなのでtrue
```

## ```==```は、equalsメソッドのシンタックスシュガー

```kotlin
1 == 1 // 1.equals(1)と同じ
```

```==``` の場合は、equals()の実装によって等価かどうか(trueかfalse)が変わってきます。
基本的なequals()の実装は、オブジェクト毎に違う整数値を返すhashCode()の比較で実装されているので```===```と同じ動きをします。

equals()は、オーバーライドが可能なので等価の基準を各々で定義できます。

## ```==```と```===```の違いは？
調べてみた私の感想としては、オーバーライド出来るか出来ないかの違いが大きいのかと感じました。

必ず同じオブジェクトか判定したい場合は```===```を、そのクラスを実装した人が等価だと思う基準で判定したい場合は```==```を使えばいいのかなと思います。
ただし、```==```があなたが思っている***"等価"***とは違う可能性があるのでequals()の実装をちゃんと理解して使いましょう。


# 参考にしたもの

- *1 [Kotlin文法 - this、等価性、演算子オーバーロード、Null安全、例外](https://qiita.com/k5n/items/6fe586bf2e5530684681#%E7%AD%89%E4%BE%A1%E6%80%A7)
汎用流体解析ソフト「F〇uent」ライクなスケールバーをvtkに表示してみた

#はじめに
汎用流体解析ソフト「F〇uent」には画面の中央下辺りにスケールバーがあり，メッシュやジオメトリの大まかなサイズを計測することができます．
今回は，vtk上でこのスケールバーを再現したいと思います．

完成イメージは下図になります．
![図1.jpg](https://qiita-image-store.s3.amazonaws.com/0/132299/fe01d949-c189-1185-ba0b-6f64ec79e6f8.jpeg)

以前に投稿した内容 ↓ をさらに拡張していきます．
[PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その2(「ファイルを開く」の実装編) ](https://qiita.com/matsubaradaisuke/items/956b9ade4a74fcbb7521 "PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その2(「ファイルを開く」の実装編)")




#環境
OS: windows10
OpenFOAM v4.0
python 3.6.4
pyqt5-5.9.2
vtk-8.0.0
numpy

#ファイル構成
case/
　├ ScaleBar.py　(本プログラム)
　├ open_file.png
　├ quit.png




スケールバーを作成するときは，vtkライブラリの次のクラスについて勉強する必要があります．

vtkLegendScaleActor

詳しくは，リファレンスを参考にしてください．


#スケールバーの実装

それでは，スケールバーを設定していきます．
[前回]("https://qiita.com/matsubaradaisuke/items/956b9ade4a74fcbb7521")のクラス「MyForm」に以下の関数を追加していきます．

```py3:ScaleBar.py

	def setupScale(self):
		legendScaleActor = vtk.vtkLegendScaleActor()
		legendScaleActor.AllAxesOff()
		self.ren.AddActor(legendScaleActor) #レンダーにアクターを配置
```

そして最後に，初期化時にこの関数を追加して終了です．

```py3:ScaleBar.py

	def __init__(self, parent=None):
		QWidget.__init__(self, parent)
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)

		self.reader = vtk.vtkOpenFOAMReader()
		self.filter2 = vtk.vtkGeometryFilter()
		self.mapper = vtk.vtkCompositePolyDataMapper2()
		self.actor = vtk.vtkActor()

		self.widget = QVTKRenderWindowInteractor(self)
		self.widget.Initialize()
		##背景色の設定
		self.ren = vtk.vtkRenderer()
		self.widget.GetRenderWindow().AddRenderer(self.ren)
		self.widget.Start()
		self.widget.show()

		self.setCentralWidget(self.widget)
		#UIのインスタンスを介してアイコンと実体(関数)をつなげる
		self.ui.actionOpenFile.triggered.connect(self.openFile)
		self.ui.actionResetFile.triggered.connect(self.resetFile)
		self.setupInitView()
		self.setupScale()　#<--------これ！

```

#使い方
モデルを回転・拡大することで，サイズを測ることができます．
今回の例には．OpenFOAMのチュートリアルにある，pitzDailyを用いています．
https://github.com/OpenFOAM/OpenFOAM-6/tree/master/tutorials/incompressible/simpleFoam/pitzDaily

例
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132299/6d384544-3658-797f-da84-86f5f2b7ead4.png)

実際のサイズを確認してみましょう．
pitzDaily/system/blockMeshDictを確認すると．．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132299/3704b3a2-feb6-33c0-1fa7-643a3de9a6ca.png)

まあ，だいぶズレてますね( ´∀｀ )
おおよその確認なので，過度な期待は禁物です．

#まとめ
view画面にスケールバーを追加しました．
最近vtkに関する記事が増えてて嬉しいです．
もっと盛り上げていきたいですね．
Javascriptで画像リサイズ(縮小)

画像アップロード機能を実装するときによく使うのでメモします。

```js
/**
 * @param {HTMLImageElement} imgEL 
 * @param {Number} maxSize 
 * @return {Promise<Blob>}
 */
const resizeImage = (imgEL, maxSize, type = 'image/png') => 
  new Promise((resolve) => {
    const ratio = imgEL.naturalWidth / imgEL.naturalHeight
    const canvas = document.createElement('canvas')
    canvas.width = ratio >= 1 ? maxSize : maxSize / ratio
    canvas.height = ratio < 1 ? maxSize : maxSize / ratio
    canvas.getContext('2d').drawImage(imgEL, 0, 0, canvas.width, canvas.height)
    canvas.toBlob(resolve, type)
  })
```
戻り値のBlobが縮小されたやつでそのままサーバにアップロードすればいい感じですね。

## 使用例

```html
<body>
  <input type="file">
  <div id="preview"></div>
  <button>アップロード</button>
  <script>
    const resizeImage = (imgEL, maxSize, type = 'image/png') =>
      new Promise(resolve => {
        const ratio = imgEL.naturalWidth / imgEL.naturalHeight
        const canvas = document.createElement('canvas')
        canvas.width = ratio >= 1 ? maxSize : maxSize / ratio
        canvas.height = ratio < 1 ? maxSize : maxSize / ratio
        canvas.getContext('2d').drawImage(imgEL, 0, 0, canvas.width, canvas.height)
        canvas.toBlob(resolve, type)
      })

    const pFileReader = blob =>
      new Promise(resolve => {
        const fr = new FileReader()
        fr.readAsDataURL(blob)
        fr.onload = e => resolve(e.target.result)
      })

    const pImage = src =>
      new Promise(resolve => {
        const img = new Image()
        img.src = src
        img.onload = e => resolve(img)
      })

    document.querySelector('input').onchange = async e => {
      const file = e.target.files[0]
      const preview = document.querySelector('#preview')
      const src = await pFileReader(file)
      const img = await pImage(src)
      // 本当に縮小されることを確認したい場合は以下をコメントアウト
      // const blob = await resizeImage(img, 100, file.type)
      // img.src = await pFileReader(blob)
      preview.appendChild(img)
    }

    document.querySelector('button').onclick = async () => {
      const file = document.querySelector('input').files[0]
      const src = await pFileReader(file)
      const img = await pImage(src)
      const blob = await resizeImage(img, 100, file.type)
      // blobをアップロード ~
    }
  </script>
</body>
```
以上！

FileReader使ってますけど,　URL.createObjURLで代用できますよ。
DTOデザインパターンでgetter/setterを利用することは思考停止していないか？

JavaでDTOデザインパターンを実装するときにsetter/getterを付けているのって
思考停止していないでしょうか、私は疑問を感じます。

※DTO Wikipedia引用
Data Transfer Object（DTO）はデザインパターンの一種で、アプリケーションソフトウェアのサブシステム間でデータを転送するのに使う

実装としてはこんな感じ。

```java
class Hoge
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}
```
目的を鑑みるとロジックを含むべきものではないものと考えます。
そうするとフィールドに対するgetter/setterがあるだけの実装になります。
カプセル化も全く機能していないので、何がしたいのかはさっぱりです。
※全体の統一性のために気持ち悪いとかそういう話は理解できます。

なのでフィールドをpublicにしてしまう実装が簡潔です。
IDEからも補完がでて便利！

```java
class Hoge
{
    public int value;
}
```

んじゃ次に突っ込まれる要因として、JavaのBeanになってないやんと
言われるかもしれません。

ただし、DTOの目的を考えるとBeanになる必要は無いはず。
なんでBeanにしたいの？と考えると

「BeanUtils.copyProperties」が使えないやんけ！と言われるかも。
でもそれって、目的と手段を勘違いしていませんか？と私は思います。
DTOとしては成立しているはずなのです。

んじゃなぜ「BeanUtils.copyProperties」を使いたいの？となると思います。

次回
   [BeanUtils.copyPropertiesを利用することは思考停止していないか？](https://qiita.com/kyasu/items/478c28ef744b17046071)

ご意見ご感想などございましたらお願いいたします。
今まで実行したコマンドをスクリプト化する

PCセットアップ等で打った手番をそのままべた書きでスクリプトにしたい。
historyコマンドで確認はよくやると思うんですが、そのままファイル出力できることに気付いたので覚書

```
history -a cmd.sh
```

cmd.shに実行手番が先頭行数なしで吐き出されます。
(今まで手動で切り貼りしてた)
[PowerApps Tip's]そっくりさん？ドロップダウンとコンボボックスのちがい

PowerAppsで、選択肢から何かを選ばせるコントロールが2種類あることをご存知でしょうか？
# 「ドロップダウン」と「コンボボックス」
![01.png](https://qiita-image-store.s3.amazonaws.com/0/215892/0c9236ea-eb93-1182-fb98-96bf82261982.png)
「ドロップダウン」と「コンボボックス」です。
何が、どう異なるのか？皆さん、説明できますか？

当方はできませんｗ

なので、調べてみました。

# 「ドロップダウン」と「コンボボックス」のちがい
実際にアプリで実行して確認したり、各々のコントロールで設定できるプロパティを確認すると、かなり異なっているコトが確認できます。公式情報を下記に並べておきますのでご確認ください。

■[PowerApps のドロップ ダウン コントロール](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/controls/control-drop-down)

> ドロップダウン コントロールを使うと、特にリストに多数の選択肢が含まれている場合に画面スペースを節約できます。 ユーザーが下向き矢印を選択して選択肢を表示しない限り、コントロールが使うのは 1 行のみです。 コントロールは、最大で 500 の項目を表示します。 

■[PowerApps のコンボ ボックス コントロール](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/controls/control-combo-box)

> コンボ ボックスコントロールで、選択する項目を検索することができます。 検索は、SearchField プロパティについてサーバー側で実行されるので、パフォーマンスが非常に大規模なデータ ソースによって影響を受けることはありません。

ドロップダウンは、単純にItemsから1つだけ選択するコントロールになります。

それに対し、コンボボックスの場合はドロップダウンの機能に加えて、さらに文字列入力による検索、単一選択モードまたは複数選択モードを指定できるなど高機能になっています。加えて、表示可能なアイテム数などスペックが異なりますね。

ドロップダウンの"強い版"がコンボボックス、というイメージでしょう。

# カスタムリストから自動生成したアプリの場合
SharePoint Online のカスタムリストから自動生成したアプリでは、選択肢の列が自動的にコンボボックスで作成されます。

例えば、下イメージのような選択肢列を持つリストからPowerApps アプリを自動生成した場合・・・
![02.png](https://qiita-image-store.s3.amazonaws.com/0/215892/10562794-9312-2150-6e8d-ac607e988754.png)
生成された「EditScreen」の該当コントロールを確認すると「コンボボックス」になっています。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/215892/8ee26fbd-53a2-0543-b09a-678190a4f883.png)
そのため、データソースをSharePoint で利用しているだけだと"そっくりさん"なコントロールがあることに気づかないかもしれませんね。

#まとめ
- PowerApps にはドロップダウンとコンボボックスの2種類 選択肢のコントロールがある
- ドロップダウンはMax 500個しか表示できない
- ドロップダウンの高機能版がコンボボックスのイメージ
- 1つのコントロール内で複数を同時に選択させたい場合は、コンボボックス必須
- SharePoint Online のリストから自動生成した場合はコンボボックスになる

自動生成される場合、とくに意識する必要はないかと思います。ゼロベースで全て手動でデザインからアプリを作成する場合は、この(コントロールとしての)選択肢の(行為としての)選択肢として把握しておくと幸せになれるかもしれませんね。
Raspberryで wifi Spycam

# ラズパイでスパイカムを作成する
# 下ごしらえ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/75fa7e38-57ef-4b52-1ed6-05bcf98ad9ef.png)
１.MicroSD　カードを用意する
2.Fat32でフォーマットする。
https://www.raspberrypi.org/documentation/installation/sdxc_formatting.md
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/eb30dbf5-1a21-8370-8743-9511a8d9b2e7.png)
# FAT32でないとダメダメ　ハマるよ!!!!
3. Raspbianのダウンロード https://www.raspberrypi.org/downloads/
4. イメージをMicro SDに展開 https://www.techspot.com/downloads/6931-etcher.html
5. ラズパイに挿入
成功すると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/98c03f01-7e14-348e-de39-e61d8091d1f6.png)

早速SSHを使えるようにする。
https://qiita.com/Halhira/items/1da2ae543217be26988a

手間がかかりますです。
## ラズパイやっているとラズベリーケークが食べたくなりました。
### ついでに手作りです。ラズパイ夜食で～す
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/b43f0f69-346d-8b71-e40d-60e9f97287d6.png)
# 手作りケーキの作り方お教えします。
# いいよね　くださいね!


open CVを導入します。
https://qiita.com/mt08/items/e8e8e728cf106ac83218
を参照に導入
sudo apt autoremove -y libopencv{3,4}、は、以前にインストールしたものを取り除くものなので、インストールされてなければ、エラーを無視してすすめてください。
bottleをインストール
```
sudo pip3 install bottle
```
プログラムを転送　Rlogin のSSHを使っています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/9541c7b8-ac2b-4173-6730-1b5041abd1b1.png)


11.raspberry pi
2.余っているWeb Camera
3.Python Program
システムポンチ絵(システム概要図みたいなもの)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274715/5f83630b-7133-8e25-13cd-9ae690bc2506.png)
簡単なプログラム

```spycam.py
from bottle import *
import cv2
class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)
    def __del__(self):
        self.video.release()    
    def get_frame(self):
        return cv2.imencode('.jpg', self.video.read()[1])[1].tobytes()
def gen(camera):
    while True:
        yield (b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + camera.get_frame() + b'\r\n\r\n')
@route('/video_feed')
def video_feed():
    response.content_type = 'multipart/x-mixed-replace; boundary=frame'
    return gen(VideoCamera())
@route('/')
def index(): 
    return '<div align="center"><h1>Video Streaming</h1><img src="/video_feed"></div>'
run(host='0.0.0.0', port=8081)
```

wifiを確認(アドレス　例は、192168.1.111)する。
1.下記のプログラムをRaspberry PIに入れる。
2.実行する

解説

``` py

return cv2.imencode('.jpg', self.video.read()[1])[1].tobytes()
```
tupleで返される値を一行に書いた。
一般的な御作法で書くと・・・

```py
success, image = self.video.read()       
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
```
yieldを用いてmotion jpegを作成

```py
yield (b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + camera.get_frame() + b'\r\n\r\n')
```
#### 「Stupid Phone」から http://192.168.1.111:8081 アクセスする。
モンティ・ホール問題が納得いかなかったので、モンテカルロシミュレーションしてみた（２）

# 続き

[モンティ・ホール問題が納得いかなかったので、モンテカルロシミュレーションしてみた](https://qiita.com/g667408/items/1a70cb4b66cc28ce1562)

シミュレーションの結果、参加者はドアを変更すると賞品を得られる確率が２倍になるのは明らか。
しかし、やはり納得がいかない。
直感的にわからない。
じゃあ、montyさんが賞品のあるドアの位置を知らなかったらどうなる？

早速、コードを修正してみました。

# 変更箇所

### 使用前

```python
        if monty_select != select and doors[monty_select] == 0:#賞品が無く、参加者が選ばなかったドアを選ぶ
            break   
```

### 使用後
もしmontyが賞品のあるドアを開けてしまったら、その回はなかったことに。
raiseで例外を投げます。
(あまり綺麗なコードではないですが。)

```python
        if monty_select != select:#参加者が選ばなかったドアを選ぶ
            if doors[monty_select] != 0:#もしmontyが選んだドアに賞品があったら。その回はなかったことにする。
                raise
            break      

```
```python
for i in range(n):#指定回数を繰り返す
    try:
        change += monty(change = True)
    except:
        change_invalid += 1 #montyが賞品のあるドアを開けてしまった。
    try:
        nochange += monty(change = False)
    except:
        nochange_invalid += 1 #montyが賞品のあるドアを開けてしまった。
```

# 修正済みコード

```python

import random
import sys

#引数
n = int(sys.argv[1])

#賞を得るのに、成功すると1、失敗すると0を返す
#change ドアを変更するか
#True:変更する
#False:変更しない
def monty(change):
    #3枚のドア
    doors = [0,0,0]
    #乱数でどのドアに賞品があるかを決める
    prize = random.randint(0,2)
    doors[prize] = 1
    #参加者がドアを選ぶ
    select = random.randint(0,2)

    #続いてmontyがドアを選ぶ
    while True:
        monty_select = random.randint(0,2)
        if monty_select != select:#参加者が選ばなかったドアを選ぶ
            if doors[monty_select] != 0:#もしmontyが選んだドアに賞品があったら。その回はなかったことにする。
                raise
            break            

    if change:#ドアを変更する場合
        while True:
            select_change = random.randint(0,2)
            if monty_select != select_change and select != select_change:#montyも参加者も選ばないドア
                select = select_change
                break
    if doors[select] == 1:#賞を得られたら1を返す
        return 1
    return 0#賞が得られなければ0を返す

change = 0
change_invalid = 0
nochange = 0
nochange_invalid= 0
for i in range(n):#指定回数を繰り返す
    try:
        change += monty(change = True)
    except:
        change_invalid += 1 #montyが賞品のあるドアを開けてしまった。
    try:
        nochange += monty(change = False)
    except:
        nochange_invalid += 1 #montyが賞品のあるドアを開けてしまった。

#結果の表示
print("turn",n)
print("change  ",change,"invalid",change_invalid)
print("nochange", nochange, "invalid" ,nochange_invalid)
```

# 実行結果

今度は、ドアを変えても変えなくてもほぼ同じになりました。
invalidがmontyが賞品のあるドアを開けてしまって無効となった回数です。
このinvalidの数分に何か原因があるんでしょうけど。
やっぱり直感的には良くわからないですね。。。

```
turn 1000
change   341 invalid 344
nochange 344 invalid 323

turn 1000
change   325 invalid 346
nochange 382 invalid 313

turn 1000
change   334 invalid 352
nochange 344 invalid 331
```
SQL postgres公式参照 between


>BETWEEN演算子を使用して、値を値の範囲と照合します。以下にBETWEEN演算子の構文を示します。

```
value BETWEEN low AND high;
```
>値がその値以上でそのlow値以下であるhigh場合、式はtrueを返し、そうでない場合はfalseを返します。

<font color="DeepPink">**実際使ってみて、はまったとこ
low AND high**</font>
左に小さい値、右に大きい値です
数値なら
1 AND 6
日付なら
'2019/04/31' AND '2019/06/31'
です。
現在の日付を出力する方法を使って
'現在の日付' AND 'それ以前の日付'
としてしまい、悩みまくった過去があり、これはわすれない！。（よく見てなかった～）

>次の文のようにBETWEEN、大なりまたは等しい（>=）または小なりまたは等しい（<=）演算子を使用して、演算子を書き換えることができます。

```
value >= low and value <= high
```

>値が範囲外かどうかを確認する場合は、次のようにNOT演算子と演算子を組み合わせBETWEENます。

```
value NOT BETWEEN low AND high;
```

>次の式は、NOTand BETWEEN演算子を使用した式と同じです。

```
value < low OR value > high
```

>多くの場合、BETWEEN 演算子はSELECT、INSERT、UPDATE、またはDELETEステートメントのWHERE句で使用されます。
[*AWS*] AWS CLIのインストール&設定メモ

# はじめに
インストール&設定メモと、エラー解決メモ。
環境は`macOS Mojave`。

# インストール時のエラー
```bash
$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py
$ sudo pip install awscli
# 以下の３つのエラーが出る
# matplotlib 1.3.1 requires nose, which is not installed.
# matplotlib 1.3.1 requires tornado, which is not installed.
# Cannot uninstall 'six'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
```

# インストール時のエラー解決
```bash
# 以下のエラーについて
# matplotlib 1.3.1 requires nose, which is not installed.
# matplotlib 1.3.1 requires tornado, which is not installed.
$ sudo easy_install nose
$ sudo easy_install tornado
```

```bash
# 以下のエラーについて
# Cannot uninstall 'six'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
$ sudo -H pip install awscli --upgrade --ignore-installed six
# これで成功する
```

# ユーザーの追加
AWS CLI用のユーザーがなければ`AMI`から作成する。
アクセスの種類として、`プログラムによるアクセス`にチェックを入れる。
AWSのコンソールにアクセスできるユーザーにしたい場合はその下にもチェックが必要。
<img width="1005" alt="スクリーンショット 2019-01-26 10.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/48912/eff4d2bd-8827-8508-2a73-adb4bf8a2aa9.png">
今回は一旦フルアクセスを許可しているが、ここは適宜適切なアクセス権の付与が必要
<img width="998" alt="スクリーンショット 2019-01-26 10.10.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/48912/f9fec6f0-d154-dc2e-f9f3-cab63094bae7.png">
ユーザーを追加すると`アクセスキーID`と`シークレットアクセスキー`が発行されるのでこれをコピーする。
<img width="990" alt="スクリーンショット 2019-01-26 10.10.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/48912/10151419-27ab-917d-ee20-a7eb35755552.png">

# CLI側の設定
```bash
$ aws configure
# AWS Access Key ID [None]: XXXXXXXXXXXXXXXX　＊適宜変更
# AWS Secret Access Key [None]: XXXXXXXXXXXXXXXX　＊適宜変更
# Default region name [None]: ap-northeast-1 ＊アジアパシフィック（東京）にした 参考: https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html
# Default output format [None]: json
```
【AWS メモ⑤】VPC Peering を使用して VPC 間の EC2 同士を接続する

仕事で使う機会があったので備忘録的なものを残しておく。

## VPC Peering でできること

・異なるVPC間を直接接続することができる。（VPC同士を直接接続する技術なのでVPC間の接続にEC2にパブリックIPを割り振る必要がない）

・アカウントが異なる場合にも接続できる。（アカウントが異なる場合、ペアリング認証時に接続先 VPCのアカウントでの承諾する必要）

・複数のVPCとの接続ができる。



## VPC Peering でできないこと

・CIDRが一致または重複するVPC間の接続はできない。

・ペアリング先のVPCがペアリングしているVPCに直接接続はできない。

　→ 接続するには、VPC-AからVPC-Bへ接続後、VPC-Cへ接続する必要がある。（NAT等も同様）



## 環境

以下の条件の AWS 環境で VPC Peering を確立する。



・VPC は VPC-A と VPC-B の二つ

・VPC-A 、VPC-B はそれぞれ subnet-a、subnet-b サブネットを持ち、EC2が1台ずつ起動している

・subnet-a には クライアント端末からの SSH 接続のみ有効とするセキュリティグループを設定

・subnet-b には 全ての接続を遮断するセキュリティグループを設定（のちにsubnet-aからの接続のみ許可する設定を付与）



イメージ
<img width="755" alt="VPC_Peering_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/f38acfc3-120b-16df-ac84-5e421a208bc7.png">

## VPC Peering の作成

サービスから VPC を選択して、 VPC画面遷移後、左端のメニューから 「ピアリング接続」を選択する。
<img width="1128" alt="VPCPeering_setting_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/f558ea2d-511b-cc24-f0ec-2e986591f4e2.png">


「ピア接続の作成」を押下する。
<img width="1128" alt="VPCPeering_setting_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/a6476725-0288-13cb-859f-87c21331549c.png">


ボタンを押下すると、ピア接続作成画面に遷移するので、

各項目に設定値を入れていく。

・ピア接続ネームタグ・・・EC2などにあるTagを同じ

・VPC(リクエスタ)　  ・・・VPC間の接続許可を申請する側のVPC（ここではVPC-Aを設定）

・アカウント　　　　・・・許可する側のアカウント

・リージョン　　　　・・・今回は同じリージョンなので「このリージョン」を選択

・VPC(アクセプタ)　   ・・・VPC間の接続を許可する側のVPC（ここではVPC-Bを設定）


設定完了後、「ピア接続の作成」を押下する。
<img width="1128" alt="VPCPeering_setting_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/2433397c-ee20-9211-4baa-faa48eff1a60.png">


接続の作成が完了すると、承諾待ちのピア接続が作成される。
<img width="1128" alt="VPCPeering_setting_4.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/210b0fdb-3391-8121-5a42-f40aff465e66.png">


アクションタブから「リクエストの承諾」を選択するとピア接続が確立する。
<img width="1128" alt="VPCPeering_setting_5.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/ebad720e-9842-1ccb-31e1-72c69cef4671.png">
<img width="899" alt="VPCPeering_setting_6.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/ce4653da-51bb-c74c-85f4-36a460f812cb.png">
<img width="899" alt="VPCPeering_setting_7.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/ec3f527c-e7ef-35ce-a589-83074c26ab39.png">


VPC-Aのルートテーブルには、送信先に VPC-BのCIDRを入力。
ターゲットには VPCペアリング接続を選択（Peering Connectionを選ぶとペアリングの候補がでる）
<img width="1128" alt="VPCPeering_setting_8.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/6713d295-7a2d-4479-367c-f80662ec42f0.png">


VPC-Bのルートテーブルには、送信先に VPC-AのCIDRを入力。
<img width="1128" alt="VPCPeering_setting_9.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/40f4c9d0-ab8d-9502-9fc6-8b8e319a18d3.png">


次に、subnet-bに設定されているセキュリティグループに VPC または subnet からの接続を許可する設定を行う必要がある。
なるべく細かくした方がいいと思うのでsubnet 単位で設定。
<img width="899" alt="VPCPeering_setting_10.png" src="https://qiita-image-store.s3.amazonaws.com/0/180939/88807942-600c-4669-4c32-bae820ccf351.png">

## 接続の確認



インターネットからの接続ができる VPC-A の EC2 に接続

```
# 作業端末から接続
$ ssh -i access.pem ec2-user@<EC2-AのパブリックIP>
```



VPC-Aの EC2 から VPC-B の EC2 に接続

```
# EC2-AからEC2-Bへの接続
$ ssh -i access.pem ec2-user@<EC2-BのプライベートIP>
```
MacBookAir2018モデルの給電ができなくなったときの対処法

Thunderbolt3（USB Type-C）の端子のついたMacBookで
給電が上手くできなくなったときの対処法。

# SMC（システム管理コントローラ）をリセット
参考：[Mac の SMC (システム管理コントローラ) をリセットする方法](https://support.apple.com/ja-jp/HT201295)
※T2セキュリティチップを搭載の場合

1. 電源オフ
2. 電源ボタンを10秒間長押し
3. 電源を入れて動作を確認

もし、上記で改善しなかった場合は、以下を追加実施。

4. 再度、電源オフ
5. 右Shift + 左option + 左control を7秒間長押し
6. 5のボタンを押したまま、更に電源ボタンを7秒間長押し
7. 再度、電源を入れて動作を確認

# PRAMクリア

1. 電源オフ
2. 電源を入れて、すぐに option + command + P + Rキーを20秒長押し
3. 起動したら動作確認

# 上記を実施してもダメな場合

[Genius Bar](https://www.apple.com/jp/retail/geniusbar/)へ
MysqlでScalikeJDBC入門2 (テスト編)

# 目的
mysqlでscalikeJDBCのコード自動生成を行い、テストまで通します。

解説したコード全体はこちら： [umeneri/scalikejdbc-example: example for scalikejdbc](https://github.com/umeneri/scalikejdbc-example)

# テスト用DBの設定

[前回](https://qiita.com/umeneri/items/77414e8c6af59f6282d3)からの続きです。

まず、テスト用DBのexample_testを作ります。

以下でログインして、

```
$ mysql -h 127.0.0.1 -uroot -P 4306
```

DBを作ります。

```
> create database example_test;
```

memberテーブルも作成しておきます。

```
> use example_test;

> CREATE TABLE member
(
  id BIGINT NOT NULL AUTO_INCREMENT,
  name VARCHAR(256) NOT NULL,
  description VARCHAR(1000),
  created_at DATETIME NOT NULL,
  updated_at DATETIME NOT NULL,
  PRIMARY KEY (id)
) ENGINE = 'InnoDB', DEFAULT CHARSET=utf8mb4, ROW_FORMAT=DYNAMIC;
```

application.confにテスト用DB設定を追加します。
ここではtestという名前のコネクション設定を新たに作っています。 example_testにアクセスします。

```scala:src/test/resources/test.conf
db.test.driver="com.mysql.jdbc.Driver"
db.test.url="jdbc:mysql://127.0.0.1:4306/example_test"
db.test.user="root"
db.test.password=""
```

## テストコードの修正
class MemberSpecの行の下に以下を設定し、jdbcでテスト用DBへアクセスできるようにします。

```scala:src/test/scala/models/MemberSpec.scala
class MemberSpec extends fixture.FlatSpec with Matchers with AutoRollback {
  config.DBs.setup('test)

  override def db = NamedDB('test).toDB
  ...
```

更に次の行に下記を追加します。
fixtureを定義することで、テスト用DBへ予めテストデータをinsertしておけますので、findのテストを失敗させずにすみます。

```scala:src/test/scala/models/MemberSpec.scala
  override def fixture(implicit session: DBSession) {
    sql"insert into member values (1, ${"Alice"}, '', current_timestamp, current_timestamp)".update.apply()
    sql"insert into member values (2, ${"Bob"},  '', current_timestamp, current_timestamp)".update.apply()
  }

```

### create, updateのテストコード修正

そのままだと`create new record`のテストが失敗します。created_atがnullになっているのが原因なので、修正します。

差分です。

```
-    val created = Member.create(name = "MyString", createdAt = null, updatedAt = null)
+    val created = Member.create(name = "MyString", createdAt = ZonedDateTime.now(), updatedAt = ZonedDateTime.now())
```

また、TODOと書かれている`save a record`のテストも修正します。


```
-    // TODO modify something
-    val modified = entity
+    val modified = entity.copy(name = "member1")
```


最後に、コマンドラインで`sbt test`を実行してすべて成功すればOKです！
【RxJS入門】Expand関数を使った再帰的なObservable

[こちら](https://www.moririn-tech.blog/en/articles/3528e025-187c-44f1-a89e-f14bec6aec26)に移行しました
こんにちは、ムラびとです。今回は、RxJSで再帰的、While文をObservableでどのように表現するかをまとめてみました。
今回は以下のように解説していきます。
なお、今回はRxjs6を使い、TypeScriptを使って書いていきます。

- RxJSとは
- expand関数とは
- expand関数の使い方

## RxJSとは
RxJSを使うと、非同期処理をみやすく簡単に使うことができるよう作られたライブラリです。
考え方としては、ベルトコンベアーに乗せられたHttpリクエストなどの非同期のデータをオペレーターを使って処理していきます。
公式サイトは[こちら](https://rxjs-dev.firebaseapp.com/)
詳しく使い方をしりたいひとは[こちら](https://www.learnrxjs.io/)
インストール方法は
```npm i rxjs```
注意：`rx`という名前のライブラリもありますが、こちらはRxJS5を使っており、書き方が若干異なります。

例として`qiita.com`をスクレイピングしてみましょう。

```typescript
import { from } from 'rxjs'; 
import { map } from 'rxjs/operators';
import * as request from 'request-promise'

from(request('https://qiita.com/'))
  .pipe(
    map(d=>'data:'+d)
  )
  .subscribe(v=>console.log(v))
```

このようにfrom関数でPromiseからObservableに変換し、map関数でそのデータを加工、subscribe関数でデータの受け取りをしています。
subscribe関数で受け取りを指定するまではObservableはデータを流さないので注意です。

## expand関数とは

Observableをスクレイピングで次のページを取得していってほしいなど再帰的に使いたい場合というのは多々あると思います。そのような時にexpand関数を使います。
expand関数はある値を引数にObservableを生成する関数を受け取り、`empty()`を返すまでその関数を再利用していきます。
[リファレンスはこちら](https://www.learnrxjs.io/operators/transformation/expand.html)


## expand関数の使い方

例として[コラッツの問題](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A9%E3%83%83%E3%83%84%E3%81%AE%E5%95%8F%E9%A1%8C)の過程を出力していきましょう。
比較のため普通の再帰関数を使った場合をみてみましょう。

```typescript
function collatz(n:number){
  console.log(n)
  if(n===1) return 1
  if(n%2===0) return collatz(n/2)
  if(n%2===1) return collatz(3*n+1) 
}

collatz(250)
```

[テストはこちら](https://stackblitz.com/edit/typescript-pr1ctm?embed=1&file=index.ts)

次にObservableで実装してみます。

```typescript
import { from,of,empty } from 'rxjs'; 
import { expand } from 'rxjs/operators';


of(200)
  .pipe(
    expand(n=>{
      if(n===1) return empty()
      if(n%2==0){
        return of(n/2)
      }
      else{
        return of(3*n+1)
      }
    })
  )
  .subscribe(
    v=>console.log(v)
  )
```

[テストはこちら](https://stackblitz.com/edit/rxjs-ox8sku?embed=1&file=index.ts)

## 終わりに

いかがだったでしょうか？
他にもいくつかRxJSについての記事を書いていますのでみていただけると嬉しいです。
docker error記録

macOS10.13.6
Safari 12.0.2(13606.3.4.1.4)
Docker Desktop Community 2.0.0.2(30215)
で、アプリでloginした状態で、runしようとした。

```
$ docker run -it kaizenjapan/100pon /bin/bash
docker: Error response from daemon: Bad response from Docker engine.
See 'docker run --help'.
```
なぜかエラーになった。コマンドラインでloginしてみた。

```
$ docker login
Authenticating with existing credentials...
Login Succeeded
KM-S10:~ administrator$ docker run -it kaizenjapan/100pon /bin/bash
Unable to find image 'kaizenjapan/100pon:latest' locally
latest: Pulling from kaizenjapan/100pon
05d1a5232b46: Download complete 
33529d049adc: Downloading   62.4MB/94.96MB
be72550a31b7: Downloading  61.89MB/1.522GB
40cab810eef6: Waiting 
90a7cfada776: Waiting 
63b10c589b27: Waiting 
3b74f2e93e93: Waiting 
4ad328879d5f: Waiting 
53bb48f40962: Waiting 
7430ebce441f: Waiting 
152f700b
```

なぜかエラーにならない。

何度か、この現象が現れたことがある。記録
Unity：GPU インスタンシング(Instancing) を WebGL がおかしい

# はじめに

*こんにちは、のんびりエンジニアのたっつーです。*
*[ブログ](https://www.fast-system.jp/)を運営しているのでよろしければ見てください。*

Unityの高速化の一般的な手法、GPU インスタンシングを使ってパフォーマンスを改善するようなデモを作成したので動作してみてください。 また、WebGLで出力した場合も有効かどうか確認し有効でしたので合わせてデモページもありますので各自の環境で試してみてください。

# Link

- デモ : [GPU Instancing無効](https://www.fast-system.jp/wp-content/uploads/static/unity-gpu-instancing-example-disabled/)
- デモ ：[GPU Instancing有効](https://www.fast-system.jp/wp-content/uploads/static/unity-gpu-instancing-example-enabled/)
- Github：https://github.com/fastsystem/unity-gpu-instancing-example

# 実装手順

こちらを参照してください
[Unity：GPU インスタンシング(Instancing) を WebGL で実行する](https://www.fast-system.jp/unity%ef%bc%9agpu-%e3%82%a4%e3%83%b3%e3%82%b9%e3%82%bf%e3%83%b3%e3%82%b7%e3%83%b3%e3%82%b0instancing-%e3%82%92-webgl-%e3%81%a7%e4%bd%bf%e3%81%a3%e3%81%a6%e9%ab%98%e9%80%9f%e5%8c%96%e3%81%99%e3%82%8b/)

# 何がおかしいのか

- デモ
  - [GPU Instancing無効](https://www.fast-system.jp/wp-content/uploads/static/unity-gpu-instancing-example-disabled/)
  - [GPU Instancing有効](https://www.fast-system.jp/wp-content/uploads/static/unity-gpu-instancing-example-enabled/)
- 操作方法
 - ホイールでドラッグ
 - ホイールでズーム
 - 右クリックでカメラの向き変更


## 初期表示が遅い

GPU Instancing無効：Unityロゴが表示後にすぐに表示される
GPU Instancing有効：Unityロゴが表示後に10秒くらいかかる。

## 操作ができない

GPU Instancing無効：マウスでの操作ができる。
GPU Instancing有効：マウスでの操作が鈍すぎて実用に耐えない。

## FPSはでている

GPU Instancing無効：20fps くらい
GPU Instancing有効：50fps くらい

# 若干の解決（2019/01/28追記）

「Quality」の設定からレベルを下げる事により本現象が若干和らいだので追記しておきます。

![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/227880/a8125e5e-0d9d-e0fc-8089-cbf729ea5816.jpeg)

![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/227880/a1632877-b843-6289-4d5c-20c0a364c662.jpeg)

# どちらがいいの？

あまり検証していないが、GPU Instancing を有効にしたオブジェクトを使いすぎると初期表示の遅さ、操作時の引っ掛かりがあり実用するのであれば無効も考えた方がよさそう。
バランスを見て有効・無効の割合をチューニングする必要がありそう。

# 終わりに

*よければ ブログ「[初心者向けUnity情報サイト](https://www.fast-system.jp/)」の方にも色々記載しているのでぜひご参照いただければと思います。*
（テスト投稿）

ヘロンの公式導出メモ

余弦定理

```math
\cos \theta = \frac{a^2 + b^2 - c^2}{2ab}
\\
\sin \theta = \sqrt{1 - \left( \frac{a^2 + b^2 - c^2}{2ab} \right) ^2}
```

三角形の面積

```math
S=\frac{1}{2} ab \sin \theta
=
\frac{1}{2} ab \sqrt{1 - \left( \frac{a^2 + b^2 - c^2}{2ab} \right) ^2}
\\
=
\frac{1}{4} \sqrt{4a^2b^2 - \left( a^2 + b^2 - c^2 \right) ^2}
```

```math
S^2 = \frac{1}{16} \left[ 4a^2b^2 - \left( a^2 + b^2 - c^2 \right) ^2 \right]
\\
=
\frac{1}{16} (2ab - a^2 - b^2 + c^2)(2ab + a^2 + b^2 - c^2)
```

拡張三平方の定理

3点$(a,0,0)$，$(0,b,0)$，$(0,0,c)$と原点$(0,0,0)$を頂点に持つ三角錐について

3点$(a,0,0)$，$(0,b,0)$，$(0,0,c)$を頂点に持つ三角形の面積$S$について

ヘロンの公式

```math
S^2 
= 
\frac{1}{16} (2\sqrt{(a^2+b^2)(b^2+c^2)} - (a^2+b^2) - (b^2+c^2) + (c^2 + a^2) )(2\sqrt{(a^2+b^2)(b^2+c^2)} + (a^2+b^2) + (b^2+c^2) - (c^2+a^2))
\\
=
\frac{1}{16} (2\sqrt{(a^2+b^2)(b^2+c^2)} - 2b^2 )(2\sqrt{(a^2+b^2)(b^2+c^2)} + 2b^2)
\\
=
\frac{1}{4}\left[(a^2+b^2)(b^2+c^2) - b^4\right]
\\
=
\frac{1}{4}a^2 c^2 + \frac{1}{4}a^2 b^2 + \frac{1}{4}c^2 b^2
```

各三角形の面積を$S_1$，$S_2$，$S_3$とすると

```math
S^2 = S_1^2 + S_2^2 + S_3^2
```

それぞれの面積を2倍にすると，平行四辺形の面積に置き換えられる

##射影

$S_1$，$S_2$，$S_3$は$S$を3方向に映した影

拡張三平方の定理から，$(S_1, S_2, S_3)$はベクトルの性質をもつ。

##余弦定理の拡張

http://www25.tok2.com/home/toretate/cos012.html

これを理解したいな
[メモ] STM32L1xx: 内蔵フラッシュメモリを壊す!(...ハズが...)


# 概要
- STM32L1系のFLASHの特定のところ消去、書き込みを繰り返し行い、どの程度で不良がでるか、を見たかったのだが。。
- だいぶ前にテストをおこなったのだが、一晩、二晩程度続けたくらいでは大丈夫だった。(ハズ..)
- データ保存に使用するのに、どの程度、耐えられるか知りたかったんだが、製品では、気にせず、使うことに。


- うまい テスト・手順・回数(日数)などあれば、**コメント**お願いします。

# 環境
- STM32L15xVC系
- Cortex®-M3, 256KB Flash, 32KB SRAM, 8KB EEPROM
- Reference manual:RM0038のProduct category definitionから、Cat.3のチップ。 
- 内蔵フラッシュについて(Cat.3)
    - Page: 消去の単位
        - 256 Bytes:  計 1024 pages 
    - Sector: 
        - 0 ~ 31 sector: 16 pages = 4 KB
        - 32 ~ 64 sector: 256 pages = 64 KB 
    - 書き込みは、WORD(32bit)単位


- Memory map (STM32L151xC STM32L152xCのデータシートの Memory mapより)<br>![image.png](https://qiita-image-store.s3.amazonaws.com/0/75594/e397fa6a-e16b-5721-08ca-d07c96e1130a.png)

- FLASH関連の使用HAL API
    - 書き込み: `HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)`
    - 消去: `HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)`
    - FLASHロック: `HAL_StatusTypeDef HAL_FLASH_Lock(void)`
    - FLASHアンロック: `HAL_StatusTypeDef HAL_FLASH_Unlock(void)`

# テスト内容
## テスト1
1. テスト方法
    1. ページ消去
    2. データチェック(ALL 0x00 ?)
    3. ページ書き込み(256Bytes 0xFFで埋める)
    4. データチェック(ALL 0xFF ?)
    5. ループ
2. 結果... 普通に使えた(ハズ)


# その他
- テストのソースコードは、見つかったら、載せる.
GatsbyJSをGoogleAppEngineで公開する時のキャッシュ設定

## GatsbyJSのキャッシュについて
[GatsbyJSのドキュメント](https://www.gatsbyjs.org/docs/caching/)に、キャッシュの設定方法が記載してあります。

超簡単にまとめると

- htmlはキャッシュしない
- static/以下はキャッシュする
- js, cssはキャッシュする
- ただし、/sw.jsはキャッシュしない 

GoogleAppEngineでgatsbyの成果物を公開する時に、このキャッシュ設定を再現してみたapp.yamlをメモしておこうと思います。

ただ、自分もちゃんと理解できてないのですがGAEは独自のキャッシュサーバにもキャッシュをしているらしく、この設定で本当に静的ページが更新されるのか良くわかってないです・・・。
とりあえず`cache-control`ヘッダが期待値通りになってることだけは目視できています。


## GAE app.yamlの設定
- `default_expiration`でcacheの期限を設定できる
- handler毎に設定したい場合はそれぞれ`expiration`を書く（省略すると前述のdefaultが使われる）

Gatsbyの成果物である`public`ディレクトリが、GAEアプリのルートにある前提としています。

```yaml
# app.yaml
# 〜関係ないところは省略してます〜

default_expiration: "0s"

handlers:
  # If the path is empty, show static index.html file
  - url: /
    static_files: public/index.html
    upload: public/index.html
    secure: always

  - url: /sw.js
    static_files: public/sw.js
    upload: public/sw.js
    secure: always

  - url: /static
    static_dir: public/static
    secure: always
    expiration: "600s"

  - url: /(.*\.(js|css))$
    static_files: public/\1
    upload: public/.*\.(js|css)$
    secure: always
    expiration: "600s"

  # Otherwise, find file in static directory
  - url: /
    static_dir: public
    secure: always

  # All URLs are handled by the Go application script
  - url: /.*
    script: auto
    secure: always
```
Gatsbyのドキュメントにはキャッシュするものについてはめちゃめちゃ長く期間が書かれてますが
GAEは１０分を推奨（多分・・・）してたのでここでは 600s にしています。

簡単ですが、以上です。
ChromeアプリモードでSlack起動

ChromeアプリモードでSlack起動
Slackアプリっぽく使う

OS :  Windows 7, 10で確認

# 使い所
SlackはWebブラウザから使えるけどWindowsアプリもある。勝手にWindowsアプリいれるな！とかいう会社の場合にアプリっぽく使える。WebアプリだからOK！
そもそもChromeが禁止の場合は・・・。


# 手順
chrome本体ファイル
C:\Program Files  (x86)\Google\Chrome\Application
のchrome.exeからショートカットを任意の場所に作成。

ショートカットのプロパティの[リンク先]に

```
--app="https://{ワークスペース}.slack.com/"
```

を追記。



# ショートカットアイコン

google画像検索でslackの画像をダウンロード

今回はjpgファイルをダウンロード

ペイントで開き、名前を指定して保存 -> bmp形式
拡張子を.icoにして保存

ショートカットのプロパティ-> アイコンの変更
保存したicoファイルを指定してOK


# 見た目
タスクバーのアイコンに大きいアイコンを使う場合はchromeウィンドウ左上のアイコンの引き伸ばしになるようで、解像度が荒い。
【今日から携わる】フィボナッチ数列で設定するmargin・padding（今ならsassの設定も公開！）

**突然ですが、margin・paddingの値を変数化してますか？**

昔はいちいちpx指定でバッチリガッチリ固定幅な余白を再現していましたが、sassを使い、変数を使い、だんだん作り方が変わってきた今日このごろです。

.m{方向}-{大きさ}　：　マージン余白のつけかた
.p{方向}-{大きさ}　：　パディング余白のつけかた

```css:昔の汎用クラスの書き方（余白）
.m-10 {
    margin: 1rem !important; }

.mt-10 {
    margin-top: 1rem !important; }

.mr-10 {
    margin-right: 1rem !important; }

.mb-10 {
    margin-bottom: 1rem !important; }

.ml-10 {
    margin-left: 1rem !important; }

.mx-10 {
    margin-left: 1rem !important;
    margin-right: 1rem !important; }

.my-10 {
    margin-top: 1rem !important;
    margin-bottom: 1rem !important; }
```

しかし、colissさんで下記の記事を見て考えが変わりました。
そしてsassで書こう！と。

>[margin, paddingなど、レスポンシブに対応したスペースをCSSで効率的に定義する方法｜coliss](https://coliss.com/articles/build-websites/operation/css/css-spacing-system-and-relative-units.html)
<img width="595" alt="スクリーンショット 2019-01-26 1.42.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/254652/86d98f52-fe51-12be-37ef-68bb82150647.png">



WEBの余白って、30px未満は細かく設定したほうがいいけれど、30pxを超える余白は5pxで刻まない方がいいこと多いですよね・・・。

ということで、最近のSass（scss）の余白の設定は以下のようになっております。

# Sassの設定

```scss:最近の汎用クラスの書き方（余白）
$space-unit : 1rem !default; //16px
$margins : (
  "xxs": (0.25 * $space-unit), // 4px
  "xs": (0.5 * $space-unit), // 8px
  "sm": (0.75 * $space-unit), // 12px
  "md": (1.25 * $space-unit), // 20px
  "lg": (2 * $space-unit), // 32px
  "xl": (3.25 * $space-unit), // 52px
  "xxl": (5.25 * $space-unit), // 84px
  "0": ($space-unit * 0)
);

@each $size,$pixel in $margins {

  .m-#{$size} {
    margin:#{$pixel} !important;
  }

  .mt-#{$size} {
    margin-top:#{$pixel} !important;
  }

  .mr-#{$size} {
    margin-right:#{$pixel} !important;
  }

  .mb-#{$size} {
    margin-bottom:#{$pixel} !important;
  }

  .ml-#{$size} {
    margin-left:#{$pixel} !important;
  }

  .mx-#{$size} {
    margin-left:#{$pixel} !important;
    margin-right:#{$pixel} !important;
  }

  .my-#{$size} {
    margin-top:#{$pixel} !important;
    margin-bottom:#{$pixel} !important;
  }

  .p-#{$size} {
    padding:#{$pixel} !important;
  }

  .pt-#{$size} {
    padding-top:#{$pixel} !important;
  }

  .pr-#{$size} {
    padding-right:#{$pixel} !important;
  }

  .pb-#{$size} {
    padding-bottom:#{$pixel} !important;
  }

  .pl-#{$size} {
    padding-left:#{$pixel} !important;
  }

  .px-#{$size} {
    padding-left:#{$pixel} !important;
    padding-right:#{$pixel} !important;
  }

  .py-#{$size} {
    padding-top:#{$pixel} !important;
    padding-bottom:#{$pixel} !important;
  }
}

```

# まとめ
margin・paddingの余白は、変数化・ルール化しましょう！
そのときのルールとして、フィボナッチ数列がおすすめです。
Date型かつ特定の日付をprestoで読むとズレる

2019-02-04 追記あり

hiveでデータ作成したとき限定なのか…？
タイトルにはDate型って書いたけどTimestampでも同様の現象が起こる。

hiveは2.1と2.3
prestoは0.17と0.21
両方でやって両方とも同じ結果
AWS　EMRでもローカルdocker上でも同じ

```
hive> create table date_test (d date);
OK

hive> insert into date_test select '1000-01-01' from camma limit 1;
OK

hive> select * from date_test;
OK
1000-01-01
```

```
presto:default> select * from date_test;
     d      
------------
 1000-01-06 
(1 row)

presto:default> select cast(d as date) from date_test;
   _col0    
------------
 1000-01-06 
(1 row)

presto:default> select cast(d as varchar) from date_test;
   _col0    
------------
 1000-01-06 
(1 row)
```

https://github.com/prestodb/presto/issues/8120
この問題かと思って確認もしたが

```
presto:default> select cast('1000-01-01' as date) from date_test;
   _col0    
------------
 1000-01-01 
(1 row)

presto:default> select cast('1100-02-28' as date) from date_test;
   _col0    
------------
 1100-02-28 
(1 row)
```

うーーーーーーーん
何か知ってる方いらっしゃったら教えてください…

## 追記
https://github.com/prestodb/presto/issues/12273

解散！
Linuxスクリプトで文字列挿入する際、複数回実行しても1行だけ挿入できるようにする

小ネタですが、よく使うので覚書として記事化。

## 普通にリダイレクトすると追記され続けてイライラ

PCセットアップ等で設定ファイルの追記等を以下のように書くことがあると思います。

```shell:write_file.sh
echo "setting_for_something" >> some_one_setting.conf
```

これを2度3度と実行すると、ファイルに同じ内容が追記されてうざい。

```
$ ./write_file.sh;./write_file.sh;./write_file.sh
$ cat some_one_setting.conf
setting_for_something
setting_for_something
setting_for_something
```

## 対処: 以前の追加分を削除しとく

回避策として、sedコマンドを使って追記設定を前もって削除。

```shell:write_file.sh
sed -i '/setting_for_something/d' some_one_setting.conf
echo "setting_for_something" >> some_one_setting.conf
```

これなら何度実行しても1行追加になるので気持ちすっきり

```
$ ./write_file.sh;./write_file.sh;./write_file.sh
$ cat some_one_setting.conf
setting_for_something
```
【Unity】チェリーを取るとパーティクル飛ばすOnTriggerEnterイベント

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1088830093135237122

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">🍒チェリー🍒を取ると✨パーティクル✨飛ばしてみたよぉ😍<br>✨キラキラキラ✨<br>（●＾o＾●）ｖ<br>「CharacterController」と「BoxCollider」<br>💖Is Trigger チェックON<br>💖Use Gravity チェックOFF<br>💖Is Kinematic チェックOFF<br>OnTriggerEnterイベントが呼ばれる<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#Unity3d</a> <a href="https://t.co/lDbPLzwyyQ">pic.twitter.com/lDbPLzwyyQ</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1088830093135237122?ref_src=twsrc%5Etfw">2019年1月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<font color="Magenta">Qiitaの容量オーバーで画像が貼り付けられなくなりました。（errorとなる）</font>
続きは、「はてなブログ」に記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2019/01/26/013200)


</br>
</br>
</br>
DOM Based XSS を防ぐ Trusted Types という仕様

## Trusted Types
DOM Based XSS を防ぐ「[Trusted Types](https://wicg.github.io/trusted-types/dist/spec/)」という仕様が、W3Cの[Web Incubator Community Group (WICG)
](https://wicg.io/)で議論されています。

Trusted Typesでは、`element.innerHTML` などにPolicyにあった値(TrustedHTML)のみが代入できるように制限されます。

TrustedHTMLの他にも、同様に指定したポリシーTrustedScript, TrustedScriptURL, TrustedURLなどがあります。

## 例
すでに、Polyfillが提供されているので実行してみる。
`TrustedTypes.createPolicy`で適応するPolicyを宣言し、文字列を引数として`createHTML`メソッドでTrustedHTMLを作成する。

このTrustedHTMLのみが、`element.innerHTML`に代入できる。
直接文字を代入しようとするとTypeErrorとなる。

```
<script src="https://wicg.github.io/trusted-types/dist/es5/trustedtypes.build.js" data-csp="trusted-types mypolicy"></script>
<script>
    function customSanitize(s){
        return s.replace("<", "&lt;");
    }

    const p = TrustedTypes.createPolicy('mypolicy',{
        createHTML: (s) => { return customSanitize(s) },
    });

    e = document.getElementsByTagName('div')[0]
    e.innerHTML = p.createHTML('<test>'); // does not throw. e.innerHTML == '&lt;test>'
    e.innerHTML = "<test>" // TypeError.
</script>
```
![tt.png](https://qiita-image-store.s3.amazonaws.com/0/32425/ba9f1055-d621-2269-8f3e-6d3710fa138f.png)

Trusted-TypesヘッダでPolicy指定することで、そのポリシーのみを適応可能になる。勝手にポリシーを作ったり、上書きでない。

```
Trusted-Types: "one", "two", "default"
```

## 感想
仕様が難しく、ポリシーの適応周りあまりちゃんと理解できなかった...
pandas 指定周期ごとのデータ数を集計する

#はじめに
pandasを使って年単位や月単位でデータ数を集計する方法について調べたので、備忘録として残します。
サンプルコードも載せていますが、メール数の集計等に使えるのではないかと思います。


```python
# 日付情報をDatetimeIndexに変換
    dates = pd.to_datetime(["2019-01-25 03:30:57", "2019-01-25 03:40:57", ...])

# DatetimeIndexをpd.Seriesに変換し、to_periodで指定の周期ごとにまとめる
    dates = pd.Series(index=dates)
    dates = dates.to_period("Y").index

# value_countsで各周期ごとのデータ数をカウントする.
    dates.value_counts().sort_index()
```

以下はサンプルです。以下の例では過去に受信したメール数を年、月、週ごとに集計してエクセルに出力しています。

```python
# -*- coding: utf-8 -*-
import argparse
import datetime
import email
import email.encoders
import mailbox
import re
import os
import sys

import pandas as pd
from pandas import ExcelWriter

#MAILBOX_PATH: mailboxのパスを指定する
#以下はubuntu上のthunderbirdのmailboxのパスの例
#MAILBOX_PATH = "~/.thunderbird/XXXX/ImapMail/XXX.or.jp/INBOX"
MAILBOX_PATH = None
if not MAILBOX_PATH:
    print("MAILBOX_PATH is not set")
    sys.exit(1)


def save_mail_statistics(dates):
    #出力先エクセル名：result.xlsx
    writer = ExcelWriter("result.xlsx")

    #pd.SeriesのindexにDatetimeIndexをセット
    dates = pd.Series(index=dates)

    #1. to_period("Y")で同一年ごとにデータをまとめる
    years = dates.to_period("Y").index
    #年ごとのメール数をカウント. sort_indexで日付の出力順をソート
    years = years.value_counts().sort_index()
    #"num_by_year"シートに出力
    years.to_excel(writer, sheet_name="num_by_year")

    #2. to_period("M")で同一月ごとにデータをまとめる
    months = dates.to_period("M").index
    #月ごとのメール数をカウント. sort_indexで日付の出力順をソート
    months = months.value_counts().sort_index()
    #"num_by_month"シートに出力
    months.to_excel(writer, sheet_name="num_by_month")

    #3. to_period("M")で同一週ごとにデータをまとめる
    weeks = dates.to_period("W").index
    #週ごとのメール数をカウント. sort_indexで日付の出力順をソート
    weeks = weeks.value_counts().sort_index()
    #"num_by_week"シートに出力
    weeks.to_excel(writer, sheet_name="num_by_week")


def decode_header(data, encoding):
    if encoding is not None:
        ret = data.decode(encoding)
    elif isinstance(data, bytes):
        ret = data.decode()
    else:
        ret = data

    return ret.strip()


def iterate_mail_headers(path):
    mail_box = mailbox.mbox(path)
    for mail in mail_box:
        try:
            data = email.header.decode_header(mail["Date"])   
            date = decode_header(data[0][0], data[0][1])
    
            yield date
        except (TypeError, UnicodeDecodeError, UnicodeEncodeError) as e:
            print(e)


def parse_email_headers(path):
    dates = []
    for date in iterate_mail_headers(path):
        dates.append(date)

    #メールヘッダの日付をDatetimeIndexに変換
    dates = pd.to_datetime(dates)
    return dates


def main():
    df = parse_email_headers(MAILBOX_PATH)
    save_mail_statistics(df)

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

エクセルへの出力結果を一部抜粋します。

* num_by_yearシート

![image.png](https://qiita-image-store.s3.amazonaws.com/0/328860/706515db-3bd6-f508-55bd-6ca6af5019fe.png)

* num_by_monthシート

![image.png](https://qiita-image-store.s3.amazonaws.com/0/328860/5b745a0e-4964-d20d-1ed1-fa7c78bbad64.png)


* num_by_weekシート

![image.png](https://qiita-image-store.s3.amazonaws.com/0/328860/2ac8a238-ddd1-a3c7-7760-7eed5d8646e0.png)
Laravelで生成するURLをHTTPS強制にする方法

いろんなやり方があるけど、たぶんこれが一番シンプル

```php5:app/Providers/AppServiceProvider.php
    public function boot()
    {
        if ($this->app->environment() === 'production') {
            \URL::forceScheme('https');
        }
    }
```