OmniAICreator/Qiita-1.07M huggingface dataset:
UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(FSBL編)


## はじめに

UltraZed-EG スターターキットに Debian GNU/Linux (v2018.2版) を構築する方法について、具体的な方法をいくつかに分けて説明します。

 * [Introduction](https://qiita.com/ikwzm/items/5b657ebd8895945c4eae)
 * [Boot Loader](https://qiita.com/ikwzm/items/a0dfef6355cf839ebc08)
   - [Sample FPGA Design](https://qiita.com/ikwzm/items/aae6e17e7d08b089e010)
   - __FSBL   (First Stage Boot Loader)(この記事)__
   - [PMUFW  (Platform Manager Unit Firmware)](https://qiita.com/ikwzm/items/06aeaa22e9b25d21ef88)
   - [BL31   (ARM Trusted Firmware Boot Loader state 3-1)](https://qiita.com/ikwzm/items/4735be0fbdd1e51c7c59)
   - [U-Boot](https://qiita.com/ikwzm/items/2a7006b6c70c8fa397dc)
   - [BOOT.BIN](https://qiita.com/ikwzm/items/d0482bf8bfc7912ff746)
 * [Linux Kernel](https://qiita.com/ikwzm/items/d5417b39c983f8e56af9)
 * [Debian9 Root File System](https://qiita.com/ikwzm/items/a0e88798ed29b30fa003)

この記事では、ZynqMP の Boot Loader で使うための FSBL(First Stage Boot Loader) の構築について説明をします。

## 必要な環境

 * Vivado SDK 2018.2

## Sample FPGA Design の構築

FSBL の構築には Sample FPGA Design のハードウェア情報が必要です。[「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Sample FPGA Design編)」](https://qiita.com/ikwzm/items/aae6e17e7d08b089e010)の通りに target/UltraZed-EG-IOCC/build-v2018.2/fpga/project.sdk/design_1_wrapper.hdf を作っておきます。

## FSBL の構築

ここでは Vivado の hsi(Hardware Software Interface) を使って構築する方法を示します。GUI を使って手で入力するのは面倒なので Tcl スクリプトファイルを用意しています。 Tcl スクリプトの詳しい内容は[「Vivado SDK でZynq FSBL(First Stage Boot Loader)をビルドするTclスクリプト(hsi編)」](https://qiita.com/ikwzm/items/e09fab6b17986471cbda)を参照してください。

```Tcl:target/UltraZed-EG-IOCC/build-v2018.2/fpga/build_zynqmp_fsbl.hsi
#!/usr/bin/tclsh

set app_name          "fsbl"
set app_type          "zynqmp_fsbl"
set hwspec_file       "design_1_wrapper.hdf"
set proc_name         "psu_cortexa53_0"
set project_name      "project"
set project_dir       [pwd]
set sdk_workspace     [file join $project_dir $project_name.sdk]
set app_dir           [file join $sdk_workspace $app_name]
set app_release_dir   [file join [pwd] ".." ]
set app_release_elf   "zynqmp_fsbl.elf"

set hw_design         [open_hw_design [file join $sdk_workspace $hwspec_file]]

generate_app -hw $hw_design -os standalone -proc $proc_name -app $app_type -compile -dir $app_dir
file copy -force [file join $app_dir "executable.elf"] [file join $app_release_dir $app_release_elf]
```

build_zynqmp_fsbl.hsi を Vivado で実行することにより target/UltraZed-EG-IOCC/build-v2018.2/zynqmp_fsbl.elf が生成されます。

```console
vivado% cd target/UltraZed-EG-IOCC/build-v2018.2/fpga/
vivado% hsi -mode tcl -source build_zynqmp_fsbl.hsi
```

## 参考

 * [「Vivado SDK でZynq FSBL(First Stage Boot Loader)をビルドするTclスクリプト(hsi編)」@Qiita](https://qiita.com/ikwzm/items/e09fab6b17986471cbda)
Bitcoin Cash raw transaction

参考
[How to create a raw Bitcoin Cash transaction using JavaScript](https://www.yours.org/content/how-to-create-a-raw-bitcoin-cash-transaction-using-javascript-f838a6786d07/)

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

```console
npm install bch-lib
```

###ライブラリのインポート

```js
var bchLib = require('@owstack/bch-lib')
```

###秘密鍵の設定

```js
var privateKey = new bchLib.PrivateKey('your private key here');
```

###transactionのUTXOを設定

```js
var utxo = {  "txId" : "f8a258720cb68be265baf6828612a401567f916ee50fc276d817f647e4bc1246", "vout" : 0, "address" : "158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1", "scriptPubKey" : bchLib.Script.buildPublicKeyHashOut("158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1").toString(),  "amount" : 0.0009887 };
```

###transactionの生成

```js
var transaction = new bchLib.Transaction()
  .from(utxo)
  .to('18dHsjN9ZZxt99cd8bFJ3r7ajWmidgJEQq', 20000)
  .fee(1000)
  .change('158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1')
  .sign(privateKey);
```

###raw transactionの確認

```js
console.log(transaction.toString());
```

例
01000000014612bce447f617d876c20fe56e917f5601a4128682f6ba65e28bb60c7258a2f8010000008a4730440220176c12031476cb9c781cd3dd47b931ae658394eaf4d22f6376d1a4ab8b0bfc5f022006deb0679cbb600899fa0345d5bf824e34fb9c5e640f8d3aa99bed34c070446d4141047aa0717672b1c86aa13d83e7c7b7cef010f8f1289d41cb14bbef20884efa5342a34a955663ace7fd5bf879f7972a97e7f28a067f74bc78a1287b06f8d6691f54ffffffff01204e0000000000001976a91453a5f0fd9b32593e0f1b4ac418773021e996457c88ac00000000


###サンプル

```js
// using osx, install brew, npm and bch-lib
// brew install npm
// npm install bch-lib
// to run the script 'node raw.js'

var bchLib = require('@owstack/bch-lib')

// you can create a paper wallet from https://walletgenerator.net/?currency=BitcoinCash
// of course, you can also create a wallet here using bch-lib
var privateKey = new bchLib.PrivateKey('your private key here');

// notice that the unspent amount has to be exact or the transaction will fail with a the following error
// 16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element) (code -26)"
var utxo = {
  "txId" : "f8a258720cb68be265baf6828612a401567f916ee50fc276d817f647e4bc1246",
  "vout" : 0,
  "address" : "158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1",
  "scriptPubKey" : bchLib.Script.buildPublicKeyHashOut("158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1").toString(),
  "amount" : 0.0009887
};

// notice that the change address is the same as the address in the utxo
var transaction = new bchLib.Transaction()
  .from(utxo)
  .to('18dHsjN9ZZxt99cd8bFJ3r7ajWmidgJEQq', 20000)
  .fee(1000)
  .change('158avSA4mpuCsKDn8ntCdf5XCrofvmy7M1')
  .sign(privateKey);

console.log(transaction.toString());
```
swiftを読めるようになろう！！２（細かいコードたち・書いたコード上書きして、くっつけてみよう編）

#コードの中でよく見る？けどあんまわかんないコード達
1.  **if文**は２択３択の時に使い、**switch文**は４択以上くらいの時に使った方がコードが可愛くなるかも！
* **int** == 小数点なし、**float** == 32ビットまでの小数点あり、 **double** == 64ビットまでの小数点あり

#書いたコードを上書きして、くっつけてみよう!!
**overrideとは**・・・ちょっと意訳すると、読んで字のごとく『上書き』である！~~いや、そのまんまやないかい！！~~  まぁ、これを書いてあげると上書きが出来るんですよね。

**⚠️下記のコード達は、説明の為に一部のコードを抜き出しているだけです。**
 
```swift 
func run() {
        print("こんばんは。")
}

override func run() {
        print("おはようございます。")
}

```
の場合、
**こんばんは。** と表示されるはずが、`` `override` ``によって**おはようございます。**と上書きしてくれます！！というコードでした。うん。

ちなみに！上書きだけじゃなくて、元のコードもくっつけて表示する場合は、

```swift 
func run() {
        print("こんばんは。")
}

override func run() {
        super.run()
        print("おはようございます。")
}
```
というように`` `super` ``を入れてあげると、元のコードも呼び出してあげられます！！
ですので、**こんばんは。おはようございます。**が表示されるようになります！

記事作成時間　約４５分
Shape Detection APIでカメラの映像から顔認識してみた

# はじめに
こちらの投稿を見て、Webカメラの映像をリアルタイムで認識できるか試してみたくなったので、サンプルを作ってみました。
[3分でできる「 顔認識 」Shape Detection API（ネット接続も不要） - Qiita](https://qiita.com/daisu_yamazaki/items/c782f0154fcb784d4406)
また、以前似たようなことをしていたので、そこからコードを持ってきたりしました。
[SkyWay × Cognitive Service - Qiita](https://qiita.com/sublimer/items/9207b7e6aeaf75717d43)
# 動作環境
* Windows10
* Google Chrome バージョン: 68.0.3440.106（Official Build） （64 ビット）

Chromeは、FaceDetectorが使えるように「Experimental Web Platform features」 `chrome://flags/#enable-experimental-web-platform-features` を `Enabled` に設定してあります。
# 実装
コードはすべてGitHubに公開しています。(もしよかったstar押していただけると嬉しいです)
[ShapeDetectionAPISample - GitHub](https://github.com/Kadoshita/ShapeDetectionAPISample)
処理の流れとしては、

1. Webカメラの映像を取得し、表示
2. 任意のタイミングで映像の一コマを `canvas` に表示
3. `canvas` の画像を `FaceDetector` で顔認識
4. 認識結果が返されたら、 `canvas` の顔の位置に枠を描画
5. 2～4を繰り返す

こんな感じです。
# サンプルコード
[サンプルコード](https://github.com/Kadoshita/ShapeDetectionAPISample)
[デモ](https://sublimer.me/ShapeDetectionAPISample/)

```javascript:main.js
navigator.mediaDevices.getUserMedia({ video: { height: 480, width: 640 }, audio: false })
	.then(function (stream) {
		video.srcObject = stream;
		localStream = stream;

		if (window.FaceDetector) {
			var detector = new FaceDetector();
			captureTimer = setInterval(function () {
				ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
				var scale = 300 / 640;
				detector.detect(video).then(function (faces) {
					ctx.lineWidth = 2;
					ctx.strokeStyle = 'red';
					for (var face of faces) {
						ctx.beginPath();
						ctx.rect(face.boundingBox.x * scale,
							(face.boundingBox.y - face.boundingBox.height) * scale,
							face.boundingBox.width * scale,
							face.boundingBox.height * scale);
						ctx.stroke();
						console.log(face);
					}
				}).catch(function (err) {
					console.error(err);
				});
			}, 1000 / fps);
		} else {
			console.error('FaceDetector is not enable!');
		}
	}).catch(function (err) {
		console.error(err);
	});
```

# まとめ
以前顔認識を行ったときは、MicrosoftのCognitive Services(Face API)を使っていましたが、この方法だと毎分5～6フレームしか認識できません。
今回のサンプルは毎秒30フレーム程度まで認識可能です。(Core i3 6006UでCPU使用率40%前後)
ブラウザだけで手軽に顔認識ができるShape Detection API、早く正式リリースになってほしいなと思います。
TypeScriptで型のユニットテストをしたい

# やり方

## 準備

```ts:test.ts
export type TypeEq<A, B> = (<T>() => T extends A ? 1 : 2) extends (<
  T
>() => T extends B ? 1 : 2)
  ? true
  : false

export function assertType<_T extends true>() {}
export function assertNotType<_T extends false>() {}
```

色々複雑になっていますが、これは any や union、never などに対応するためです。
ここらへんの型は少し特殊なため、このようにしないと正常にテスト出来ません。

## テストの書き方

```ts
assertType<TypeEq<1, 1>>()
assertNotType<TypeEq<1, 2>>()
```

テストが正しくなければコンパイルエラーが発生します。

## 例

```ts
import { TypeEq, assertType, assertNotType } from "./test"

assertType<TypeEq<1, 1>>()
assertNotType<TypeEq<{}, { x: 1 }>>()
assertNotType<TypeEq<1, 2>>()
assertNotType<TypeEq<1 | 2, 1>>()
assertNotType<TypeEq<1, never>>()
assertType<TypeEq<never, never>>()
assertNotType<TypeEq<1, any>>()
assertType<TypeEq<any, any>>()
assertNotType<TypeEq<1, unknown>>()
assertType<TypeEq<unknown, unknown>>()
```

# そもそも何でこんなものが必要なの？

通常の TS の使い方なら必要ありません。
しかし、ts2.1 で Mapped types が入り、ts2.8 で Conditional Types が入り、ts3.0 で Tuple 関連の型システムが強化され TS の型システムはより複雑に、そして高機能になっています。
このような型システムをフル活用すると例えばタプル型を`Reverse`や`Zip`するといったとても複雑な事を行えます。[\[参考\]](https://github.com/Microsoft/TypeScript/pull/24897)(例えば`Zip<[1,2,3],[10,20]>`は型`[[1,10],[2,20]]`を返すなど)
つまり`type`をただの型エイリアスではなく「型を受け取り型を返す関数」として使うことができます。
当然中身はかなり複雑ですし、バグも発生します。
関数のようなものなので正しい値を返してくれるかのテストを行いたいのです。

例えばさっきの例なら

```ts
assertType<TypeEq<Zip<[1, 2, 3], [10, 20]>, [[1, 10], [2, 20]]>>()
```

のように書くことでテストを行えます。
Stellar raw transaction

Stellarで、署名済みトランザクションを生成して、別のマシンからトランザクションを送信する方法について。

参考 https://www.stellar.org/developers/horizon/reference/resources/transaction.html

#XDR
XDRとは、External Data Representationの略で、別のstellar coreでトランザクションを扱うためのデータ形式。JSONなどではなくバイナリで、stellar SDKにデータ構造の処理が含まれている。

Transactionに、xdrが入っている。

| Attribute | Type | comment |
|:--|:--|:--|
| envelope_xdr | string | A base64 encoded string of the raw TransactionEnvelope xdr struct for this transaction |
| result_xdr | string | A base64 encoded string of the raw TransactionResultPair xdr struct for this transaction |
| result_meta_xdr | string | A base64 encoded string of the raw TransactionMeta xdr struct for this transaction |
| fee_meta_xdr | string | A base64 encoded string of the raw LedgerEntryChanges xdr struct produced by taking fees for this transaction. |

## Post Transaction
参考 [Post Transaction](https://www.stellar.org/developers/horizon/reference/endpoints/transactions-create.html)
/transactions
パラメータtxにBase64エンコードしたenvelope_xdrを指定する。(例:"AAAAAO…f4yDBA==")

| name | loc | notes | example | description |
|:--|:--|:--|:--|:--|
| tx | body | required | AAAAAO…f4yDBA== | Base64 representation of transaction envelope XDR |

Response

| Name | Type |  |
|:--|:--|:--|
| hash | string | A hex-encoded hash of the submitted transaction. |
| ledger | number | The ledger number that the submitted transaction was included in. |
| envelope_xdr | string | A base64 encoded TransactionEnvelope XDR object. |
| result_xdr | string | A base64 encoded TransactionResult XDR object. |
| result_meta_xdr | string | A base64 encoded TransactionMeta XDR object. |
M5StackのDHT12サンプル(温湿度センサ)をいじって遊ぶ

神か〜みたいな人しか見かけないので素人がセットアップをしてみます．

![IMG_20180807_230841159_small.png](https://qiita-image-store.s3.amazonaws.com/0/99470/f20f534d-4d55-ce49-1412-9f05d97dd495.png)

# だいたいの手順
1. 買います．M5Stack Grayとプロトキットを買いました．  
  https://www.switch-science.com/catalog/list/770/
2. 環境のセットアップを行います．公式のセットアップを参考にしました(後述)  
  http://m5stack.com/assets/docs/index.html
3. サンプルを読み込んで，そこそこにいじります(後述)

# 環境のセットアップ
macOS High Sierra環境で行いました．
http://m5stack.com/assets/docs/index.html を見つつ進めます．

## ドライバのダウンロードとインストール (Installing the USB Driver)
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers から適切なものを持ってきます．

`do NOT use the Windows 10 Universal (v10.1.1) driver!`とのことなのでWindowsの人は注意が必要そうです．
※macOSの場合，インストール中にセキュリティ警告が出るので，システム環境設定→セキュリティとプライバシーから許可を出さないといけないという別の注意があります．

## ESP32 Arduino Coreの導入 (Installing the ESP32 Arduino Core)
OSごとに手順が異なります．

macOSの場合は　https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/mac.md#installation-instructions-for-mac-os を参照して進めます．
1. Arduino IDEの導入(まだの場合)
2. おまじないを実行
  ターミナルを開いて以下をペーストし，EnterでOKとのこと

```bash
mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && \
python get.py
```
このあと，Arduino IDEをすでに開いている場合は再起動しておきます．

## Arduino用ライブラリのダウンロード (Download Library)
Arduino IDEから行う方法をなぞります．

1. Arduino IDEを起動して，`スケッチ`→`ライブラリをインクルード`→`ライブラリを管理`を選択
2. 検索フィルタに`m5stack`と打ち込んで，`M5Stack`を選択し，`インストール`をクリックし，インストールします．
3. インストールが完了したらサンプルやらなんやらが使えるようになります．

# DHT12向けサンプルを読み込んでいじる
## まずは動かしてみる
M5StackのUSB-Cポート横の穴に温湿度センサを繋いで，USBケーブルでPCに繋いでおきます．
Arduino IDEを開き，`ファイル`→`スケッチ例`から「カスタムライブラリのスケッチ例」にある`M5Stack`→`Modules`→`DHT12`を選びます．
サンルが開いたら，`ツール`→`ボード`から`ESP32 Arduino`→`M5Stack-Core-ESP32`を選びます．ついでに`ツール`→`シリアルポート`→`/dev/cu.SLAB_USBtoUART`も選んでおきます．
準備ができたらウィンドウ左上にある「→」ボタンを押しましょう．動きますね．ただ，ちょっと表示が変な上に，画面をいっぱいにしてもリフレッシュされません．

## そこでこんなふうに変えてみました
ちょっとしたタイポ(`M5.Lcd`にすべき部分が`Serial`になっている)のと画面がいっぱいになっているかの判定がないのが原因なのでちょっといじってみました．
ついでにFやKでの温度をシリアルに流すのも止めてしまいました．

```C:DHT12mod.ino
#include <M5Stack.h>
#include "DHT12.h"
#include <Wire.h>     //The DHT12 uses I2C comunication.
DHT12 dht12;          //Preset scale CELSIUS and ID 0x5c.

// 画面に何行表示したかのカウント
int count = 0;

void setup() {
  M5.begin();
  Wire.begin();
  Serial.println("Testing DHT12 lib:");
  M5.Lcd.println("Testing DHT12 lib:");
}

void loop() {
  //Read temperature with preset scale.
  Serial.print("Temp.: ");
  M5.Lcd.print("Temp.: ");
  Serial.print(dht12.readTemperature());
  M5.Lcd.print(dht12.readTemperature());

  //Read humidity.
  Serial.print("*C  Humid: ");
  M5.Lcd.print("*C  Humid: ");
  Serial.print(dht12.readHumidity());
  M5.Lcd.print(dht12.readHumidity());
  Serial.println("%RH");
  M5.Lcd.println("%RH");

  // 表示回数の更新
  count++;
  
  delay(5000);

  // 1文字の高さが8pxなので30行出すといっぱいになる
  // 30行表示したら画面をクリアして，一番上から再開
  if(count == 30){
    count = 0;

    Serial.println("Clear LCD Output...");
    
    M5.Lcd.fillScreen(0x0);
    M5.Lcd.setCursor(0, 0);
  }
}
```

以上！これで画面いっぱいになったらクリアしてくれます．
youtubeの埋め込み動画を、一行でwebサイトの横幅に合わせるCSS

### 三行で解説

- youtubeの埋め込み動画の横幅が、webサイトより大きくなる原因は、iframeのwidth指定が原因
- よっぽど変な組み方のHTMLやCSSでない限り、以下のCSSを入れることで解決するはず
- `iframe[src^="https://www.youtube.com/embed/"] { max-width: 100%; }`

### もうちょっと細かく解説

　youtubeの動画から埋め込みコードを取得すると、以下のようなHTMLタグがコピーされる。

```html:youtubeで、右クリック→埋め込みコードをコピーにより取得できるタグ（見やすさのため、途中で改行）
<iframe width="1133" height="637" src="https://www.youtube.com/embed/f0RJ1_709DY" 
frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
```

　これをそのままコピペすると、サイトの造り（特にスマホ）によっては枠の横幅をはみ出すことがある。

・yotubeの埋め込み動画が、枠をはみ出すイメージ図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/111447/91288c88-1ef3-43f7-bd65-e1335b2a861f.png)

　デベロッパーツールで試した感じ、`<iframe>`にwidth系のCSSを適用したら解決しそうな感じだった。
　ただ、そのためにclassを追加したり、親`<div>`を作るのは嫌なので、youtubeの`<iframe>`のみに適用する方法を検討した。
　その結果、以下のCSSを入れることで、対応できた。

```css:youtubeの埋め込み動画を、枠からはみ出させないCSS
iframe[src^="https://www.youtube.com/embed/"] {
 max-width: 100%;
}
```

　httpや//で参照したり、他のドメインの埋め込み動画だった場合は、このままだと適用されません。
　余程変なことでもない限り、既存のCSSには影響はしないはず。
　`height:auto;`を入れても良い気はするけれど、自分が試した範囲では動画がとても小さくなった。

### 備考

　投稿の直前に、念のため既存のqiita記事を探してみたら、既に既出だった。
>Youtubeの埋め込みタグを編集せずにレスポンシブ化
>　https://qiita.com/torosalmon/items/e65ed8fcf61c2e5ff8ee#3

　削除するのも勿体ないので、このまま投稿。
Railsのversion更新時に伴うactiverecord-session-storeの振る舞いについて

# RailsのSession管理について
RailsでSessionの管理を行う際に、SessionStoreという形式が提供されています。
ファイルでいうところの ``` config/initializer/session_store.rb ``` です。

デフォルトではCookieStoreというブラウザのCookieを使う方法が利用されています。

* https://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html

CookieStoreは、サーバを通ることがないため非常に高速ですが、いくつのか欠点もあります。

1. 逆にサーバからSession情報を変更したいタイミングでアクセスができない。
2. CookieSessionへの再生攻撃やセッションハイジャックなどのセキュリティリスク
    * https://railsguides.jp/security.html#cookiestore%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E5%86%8D%E7%94%9F%E6%94%BB%E6%92%83

他にもありますが、プロトタイプを作る際などには他のサーバやmiddlewareを用意する必要もありませんが、サービスが伸びてくるにつれ、上記の欠点が浮き彫りになってくると思います。

# ActiveRecord-Session_Storeについて
* https://github.com/rails/activerecord-session_store

これはActiveRecordでSessionを管理する方法です。すなわちブラウザCookieではなく、DBでsessionを管理します。
gemとして提供されており、READMEのInstallationを行うだけでよく、非常に楽です。


他にもSessionStoreとしてはredis-railsが有名でしょうか。

* https://github.com/redis-store/redis-rails

## Sessionのloadとdump

ActiveRecord-Session_Storeでは、serializerというどういった形式でsessionを保存するのかが記載されています。

https://github.com/rails/activerecord-session_store/blob/master/lib/active_record/session_store.rb#L42

1. MarshalSerializer
  * Marshalモジュールにて書き出し、読み込みを行いBase64で加工をしています。
    * https://docs.ruby-lang.org/ja/latest/class/Marshal.html 
2. JsonSerializer
  * 名の通り、JSON形式で管理をします。 
3. HybridSerializer
  * Marshal形式からJson形式への変更を行うhybridな管理法です。
4. NullSerializer
  * データを何も加工せず、そのまま保存する形式です。


## Rails version更新時に伴うactiverecord-session-storeの振る舞いについて
ここでようやくタイトル回収です。

Railsのversionを更新する際には、ActiveSupportにて定義されている```Marshal#load```の形式も変わります。

1. 4.2系の場合
    * https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/core_ext/marshal.rb
2. 5.1系の場合
    * https://github.com/rails/rails/blob/5-1-stable/activesupport/lib/active_support/core_ext/marshal.rb

version upの際に、SessionデータをMarshal形式で保存していると、
例として4.2から5系へと更新をするとして
更新タイミングでMarhsalの形式が変更され、**sessionを読み込むのと同時に値が変わる可能性があります。**

何もなければ問題はありませんが、**一部のデータではempty hashの値がnilになっていたりと、version更新時に障害となる可能性があります。**

## 対策
対策としては簡単で、Session情報を削除するだけです。
そうすることで、Railsの新規versionで新しくSessionデータが作られるので、versionの変更によるデータ不整合は起きません。

```
$ bin/rake db:sessions:clear
```

とすることで、sessionsテーブルがtruncateされ、sessionデータを空にすることができます。

とはいえ本当に空にしていいのかは**アプリケーションの実装にもよると思います** (immutableではないなど)
その場合は、Railsのversion更新前に```HybridSerializer```を利用し、Marshal形式からJSON形式へ変更をしておくと安心できるかもしれません。
【Game a Week】１週間目

# Game A Week
1. 一週間（月曜日から日曜日）に一本ゲームをリリースする。
2. 日曜日（まで）に制作したゲームを何らかの手段で公開する。
3. 制作したゲームは_Game A Week_が終わるまで改変しては行けない。

# なぜGame A Weekをやろうと思ったか
僕はゲームを作るのが好きなのですが、技術が劣っている部分が多く、この_Game A Week_をしながらゲーム開発に関する知識や技術を増やせないかと思い、始めることにしました。

# 今回作ったゲーム
一週間目で作ったゲームは「SwitchAndGet」。
Unityで開発しました。
プラットフォームはWeb(WebGL)です。

あまりUnityには慣れていませんがちょっとしたゲームも

## ゲームの詳細
実行すると_タイトル_が表示されます。
![スクリーンショット 2018-08-10 20.08.03.png](https://qiita-image-store.s3.amazonaws.com/0/154299/21ea0487-c6a3-b6fd-3653-88ccaddc6d26.png)

_Play_をクリックするとゲームスタートです。
![スクリーンショット 2018-08-10 20.09.31.png](https://qiita-image-store.s3.amazonaws.com/0/154299/99a319d1-4c8a-7a82-f9aa-8e4c227f6488.png)

操作方法はシンプルで**スペースキー**を押すとプレイヤーが移動します。
ただし移動には規則があり、**プレイヤーが下にいるときは上に、プレイヤーが上にいるときは下に**移動します。
移動するたびに得点が増えます。
![スクリーンショット 2018-08-10 20.10.26.png](https://qiita-image-store.s3.amazonaws.com/0/154299/492e9be0-6e2d-d334-65d3-71b66d97a902.png)
右から出てくる**障害物に当たってしまうとゲームオーバー**です。
![スクリーンショット 2018-08-10 20.11.19.png](https://qiita-image-store.s3.amazonaws.com/0/154299/13dfbbcb-4ffc-2bb6-e088-55f6de0f28f7.png)
制限時間などの機能も考えましたが、ギリギリ間に合いませんでした。

## URL
最初はiOS向けに作っていたので
[ここから](http://game-a-week.hota1024.com/projects/SwitchAndGet)Web版が遊べます。
ぜひ遊んでみてください。
※WebGLだとスコアが表示されませんでした。いろいろ調べてみましたが、時間切れで間に合いませんでした。どなたか

# １周間目の感想
何故かアイディアって寝てるときに出てくるんですよね..
暗いところで急に明るい画面を見てメモするのがしんどいです（笑）
このゲームのアイディアは月曜日に思いついたものに、少し時間をかけて掘り下げたものです。

作っていて少しハマったところが当たり判定です。
最初は、プレイヤーと障害物の当たり判定がうまくいきませんでした。
プレイヤーにも障害物にも`BoxCollider2D`を付けているのに`OnTriggerEnter`が動かなくて、かなり悩みました。
ネットで30分ぐらい調べたところどうやら`Rigidbody2D`が必要だったみたいです。

最初はこのぐらいのゲームしか作れませんが、少しずつ一週間で本格的なゲームを作れるようになりたいです。

# 最後に
ここまで読んでいただきありがとうございます。
良ければアドバイスや質問よろしくおねがいします。
【仕事メモ】OpenAM(Ver13) Office365との認証連携（２）

# おさらい
前回まででIdPとトラストサークルの設定、Office365をSPとして登録する部分までが完了しました。
今回はSAML連携するための属性マッピングとユーザーの属性情報変更などを実施する手順を記載します。

## エンティティプロバイダの設定変更
Office365とOpenAMユーザー(OpenDJ上に存在するユーザー)を社員番号(employeeNumber)属性でマッピングしようと思います。
まずはOpenAMトップ画面から「FEDERATION」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/d4b8a2a7-69c0-de1c-3979-ffc464ffecb5.png)

「エンティティプロバイダ」の設定にOffice365の設定が表示されているので「名前」欄のリンクをクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/13f1cbd0-9250-26ac-b888-238d32600c15.png)

次にNameIDの書式という項目にemployeeNumberを追加していきます。
Office365は下記のような書式で属性を認識します。

```powershell:NameID書式
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent=【マッピングする属性名】"
```

上記の書式でマッピングするNameIDを追加します。
今回は以下の属性を追加です。

```powershell:追加するNameID
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent=employeeNumber
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/ebd33886-6fb5-f2c7-440d-9dfa797fbe5f.png)

次に「表明処理」の項目で設定を追加します。
追加するのは「IDPEmail=mail」という属性です。
この「IDPEmail」はOffice365側で指定された属性なので、他の名称に変更することは不可です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/a9f0ee5b-8dc3-c283-d50c-b1e56233e79b.png)

設定を追加したら、「保存」をクリックします。
とりあえず↓のような表示が出れば、OKです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/748e7cc2-384c-ef47-cc68-89aa80c812e2.png)

ここまでの設定でOpenAM側におけるOffice365アカウントの社員番号(employeeNumber)属性、
メールアドレス(UPN)との属性マッピング設定が完了しました。

## OpenAMユーザーの属性値変更
次にOpenAMに登録しているユーザーの属性値にOffice365のログインIDとなるUPNの属性を設定します。
OpenAMトップ画面からデータストアを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/29d8f077-2089-4fb8-a0b9-91e09db9a2f7.png)

次に「対象」を選択して、以前作成したユーザーを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/c7ab3109-13d8-eeab-59aa-7616eb1b4682.png)

※この部分に関する操作の詳細は以前の記事に記載しているのでそちらをご覧ください。

__【仕事メモ】OpenAM(Ver13) データストアの連携とローカル認証の確認（２）__
https://qiita.com/Blue2012/items/e0884082878386937a2d

下記の属性値をそれぞれ編集します。

　・電子メールアドレス：ユーザー名@Office365のドメイン名(独自ドメインを取得している場合はその値)
　・社員番号：任意の値

属性の編集が完了したら「保存」をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/138274/cfb25f8b-c243-c8d8-34bf-802773adb2a9.png)

ここまででOpenAM側の属性マッピング設定、ユーザー属性の変更作業が完了します。

## 次回予告
次回はOffice365側のSAML連携設定を行います。
設定が完了するとOpenAMにログインしたユーザーはOffice365にSSO可能になります。
クソゲー街道

# クソゲーとは
クソゲー、それは大ヒットタイトルになろうとするもなりきれなかった奴らの総称だ
そんなクソゲーのソースコードを1つ公開(後悔)しようと思う

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;//シーン遷移扱う

public class ManagerScript : MonoBehaviour
{
	[SerializeField] Button dontPushButton;//DontPushButtonをUnityからアタッチ
	[SerializeField] Button daihyoButton;//DaihyoButtonをUnityからアタッチ
    
	[SerializeField] Sprite[] sprites = new Sprite[8];//画像Unityからアタッチ
	int spriteNum;//どの代表画像を表示するか指定(ランダム取得)

	float timer;//タイマー
	public float scoreTimer;//スコア計測の為のタイマー
	bool scoreMeasurement;//score計測をするかどうかのフラグ
	float daihyoInterval;//daihyoが表示されるまでの時間(Random.Rangeで取得)
	bool isDaihyou;//daihyouの表示を司るフラグ

	public float score;

	void Start()
	{
		GetRandomDaihyoImage();//代表の画像をランダム取得

		daihyoInterval = Random.Range(1.0f, 5.0f);//1-5秒の間をランダム取得→変数daihyoIntervalに格納

		daihyoButton.gameObject.SetActive(false);//最初DaihyoButtonは無効化
		isDaihyou = false;//最初isDaihyouはfalse
		scoreMeasurement = false;
		Debug.Log("Daihyo False");
	}

	void Update()
	{
		timer += Time.deltaTime;//タイマースタート

		if (timer > daihyoInterval)//timerが任意の値を超えた時
		{
			if(isDaihyou == false)
			{
				daihyoButton.gameObject.SetActive(true);//最初DaihyoButton有効化
                Debug.Log("Daihyo True");

				isDaihyou = true;//繰り返し呼ばれない為の工夫
				scoreMeasurement = true;//scoreTimerスタート
			}
		}

        //DaihyoButton押したら呼ばれる
		if(scoreMeasurement == true)
		{
			scoreTimer += Time.deltaTime;//score計測の為のタイマー開始
		}
	}

	//DontPushButton押した時に呼ばれる関数
	public void DontPushButton()
	{
		Debug.Log("Pushed DontPushButton");
		SceneManager.LoadScene("GameOver");
	}

	//DaihyoButton押した時に呼ばれる関数
	public void DaihyoButton()
	{
		scoreMeasurement = false;
		PlayerPrefs.SetFloat("score", scoreTimer);//LastScoreの名前でscoreTimerの値を保存
        
		Debug.Log("Pushed DaihyoButton");
		SceneManager.LoadScene("End");//Endシーンに移行
	}

    //代表の画像をランダム取得
	void GetRandomDaihyoImage()
	{
		spriteNum = Random.Range(0, 8);//1-8の整数ランダム取得
		daihyoButton.image.sprite = sprites[spriteNum];//ランダムな代表画像をdaihoButtonに適応
	}
}
```

これで以上だ。
こいつを殺すも死なすもあなた次第。
Promiseと配列

次のような、配列の各要素に対して、何かの関数(syncFunc)を呼び出す処理をしているコードをPromise版のasyncFuncを使う形に置き換える時用のメモ

```
["foo", "bar", "baz"].forEach((e)=>{
  syncFunc(e);
});
```

以下のコードは全てasync function内にあるものと思ってください。

### 配列内の各要素に対する処理を並列に行なっても問題無い場合
```
await Promise.all(["foo", "bar", "baz"].map((e)=>{
  return asyncFunc(e);
}));
```
for ofを使うとこういう書き方もできます。

```
const tmp=[];
for(const e of ["foo", "bar", "baz"]){
  tmp.push(asyncConsoleLog(e));
}
await Promise.all(tmp);
```

promiseを格納する配列を別に用意する必要があるのがちょっと美しくないですが、関数に渡すデータが複数の配列に入っている時なんかは、このままforループを増やしていって、最後に一回Promise.allすれば良いので便利そうですね。

### 順次実行する(前の要素の処理が終わってから次の処理を行う)必要がある場合
```
await ["foo", "bar", "baz"].reduce((p,e)=>{
  return p.then(()=>{
    return asyncFunc(e);
  })
},Promise.resolve())
```
こちらも、for ofを使うと次のように書き換えられる。

```
for(const e of ["foo", "bar", "baz"]){
  await asyncConsoleLog(data);
}
```

こっちは圧倒的にfor ofの方が便利そうです。というか、そもそものreduce関数の使い方が分かり難いだけとも言えるかもしれませんが。


<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="クリエイティブ・コモンズ・ライセンス" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />この記事は <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">クリエイティブ・コモンズ 表示 4.0 国際 ライセンス</a>の下に提供されています。


---
2019/3/27 reduce関数と書くべきところをmap関数と書いていたので訂正しました。
Windows10でKerberosにシングルサインオンする

# 動機
既に動いているKerberosレルムに、Windows10を足してみたいとずっと思っていた。
Samba 4からドメインコントローラーが作れるそうなので、あまり意味がないかもだが、お手軽だったので、メモ。
正しいかは自信なし。
前に試した時は、結局うまくいかなかった記憶があるが、やったことはWindows2000の時代と同じ。

# 環境
- OpenBSD 6.3 + heimdal-7.5
- Windows10 Insider Preview RS5 17728

# 前提
- Kerberosレルムを作成済み
- ユーザープリンシパルを作成済み
- sshなど他の環境で、ユーザープリンシパルの認証を確認済み
- WindowsホストのDNSレコードを作成済み
- WindowsホストのNTPを設定済み

# KDCの設定
## ホストプリンシパルの追加
ランダムパスワードの生成(`add -r`)ではなく、パスワードを手で入力(`add`)する。

```
# kadmin -l
kadmin> add host/win.example.org
```

# Windowsの設定
やっていることは、ほとんど[こちらの記事](http://www.monyo.com/technical/windows/kerberos2.html)そのまま。
ちょっとだけオプションの名前が変わっている模様。

## Kerberosの設定
`コマンド プロンプト`を`管理者として実行(A)`。
`ksetup`のマニュアルは、WindowsServer用だが[こちら](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ksetup)を参照した。

- Kerberosレルムを設定する `ksetup /setrealm EXAMPLE.ORG`
- KDCを設定する `ksetup /addkdc EXAMPLE.ORG kdc.example.org`
- ホストプリンシパルを設定する `ksetup /setcomputerpassword <パスワード>`
 - パスワードは、ホストプリンシパル作成時に付けたもの
- ユーザープリンシパルとWindowsのアカウントを紐付ける `ksetup /mapuser * *`

設定が終わったら、まとめて再起動。

## ホスト名の確認
[こちら](http://d.hatena.ne.jp/JULY/20110805)によると、フルコンピューター名がFQDNと一致している必要がある。
`ksetup /setrealm`でDNSサフィックスが変更されるが、念のためフルコンピューター名を確認する。

- `システムのプロパティ`->`コンピューター名`の`フル コンピューター名`

ドメイン名が付いていない場合、DNSサフィックスを修正して、フルコンピューター名を再確認する。

 - `変更(C)...`->`詳細(M)...`で`このコンピューターのプライマリDNSサフィックス(P):`

# Windowsのローカルアカウントの追加
ローカルのユーザーアカウントを作成する。[本家記事](https://support.microsoft.com/ja-jp/help/4026923/windows-10-create-a-local-user-or-administrator-account)を参照。
`アカウントの種類`は設定しておくが、パスワードは設定しなければ、入れないアカウントができる…と思う…。

# Windowsにサインイン
`hoge@EXAMPLE.ORG`のように、`ローカルアカウントのユーザー名@レルム名`と、ユーザープリンシパルのパスワードで、サインインできた。

# 宿題
- エクスプローラーが固まるようになったのは…17728のせい?
    - 追伸: 17758では起こらなくなった模様
- 暗号方式は…どれが使われている?
- パスワード変更
- IPv6
- Sambaのドメインコントローラー
angular6 の i18n で生成した xlfファイルをマイクロソフトの多言語アプリ ツールキットで編集可能にする

body タグの下に `<group id="MICROSOFT.VISUALSTUDIO.VALIDATION/STRINGS.RESX" datatype="resx">`タグを追加する。

```
<body>
<group id="MICROSOFT.VISUALSTUDIO.VALIDATION/STRINGS.RESX" datatype="resx">
  <trans-unit...>
    ...
  </trans-unit>
</group>
</body>
```

多言語アプリ ツールキット 4.0 エディター
https://developer.microsoft.com/ja-jp/windows/develop/multilingual-app-toolkit
AWS EC2 インスタンス立ち上げ

#EC2の立ち上げからログインまで

個人的な環境の立ち上げ方法の覚書
前提として、AWSのコンソールにログインできる(AWSのアカウントがあることが前提です)

## インスタンス起動
AWSコンソール画面から「EC2」を選択。
「EC2」の画面中部にある「インスタンスの作成」を選択

- OSの選択：Amazon Linux 2

特にこだわりがなければこちらに(モジュールのインストールの仕方がちょっと特殊ですが・・・)。2017年12月にリリースされ、LTS(長ーくサポートしていきます)となっているので。

- インスタンスタイプ：t2.micro

こちらも特にこだわりなければ。

ここまでで「作成」ボタンを押すと、確認画面が出てきます。細かく設定していきたければ、「インスタンス詳細の設定」で。

- セキュリティグループ：以下参照

確認画面で「セキュリティグループの編集」と押してもらうか、詳細設定中の画面で設定できます

最低限、sshで繋ぐ用とhttpでwebページを確認できる用があればいいかなと。
![セキュリティグループ.png](https://qiita-image-store.s3.amazonaws.com/0/92773/a6eb7410-6704-687e-139d-f67a064883c6.png)
ソースを「カスタム」→「マイIP」にすると、自動で今使っているPCのIPを設定してくれます。
普段使いのPCで一旦ここからしかアクセスしないのであればこれでもいいと思います(＊固定IPじゃないと思うのでいろいろ設定完了したら変更してください)。

- キーペアの生成

「作成」を押すと、最後にキーペアの作成画面が出てきます。
　　・ 新しいキーペアの作成
　　・ 自分の好きな名前にして<font color="Red">「キーペアのダウンロード」</font>
　　 例）aws_me → aws_me.pem というファイル名でダウンロードできます
　　　　ログイン時に必要なので、わかるところに保存しておいてください。

＊ 保存キーファイルのパーミッション変更（しておかないとログインで怒られる）

```
$ chmod 400 [DLしたキーファイル(.pem)] 
```

## インスタンスにログイン
コンソール画面「EC2」の左にある「インスタンス」を選択すると、先ほど作成したインスタンスがあります。
パブリックDNS(もしくはパブリックIP)をコピーして以下のコマンドでログイン

```
$ ssh ec2-user@[パブリックDNS] -i [DLしたキーファイル(.pem)] 
```
＊ デフォルトユーザ：ec2-user

### ユーザの作成
「ec2-user」(デフォルトユーザ)のままというのも嫌なので自分のユーザを作ります
例）ユーザ名：hoge（適宜自分の好きな名前で）

```ユーザ作成&パスワード設定.
$ sudo adduser hoge
$ sudo passwd hoge
```
```wheelグループ(ec2と同じグループ)に作ったユーザを追加.
$ grep wheel /etc/group　
wheel:x:10:ec2-user   　　　　　　　　　　　#現在のメンバー確認

$ sudo usermod -G wheel hoge

$ grep wheel /etc/group
wheel:x:10:ec2-user,hoge　   #加わったことを確認
```
```ec2-userのssh情報一式をコピー.
$ cd /home/hoge
$ sudo rsync ../ec2-user/.ssh/authorized_keys .ssh/
$ sudo chown -R hoge:hoge .ssh
$ sudo chmod -R go-rwx .ssh   #グループ(g)、その他(o)から全権限(rwx)を引く(無くす)
```
```新ユーザでrootになれるようにしておく.
$ sudo visudo

  ## Allow root to run any commands anywhere
  root    ALL=(ALL)       ALL
+ hoge    ALL=(ALL)       NOPASSWD: ALL
```

- ログインしなおし

```
$ ssh hoge@[パブリックDNS] -i [DLしたキーファイル(.pem)] 
```

<font color="Red">ちゃんと作ったユーザでログインできてから「ec2-user」は削除してください</font>

```ec2-user削除.
sudo userdel ec2-user
```

とりあえずここまで。
Retroscope をつくろう


# はじめに

これは [State of the Map Japan 2018](https://stateofthemap.jp/2018/) の講演で使用したサンプルコード置き場です。

# 1. OpenStreetMap を表示しよう

このコードが

```a.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>hello leaflet</title>
  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js"></script>
</head>

<body>
  <div id="map" style="position:absolute;top:0;left:0;bottom:0;right:0;"></div>
  <script>
    var map = L.map("map").setView([35.671872, 139.754969], 18);
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution: "&copy; <a href='http://osm.org/copyright'>OpenStreetMap</a>contributors"
    }).addTo(map);
  </script>
</body>

</html>
```

こうなります

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/7cb7b49a-80a4-a4b0-dda2-9849b50800de.png)

# 2. Retroscope を表示しよう

このコードが

```b.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>retroscope</title>
  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js"></script>
  <script src="https://frogcat.github.io/leaflet-tilelayer-mask/leaflet-tilelayer-mask.js"></script>
</head>

<body>
  <div id="map" style="position:absolute;top:0;left:0;bottom:0;right:0;"></div>
  <script>
    var map = L.map("map").setView([35.671872, 139.754969], 18);
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution: "&copy; <a href='http://osm.org/copyright'>OpenStreetMap</a> contributors"
    }).addTo(map);

    var layer = L.tileLayer.mask("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg", {
      attribution: "<a href='http://maps.gsi.go.jp/development/ichiran.html'>地理院タイル</a>"
    }).addTo(map);

    map.on("mousemove", function(event) {
      layer.setCenter(event.containerPoint);
    });
  </script>
</body>

</html>

```

こうなります


![retroscope.gif](https://qiita-image-store.s3.amazonaws.com/0/82494/436ef2b5-0a08-ff91-1b3a-d101922ea580.gif)
Railsの不特定ModuleやClass(Modelなど)で`_path`を使う

# 名前付きルーティング
Railsでは`path/to/foo`を表示するために`foo_path`のような便利なメソッド([Url Helper](https://railsguides.jp/routing.html#%E3%83%91%E3%82%B9%E3%81%A8url%E7%94%A8%E3%83%98%E3%83%AB%E3%83%91%E3%83%BC))があります。  
しかしこの機能はController、HelperとViewでしか使えません。もしmodelや自作moduleで`foo_path`を呼ぶと、下記エラーが発生します。

```ruby
class Foo
  def self.show_path_1
    foo_path
  end

  def show_path_2
    foo_path
  end
end

Foo.show_path_1
# => NameError: undefined local variable or method `foo_path' for Foo:Class

foo = Foo.new
foo.show_path_2
# => NameError: undefined local variable or method `foo_path' for #<Foo:0x007fccd191b8b0>
```

# 一般的な解決法
`Url Helper`は`Rails.application.routes.url_helpers`より提供されていますので、下記書き方で解決できます。

```rb
Rails.application.routes.url_helpers.foo_path
# => path/to/foo
```

ちなみに`rails console`の場合、`app.foo_path`でもつかえます。

# もっと自然な書き方
pathを書くたびに`Rails.application.routes.url_helpers`を書くのはやっぱり不自然ですね。ControllerやViewのように`foo_path`を直接書く方法があるでしょう？  
一言いうと、あります。Gem [Sitemap Generator](https://github.com/kjvarga/sitemap_generator)を使う時、`sitemap.rb`の中で`foo_path`を書けます。  

もしクラスメソッドで使いたい場合、この書き方で

```rb
class Foo
  class << self
    include Rails.application.routes.url_helpers
  end

  def self.show_path_1
    foo_path
  end
end

Foo.show_path_1
# => path/to/foo
```

もしインスタンスメソッドの中で使いたい場合、こちらの書き方で

```rb
class Foo
  include Rails.application.routes.url_helpers

  def show_path_2
    foo_path
  end
end

foo = Foo.new
foo.show_path_2
# => path/to/foo
```

# 参考
- https://stackoverflow.com/questions/6074831/how-to-access-url-helper-from-rails-module#answer-23272893
- https://qiita.com/gogotanaka/items/c931360b3f6248959f89
- https://qiita.com/miyazawa_shi/items/ad587553041a8a484415
- [Rails: URLヘルパーをビューやコントローラ以外の場所で使う（翻訳）](https://techracho.bpsinc.jp/hachi8833/2021_03_05/104476)
- [【Rails】urlヘルパーでhostの指定](https://qiita.com/koki_73/items/0ce9ba6d2b28eff5ea42)
【初心者向け】OpenCVで顔検出を行う（静止画）

#はじめに
1週間前にOpenCVを始めてからハマりっぱなしですww
今回はOpenCVを用いて顔検出を行ってみます．
**※まだOpenCV超初心者なので間違いなどあればご指摘ください**

#環境
- OpenCV v3.4.2
- VisualStudio2017
- 顔検出に用いるカスケード分類器（[ここからダウンロードしてください](https://github.com/opencv/opencv)）

※正面の顔を検出するカスケード分類器は，上記のGitHubからダウンロードしたファイルの
 "opencv-master\opencv-master\data\haarcascades"の中に入っている【haarcascade_frontalface_alt.xml】を使います．

#入力画像
今回はお馴染みのLenaさんを使って行います．
![lena.jpg](https://qiita-image-store.s3.amazonaws.com/0/257442/64132491-001f-3783-afbf-99066f90bbdf.jpeg)

#ソースコード
```cpp:detectFace.cpp
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <vector>

using namespace cv;
using namespace std;

int main()
{
	CascadeClassifier cascade;
	cascade.load("ファイルまでのパス/haarcascade_frontalface_alt.xml"); //正面顔情報が入っているカスケードファイル読み込み
	Mat img = imread("ファイルまでのパス/lena.jpg", IMREAD_UNCHANGED); //入力画像読み込み
	vector<Rect> faces; //輪郭情報を格納場所
	cascade.detectMultiScale(img, faces, 1.1, 3, 0, Size(20, 20)); //カスケードファイルに基づいて顔を検知する．検知した顔情報をベクトルfacesに格納

	for(int i = 0; i<faces.size(); i++) //検出した顔の個数"faces.size()"分ループを行う
	{
		rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 3, CV_AA); //検出した顔を赤色矩形で囲む
	}

	imshow("detect face", img);
	waitKey(0);
}
```

#出力画像
以下のように出力されました．正常に顔を検出できていますね．
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/257442/443c65e8-2870-60c7-453c-9e9fc6cda6fd.png)

#おまけ
他の画像でも顔検出を行ってみました．
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/257442/bcde380a-ca4e-6ed9-6eb7-48da0c9fe63b.png)
やっぱり顔が少し横に向くと検出が難しくなるみたいですね．


#おわりに
~~次はUSBカメラで撮影した動画に対してリアルタイムで顔検出を行う予定です．~~
実装しました！よかったら合わせて読んでください↓↓
[【初心者向け】USBカメラで撮影した動画をリアルタイムで顔検出](https://qiita.com/yutoakaut/items/6787aed37721a8a22f64)
【SQL】CONCATで追加したいけどNULLじゃできない！！

#はじめに：SQLでCONCATを使ってテキストを追加したかった。

前提

- columnの値がNULLである可能性がある
- 既にあるはずの値を消さずに更新したい


```sql

UPDATE table SET column = CONCAT('先頭に追加じゃ！！', column);
```
columnがNULLだとUPDATEできないじゃん！

##IFNULLを使って解決しよう！！



```sql
UPDATE table SET column = CONCAT('先頭に追加じゃ！！', IFNULL(column, ''));
```
NULLだったら''を突っ込んでやりゃええやん！

##改行もしたかった！！

```sql
UPDATE table SET column = CONCAT('LFで改行じゃ！！\n', IFNULL(column, ''));

UPDATE table SET column = CONCAT('CRLFで改行じゃ！！\r', IFNULL(column, ''));

UPDATE table SET column = CONCAT('両方やっちまえ！！\r\n', IFNULL(column, ''));
```

改行する時のLFとCRLFの気遣いの仕方をあまり理解してないけど今回はLF`\n`にしましたとさ～

おわり
エンジニア歴4ヶ月になって初めて知りました。
やっぱり実務しないと調べませんね～
【自分用メモ】光回線の現調って何するの？

オフィス移転時に色々体験したことを、主観的なコメントとして残しておきます

# 現調について
- オフィスビルに必要な回線があることを確認する。
    - 普通のオフィスビルだと、MDFやEPSにNTTとKDDIのPD盤があるか確認することになる。
- 回線引き込みフロアまでの配線ルートの確認
    - 回線を引き込む場所に一番近いPD盤から、どのように配線するのか実際に目で見て確認する。

# やってみて気づいたこと
- 回線業者の現調の前に、自分たちで事前に現調しておく
    - MDFはEPSへの入室の仕方や、PD盤の場所はあらかじめ把握しておいたほうが、改正業者さんとの話が早い。
- 共用部(EPSなど)から、テナント内まで配線用の配管を設置するか否か
    - 回線業者から質問を受けた中で一番多かったのが、配線ルートに配線用の管(PF管)を設置するのかということだったので、事前にわかるようであれば確認しておくと良い。一般的には設置するらしい。
- フロアレイアウト図や配線計画資料は必須
    - これが無いと話にならないので、事前に入手しておく

※今後、思いついたことをドンドン追記する予定です。
統計学ド素人がABテストをカイ２乗分析でRubyに実装する

統計と確率でおよそ３０年前に数学に躓いた私ですが、「君って本当は文系だよ」とめちゃIQ高い大先輩に指摘されてもめげずに（若い盛りで「んなことはない。『俺はできるっ』」で）頑張ってIT技術者になって、しっかり飯を食ってます。

でも、数字はやっぱり苦手（確定申告で毎年吐きそう）。でも数字の羅列を聞いたり見たりするとグラフが頭に浮かぶことがあるので、そのあたりビジュアルで理解しているんだろうなと実感。

そんな私がABテストのExeclスプレッドシートをRubyに移植することになり、「はぁ？なんじゃこりゃわけわからん！」って叫びながら、クッション抱いて床でゴロゴロしているうちに『くっそ〜！理解したいぞ！』ってなって、それからようやく１年経って落ち着いたので、そのあたりまとめることにした次第です。（只今随時追記中）

そういえばニュートンも神学を志していたとき偶然立ち寄った古本屋で数学の本を手に取り「はぁ？わけわからん！くっそ〜理解したいぞ」って頑張ったら天才性を発揮して天才数学者になったらしいので励まされている次第で…

# カイ２乗分析ってなに？

[カイ二乗分布表](http://www3.u-toyama.ac.jp/kkarato/2014/statistics/handout/chisqdist.pdf)。これを見ると「自由度1」で、「有意水準5%」に置くと、「3.84」というのが出てきます。これが『棄却域』。この棄却域を上回る「検定統計量」が算出されれば「帰無仮説は棄却される」のだそうです。

ムズイ…ムズムズする。

以下、なにがしか啓発を与えられ次第追記します。

# 参考資料
[カイ二乗分布のわかりやすいまとめ](https://to-kei.net/distribution/chi-squared-distribution/)
[そのABテスト正しいですか?](http://kengos.jp/2013/05/13/ab-test-1.html)
[独立性の検定（カイ二乗検定）を３ステップで説明](https://mathwords.net/dokuritusei)

# 使用ライブラリ
[Module: Distribution::ChiSquare::Ruby_](https://www.rubydoc.info/gems/distribution/0.7.3/Distribution/ChiSquare/Ruby_)
[ React ]  住所だけ入力すればOKなGoogle mapコンポーネント



業務の中でrecomposeを使って再利用可能なGoogle Mapコンポーネントを作ったので、今後使い道がある時用にメモ。

丸コピで使えます。
エラーハンドリングもしています。

もっとスマートな書き方あったら教えて欲しいです。。


### 完成形
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/992eed92-4950-791a-2592-4d62d7a8b66a.png)


### npm
```
// React、PropTypesは省略します。

npm i -S recompose Geocode react-google-maps
```


### コンポーネント

```jsx:Map.jsx
import React from 'react';
import PropTypes from 'prop-types';
import Geocode from 'react-geocode';
import {
  compose,
  lifecycle,
  withState,
} from 'recompose';
import {
  withScriptjs,
  withGoogleMap,
  GoogleMap,
  Marker,
} from 'react-google-maps';

const apiKey = "あなたのAPIKEY";

const MapWithAMakredInfoWindow = compose(
  withScriptjs,
  withGoogleMap,
)(({
  lat,
  lng,
}) => (
  <GoogleMap
    defaultZoom={15}
    defaultCenter={{ lat, lng }}
  >
    <Marker position={{ lat, lng }} />
  </GoogleMap>
));

const Map = compose(
  withState('geocode', 'setGeocode', { lat: 0, lng: 0 }),
  lifecycle({
    componentDidMount() {
      Geocode.setApiKey(apiKey);
      Geocode.fromAddress(this.props.location)
        .then((response) => {
          const { lat, lng } = response.results[0].geometry.location;
          this.setState({
            lat,
            lng,
          });
        })
        .catch(() => {
          this.setState({
            lat: undefined,
            lng: undefined,
          });
        });
    },
  }),
)(({
  lat,
  lng,
  location,
}) => {
  if (!lat || !lng) {
    return (
      <div>
        <p>住所が誤っています。</p>
      </div>
    );
  }
  return (
    <div className="access-map-wrapper">
      <MapWithAMakredInfoWindow
        googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${apiKey}&v=3.exp&libraries=geometry,drawing,places`}
        loadingElement={<div style={{ height: '100%' }} />}
        containerElement={<div style={{ height: '30vmax' }} />}
        mapElement={<div style={{ height: '100%' }} />}
        lat={lat}
        lng={lng}
        location={location}
      />
      <a href={`comgooglemaps://?daddr=${lat},${lng}`}>
        Googlemap アプリで開く
      </a>
    </div>
  );
});

Map.propTypes = {
  location: PropTypes.string.isRequired,
};

export default Map;

```


これで呼び出し側からはシンプルに

```
<Map location="表示したい住所" />
```

だけで呼べるので便利ですね〜
OSごとに異なるインストール処理をするPipfileの作成方法（具体例：PyTorch v0.4.1）

###### (An English translation is available [here](https://dev.to/tomoyukiaota/creating-a-pipfile-which-has-different-installation-instructions-depending-on-operating-systems-pytorch-v041-as-an-example-56i8).)

この記事では、PipenvでOSごとに異なるインストール処理をするパッケージがある場合において、Pipfileの書き方について説明します。

具体例として、[PyTorch](https://pytorch.org/) v0.4.1について、macOS/Windowsに両対応するPipfileを作成します。

# はじめに

多くのパッケージでは、インストール方法はOSによらず共通です。例えば、numpyであれば、

```bash
pipenv install numpy
```
とすればOKです。

しかし、例えば、[PyTorch](https://pytorch.org/) v0.4.1については、macOSでは、

```bash
pipenv install torch
```

ですが、Windowsでは、

```
pipenv install http://download.pytorch.org/whl/cpu/torch-0.4.1-cp36-cp36m-win_amd64.whl 
```

と、インストール方法が異なります。（この例では、PyTorchのインストールオプションとして、Python 3.6のCUDAなしバージョンを使うものとします。）

Pipfileでは、macOSであれば前者の処理、Windowsであれば後者の処理をするように書く必要があります。どのようにすれば実現できるのでしょうか？

# 方法
`sys_platform`を指定すればOKです。[Pipenvの公式ドキュメント](http://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#specifying-basically-anything)に、特にWindowsのみ`pywinusb`をインストールする例について記載があります。

PyTorch v0.4.1については、私が使っているPipfileでは、次のようになります。

```bash

[[source]]

url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"


[packages]

theano = "*"
tensorflow = "*"
keras = "*"
numpy = "*"
scipy = "*"
matplotlib = "*"
seaborn = "*"
jupyter = "*"
jupyterlab = "*"
ipython = "*"
pandas = "*"
scikit-learn = "*"
spyder = "*"
pillow = "*"
torch = {version = "==0.4.1", sys_platform = "== 'darwin'"}
"b4b7455" = {file = "http://download.pytorch.org/whl/cpu/torch-0.4.1-cp36-cp36m-win_amd64.whl", sys_platform = "== 'win32'"}
torchvision = "*"


[dev-packages]

pylint = "*"


[requires]

python_version = "3.6"

```

`[packages]`の

```
torch = {version = "==0.4.1", sys_platform = "== 'darwin'"}
"b4b7455" = {file = "http://download.pytorch.org/whl/cpu/torch-0.4.1-cp36-cp36m-win_amd64.whl", sys_platform = "== 'win32'"}
```

で、`sys_platform = "== 'darwin'"`がmacOSの場合、`sys_platform = "== 'win32'"`がWindowsの場合を意味しています。

なお、`"b4b7455"`は、Windows上で`pipenv install http://download.pytorch.org/whl/cpu/torch-0.4.1-cp36-cp36m-win_amd64.whl`を実行すると、Pipfileに記載されます。その状態のPipfileに、`sys_platform = "== 'win32'"`を追記します。

GitHubに[pipenv_cross-platform_example](https://github.com/TomoyukiAota/pipenv_cross-platform_example)というリポジトリを作成し、PipfileとPipfile.lockを置きましたので、参考にしてください。
Delphi / C++Builder / RAD Studio 向けに最近リリースされたインストーラやパッチのリストを Google Spreadsheet で取得する

# インストーラやパッチの情報、ダウンロードURLをスプレッドシートで一覧表示したいのです

Delphi / C++Builder / RAD Studio のインストーラやパッチは基本的に https://cc.embarcadero.com/myreg に EDNアカウント（Embarcadero Developer Network）でログインしてダウンロードできます。

ダウンロードページではこんな風に一覧表示されます（ログインするEDNアカウントのライセンスやサブスクリプションの状況等により表示内容は異なります）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/bbbf9cd7-58b2-b081-ac5f-afec81f50cc5.png)

しかし、cc.embarcadero.com の表示は、製品のリリース直後などは利用者のアクセスが集中したり、また、エンバカデロ製品をたくさん所有している場合にも、表示される一覧が多いために少し待たされることがあるようです。

それを回避するため、直近のインストーラやリリースの情報だけを取得して、Google Spreadsheet に入れてみようと思い立ちました。

ただし、こういうリストを手作業で管理するのは意味がないので、できるかぎり自動的にアップデートされるように管理します。。


# キーポイント

## cc.embarcadero.com の RSS feed で情報がとれました

https://cc.embarcadero.com/rss にアクセスしてみると、RSS feed が取得できます。中身はこういう内容ですので、まさに欲しい情報が含まれています。そして、この記事の投稿時点での最新のパッチも確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/2a464eb5-1f1e-6325-c7b1-22fae0d9a56b.png)


## RSS feed は標準のワークシート関数だけで読み込める

Google Spreadsheet には '''IMPORTFEED''' というワークシート関数があります。
https://support.google.com/docs/answer/3093337?hl=ja

これを実行する計算式を以下のように作ってみました。これを Google Spreadsheet のA1セルに放り込んでみてください。

```
=IMPORTFEED("https://cc.embarcadero.com/rss", "items",TRUE,50)
```

そうすると、こんな情報がとれるはずです。直近50件分の情報が取れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/0603d505-7869-cb50-dbfd-24f763cc18a2.png)

このフィードのデータはimportfeed自体が内部でキャッシュするようで、12時間くらいはキャッシュから値が返されるようです。


## このリストから必要な情報だけを抽出したい

一覧には、IDERA製品となったものも含まれていますが、これは除外しようと思います。そういうときに Google Spreadsheet の ```QUERY``` を使うと、SQL を実行するかのごとく、データ抽出できます。

別のシートを作成して、こんな計算式をA1に投入します。

```
=QUERY('シート1'!A:D,"select A,B,C,D where A contains 'RAD Studio' or A contains 'Delphi' or A contains 'C++Builder'",true)
```

そうすると、Titleに Delphi / C++Builder / RAD Studio を含む行だけが抜き出されるはずです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/a22a5a00-3164-8773-f727-3a5527ef843e.png)


なお、本当は以下のように正規表現マッチで書きたいのですが、IMPORTFEED で取得したデータには matches は効かないみたいです。

```
=QUERY('シート1'!A:D,"select A,B,C,D where A matches 'RAD Studio|DelphiC\+\+Builder'",true)
```

というわけで、こんな方法でデータを抽出できました。一部、製品のインストーラやパッチでは無いものも見えていますが、ざっくり作ったのでこんな感じでゆるく動いてくれれば、自分的にはOKです。この方法ならWebページをスクレイピングする必要はないですし、情報は自動更新されますから管理も省力化できますし。
Ruby—Stringの掛け算で水平線(区切り線)を出力する

## 君はRubyらしさを感じられるか

このコードに

```rb
puts '=' * 50  # ==================================================
```

## Links

- [Ruby—Print horizon line by string multiplication](https://gist.github.com/YumaInaura/6e481553c31f997ac4ba531d59aac224)










<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
仮想通貨のマイニングとは

#はじめに
仮想通貨の記事で「マイニング(採掘)」という言葉が出てきます。マイニングについて処理内容を調べてみました。

#bitcoinのマイニングとは

「誰にも邪魔されない、誰にも止められない「送金記録」を記録できれば仮想通貨が実現できる」とサトシ・ナカモト氏が考え、仮想通貨bitcoinができたそうです。

bitcoinはブロックチェーンと呼ばれる公開分散元帳に記録されていきます。
ブロックチェーンは下図のようなデータ構造を持ちます。

![blockchain-how-it-works-100673585-orig-100741478-large.jpg](https://qiita-image-store.s3.amazonaws.com/0/272771/b1a84492-1376-4dde-3fb0-e02d6e0c431f.jpeg)
[What is blockchain and how does it work?! より引用](https://www.cio.com/article/3055847/security/what-is-blockchain-and-how-does-it-work.html)

Block Chainのヘッダーには
・前のブロックのハッシュ値(Hash of previous block header)
・トランザクション(取引履歴)のハッシュ値(Merkle root、トランザクションのハッシュ値は特殊なハッシュ値計算を行っています)
・ノンス(nonce)
があります。

マイニングというのはBlock Chainのヘッダーのハッシュ値の先頭がある数分0で埋め尽くされた値となるようなノンスを見つけ出すことです。
0がいくつなのかは「難易度」によって動的に変わるそうです。

ノンスは単なる整数値なので手当たり次第設定、ハッシュ計算して条件に合うハッシュ値になっているかを確認という作業を延々繰り返します。マイニングに世界で最初に成功した人には報酬がbitcoinで支払われます。

2018年8月現在は、報酬として12.5BTC(≒871万円)を受け取ることができます。めっちゃ高いですね。。なのでマイニングするウィルスが流行ってます。

#感想
広告の代わりに「計算させて」というビジネスモデルも考えられるんじゃ？
モバイルで電池バカ食いされたらたまらないのでProcessのpriorityは低くして、、、とか。
ひとやま当てたくなりますねー

#参考

[いちばんやさしいブロックチェーンの教本](https://www.amazon.co.jp/dp/B075CFG2TY/)

[Interface(インターフェース) 2018年 08 月号 特集 IoT新技術 なるほどブロックチェーン](https://www.amazon.co.jp/dp/B07CXGKZBB/)

[【トレンドマイクロセキュリティブログ】2018 年にサイバー犯罪者が狙う最大の標的は「仮想通貨の発掘」？](https://blog.trendmicro.co.jp/archives/17083)

[【トレンドマイクロセキュリティブログ】「ファイル感染型コインマイナー」を確認。既存ランサムウェアのコードを再利用](https://blog.trendmicro.co.jp/archives/17309)

[マイニングウイルスとは？その原因・駆除方法や具体的対策を整理](https://cybersecurity-jp.com/cyber-terrorism/25620)

[What is blockchain and how does it work?!](https://www.cio.com/article/3055847/security/what-is-blockchain-and-how-does-it-work.html)


#履歴
2018/08/12 初版