OmniAICreator/Qiita-1.07M huggingface dataset:
VMware Workstation15のUbuntu-Server 20.04 にWindows10のディレクトリをマウントする方法

調べるとやり方を説明するサイトはいくつか出てくるのですが、
自分用に簡潔なやり方を残しておきます。
Ubuntu Desktopでも同様のやり方で共有できました。

## 1.Ubuntu Serverのイメージをダウンロード
[jp.ubuntu.comのダウンロードページ](https://jp.ubuntu.com/download)からイメージをダウンロードする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458010/4cc499b2-3e37-276c-05c4-c767bec089d3.png)


## 2.VMWareにインストールする

調べるとすぐに出てくると思うのでここでは割愛します


## 3.VMWareの設定で共有フォルダを指定する

Ubuntuを起動していない状態で下記のとおり設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458010/1b44ef33-e07c-e0e3-eb53-67b2afc7e9fc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458010/ae950932-36aa-c885-85ba-a84b1d8d3f1f.png)

ここで共有したいホストのディレクトリと、マウントされたときのディレクトリ名を決め、次へを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458010/e12be4fa-d780-348e-a5d1-3769fa89d19a.png)


デフォルト設定のまま完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458010/f9b3a628-b578-c0f6-764a-f3608d80082c.png)

この部分はお好みですが、私は常に有効で進めます。
設定が完了したらOKを押して設定を閉じます。

## 4.必要なツールをインストール
### unzip

```bash
$ apt install unzip
```

## 5.vmware-tools-patches をインストールする

Ubuntu-Serverを起動し、適当なディレクトリで下記コマンドでツールをインストールします。

```bash
$ git clone https://github.com/rasa/vmware-tools-patches.git
$ cd vmware-tools-patches
$ ./download-tools.sh latest
$ ./untar-and-patch.sh
$ ./compile.sh
```

ここまで完了したらUbuntuを再起動します。
※Ubuntu Desktopの場合、再起動後にマウントが完了しているはずです。


## 6.マウント

```bash
sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other
```
下記ディレクトリに共有フォルダがマウントされ、使用することができます。

```
cd /mnt/hgfs
```

## 7.マウントの自動化

6.の手順だと再起動するたび設定が初期化されるので、
起動時にマウントしてしまいたい場合は設定してください。

こちらを最終行に追加

```:/etc/fstab
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other 0 0
```
AtCoder Beginner Contest 169, D. Div Game の短めのコード

「$p^1, p^2, p^3, \ldots$ で割っていって割れた回数を記録し、
回数の記録を中止して$p$で割れるだけ割っておく」
を $p = 2, 3, 5, 7, 9, \ldots , \sqrt{N}$ で繰り返す。
素数がまだ残っているなら 1 を足す。
みたいな。

```
N = int(input())
n, p, score = N, 2, 0
while p ** 2 <= N:
  e = 1
  while n % (p ** e) == 0:
    n //= (p ** e)
    score += 1
    e += 1
  else:
    while n % p == 0:
      n //= p
    p = p + 1 if p == 2 else p + 2
else:
  if n != 1:
    score += 1
print(score)
```

もう少しだけ短く

```
N = int(input())
n, p, score = N, 2, 0
while p ** 2 <= N:
  e = 1
  while n % (p ** e) == 0:
    n //= (p ** e)
    score += 1
    e += 1
  else:
    while n % p == 0:
      n //= p
    p += 2 - (p == 2)
else:
  score += n > 1
print(score)
```
yukicoder contest 251 参戦記

# yukicoder contest 251 参戦記

## [A 1070 Missing a space](https://yukicoder.me/problems/no/1070)

0を先頭にできないのでその分だけ差っ引けばいい.

```python
C = input()

print(len(C) - 1 - C.count('0'))
```

## [B 1071 ベホマラー](https://yukicoder.me/problems/no/1071)

まずベホマラーのほうが消費 MP が少ない場合は全部ベホマラーで良い. また、ベホイミ N 回の消費 MP よりベホマラーの消費 MP の方が多い場合は全部ベホイミで良い. 問題はその中間なわけですが、例えばベホマラーの消費メモリがベホイミの2倍であれば、一番さいだい HP が高い人以外をベホマラーで回復し、終わったら残り一人の回復が終わってない人をベホイミで回復する. ベホマラーの消費メモリがベホイミの 1.1 倍でも 1.9 倍でも同じ. 2.1 倍ならさいだい HP が一番目と二番目に高い人以外をベホマラーで回復し、終わったら残り二人の回復が終わってない人をベホイミで回復する. つまり ベホマラーの消費メモリのベホイミに対する倍率の ceil になる. 初期 HP が1であることには注意.

```python
from math import ceil

N, K, X, Y = map(int, input().split())
A = list(map(int, input().split()))

B = [((a - 1) + K - 1) // K for a in A]
B.sort(reverse=True)

if Y <= X:
    print(Y * B[0])
    exit()
t = ceil(Y / X) - 1
if t < N:
    print(Y * B[t] + X * sum(B[i] - B[t] for i in range(t)))
else:
    print(X * sum(B[i] for i in range(N)))
```

## [C 1072 A Nice XOR Pair](https://yukicoder.me/problems/no/1072)

A のそれぞれの個数を数えて、A と A xor X のそれぞれの個数をかけ合わせたものを合計する. A or X のときに A との組になってダブルカウントになってしまうので最後に2で割ればいい. が、X = 0 のときだけが特殊で A xor 0 = A で自分自身と組み合わせることになるのでその場合だけ <sub>Aの個数</sub>C<sub>2</sub> を合計する.

```python
N, X = map(int, input().split())
A = [int(input()) for _ in range(N)]

d = {}
for a in A:
    d.setdefault(a, 0)
    d[a] += 1

result = 0
if X == 0:
    for v in d.values():
        result += v * (v - 1) // 2
    print(result)
else:
    for k in d:
        if k ^ X in d:
            result += d[k] * d[k ^ X]
    print(result // 2)
```

## [D 1073 無限すごろく](https://yukicoder.me/problems/no/1073)

敗退. ナイーブなのは書けますけどね. N≤10<sup>18</sup> は無理ですよね.
「複数代入」ってなに？-猿でも分かるlaravel解説-

#複数代入とは？
データベース作成において登場する「複数代入」という概念、最初は意味わからないですよね。
大丈夫です、それ、サルでもわかります。
猿でもわかるように複数代入を解説します。

結論から言うと複数代入とは**複数のカラムにデータを入れること**です

`例えば、passwordだけ更新出来る画面が有ったとして、ブラウザに表示されるのはpasswordフィールドだけですが、ブラウザをちょっといじれば入力項目を追加できます。これが複数代入です。
大抵、他の項目も更新出来てしまう問題を回避するために、複数の項目に代入出来ない様にしています。`


はい、そのまんまです。

また、よく出てくるEloquentに関する記事では次のような説明を行っていました。

>Eloquentユーザーからの入力を元にデータを保存する場合、悪意のあるユーザーがこちらの意図しないデータの保存・更新を行うように複数の項目を代入してくることです。
例えば、ユーザー作成の際に管理者権限にするかどうかは通常のページにはPOSTする項目として設定していないにも関わらず、悪意のあるユーザーが独自に項目を追加しPOSTすることで、管理者になってしまうようなものです。

以上が**複数代入**です。
皆さんの理解に助けになっていると幸いです。
パーティションプロジェクションを使うとAthenaのパーティション更新を不要にできる

面倒なAthenaのパーティション更新作業が不要になる、[パーティションプロジェクション](https://docs.aws.amazon.com/athena/latest/ug/partition-projection.html)という機能が静かにそして力強くリリース(2020年5月21日)されました。

# 今まで

Athenaは新しいパーティションを認識させるための作業が必要で、
定期的に[ALTER TABLE ADD PARTITION](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/alter-table-add-partition.html)や[MSCK REPAIR TABLE](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/msck-repair-table.html)を実行したり、Glueクローラーを実行させる必要がありました。

`ALTER TABLE ADD PARTITION`や`MSCK REPAIR TABLE`を定期的に実行させるためには、Lambdaを使ったり自前の仕組みを用意する必要があり面倒です。
Glueクローラーは手軽ですが、料金が高いです。(1分しか動かなくても10分の料金が取られるので1時間に1回動かすと、 0.44USD/h * 1/6 * 24 * 31 で クローラー1個に月$54.56かかる)

「パーティション更新のためになんでこんなに苦しまないといけないんだ。Hive形式になっていたら自動で更新してくれてもいいじゃないか」と全Athenaユーザは思っていたと思いますが、やっとパーティション更新から開放されるときが来ました。

# パーティションプロジェクションによるパーティション管理の自動化

それでは実際にパーティションプロジェクションを使ってみましょう。
S3には `s3://<bucket>/app_log/year=2020/month=6/day=5/hour=1/` のようなHive形式で保存されているものとします。

Hive形式じゃない場合は以下を参照ください
https://docs.aws.amazon.com/athena/latest/ug/partition-projection-kinesis-firehose-example.html

## Glueのテーブル編集画面を開く
Glueのテーブル詳細画面にいったら、「テーブルの編集」をクリック。
以下のような画面になります。
<img width="847" alt="スクリーンショット 2020-06-05 23.12.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14124/c27d4482-f6c2-dcff-351c-a276d537f2c3.png">


## テーブルプロパティにパーティションプロジェクションの設定をする
編集画面の下の方に `テーブルのプロパティ`という欄があります。ここにパーティションプロジェクションの設定を入れていきます。
<img width="608" alt="スクリーンショット 2020-06-05 23.11.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14124/544634e4-b44e-1a2a-710c-cc46b776e229.png">

先に設定が完了した画像を見せます。こんな感じです。
<img width="585" alt="スクリーンショット 2020-06-05 23.17.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14124/c508ec86-acf2-57fe-9ee7-8c1369dc7536.png">

まず、 `projection.enabled`という項目が必要で、`true`を入れるとパーティションプロジェクションがONになります。 `false`にするとOFFになります。

そして `projection.columnName.type` と `projection.columnName.range` ですが 
typeのほうには、enum, integer, date, injected が選択できます。詳しくは[こちら](https://docs.aws.amazon.com/athena/latest/ug/partition-projection-supported-types.html#partition-projection-injected-type)。今回はintegerを選択。
rangeにはその値が取りうる範囲を指定します。 `下限値,上限値`という入力の仕方です。

あとはAthenaから以下のようなパーティションを指定したSQLを実行すればOKです。

```sql
SELECT *
FROM "my_db"."app_log"
WHERE year = 2020 AND month = 6 AND day = 5 AND hour = 12
ORDER BY time DESC limit 10;
```


# まとめ

ちょっとした設定が必要ではありますが、パーティション更新作業が不要になったのは大変嬉しいですね。
またパーティション数が多いテーブルではパーティションプロジェクションを使ったほうがクエリ実行が速くなるそうです。

ちなみにこちらのユーザガイドでは日本語でパーティションプロジェクション機能の説明がされてます。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/athena-ug.pdf
M5StickV / UnitV 向け .kfpkg の作り方 (Windows)

M5StickV や UnitV 向けの配布用パッケージ(.kfpkg)の作り方を説明します。作成したアプリケーションのファームウェアのバージョンを固定できたり、microSD カード不要で動作させることができるようになります。なお、この手順により既存のファームウェアが上書きされてしまうので古いファームウェアが必要な方は実行しないでください。

# 事前準備
microSD カードを前提としたアプリケーションを作成している場合は micropython のソースコードの ```/sd``` を ```/flash```  にするなど変更してください。また、配布用ディスクイメージは 3MB で固定なのであまり大きなファイルは利用できません。特に、機械学習モデルを利用している場合には、ファイルから読み取るのではなく、内蔵 Flash の特定領域(例えば ```0x300000```)から読み込むように変更します。

# SPIFFS ディスクイメージの作成
それではまず配布したいアプリケーションのディスクイメージを作成していきます。 ここで作成したディスクイメージが ```/flash``` 以下に格納されます。

1. WSL 上に Ubuntu 18.04 LTS をインストールします。[Microsoft Store](https://www.microsoft.com/ja-jp/p/ubuntu-1804-lts/9n9tngvndl3q?activetab=pivot:overviewtab)を利用するのが簡単です。インストールが終わるとユーザー名とパスワードを聞かれるので適宜設定します。
2. Ubuntu 上で下記を実行します。

```
$ sudo apt-get update
$ sudo apt install make
$ sudo apt install g++
```
3. Windows のデスクトップ上に spiffs というフォルダを作成します。
4. Ubuntu 上で下記を実行します。

```
$ cd /mnt/c/Users/(ユーザー名)/Desktop/spiffs
$ sudo git clone https://github.com/sipeed/MaixPy.git
```
5. Windows のエクスプローラで ```spiffs\MaixPy\tools\spiffs``` に移動し、fs フォルダを作成、その中に boot.py など配布用パッケージに含めたいファイル一式をコピーします。
6. Windows のエクスプローラで ```MaixPy\projects\maixpy_m5stickv\builtin_py``` の中身を上記の fs フォルダに上書きコピーします。
7. Ubuntu 上で下記を実行します。

```
$ cd MaixPy/tools/spiffs
$ sudo python3 gen_spiffs_image.py ../../projects/maixpy_m5stickv/config_defaults.mk
```

成功すると下記のように表示されます。ディスクイメージは 3MB で固定なので、エラーになる場合はファイルを減らしてください。特に、ファイルサイズの大きい .kmodel はディスクイメージに追加するのではなく、.kfpkg 作成時に別途追加するようにします(後述)。

```
[SUCCESS] image file in fs_image
[USAGE] Please flash fs_image/maixpy_spiffs.img to address 0xD00000 of flash with flash tool kflash_gui
```


以上で、```spiffs\MaixPy\tools\spiffs\fs_image``` に ```maixpy_spiffs.img``` というファイルができます。

# .kfpkg の作成
.kfpkg の作成には、ファームウェア (.bin)、SPIFFSイメージ (.img)、(機械学習モデルがあれば .kmodel) が必要です。 

1. https://docs.m5stack.com/#/en/quick_start/m5stickv/m5stickv_quick_start の click to download firmware をクリックして M5StickV_Firmware_v5.1.2.kfpkg をダウンロード。下のほうにある Kflash_GUI もあわせてダウンロードし展開しておきます。
2. .kfpkg の拡張子を .gz に変更して展開し、```maixpy.bin``` があることを確認します。
3. kflash_gui.exe を起動し、Open File をクリックして、```maixpy.bin``` を選択します。
4. 続いて Add File をクリックし、Open File をクリックして、上記で作成した ```maixpy_spiffs.img```　を選択、```0x00000``` と表示されている部分を ```0xD00000``` に変更します。
5. 機械学習モデル(.kmodel) がある場合は、Add File をクリックして、ファイルを追加し、```0x300000``` に変更します。
6. Pack to kfpkg をクリックして、 .kfpkg を作成します。

以上です。

# 元に戻す
https://docs.m5stack.com/#/en/quick_start/m5stickv/m5stickv_quick_start から M5StickV_Firmware_v5.1.2.kfpkg をダウンロードして kflash_gui.exe で書き込めば Quick Start の初期状態になります。

# 参考リンク
- [M5StickV Quick Start](https://docs.m5stack.com/#/en/quick_start/m5stickv/m5stickv_quick_start) (UnitVも同じ手順です。ファームウェアも共通です。)
- [spiffs tools](https://github.com/sipeed/MaixPy/tree/master/tools/spiffs) (Sipeed)
Python 3 イテレータ型の要素に2つの値が同時に出現する回数を数える

イテレータ型（リストやタプル）の要素にある2つの要素が同時に出現する回数を数えるコードです。イテレータ型の要素の組み合わせ（`itertools.combination`）、イミュータブルセット（`frozenset`）、キーを指定した`sorted`のサンプルコードでもあります。

# コード
```py:count_colocation2.py
import itertools
import typing
from itertools import chain


def count_colocation2(
        iteriter: typing.Iterable
        ) -> typing.Dict[frozenset, int]:
    """
    イテレータ型（リストやタプル）の要素にある2つの要素が同時に出現する回数を数える。
    """
    if not isinstance(iteriter, typing.Iterable):
        raise TypeError()
    # 組み合わせを準備する
    comb = itertools.combinations(frozenset(chain.from_iterable(iteriter)), 2)
    comb = [frozenset(item) for item in comb]
    # 順に調べて組み合わせの存在する数を加算
    d = {key: 0 for key in comb}
    for entry in iteriter:
        for pair in comb:
            t = tuple(pair)
            if t[0] in entry and t[1] in entry:
                d[pair] += 1
    return d

```

```py:1.py
from pprint import pp

from count_colocation2 import count_colocation2

ll = [
        ["a", "b", "c"],
        ["d", "e", "f"],
        ["a", "d", "f"],
        ["b", "d", "f"],
    ]

coloc2 = count_colocation2(ll)
# 値を降順でソート
pp(sorted(coloc2.items(), key=lambda item: item[1], reverse=True))

"""
[(frozenset({'f', 'd'}), 3),
 (frozenset({'f', 'e'}), 1),
 (frozenset({'f', 'b'}), 1),
 (frozenset({'f', 'a'}), 1),
 (frozenset({'d', 'e'}), 1),
 (frozenset({'d', 'b'}), 1),
 (frozenset({'d', 'a'}), 1),
 (frozenset({'b', 'a'}), 1),
 (frozenset({'b', 'c'}), 1),
 (frozenset({'a', 'c'}), 1),
 (frozenset({'f', 'c'}), 0),
 (frozenset({'b', 'e'}), 0),
 (frozenset({'e', 'a'}), 0),
 (frozenset({'e', 'c'}), 0),
 (frozenset({'d', 'c'}), 0)]
"""

```

# 備考
## `frozenset`
`frozenset`は`set`のイミュータブル版です。`set`は`add`や`update`で内容を変更できますが、`frozenset`は変更できません。一方、`frozenset`はハッシュが取得できるので辞書のキーになれます。

```py
# 次の行をコメント解除するとエラーが発生します。
# print(hash(set(["a", "b", "c"])))
# TypeError: unhashable type: 'set'

# 正常に完了します。
print(hash(frozenset(["a", "b", "c"])))
```

同じ辞書のキーとなれるイミュータブル型に`tuple`があります。`tuple`は要素の順番を区別しますが、`frozenset`は区別しません。

## `typing.Sequence`、`typing.Iterable`
Pythonには`list`、`tuple`、`set`、`frozenset`のようなクラスがありますが、これらは共通の機能で分類できます。`list`、`tuple`はインデックスでアクセスできることからシーケンス型（`typing.Sequence`）に分類されます。また、`list`、`tuple`、`set`、`frozenset`はイテレーターを提供することから`typing.Iterable`に分類されます。

`typing.Sequence`と`typing.Iterable`は型として定義されており、型ヒントで使用する他、`isinstance`や`issubclass`でも使用できます。

## イテレータ型の組み合わせタプルのリスト
`itertools.combinations`によりイテレータ型（`typing.Iterable`）の要素から任意の数の組み合わせタプルのリストが作成できます。

## `set`/`frozenset`の要素へのアクセス
`set`/`frozenset`はインデックス`[index]`ではアクセスできません。`list()`や`tuple()`で一度`list`や`tuple`に変換すればアクセスできます。イテレータ型ではあるので`for`は使用できます。

## 辞書の非破壊的ソート
`sorted()`の`key=...`にラムダ式を指定して辞書を非破壊的にソートできます。辞書のキーと値のペアは`dict.items()`で取得することに注意してください。`dict`そのものを`sorted`に渡すとキー名が`sorted()`の対象となります。

```py:キーでソート
sorted(dict.items(), key=lambda item: item[0])                # 昇順
sorted(dict.items(), key=lambda item: item[0], reverse=True)  # 降順
```

```py:値でソート
sorted(dict.items(), key=lambda item: item[1])                # 昇順
sorted(dict.items(), key=lambda item: item[1], reverse=True)  # 降順
```
2020/06/05 プログラミング(フロントエンド)学習6日目 メモ

# 本日の学習範囲
### ドットインストール
・詳解CSS レスポンシブウェブデザイン編 #01〜#02
### 基本情報技術者テキスト
・特集部分
（学習時間：2時間）
## CSS学習メモ
### line-heightプロパティ
`{line-height ○○;}`
行の高さを指定する
数値のみで指定した場合は、フォントサイズ×数値=行の高さとなる
## その他
はじめてのCSSの動画全て視聴した後、動画を見ながら書いてきたコードを、
ブラウザに表示されているページのみを見て書けるかやってみた。
align-itemsやline-style-typeなどのプロパティ名は、
メモを見たりデベロッパーツールを見たりしないと思い出せなかった。
動画を見ながら書いてきたコードと全く一緒ではないが、
見栄えは一緒にすることができた。
IPv6下でFWが有効化されていない意味を考える(1)

#前置き
どなたかが言いました
「IPv6では個人に割り当てられるIPは星の数ほどあるので、総当たりでPINGを打っても当たりっこない」

本当にそうでしょうか？
例として有名どころのNASをアタックする例を考えます。

ちなみにラズパイが乗っ取られるとこうなります。
https://qiita.com/maccadoo/items/56e2ad31cc6627ad7dfe

続編も書いてみました
https://qiita.com/maccadoo/items/56e2ad31cc6627ad7dfe

#手順
さてあなたがこのサイトにアクセスしてきた時点で、あなたのIPv6はサイト管理者にわかってしまいました。
あなたは、おそらくWindowsやmacOSやLinux、iPhoneやAndroidなどある程度のセキュリティを確保した機器(FWや匿名IPv6アドレス)でアクセスしているため、この機器に対してアタックをかけるのは効率が悪いのでやめときましょう。
しかし、あなたのIPv6からネットワークのプレフィクス(先頭から64bit)はわかってしまいました。

IPv6は128bitなので残り後半64bitを潰せばあなたの負けです。
残り後半64bitはインターフェースID、またはインターフェース識別子と言われます。

さてIPv6のプレフィクスがばれた時点でプロバイダがばれます。
プレフィクスの中の先頭21bitがプロバイダ情報だからです。
自分のプロバイダは以下から検索してみてください。
https://www.nic.ad.jp/ja/ip/irr/

さて、ここでじっくり品定めですね。
最近、話題のNUROにしようか。それとも網内折り返しはFWが全通過のNTTやSBにしようか。うっしっしってとこです。
https://qiita.com/maccadoo/items/41e4cde50d1a288a19d6
私の検索では見つからなかったのですが、auも網内折り返しはFWが全通過なんでしょうかね？コメントください。

さて攻撃対象は某有名どころのNASにします。理由は以下です。
1.初期ID/PASSが分かっている
2.初期状態ではFWが有効化されていない(またはFW機能そのものがない)
3.初期状態のIPv6がEUI-64形式のインターフェースIDが設定されている

ここで効いてくるのが、3.EUI-64形式のインターフェースIDです。
平たく言えば、macアドレスからインターフェースID生成する方法です。
https://www.infraexpert.com/study/ipv6z4.html

今回、予めターゲットは指定しているため、macアドレスは絞れます。
おっと、macアドレスの48bitのうち、前半24bitがベンダーIDであることがわかりました。
https://ja.wikipedia.org/wiki/MAC%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9

macアドレスとベンダーは以下のサイトで検索がかけれます
https://uic.jp/mac/vendor/search/

| MAC  | vendor |
|:--:|:--:|
| 24:5E:BE  | Q社 |
| E8:43:B6  | Q社 |

EUI-64形式のインターフェースIDは48bitのmacアドレスを水増しして64bitにしているため、インターフェースIDの先頭から40bitは判明してしまいました。

| MAC  | インターフェースID |
|:--:|:--:|
| 24:5E:BE  | 275E:BEFF:FEXX:XXXX |
| E8:43:B6  | EA43:B6FF:FEXX:XXXX |

大変です。残り24bit、3オクテットしかありません。
確率にして約1678万分の1、しかも相手は永久に変わらないインターフェースIDのため、時間をかけてPINGを打っていけば良いことになります。
PINGが帰ってきたらビンゴ。
初期ID/PASSでアクセスを試みるなり、ブルートフォースアタックをかけるなりできてしまいます。
あるいは、永久に変わらないインターフェースIDを利用して、セキュリティホールが見つかるまで待つということもできてしまいます。

これをセキュアな状態と言えるでしょうか？
あなたは、どのように対策します？

#対策
筆者は、HGWでのFW有効化とインターフェースIDを任意の数値に置き換えるという手法を取っています。

HGWでのFW有効化
https://qiita.com/maccadoo/items/41e4cde50d1a288a19d6

インターフェースIDを任意の数値に置き換える
https://qiita.com/maccadoo/items/84c8ebaa4ad541ccea3b

#その他
IPv6でサーバーを立てるとなると、匿名IPv6は使えないため何かしらの対策が必要ですので苦労しますね。

最近のローカルネットワークでの名前解決はmDNSを利用しており、こいつはIPv6のグローバルを返してくるので、おそらく個別のFWでグローバルIPv6全遮断、リンクローカルのみ通過とかやると、ローカル環境で障害が出るでしょうね。
https://qiita.com/maccadoo/items/48ace84f8aca030a12f1

IPv6を諦めるのが手っ取り早いのかな？
iOSのURLスキームの脆弱性について

# 概要

iOSのURLスキームが意外と脆弱だから気をつけた方が良いよと言う話をします。

※違うよ、とかあれば気軽にコメント頂ければ幸いです
<font color="Red">※すみません、間違って一度記事を削除してしまいました。。orz もう一度再掲します</font>

# iOSのURLスキームについて

下記のようにURLスキームを叩くことがあると思うのですが、

```
hoge://〜
```

これってどの情報を元にどのアプリがこのURLスキームを受けるか決めているのでしょうか。

答えとしては、どのアプリが受け取ると言う情報が入っている訳ではありません。

なので

AアプリとBアプリでそれぞれ同じプロトコル名で受け取るようにしていた場合、どちらがそのURLスキームを受け取るかわかりません
(過去に確認した挙動だと、先にインストールされている方のアプリが受け取るようです)

Aアプリ

```
hoge://〜
を受け取るように実装
```

Bアプリ

```
hoge://〜
を受け取るように実装
```

奪い取りたいURLスキームのプロトコルなんて他の人わからないじゃんって思うかもしれませんが、
ツールなどで結構に気軽に他のアプリが受け取るURLスキームは調べることはできるようです。

Androidの場合は下記のように(アプリのパッケージ名)を指定することで起動するアプリを指定できます。

```
intent://〜#Intent;package=(アプリのパッケージ名);scheme=hoge;end;
```

# SFSafariViewControllerの例外

アプリからSFSafariViewControllerを開きURLスキーム(Deeplink)で戻ってくることがあると思いますが、
その場合はSFSafariViewControllerを開いたアプリが優先的にURLスキームを受け取るようで、
他のアプリに先に奪い取られてしまうことはないようです。

# まとめ

iOSでSFSafariViewController以外でURLスキームを送信・受信する際は、セキュリティに影響するような情報の受け渡しはやめよう。
iOSのURLスキームは他のアプリが受け取る可能性があることを考慮しよう。

参考:
https://blog.trendmicro.co.jp/archives/22020
Pythonで自分の日記をテキストマイニングしてみる

#  経緯
下記記事で勉強したjanomeをローカル環境にて実行。自分の書いた日記をテキストマイニングしてみます。
https://mocobeta.github.io/janome/

#環境
-PYthon 3.7.4
##使用モジュール
-Janome 0.30.10
-wordcloud 1.7.0

モジュールのインストールからです

```
pip install Janome
pip install wordcloud
```

モジュールのフォルダにcd　で入って以下を実行するのを忘れずに(自分は忘れた)

```
Python setup.py install
```

処理の順番
1.テキストファイル(.txt)の用意
2.テキストの単語分割
3.ワードクラウドの作成

```python

from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.charfilter import *
from janome.tokenfilter import *
from wordcloud import WordCloud

#認識できない文字の置き換えやフィルタをかける品詞を指定する関数
def create_analyzer(): 
  tokenizer=Tokenizer()
  char_filters=[RegexReplaceCharFilter('《.*?》', '')]  #文字列の置き換えを行うフィルタ
  token_filters=[POSKeepFilter(['名詞','形容詞','形容動詞','感動詞']),POSStopFilter(['名詞,非自立','名詞,代名詞']),ExtractAttributeFilter('base_form')]
  #Keepで対象詞、topで除くもの、Extractで基本形のみ対象にする
  #今回は名詞、形容詞、形容動詞、感動詞を対象にしました

  return Analyzer(char_filters,tokenizer,token_filters=token_filters)

#文章を単語分割してテキストファイルとして返す関数
def split_text(src, out): #ユーザー辞書の情報を適用し文章を単語分割して前処理する
  #src で渡されたファイルを読み，単語分割して out に書き出します。
  a=create_analyzer()
  with open(src,encoding='utf-8') as f1:
    with open(out, mode='w', encoding='utf-8') as f2:
      for line in f1:
        tokens=list(a.analyze(line))
        f2.write('%s\n' % ' '.join(tokens))


split_text('data/diary.txt', 'words.txt')
with open("words.txt",encoding='utf-8')as f:
    text=f.read()

wc = WordCloud(width=1920, height=1080,
               font_path="fonts/ipagp.ttf", #フォントのダウンロード
               max_words=100,#ワードクラウドに記載する単語の数
               background_color="white",#背景色
               stopwords={"自分","ない","いい","よい"}) #禁止ワードを設定

wc.generate(text)
wc.to_file('data/test_wordcloud.png')
```

一番最初の関数 create_analyzerで専門用語を記述する辞書のcsvファイルを追加したりできますが今回は省略しました。
繰り返しですが下記ページで勉強できます
https://mocobeta.github.io/janome/

下記のようなpngファイルができました。今後はwebスクレイピングで拾ってきた情報やAPIと組み合わせてJSONファイルからの読み込みなどをやっていきたいです。

![test_wordcloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648828/fed51120-039d-1459-303e-5216cb17b8d7.png)
ゼロから始めるLeetCode Day47 「14. Longest Common Prefix」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day46「406. Queue Reconstruction by Height」](https://qiita.com/KueharX/items/3a3b4c95a1e98cf799e0)

今はTop 100 Liked QuestionsのMediumを解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。


# 問題
[14. Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/)

難易度はEasy。
箸休め的に解いた問題なのでそこまで難しくはないかもしれません。

問題としては、与えられた文字列の配列において、それぞれの文字列の中で最も長い共通部分を返すような関数を設計する、というものです。
仮に何も共通部分がない場合は`""`を返します。


>Input: ["flower","flow","flight"]
Output: "fl"
Example 2:

>Input: ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.

# 解法

```Python
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if not strs:
            return ""
        ans = ""
        for num in zip(*strs):
            if len(set(num)) == 1:
               ans += num[0] 
            else:
                return ans
        return ans
# Runtime: 32 ms, faster than 74.42% of Python3 online submissions for Longest Common Prefix.
# Memory Usage: 14.1 MB, less than 22.07% of Python3 online submissions for Longest Common Prefix
```

zip関数を使って解きました。
Easyなのでそこまで難しいと言える内容ではなかったですが、頭の運動としては楽しかったので解いてみることをお勧めします。

~~特に解説すべきことがない・・・~~

では箸休めの問題ですし今回はここまで。
お疲れ様でした。
定番の顔メッシュ貼り替えをWeb+facemeshで実装してみた その２

[facemesh](https://github.com/tensorflow/tfjs-models/tree/master/facemesh)にある[UVメッシュ](https://github.com/tensorflow/tfjs-models/blob/master/facemesh/src/uv_coords.ts)に合わせて絵を書くことで任意のマスクが作成できます。


下絵
![uvmesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/d65f713e-9bea-e408-20a7-cfd1034e9292.png)

作成した画像
![black_face.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/fdea8742-6e9c-8ced-eb4e-9240b4276b47.png)

某アニメの悪役フェースをイメージしたのですがただの雑コラにしかなりませんでした。orz

## オンラインデモ

スマホからも見れます。適当に拡大してお試しください。
https://mbotsu.github.io/facemask/black/


## コード

https://github.com/mbotsu/facemask/tree/master/black


[前回の記事](https://qiita.com/mbotsu/items/b07934b16aca9e9fc51e)
Node.js + axios で XMLのレスポンスを扱う

## はじめに

最近、Node.js + axios の組み合わせでレスポンスボディがXMLで返ってくるWebAPIを呼び出すことがあったので、その時にやったことを書いておきます。

## axiosでXMLを扱うには

axiosでレスポンスボディがXMLの場合、次のように`config.responseType`に`'document'`を指定すると、Documentオブジェクトとして取得することができます。

```js
const url = 'https://status.aws.amazon.com/rss/appsync-ap-northeast-1.rss';
const config = {
  responseType: 'document'
};
const response = await axios.get(url, config);
const data = response.data; // data は Documentオブジェクト
```

ただし、これは実行環境がブラウザの場合でNode.jsの場合はXMLが文字列をとして返ってきます。
XML文字列のままでは困ります。（Documentオブジェクトだとしても扱いやすはないですが...）
やはり、扱い慣れたJSON(JavaScriptオブジェクト)だと嬉しいです。
なので、XMLとJSONに変換してやります。

axiosは`config.transformResponse`でレスポンスの変換処理をカスタマイズできます。
transformResponseにはレスポンスを変換する関数の配列を設定できます。今回は [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) でXMLをJSONに変換するようにしました。

コードは以下のようになります。

```js
const axios = require('axios');
const xml2js = require('xml2js');

const fetchXml = async () => {
  const config = {
    // responseType: 'document', 'document'はブラウザ環境以外ではtextと同じ
    transformResponse: [(data) => {
      let jsonData;
      const parser = new xml2js.Parser({
        async: false,
        explicitArray: false
      });
      parser.parseString(data, (error, json) => {
        jsonData = json;
      });
      return jsonData;
    }],
  };
  return await axios.get('https://status.aws.amazon.com/rss/appsync-ap-northeast-1.rss', config);
};

fetchXml()
  .then(response => console.log(JSON.stringify(response.data, null, 2)))
  .catch(e => console.error(e));
```

実行結果は、次のようになります。

```json
{
  "rss": {
    "$": {
      "version": "2.0"
    },
    "channel": {
      "title": "AWS AppSync (Tokyo) Service Status",
      "link": "http://status.aws.amazon.com/",
      "language": "en-us",
      "lastBuildDate": "Fri, 05 Jun 2020 00:05:20 PDT",
      "generator": "AWS Service Health Dashboard RSS Generator",
      "description": "AWS AppSync (Tokyo) Service Status",
      "ttl": "5"
    }
  }
}
```

## まとめ

axiosではtransformResponseでレスポンスの変換処理をカスタマイズできます。この部分でXMLをJSONに変換すれば axios.get() などのレスポンスオブジェクトは変換済みの形式で取得できます。

今回は、xml2jsを使いましたが、XMLをJSONに変換するモジュールは他にも [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) などがあるので要件にあったもの選んで使えばいいと思います。ただし、transformResponseに設定する関数は非同期処理を扱えない(Promiseを返したりはできない)ので変換処理が同期的に実行できるモジュールを選ぶ必要があるので注意です。
TypeScript の型推論をテストする

TypeScript で複雑な型定義をするにあたり「テストを書きながら効率的に行いたい！」と思ったことはありませんか？TypeScript では Compilerレイヤーの API が Node.js に向け公開されており、環境コンテキストを加味した推論まで取得することが可能です。

本稿では、CompilerAPI をテストに活用するアプローチを紹介します。


## tl;dr

サンプルリポジトリを用意しました。
https://github.com/takefumi-yoshii/ts-type-inference-test

```__tests__/widening.ts
const w0 = 0;
const n1 = 1 as const;
const n2 = 2 as 2;

const _w0 = { val: w0 }["val"];
const _n1 = { val: n1 }["val"];
const _n2 = { val: n2 }["val"];
```

こちらのファイルと対になるテストは、次の様に書かれています。

```__tests__/widening.test.ts
const srcFileName = `__tests__/widening.ts`;
const infer = createDeclarationInferencer(srcFileName);

// Widening Literal Type の挙動をテストで確認する

test("Widening Literal Type looks like as literal.", () => {
  expect(infer("w0")).toBe("0");
  expect(infer("n1")).toBe("1");
  expect(infer("n2")).toBe("2");
});

test("Widening Literal Type go unnoticed until used.", () => {
  expect(infer("_w0")).toBe("number");
  expect(infer("_n1")).toBe("1");
  expect(infer("_n2")).toBe("2");
});
```

変数「w0」にマウスオーバーし『ヨシ！0が推論されてるね』と目視で確認していた作業そのものが、テストコードに落とし込まれていることが伺えます。`_w0`の推論が`number`になってしまうところが、Widening Literal Type の特徴ですね。


## テスト対象は推論結果

filter処理を施した配列を、変数に代入。この変数を調べてみます。

```__tests__/userDefinedTypeGuard.ts
const arr = [1, 2, 3, undefined, null];
const res1 = arr.filter(removeUndefined1);
const res2 = arr.filter(removeUndefined2);
const res3 = arr.filter(removeUndefined3);
```

配列のfilterには、User Defined Type Guard を利用することが定石ですね。

```__tests__/userDefinedTypeGuard.ts
function removeUndefined1<T>(args: T) {
  return args !== undefined;
}
function removeUndefined2<T>(args: T): args is Exclude<T, undefined> {
  return args !== undefined;
}
function removeUndefined3<T>(args: T): args is NonNullable<T> {
  return args !== undefined;
}
```

以下のテストは全てパスします。型情報を文字列として解釈していることがわかります。

```__tests__/userDefinedTypeGuard.test.ts
test("Changes Inference by User Defined Type Guard", () => {
  expect(infer("res1")).toBe("(number | null | undefined)[]");
  expect(infer("res2")).toBe("(number | null)[]");
  expect(infer("res3")).toBe("number[]");
});
```



## infer関数

infer関数は、特定ファイルで宣言されている、変数の型推論を調べることができます。
ASTをトラバースし、変数宣言に適用されている型を、文字として取得しています。

```__tests__/__utils__/traverser.ts
export function getInferredTypeStringByDeclarationName(
  checker: ts.TypeChecker,
  source: ts.SourceFile,
  declarationName: string
) {
  let res: string | undefined;
  function visit(node: ts.Node) {
    switch (node.kind) {
      // 変数宣言 Node であり
      case ts.SyntaxKind.VariableDeclaration:
        // 変数名が 期待値である場合
        const name = node.getChildAt(0).getText();
        if (name === declarationName) {
          // ts.TypeChecker で推論適用されている型を得る
          const type = checker.getTypeAtLocation(node);
          // 型情報を文字列化する
          res = checker.typeToString(type);
        }
        break;
    }
    if (res) return;
    ts.forEachChild(node, visit);
  }
  visit(source);
  return res;
}
```

特筆すべきは、今回も`ts.TypeChecker` です。特定の Node まで絞り込み、その Node を対象に TypeChecker の API を適用することで、様々な情報を引き出すことが可能です。


## まとめ

CompilerAPI を利用した、複雑な型定義のテスト手法はこの限りではありませんので、要件に応じてトラバーサーを書くと良いと思います。VS Code で知り得る情報ならば、だいたい Node.js Application に落とし込めると見込んで良いでしょう。
railsのコールバックについて調べてみた

***

##前提
コントローラーの記述量が増えてくると、スクロールする必要性が出てきて、段々と見にくくなってきますよね。

うまくコールバックを使えるようになりたいなと思い、今回よく使いそうなコールバックをまとめてみようと思います。

Railsガイドの内容をざっくり目を通して、走り書きしたので
あれって？箇所がありましたら、すいません...&ご指摘ください。
[Active Record コールバック](https://railsguides.jp/active_record_callbacks.html)

***

#コールバックとは
**1.オブジェクトの生成・更新・削除のタイミングで呼び出されるメソッド**
**3.オブジェクトの状態が切り替わる「前」または「後」にロジックをトリガ**
**2.トリガに対してメソッドを共通化できる**

2つ目は、うまく使いこなせれば便利だろうけど、そこまでまだ道のりは長そう。

##オブジェクトの作成,更新
```
**before_validation**
**after_validation**
**before_save**
**after_create**
**after_save**
```


##オブジェクトのdestroy

```
**before_destroy**
**after_destroy**
```

##after_initializeとafter_find

```
class User < ApplicationRecord
  after_initialize do |user|
    puts "AQ"
  end
 
  after_find do |user|
    puts "QA"
  end
end

>> User.new
"AQ"
=> #<User id: nil>
 
>> User.first
"AQ"
"QA"
=> #<User id: 1>
```

##コールバックの実行

コールバックのトリガーとなる

```
**create**
**create!**
**destroy**
**destroy!**
**destroy_all**
**save**
**save!**
**update_attribute**
**update**
**update!**
**valid?**
```




##コールバックをスキップする
検証(validation)と同じく以下のメソッドでコールバックをスキップ

```
**delete**
**delete_all**
**update_column**
**update_columns**
**update_all**
```

##コールバックの停止

```
**throw :abort**
```

***

今日はこんなところにしておきます。
それでは。
ActionController::UnknownFormatエラーになった時の対処法

#ActionController::UnknownFormatエラーになった時の対処法
railsでアプリ開発をしている際にでたので自分が行った対処法を書いておきます。
ちなみにnewアクションで投稿機能を実装しようとした時に遭遇しました。
[![Image from Gyazo](https://i.gyazo.com/12f067b7f48db737083992a76fa57cd1.png)](https://gyazo.com/12f067b7f48db737083992a76fa57cd1)

new is missing a templete for this request format and variantとのことです。
newのテンプレートのリクエストフォーマットがミスってる、、、？という低レベルな訳をしたところで、先を読んでいくとあることに気付きました。
次のエラー文request.formats:["text/html"]はrequestはhtmlでそのhtmlがミス（ないよ）っているよということのようです。

new.html.erbを見てみるとファイル名がnew.hml.erbと誤字ってました。
しょうもないミスでしたが、修正すると正常に動作しました。

##まとめ
ActionController::UnknownFormatエラーがでた時はビューのファイル名の誤字だったり、ビューが正しい場所にあるか、そもそもビューを作ったかなどを確認すれば大丈夫かと思います。

お役に立ったら幸いです。
最後までご覧いただきありがとうございました。
[PlatformIO IDE]　３Dプリンタメインボード SKR v1.3 セットアップ

# はじめに
3Dプリンタのメイン基板に高性能なSKRを使用。高性能な3Dプリンタの基盤

<div align="center">
<img width="200" alt="46bf5744-d383-4c45-b288-51fa6d50173d.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/f3f15912-3b9c-a5ee-a0ad-e4d7609b8cc6.jpeg">
</div>

### 環境
Windows 10
SKRv 1.3（最新版はv1.4だがトライのため）
Touch display（品番後で）

### 作るもの
Marlin2.0を搭載したSKRのセットアップ。

### 対象読者
3Dプリンタの基盤を、高性能なものに変更したいかた。
SKR基板に興味があるかた。

# 内容
基本は下記リンクのマニュアルに従う。
https://github.com/bigtreetech/BIGTREETECH-SKR-V1.3/tree/master/BTT%20SKR%20V1.3

## 基盤セットアップ
1 電源として、USB供給と、12V/24Vの端子供給があり、下図のShort circuit pinでどちらかを選択する。  
<img width="300" alt="aaa" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/df7d92ca-0f13-2342-f6d8-9a0b1be162d0.jpeg">

2 USBでPCとSKRボードと繋ぐ
必要あれば、上記マニュアルをもとに、USBドライバをインストール

## ソフトウェアセットアップ
1. VS codeインストール
2. PlatformIO IDEのインストール
https://marlinfw.org/meta/download/

3. ダウンロードMarlin2.0コード
git clone git@github.com:MarlinFirmware/Marlin.git

4. open VS code
5. open marlin project
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/473e8b83-3198-c202-8c1e-d7b237c31b56.png">
6. デフォルト基盤をSKRに変更
![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/35b1657c-95f8-286c-3032-a132349bb6b3.gif)
7. Serial Portを変更（エミュレータまたは通常ポートで動作させるため）
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/26c83047-dd05-ae19-0a2e-72d10a67df0a.png">
8. チップ番号を変更
platform.iniにて、チップ番号をSKRv1.3に合わせて"LPC1768"に変更
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/855b65de-dac1-defa-c72d-b16330bae848.png">
9. ビルド
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/8d19d19b-ab41-4296-9da4-76bbfbfe5873.png">
10. ビルド結果の確認
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/2868d09d-ca7d-fe66-3e3b-6dd4d95a4903.png">
11. SKRボードのSDカードへアップロード
マニュアルでコピーする事も可能だが、下図のアップロードボタンより、アップロード可能
<img width="500" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/54da7df5-d470-377a-ba35-20c4150a141f.png">
アップロードが無事に終わっていれば、下図の通り、SDカードにfirmware.binが保存されている。
<img width="300" alt="1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/5ffb115a-22b2-380b-aa17-808c7655caa1.png">






### 実行
後は基盤を再起動し、動作確認を行う。注意しないといけないのは、モータ等を動かす場合は、USB電源での供給ではなく、上記の基盤セットアップ時に入れ替えたcircuit pinをINTに変更し、電源端子から12V/24Vを供給する必要有。


# 参考サイト一覧
https://terutakke.com/diary/marlin2-0-x-change/
https://www.youtube.com/watch?v=oaXfXkPYHpw
EC-CUBE4の多言語化対応（サブディレクトリで分けたり、ユーザー側画面と管理画面で分けたり）

## [公式の多言語化対応](https://doc4.ec-cube.net/i18n_multilingualization)の問題点

- 各言語の`messages.[lang].yaml`を用意しても一言語しか使えない。
- ユーザー側画面と管理画面で表示言語を分けることが出来ない。

## 解決策
[Symfony3のルーティング機能](http://symdoc.kwalk.jp/doc/book/routing)を使う。

下記のコード変更例では、`.env`ファイルの`ECCUBE_LOCALE`の値に関係なく、
ユーザー側画面は、URLのサブディレクトリによって日本語と英語の表示が分かれ、
管理画面は、日本語で固定表示される。

```yaml:app/config/eccube/routes.yaml
# ユーザー側画面のルーティング
controllers:
    resource: ../../src/Eccube/Controller/
    type: annotation
    prefix: /{_locale}
    requirements:
        _locale: en|ja
# 管理画面のルーティング
admin_controllers:
    resource: ../../src/Eccube/Controller/Admin/
    type: annotation
    defaults:
        _locale: ja
```

## 課題
- あくまでもソースファイルでの多言語化対応であるため、依然として、DBの中に入っている内容の多言語化は出来ない。
【言語処理100本ノック 2020】第7章: 単語ベクトル

## はじめに
自然言語処理の問題集として有名な言語処理100本ノックの[2020年版](https://nlp100.github.io/ja/)が公開されました。
この記事では、以下の第1章から第10章のうち、「第7章: 単語ベクトル」を解いてみた結果をまとめています。

本編は以下のリンク先に移転しました。
https://amaru-ai.com/entry/2022/10/13/200754

[全100問の解答へ](https://amaru-ai.com/entry/2022/10/15/204035)
VPCについて

#前提
VPCについて学んだことを書いていきます。

#本題

#VPCとは？
・アカウントに紐づく仮想ネットワーク空間
・他のVPCと論理的に区別されている

VPCはAZ（アベイラビリティーゾーン）を跨げるが、リージョンは跨げない。

リージョン　＝　国
AZ　＝　データセンター

・サブネット
大きなネットワークを複数の小さなネットワークに分割管理セキュリティレベルを高める
サブネットはAZを跨ぐことはできない。
サブネットの分割単位は/24がおすすめ。

片方のデータセンターに何かしらの障害が発生した場合でももう片方のデータセンターでサービスを継続できる。

VPCのなかにAZを2つ使用。それぞれのデータセンターにサブネットを2つずつ作成。
#パブリックサブネット
インターネットと通信を行う目的で作られたサブネット

#プライベートサブネット
インターネットと接続せず、内部の接続のみを目的に作られたサブネット

/16　←CIDR（サイダー）表記
第３オクテット、第４オクテットが自由に設定できる。

/24
第４オクテットを自由に設定できる。
0〜255まで使用できる。
※最後の4IPと最後の1IPはAWSが予約しているため使用できない。

/32
特定のIPアドレスを示すことになる

/8
第２、第３、第４オクテットが自由に設定できる。


#ルートテーブルとは？
サブネットに関連付けて使用するものでサブネットから外にでる通信をどこに向けて発信するか決めるルール、定義のこと。

サブネットはルートテーブルを最低でも何か一つ設定しなければならない。
デフォルトからあるルートテーブルは「メインルートテーブル」と呼ぶ。
メインルートテーブルの使用は控える。

#インターネットゲートウェイ（IGW）
VPCにアタッチして使用するネットワークコンポーネントでEC2インスタンスはインターネットへ通信できるようになる。

インスタンスがインターネットにアクセスするには、インスタンスにElasticIPかPublicIPをアタッチしなければならない。

ElacticIP
→インスタンスにアタッチ・デタッチ可能で、静的なインターネットと通信することができるIPアドレス。
※インスタンスが再起動、停止、終了した場合も同じIPアドレスで使用ができる。

PublicIP
→AWSのIPアドレスプールより割り当てられるインターネットと通信することができるIPアドレス。

EC2インスタンスはVPC内のIPレンジしか認識できない仕様となっている。

セキュリティグループ
EC2インスタンス単位で設定。（許可ウォールを設定する）
ポート２２、　１０.０.０.１
ポート２２、　All
全てのポート２２の通信が許可される。

ネットワークACL
サブネット単位で設定するファイアーオール
ルールは番号で管理され、小さい番号から順次強化されていく。
マッチした瞬間に以降の番号の許可はしない仕様になっている。
リールの最後には暗黙のDENYが待ち受けている。
このルールは削除することはできない。
mysql のバックアップとリストア

ワードプレスを移行するとき用のメモ

## データベースを指定してバックアップ

```
$ mysqldump --add-drop-table -h example.com -u username -p dbname > dump.sql
Enter password: (パスワードを入力する)
```

## リストア

```
mysql -u username -p dbname < dump.sql 
```

## 参考

- https://wpdocs.osdn.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97
VuePressでなぜかホットリロードが効かなくなってた....!

VuePressは、Vue.js製の静的サイトジェネレーターです。
うろ覚えですが前のときはまだ効いていたような気がしてたんですが、最近VuePressを使っていると...

> あれ...? ホットリロードされてない...!?

という現象に出くわしたので、メモ的に残しておこうと思います。

**執筆時のVuePressバージョン（2020/06/05時点）**

```
"vuepress": "^1.5.0"
```

## いまのところの解決策...!
調べてみると、2020/05/18時点でGitHubにissueが立てられていました。
[Hot reload not working · Issue #2392 · vuejs/vuepress · GitHub](https://github.com/vuejs/vuepress/issues/2392)

issueのコメントによると、どうやら**watchpack**という依存パッケージのバージョンを変えればいまのところいいっぽい...。

```package.json```に以下の記述を追加して、再度```yarn install```します。

```package.json
"resolutions": {
  "watchpack": "1.6.1"
}
```

自分はこれでホットリロードが効くようになりました！
**おそらくVuePress側のバグなのとissue対応の優先順位も高になっているので、次のバージョンあたりで修正されているんじゃないかなと思います、、、！**


### 余談
```package.json``` の ```resolutions``` フィールドは、直接的な依存関係はいじらずに対象の依存パッケージを指定したバージョンで上書きしてくれるような機能みたいです。
これを見るまで知らなかったので、少しタメになりました。
技術論文の書き方（初心者向け）

#初心者のための技術論文の書き方

- なるべく短い文日本語で書きなおす。 20-30単語。



- 受動態、無生物主語、関係代名詞をつかい英語らしくかく

- 図表を結果で示すなら受動態がよい 

- 無生物主語は条件、手段、方法や因果関係などの意味になる

- 無生物主語は5文型とセットのパターンが多い





##技術論文の読み方

- 段落の最初のセンテンスはよむ

- 段落の最後のセンテンスもよむ

- We, study, research, paper などを含む文は読む

- Howevwe など逆説の後はよむ

- 動詞に注目し文型、構文を取りながら読む

- 図表などをさっと目を通しおく

- abstractは論文の必要十分な要約なので必ずよむ
 

- 


##



#技術論文のおとしあな


- 定冠詞、不定冠詞はとりあえず特定、一般もしくは初登場、二回目登場で使い分ける。

- 複数系にして逃げるもあり




#論文のかたち

##タイトル

- 頭文字、名詞、（動詞）はイニシャル大文字

- 前置詞は小文字

- 先頭のtheは省略されることも

- かかなくてもわかることはかかない
　studyとかいらないから



##著者

- 筆頭執筆者とセカンドオーサには天と地ほどの差がある


##所属

- 普通に書けばよい 

##要約

-  かなり重要

- 200 words 程度にまとめることがおおい

- セクションを網羅していくようにまとめ挙げる
最後に書く


##キーワード

- 独自性がわかる単語を選ぶ

- タイトルにない単語を最初にのせるのがよい


##序章

- 論文の目的はなに？
何を明らかにしたいの？
この研究のやる意味ってなに？

- この研究は意義があるんだぞーっと他分野のひとにも思わせる背景だったりを書いていく

- 先行研究の課題って何？何を検証するの？

- 序章だけで1割以上をしめることになる

##手法

- 自分の参考文献など大いに参考にする
 
##結果

- 図表を中心に、文を添えていく。

- 図表をわかりやすく簡潔に説明する。

- 正確かつ客観的に述べる

##考察

- 難しい

- 結果からわかることをいかに説得力のある考察ができるか

- 表現もパターンではないので、まず簡単でもいいから書いてみる。


##まとめ

- 過不足なくまとめる

-  扱った内容を全体的に触れていく

##　参考文献


- 書式に合わせる


##注意

- 当たり前のことであっても，参考文献を提示する

例えば，「近年，二酸化炭素排出量が増加しており，地球温暖化が進行しているため．．．」は自分の独自意見でなくあくまで，裏付ける調査に基づくものであると示す．

- コピペににならないように，自分で構成・言い回しを考える．

ある程度決まり切った，表現だとしても自分の頭で考えたり，パラフレーズする必要がある．また引用も明記するべし．

- 
 





#この記事の参考文献
マンガでわかる技術英語

坂本　真樹　/著, 深森　あき　/作画, トレンド・プロ　/製作, 株式会社トレンド・プロ

NASAに学ぶ英語論文・レポートの書き方, メアリ k マカスキル著, 片岡　英樹　訳解説, 共立出版
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～HTML第1-2回～

# アジェンダ
* マークアップとは
* HTMLの正式名称
* HTMLのタグとは

# マークアップとは
マークアップとは、「どこから」「どこまで」に何があるかを記すこと。
また、「ここに何があるのか」を記すこと。

# HTMLの正式名称
HTMLの正式名称は「HyperText Markup Language」。
すなわち、HTMLはハイパーテキストを作成する言語ということ。

HyperTextとMarkup Languageの意味を調べると、以下のとおり。

> ハイパーテキスト (hypertext) とは、複数の文書（テキスト）を相互に関連付け、結び付ける仕組みである。「テキストを超える」という意味から"hyper-"（～を超えた） "text"（文書）と名付けられた。
参考 : [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%82%A4%E3%83%91%E3%83%BC%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88)

> マークアップ言語（マークアップげんご、英: markup language）は、組版指定に使われる言語と言える。視覚表現や文章構造などを記述するための形式言語である。
参考 : [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E8%A8%80%E8%AA%9E)

# HTMLのタグとは
文章を<○>と</○>で囲うことで、その文章の特徴を記すことができる。
この<○>と</○>のことをタグという。

## 実践
例えば、次のような文章がある。

```
Headline

This is 1st paragraph.
HTML is the abbreviation for Hyper Text Markup Language.
Tags represent the characteristics of the text.

This is 2nd paragraph.
```

各文章にタグをつけて、特徴を付ける。
\<h1>\</h1>は、囲った文章が見出しであることを示すタグ。
\<p>\</p>は、囲った文章が一つの段落であることを示すタグ。


```HTML:index.html
<h1>Headline</h1>

<p>
This is 1st paragraph.
HTML is the abbreviation for Hyper Text Markup Language.
Tags represent the characteristics of the text.
</p>

<p>This is 2nd paragraph.</p>
```

このindex.htmlをWebブラウザで開くとこんな感じ。
![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/04f99f5d-df2d-d993-b099-3ea46972c303.png)

見出し、段落が表現できている！

# おわりに
今回は、HTMLが作る文章についての内容だった。
講座の内容よりも、自分の言葉で記事にする方が何倍も難しい。

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/5adf8bf0132f100d615c)

# 参考
[1-2 マークアップ（はじめてのHTML）](https://www.youtube.com/watch?v=zIljOcdCOH4&list=PLjw-30bsJNVU87F5iCPAW9kB4QDUGQxUG&index=2)
sshでminiとasuraに接続

#授業で行ったことをメモ

##1.公開鍵と秘密鍵を作成

・cd .ssh （サーバーに接続）
・cat id_rsa.pub （公開鍵作成）

をターミナルで打つと、公開鍵が作成されるのでrsa ~を保存しておく。

##2.miniへ接続

・ssh アカウント名@192.218.172.38
・パスワード入力
・ssh-keygen （キーペア作成）
・enter 3回
・cd .ssh

emacsでauthorized_keysを開き、コピーした公開鍵を貼り付ける。

・cat id_rsa.pub

この公開鍵も、1と同じ様に保存しておく。

##3.asura0に接続

・ssh アカウント名@asura0
・パスワード入力
・ssh-keygen
・cd .ssh

emacsでauthorized_keysを開き、1と2でコピーした公開鍵を貼り付け。

・cat id_rsa.pub

1.2と同様にコピー

##GitHub

・GitHubのアカウントへログイン
・Settings
・SSH and GPG keys
・New SSH key
・Titleはasura0
・Keyに1.2.2でコピーしたsshを貼り付け．
[AWS] Amazon RDSのセキュリティついて

#RDSとは
リレーショナルデータベースを簡単にセットアップ、運用、スケーリングできるウェブサービス。
MariaDB , MySQL, Oracle, PostgreSQLなどが使える。

#RDSで使えるセキュリティ
###IAM
どのユーザーがAmazon RDSリソースを管理できるかを決められる。
例　ユーザーによるDBインスタンスの作成、情報入手、変更、削除など

###セキュリティグループ
・どのIPアドレスやEC2インスタンスがRDSで管理するデータベースに接続できるかを制御。
・セキュリティグループで指定されていないアクセスはすべて禁止される。

###Amazon RDSの暗号化を利用
・DBインスタンス、および保管時のスナップショットを保護。
・暗号化にはAES-256暗号化アルゴリズムを使用。
READMEの使い方

# プログラミングの勉強日記
2020年6月5日　Progate Lv.83
ウェブページ制作中
READMEを作ってみた

##READMEとは
　説明書みたいなもの。ソースコードをみる前にREADMEを見てもらうことで、概要を掴んでもらう。

##GitHubでの作成方法
　GitHubでは簡単にREADMEを作成することができる。

①リポジトリを作成する。
②リポジトリの作成後画面を開いてAdd a READMEをクリックする。
<img width="757" alt="README.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/cbaba0d1-8b9c-2d4c-f757-0607ba57e9d9.png">

③ファイルの編集画面が開くのでファイルを編集して、Commit a new fileをクリックする。
<img width="387" alt="README2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/d62a1d27-4348-7e95-e08b-7533b8747f54.png">

④READMEが作成される
<img width="507" alt="README3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/f27412d4-7308-9bac-6ad1-0a7f96b037df.png">

⑤READMEを編集するときは鉛筆マークを押すと編集できる。
<img width="522" alt="README4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/2073db22-e053-3b73-9ea6-cfbee956264d.png">


##READMEの書き方
　READMEは<font color=blue>マークダウン方式</font>に沿って編集する。（Qiitaと同じ感じ）

###改行を入れる
　行末に半角スペースを2回入れるか、`<br>`を使う。

```:例
改行をする␣␣
改行をする<br>
```

###改行を入れる
　改行を開けるときは空行をあけるだけでいい。

```:例
1段落目

2段落目
```

###強調する
　アスタリスクまたはアンダーバーで囲う。より強い強調をしたときは2つのアスタリスクまたはアンダーバーで囲う。

```:例
*強調* 
_強調_
**より強い強調** 
__より強い強調__
```

###見出しを入れる
　見出しは「`#`+`半角スペース`+`見出し名`」の形で記述する。<font color=blue>半角スペースを入れることに注意する。</font>

```:例
# 見出し１(h1)
## 見出し２(h2)
### 見出し３(h3)
#### 見出し４(h4)
```

###コードを表示する
　1行のコードはバッククォーテーション(Windowsの場合は「shift」+＠)で囲う。複数行のコードは半角スペースを4つ行の先頭に付ける。

```:例
`$('.prev').hide();`

␣␣␣␣$('.prev').hide();
␣␣␣␣$('.next').hide();
```

###リンクを入れる
　`[文章](リンク先のURL)`を使う。
【Golang】ゴルーチン⑥関数から関数に値を渡して処理

#【Golang】ゴルーチン⑥関数から関数に値を渡して処理
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。


```
package main
// fan-out fan-in
//funcの結果をfuncに渡し、最後に結果をmainに持っていく。

//処理を分けたい時など。func → func でデータを渡す。

import (
	"fmt"
)

//15回まわす
func producer(first chan int) {
	defer close(first)
	for i := 0; i < 15; i++ {
		first <- i
	}
}

//first,secondを引数
//(first <-chan int受信, second chan<- int送信) で明示的にしていると分かりやすい。
func multi3(first <-chan int, second chan<- int) {
	defer close(second)
	for i := range first {
		//3倍して、チャネルに追加
        second <- i * 3
	}
}

func multi5(second <-chan int, third chan<- int) {
	defer close(third)
	for i := range second {
		third <- i * 5
	}
}

func main() {
	first := make(chan int)
	second := make(chan int)
	third := make(chan int)

	go producer(first)

	//3倍
	go multi3(first, second)

	//5倍
	go multi5(second, third)

	//therdをforで回す
	//Producer > multi3 > multi5の順で値が渡される
	for result := range third {
		fmt.Println(result)
	}
}
```
Unityで「XInput1_3.dll not found.」とエラーが出たときの対処法

# はじめに
UnityにてWindowsで動作するアプリを作成し、Buildした後、実行したら「XInput1_3.dll not found.」とエラーが出たので対処法をまとめました

# 対処法
DirectXのランタイムをインストールしたら、解消されました（以下より、入手可能）

[DirectX エンド ユーザー ランタイム Web インストーラ](https://www.microsoft.com/ja-jp/download/details.aspx?id=35)

# 発生したエラー内容
エラーは以下のフォルダにあるファイルに出力されました

C:/Users/username/AppData/LocalLow/CompanyName/ProductName/output_log.txt

```output_log.txt
Initialize engine version: 2018.4.21f1 (fd3915227633)
GfxDevice: creating device client; threaded=1
Direct3D:
    Version:  Direct3D 11.0 [level 11.1]
    Renderer: NVIDIA GeForce GTX 1050 (ID=0x1c8d)
    Vendor:   
    VRAM:     2006 MB
    Driver:   22.21.13.8205
Begin MonoManager ReloadAssembly
- Completed reload, in  0.880 seconds
<RI> Initializing input.
XInput1_3.dll not found. Trying XInput9_1_0.dll instead...
<RI> Input initialized.
```

# まとめ
エラーでお困りの方は参考にしてみてください

# 参考
[DirectX エンド ユーザー ランタイム Web インストーラ](https://www.microsoft.com/ja-jp/download/details.aspx?id=35)
tmuxの備忘録

#仮想端末を使用するとssh接続などで便利

-  ssh接続が途中で切れてしまっても、再接続すれば作業をそのまま再開できる。
- 画面分割機能があるので、ウィンドウがすっきり整理される。
- 嬉しい時計機能もある。



##gnone端末の主なコマンド

tmuxの立ち上げ。ワークスペースができる、

```
$tmux 
```


出たいとき

```
$exit
```

やっぱりもう一度入りたいとき

```
$tmux a
```

画面を割りたいとき
$ctr+bを押してから

横割り

```
$"
```

縦割り

```
%
```

#便利機能

（更新予定）
#【Rails Gem】 Rubocopの除外設定 <missing top-level class documentation comment ><# frozen_string_literal: true>

#【Rails Gem】 Rubocopの除外設定

Rubocopのデフォルトのアラートを一部無効にする設定を行ったので、
そのときの手順をまとめます。

## 目次
* [動作環境](#動作環境)
* [やりたいこと](#やりたいこと)
* [手順](#手順)
  * [.rubocop.ymlの作成](#.rubocop.ymlの作成)
  * [.rubocop.ymlの編集](#.rubocop.ymlの編集)
  

---------------------------------------
## 動作環境
`OS : macOS Mojave 10.14.6`
`ruby : 2.6.5`
`rails : 5.2.4`
`rubocop-0.82.0 : global(開発用PC)にインストールしています`

## やりたいこと

rubocopによる自動フォーマットを利用していますが以下の理由によりアラート・自動整形のデフォルト設定を変更します。

1. `missing top-level class documentation comment`という
アラートが何度も出るため、このアラートをオフにすること.

2.`frozen_string_literal: true`が全てのファイルの先頭に記載されるため、
この設定をオフにすること.


## 手順

Rubocopのインストール手順は省略します。



### .rubocop.ymlの作成
.rubocop.ymlをユーザのホームディレクトリに作成します.

```bash:Terminal
$ pwd
/Users/xxxx
$ touch .rubocop.yml
```

### .rubocop.ymlの編集

viで.rubocop.ymlを開きます。

```terminal
$ vi .rubocop.yml
```
### missing top-level class documentation commentの除外設定

そして以下のコードを追加します。

```yml:.rubocop.yml
#追加
Documentation:
  Enabled: false
```

### frozen_string_literal: trueが付かないようにする

また`frozen_string_literal: true`には以下のコードを追加します.

```yml:.rubocop.yml
#追加
Style/FrozenStringLiteralComment:
  Enabled: false
```

*補足
>Ruby3.0では文字列は変更不可(イミュータブル)な文字列に移行する計画があります。
ただRuby2.2では文字列のデフォルトが変更可(ミュータブル)のため、
Ruby3.0への移行を支援するため、`frozen_string_literal: true`をつけることで文字列をイミュータブルにすることができるようです。
詳細はこちらの記事になります。
https://qiita.com/gipcompany/items/256a36ac727025f8f525


最後に.rubocop.ymlを保存して終了し、VS codeを再起動して確認します。

```yml:.rubocop.yml(最終版)
Style/FrozenStringLiteralComment:
  Enabled: false
Documentation:
  Enabled: false
```
シンボリックの備忘録

#シンボリックリンク




##コマンドの使用方法
リンクを貼りたいﾃﾞｨﾚｸﾄﾘに移動し、相対パスor絶対パスで参照先ファイルを記述し、貼り付け先./もしくは./ファイル名を記述する。
オプションとして-sfを指定してやる。

###使用例
hoge/b.txtをカレントディレクトリにa.txtという名前でリンクを貼りたい

```
$ln -sf  ../../hoge/b.txt  ./a.txt
```


リンクを削除したいなら次にようにコマンドを打つ。

```
$unlink a.txt
```

```
rm a.txt
```
でも可だが非推奨。


⁂リンクの参照先はファイルでもディレクトリでも可能。
ディレクトリごとリンクをはった場合は、貼ったリンクの直下は実物のファイルなので注意！





#シンボリッリンクのコピー

##リンク元をさかのぼってコピーする

``` 
rsync -avz -–copy-links  ./hoge1   ./hoge2

```
バッククオートをgsubで置換するときの注意

TeamsにAPIで投稿するときに文字列内のバッククオート（'`'）がMarkdownで処理され見た目がおかしくなったため、バックスラッシュ（'\'）を前に置いてエスケープしようとしたらうまくいかなかった。

```example.rb
s = 'abc`123`xyz'  # 'abc\`123\`xyz' にしたいのに
puts s.gsub(/`/, '\`') # => abcabc123abc`123xyz
```

なぜこんなことに・・・、と思ったら'\\`'は置換文字列内でマッチした部分文字列として使われるらしい。

[instance method String#gsub](https://docs.ruby-lang.org/ja/1.8.7/method/String/i/gsub.html)

バックスラッシュを増やしたらうまくいった

```example.rb
s = 'abc`123`xyz'
puts s.gsub(/`/, '\\\`') # => abc\`123\`xyz
```

それにしても、Markdown無効で投稿できる機能が欲しい。。。
【WBF】指紋の登録時に指紋をキャプチャする最大回数を取得する

# 概要
Windows Hello等、指紋認証を利用した事のある方はご存知かと思いますが、認証に使用する指紋の登録時にはセンサーを何度かスワイプorタッチして指紋をキャプチャする必要があります。ここではこのキャプチャする最大回数を取得します。

# サンプルコード
```C++:main.cpp
// ====================================================================================================
//	インクルード
// ====================================================================================================
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include <WinBio.h>

// ====================================================================================================
//	ライブラリ
// ====================================================================================================
#pragma comment(lib, "WinBio.lib")

// ====================================================================================================
//	エントリーポイント
// ====================================================================================================
int main()
{
    HRESULT hr = S_OK;

	WINBIO_SESSION_HANDLE sessionHandle = NULL;
	PVOID PropertyBuffer = NULL;

	try
	{
		// システムプールに接続する
		hr = WinBioOpenSession(WINBIO_TYPE_FINGERPRINT, WINBIO_POOL_SYSTEM, WINBIO_FLAG_DEFAULT, NULL, 0, NULL, &sessionHandle);
		if (FAILED(hr))
		{
			wprintf_s(L"WinBioOpenSession failed. hr = 0x%x\n", hr);
			throw hr;
		}

		// 使用するセンサーを指定する
		wprintf_s(L"Tap the sensor once...\n");

		WINBIO_UNIT_ID unitId = 0;
		hr = WinBioLocateSensor(sessionHandle, &unitId);
		if (FAILED(hr))
		{
			wprintf_s(L"WinBioLocateSensor failed. hr = 0x%x\n", hr);
			throw hr;
		}

		// キャプチャ最大回数の取得
		SIZE_T PropertyBufferSize = 0;
		hr = WinBioGetProperty(sessionHandle, WINBIO_PROPERTY_TYPE_UNIT, WINBIO_PROPERTY_SAMPLE_HINT, unitId, NULL, WINBIO_SUBTYPE_NO_INFORMATION, &PropertyBuffer, &PropertyBufferSize );
		if (FAILED(hr))
		{
			wprintf_s(L"WinBioGetProperty failed. hr = 0x%x\n", hr);
			throw hr;
		}

		wprintf_s(L"WINBIO_PROPERTY_SAMPLE_HINT [%d]\n", *((PULONG)PropertyBuffer));
	}
	catch (HRESULT hrError) { hr = hrError; }
	catch (...) { hr = E_UNEXPECTED; }

	if (PropertyBuffer != NULL)
	{
		WinBioFree(PropertyBuffer);
		PropertyBuffer = NULL;
	}

	if (sessionHandle != NULL)
	{
		WinBioCloseSession(sessionHandle);
		sessionHandle = NULL;
	}

	_getch();
	return 0;
}
```