OmniAICreator/Qiita-1.07M huggingface dataset:
Scala traitとnative JS traitとnon-naitive JS trait

native JS typeとnon-native JS typeという概念がある。
それぞれのtypeのtraitが存在し、そもそものScalaのtraitに加えて、

* scala trait (勝手に呼んでいる)
* native JS trait
* non-native JS trait

の三種類が存在する。

# native JS trait

native JSはJavaScriptで実装されたライブラリを読み込んで使う場合に使う。
いくら書いてもJavaScriptコードは生成されない。
Scala.js上でインスタンスをつくるには`js.Dynamic.literal`を使用する。
facadeを書くのに使う。

例

```scala
@js.native
trait Point extends js.Object {
  val x: Int
  val y: Int
}

val point = js.Dynamic.literal(x = 1, y = 2).asInstanceOf[Point]
js.Dynamic.global.console.log(p)   // => {x: 1, y: 2}
```

`js.Any`の派生をミックスインしていて、`@js.native`が付与されてるのがポイント。

より詳細はこちらに。
https://www.scala-js.org/doc/interoperability/facade-types.html


# non-native JS trait

Scala.jsで実装したJSのコード。
classにミックスインしたり、無名クラスでインスタンスが作れる。
JavaScriptのオブジェクトとして利用可能
メソッドは定義できない。

例

```scala
trait Point extends js.Object {
  val x: Int
  val y: Int
}
val point = new Point {
  override val x: Int = 1
  override val y: Int = 2
}
js.Dynamic.global.console.log(point)  // => { x: 1, x: 2}
```

利用には、
`@ScalaJSDefined`アノテーションをつけるか、sbtに以下のコードを貼り付ける必要がある。

```scala
scalacOptions += "-P:scalajs:sjsDefinedByDefault"
```

native JSに比較して、安全にインスタンスが作成できる。

より詳細はこちらに。
https://www.scala-js.org/doc/interoperability/sjs-defined-js-classes.html

# Scala trait

普通のScalaのトレイト
何らかのコードが生成される。
普通に使える。
定義したフィールドがプロパティと一致しないため、JavaScriptのオブジェクトとしては使えない。

```scala

trait Point {
  val x: Int
  val y: Int
}
val point = new Point {
  override x: Int = 1
  override y: Int = 2
}
js.Dynamic.global.console.log(p.asInstanceOf[js.Any])   // => $c_LPointScala { 'x$1': 1, 'y$1': 2 }
println(p.x) // => 1
```

プロパティはフィールド名と一致しない。
代わりにgetterが定義されてるのを確認できる。
JSのライブラリに渡して安全に動くとは限らない。

# まとめ

| | native JS | non-native JS | Scala |
|----|-----------|--------------|---------|
|インスタンス作成 | js.Dynamic.literalで | できる | できる |
|メソッド定義 | インターフェースのみ実装は生成されない | できない(抽象クラスでできる) | できる |
|js Objectとして使用 | できる | できる | できるがおすすめできない |
micro:bit 4足歩行ロボット、サーボを電池BOXの裏に両面テープで貼り付けるだけでできた

#■はじめに
電池BOXの裏にサーボを両面テープで貼りつけただけという、小学生でも余裕で行ける4足歩行ロボットを作ったので紹介します。ソフトウェアも簡単で、ブロックプログラムで作りました。サーボは4台使うので、拡張ボードで繋ぎました。なかなか楽しい動きをするので、ぜひ楽しんで下さい。

ちなみに、obniz版の4足歩行ロボットの記事もあります。
https://qiita.com/Google_Homer/items/c332c8c4f778bb31b3a1
#■まずはデモ動画から
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/microbit?src=hash&amp;ref_src=twsrc%5Etfw">#microbit</a> <a href="https://twitter.com/hashtag/4%E8%B6%B3%E6%AD%A9%E8%A1%8C%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#4足歩行ロボット</a><br>電池BOXの裏にサーボを貼り付けただけの4足歩行ロボットのmicro:bit版もできた。 <a href="https://t.co/pmgZIfsgAZ">pic.twitter.com/pmgZIfsgAZ</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1105098817165094912?ref_src=twsrc%5Etfw">2019年3月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#■ロボット組み立てに必要なもの
① サーボモーター Tower Pro SG90 or SG92R × 4 
② 強力タイプの両面テープ少々
③ 単三×4本の電池BOX (下記拡張基板に接続し、micro:bitにも給電されます。)
④ サーボ拡張基板 kitronik-I2C-16-servo
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/fcce5e5c-b0df-1d98-f6e0-bf97e2bfdd48.png)
#■ロボットの組み立て方
***・サーボを両面テープで電池BOXの裏に貼り付ます。***
***・足はサーボ付属のホーンを使います。***
***・回転角度90度で直立するよう取り付ます。***
***・サーボの向きは必ず写真と同じにして下さい。***
***・電池BOXの上に適当にmicro:bitを盛ります。***
***・拡張基板のServo1から順に、後左足→後右足→前左足→前右足のサーボ端子を刺します。***
![WIN_20190311_21_52_51_Pro.jpg](https://qiita-image-store.s3.amazonaws.com/0/234533/94fcb21a-3c2d-7624-a6d7-de3f9b2cd613.jpeg)
![WIN_20190311_22_22_01_Pro.jpg](https://qiita-image-store.s3.amazonaws.com/0/234533/12be7506-e0f6-6771-81fb-b263a13b5515.jpeg)
![WIN_20190311_22_21_06_Pro.jpg](https://qiita-image-store.s3.amazonaws.com/0/234533/c5395a8c-c25f-f736-03cd-28a325ea7f31.jpeg)
![WIN_20190311_22_21_17_Pro.jpg](https://qiita-image-store.s3.amazonaws.com/0/234533/d64827ea-3cce-d480-bb50-e50e60227787.jpeg)

#■ブロックプログラム
***Aボタンで前進***、***Bボタンで後進***します。いずれも10歩、歩きます。
歩行ロジックは***「トロット歩容」モデル***を模しています。
プログラム中の角度は絶対値ですがサーボの組付け方向によって反転していたりしてどんな動きをさせているのか分かり難いので、***コメントは直立90°からの相対角度で表記***して意味がわかりやすくしています。
***サーボドライバーは拡張機能の「kitronik-I2C-16-servo」を使いました。***
![microbit 4足歩行ロボット プログラム.png](https://qiita-image-store.s3.amazonaws.com/0/234533/bda6842f-c224-c78d-8dc9-84e09bd3f1b8.png)

以上です。
コンテナ間通信する（ECS、Fargate起動）

## 概要

Fargateを使っている時にコンテナ間通信をする方法のメモ。
localhostからコンテナ毎に割り当てたポートへアクセスできる。
※あるコンテナに8888をマッピングしている場合、 `localhost:8888` みたいな感じで。

ちなみにFargate起動の場合、リンクやホスト名指定はできないのでこの方法でやるしかない、多分。

## メモ

Fargateを使っている時、コンテナ間の通信はlocalhostを使う。
例えばタスク定義内で、
コンテナA：ポート80
コンテナB：ポート8888
のような場合、コンテナAからコンテナBの8888ポートへ通信したい場合、指定の仕方は `localhost:8888` になる。

## 参考

* [AWS Fargateでコンテナ間通信させたいとき](https://qiita.com/taishin/items/84122ad85bedf8b8a682)
[Amazon WorkSpaces]AmazonLinux2にChromeインストール

Amazon Linux release 2 (Karoo)

```sh
sudo vi /etc/yum.repos.d/google.chrome.repo
```

```google.chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
```
```sh
sudo yum install google-chrome-stable
```
M5StackとGPSで遊ぶ

Pythonが動くマイコンで遊んでみようと思いM5Stackを買いました。

* https://m5stack.com

M5StackはEspressif ESP32マイコン、ディスプレイ、SDカードスロット、ボタン、ブザーが搭載されており、かわいいプラスチックの筐体にパッケージされています。基板をむき身で持つよりずっと安心できますね。

製品ラインナップはマイコンが搭載される **コア** とセンサ機器を搭載する **モジュール** に分かれています。 モジュールにはコアの下側にスタックして接続するものとGroveコネクタにより接続するものがあります。


# 買ったもの

* M5Stack Fire (失敗!)
* M5Stack Gray
* M5Stack GPS Module

![MVIMG_20190306_135111.jpg](https://qiita-image-store.s3.amazonaws.com/0/29860/adea0f23-b7a6-bc1e-1eed-e9f2975ca369.jpeg)


## M5Stack Fire

M5Stack Fireはコアの一つで、標準のコアに9軸センサとPSRAMが追加されています。

メモリも多いし、9軸センサも載ってるし、バッテリ付きモジュールも同梱してるし、これは便利だと思ったわけですが罠がありました。同時に購入したGPSモジュールが動きません。

MicroPythonからGPSモジュールのUARTにアクセスするとリブートしてしまい、何故だろうと調べまくった結果、以下のことがわかりました。

* M5Stack FireのPSRAMは16番、17番ピンを使用 (回路図)
* GPSモジュールのUARTは16番、17番ピンを使用

おい嘘だろ…。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Yes port c is conflict with psram, so , because there are not enough serial to use. The psram doesn’t suggested a long wire extension, so if run not well, u can try to cut the pin of the bottom’s g16/17 pin, it will be okay</p>&mdash; M5Stack (@M5Stack) <a href="https://twitter.com/M5Stack/status/1026125631757508608?ref_src=twsrc%5Etfw">2018年8月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


カッとなったわたしはPSRAM未搭載の別のグレードであれば動くだろうと考え千石通商へ走り、M5Stack Grayを手に入れました。こちらは正常に動作。


# 開発環境の構築

MicroPythonを動かすには以下のツールが必要です。

* [silabs vcp driver](https://jp.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)
* [esptool](https://github.com/espressif/esptool)
* [M5Cloud firmware](https://github.com/m5stack/M5Cloud/tree/master/firmwares)
* [adafruit ampy](https://github.com/pycampers/ampy)

## UART VCPドライバのインストール

Macの人はbrewでインストールすると簡単です。

```console
brew cask install silicon-labs-vcp-driver
```

## esptoolのインストール
Macの人はbrewでインストールすると簡単です。

```console
brew install esptool
```


## adafruit ampyのインストール

brewで提供されていないのでpipでインストールします。
（Python2じゃないと動かなかったような気がする）

```console
pip install adafruit-ampy
```

## ファームウェアのインストール

esptoolがインストールされていれば以下の手順でインストールできます。 `firmware.bin` はダウンロードしたファイルを指定しましょう。

```console
esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART erase_flash
esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART write_flash --flash_mode dio -z 0x1000 firmware.bin
```

# GPSモジュールを駆動するサンプルコード

Ambientさんのサイトで書かれていた [M5StackでGPS衛星の現在位置を表示する](https://ambidata.io/blog/2018/10/12/m5stack_gpswatch/) をSDカードにGPSログを取得するよう改造して動かしました。 `main.py` と `micropyGPS.py` を同じディレクトリに置いたら次のようにファイルを転送します。

```console
ampy -p /dev/cu.SLAB_USBtoUART put main.py
ampy -p /dev/cu.SLAB_USBtoUART put micropyGPS.py
```

M5Stackの側面についているボタンを短押しするとリセットされ、プログラムが実行されます。

![00100lPORTRAIT_00100_BURST20190311220859759_COVER.jpg](https://qiita-image-store.s3.amazonaws.com/0/29860/da71cd2b-c41e-f652-72ec-0c68f5f6b0a8.jpeg)


改造後のコードはgithubに上げました。

* https://github.com/key/m5stack-gps
Docker - Get Arguments from Docker Run Command as Golang Main Function Arguments

# 1. Modified Dockerfile.
```dockerfile:Dockerfile
FROM alpine:3.9
...
ENTRYPOINT ["./app"]
CMD ["ARG_DEV"]
```

# 2. Run your docker image.
```
docker run -d me/app ARG_PROD
```

# 3. Add below code in your main().
```golang:main.go
...
func main() {
	arg := os.Args[1] <--- You can get "ARG_PROD" here.
...
}
```

https://stackoverflow.com/questions/40873165/use-docker-run-command-to-pass-arguments-to-cmd-in-dockerfile
オイラー法による非等温反応の計算

# <font color="Red">オイラー法で非等温反応を解くだけ</font>
## 背景
　Oiita自体に投稿するのが初めてなので最近始めたGitの練習と合わせて投稿してみるだけ、あとMarkdown記法の練習もかねて。ついでに言うなら化学系の投稿が少ないので少し寂しいので。
　Gitのリポジトリは[ここ](https://github.com/ac-yasushi/eular_method)

## 計算手法
　オイラー法を説明する必要は全くないと思うので、実際の設計方程式を変形した形で下に示す。
  
$$\frac{dx_A}{dt}=\frac{r_A}{C_{A0}}=k_oexp(-E/RT)(1-x_A)$$ 

$$\frac{dT}{dt}=\frac{r_AΔH}{ρc_{pm}}-\frac{UA(T_s-T)}{Vρc_{pm}}$$ 

　上の2式をオイラー法で解く(上：設計方程式、下：熱収支式)。上の反応速度に注目すれば分かるが、反応速度は温度に対して**指数関数的に変化する**。なので等温反応を仮定して解くと実際の反応時間と反応率に対して大きく違う答えが出てくる。

## 練習問題
　培風館の『反応工学』の例題を取り上げる。 

>A→Cで表される液相反応を非等温の回分反応器を用いて行う。すなわち、内径D=0.8 m、高さ1.3 mの撹拌僧にAのみからなる原料を500 ㎏仕込んで、槽の側面と底部をジャケットでつつみ、その中に熱媒体を流して、槽外壁を常に613 Kに保って反応させる。反応率が95%になる反応時間を求めよ。本反応は1次反応であって、反応速度は次式で与えられる。

>-ra=3.228×10^13×exp(-E/RT)×Ca

>ただし、E=186.2×10^3 J/mol
反応熱 ΔH=62760 J/mol
反応液密度 ρ=900 ㎏/m^3
反応液の平均比熱容量 Cp=2.51×10^3 J/kg/K
Aの分子量 M=385×10^-3 kg/mol
総括伝熱係数 U=523 W/m^2/K

>培風館『反応工学』 p170 例題7・4

## 解法
　基本的にオイラー法では$a<b$に対して区間$[a,b]$を何ステップに分けるかで決めるが、ここではstepで定めた時間数を終了条件まで計算し続ける。反応速度式の計算ならそこまで問題にならない。気になるなら微分方程式を反転させて(逆数を取って)終了条件の$x_A$に対して区間で区切ればいい。
  
　言語はPython、環境はJupyter notebookで行った。コードは[ここ](https://github.com/ac-yasushi/eular_method)。化学系では実行速度や過去の遺産によりいまだにFORTRANやCが活用されているがこれくらいはpythonで問題がない。むしろグラフ描画がやりやすい分、個人的には好みである。設計の段ではExcel+VBAというのも計算とグラフ、表計算の3点セットで使いやすい。
  
　反応率$x_A=0.95$で終了。$step=0.1 s$で19988回。2000秒で反応終了。これくらいならすぐ。
　反応率の変化と温度変化を下に示す。
![x_t.png](https://qiita-image-store.s3.amazonaws.com/0/371781/464869cf-6b2e-08fe-699d-638ef5d9883f.png)
![T-t.png](https://qiita-image-store.s3.amazonaws.com/0/371781/0639bfaa-0538-2171-dc32-c7bb2fc669db.png)
　温度の単位はK。613K(330℃)から反応がスタートしたが途中で吸熱反応により温度が590Kまで低下しているのが分かる。

## 等温と非等温
　例題はここまでだが、実際に温度変化がどれくらい反応に寄与しているのかを計算してみる。つまり熱収支式を無視して613K一定で設計方程式を解く。
  
　そのあと613Kではなく100℃低い513Kで計算をして結果を見る。コードは[ここ](https://github.com/ac-yasushi/eular_method/blob/master/eular_cal_isothermal.ipynb)
  
　613Kでの等温の結果は以下のようになった。
![T-Tiso-t.png](https://qiita-image-store.s3.amazonaws.com/0/371781/5bf36508-2777-7c62-b633-e03dca6a2879.png)
　オレンジの線が等温での計算結果である。20K程度温度が下がっただけで反応時間が3倍程度になることが分かる。反応速度がいかに温度変化に敏感かよく分かる。

---
　次に513Kでの非等温反応を解いてみる。が、解いてみた温度変化の式が下になる。
![T513-t.png](https://qiita-image-store.s3.amazonaws.com/0/371781/f48e30b3-87b2-54a1-c7c1-da91aab64a2c.png)
　反応を通して513K一定であることが分かる。100℃低いと反応速度が極端に遅くなるので反応熱より壁面からの熱伝導のほうが圧倒的に大きくなる。
  
　今度は同じく513Kでの等温ー非等温を比べてみる。
![x513_t.png](https://qiita-image-store.s3.amazonaws.com/0/371781/e70d5889-66aa-1fa7-b964-3f6bb4cc199a.png)
　完全に等温反応と非等温の反応が一致している。
  
　それにしても613Kで2000sの反応が513Kで800000s、ほとんど9日かかる。この場合、温度が高いほうが有利である。
　しかし、今回は吸熱反応で温度が下がる方向にはたらいたが、発熱反応で温度が上がる場合、上に見たように反応速度が急激に上昇しそれがさらに温度を上げるので熱暴走の危険がある。その辺は熱的安定性の問題になるが、温度が簡単に上昇するような状況は良くない。
vue-metaでbodyにクラスを追加する

今回はbodyに対してclassタグを追加する方法です。

業務でmodal windowを実装する時に知った知見だったので、記事にしようと思いました。

### 実装方法
vue-metaにはdefaultでbodyAttrsという機能があります。（https://github.com/nuxt/vue-meta#bodyattrs-object）
こちらを使うとbody自体にclassなどを付与することができます。

サンプルコードは以下のような感じです。

```js
<template>
  <div @click="clickHogeHoge"/>
</template>

<script>
export default {
  name: 'BaseHeader',
  head() {
    return {
      bodyAttrs: {
        class: this.isOpen ? 'body--fixed' : ''
      }
    }
  },
  data() {
    return {
      isOpen: false
    }
  },
  methods: {
    clickHogeHoge() {
      this.isOpen = !this.isOpen
    }
  }
}
</script>
```
clickHogeHogeというmethodでclickされたらフラグを切り替え、bodyAttrsにある`this.isOpen`がtrueだった場合bodyに`body--fixed`というclassが付与されます。
文系エンジニアが社会人2年目で初めてサイトを作ったので公開してみた。(工数：1週間)

変態エンジニアが初めてサイトを公開したので宣伝も兼ねて紹介させてください。
文系出身だとこれくらいのレベルなんやで？ってことが伝わればいいと思います。

## 環境
AWS Lightsail $10プラン(会社支給)
PHP 7.2
Laravel 5.5
Mysql 5.6
bootstrap
let's encrypt

## 開発環境
Docker

## つくったサイト 「エロURL保管庫」
https://yorozun.xyz/
いやんうふんなURLを保存できます。
検索機能があるので「あの動画どれだっけ？」を防ぐことができます。

![スクリーンショット 2019-03-12 0.26.03.png](https://qiita-image-store.s3.amazonaws.com/0/375645/219543fa-664c-d5ca-82fe-dd56651155d0.png)
![スクリーンショット 2019-03-12 0.26.36.png](https://qiita-image-store.s3.amazonaws.com/0/375645/17a99c77-8eef-24f6-6057-598cc172aade.png)


## つくった背景
友人がいやんうふんな動画をローカルに保存せず、メモ帳にURLを貼り付けて保存してるってやつがいたんですよ。
そんな友人のためにサイトをつくってみました！

## 機能一覧

- URLの保存
- URLの編集
- URLの削除
- URLの検索機能

たったのこれだけです。
これだけでも最低限のサイトとしての機能は備わっていると思います。
すぐにランキングやいろんな機能を追加していきますが、最低限の機能がそろったのでリリースしました。

## サービス思考の新人エンジニアへ

新人エンジニアだと「新しいサービスをつくりたい！」と思っても

- 計画段階で挫折
- 実装する機能がありすぎて挫折
- 友人をまとめられずに挫折
- 途中で飽きる
- 仕事が忙しくなってやる気が出ない

上記の理由でリリースまでこぎつけないことがほとんどです。(ちなみに僕のことです)
大きなものを作ろうとすると99%挫折します。

1ヶ月以内でつくれる小さなサイトを目指すとリリースまでできる可能性が高いです。
そして重要なのが「不完全でもいいからリリースすること」。

正直どこまでやっても「機能が足りない。。」「デザインがださい。。」
とやりつくせないことばかりです。
不完全でもいいので１回リリースしてみるとサイトの規模感がわかって次のステップに進みやすいです！


あと大事なことを伝え忘れてました。
メールアドレスは存在しないものでも登録できるので使ってみてください。お願いします！

## その他こんなことをやりました
・【機会学習】しずかちゃんのお風呂画像はエロいのか機械学習で検証してみた
https://teepo.net/%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0/%e3%80%90%e6%a9%9f%e4%bc%9a%e5%ad%a6%e7%bf%92%e3%80%91%e3%81%97%e3%81%9a%e3%81%8b%e3%81%a1%e3%82%83%e3%82%93%e3%81%ae%e3%81%8a%e9%a2%a8%e5%91%82%e7%94%bb%e5%83%8f%e3%81%af%e3%82%a8%e3%83%ad%e3%81%84/

## 最後に
AWSでこういうサービスってダメなんじゃないかとビクビクしてます。。。
プログラミング・スキルチェック問題「日付データの変換」ランクC

## はじめに

パイザ・スキルチェックの問題が"自由"に使えないので、学習者向け問題を自作してみました。なお、この問題はGNU GPLです。"自由"にご使用ください。

## 問題

西暦日付（ハイフン区切り）が、入力として与えられます。

これを西暦日付（スラッシュ区切り）で出力してください。

例）2019-04-01 → 2019/04/01

なお、入力が西暦日付（ハイフン区切り）の形式ではない時は、Falseを出力してください。

### 入力される値
1行目には西暦日付（ハイフン区切り）の文字列"Y/M/D"が入力されます。

### 期待する出力
西暦日付（ハイフン区切り）ならば西暦日付（スラッシュ区切り）、違う場合はFalseを出力してください。

### 条件
文字Yは、0000～9999
文字Mは、01～12
文字Dは、01～31

※前ゼロの有無と存在しない日付（2/31など）については問題が難しくなるため、考慮してもしなくてもかまいません（回答の成否に影響しないものとします）

### 入力例1

> 2019-03-23

### 出力例1

> 2019/03/23

### 入力例2

> 2019.03.23

### 出力例2

> Flase

## 回答例

###python3の例

```python3:python3.py
# coding: utf-8
# Your code here!
import sys

line = input().split("-")

# 要素数チェック
if len(line) != 3:
    print("False")
    sys.exit()

flg = 0

for x in line:
    if not x.isdigit():
        print("False")
        sys.exit()

if not (int(line[0]) >= 0 and int(line[0]) <= 9999):
    print("False")
    sys.exit()

if not (int(line[1]) >= 1 and int(line[1]) <= 12):
    print("False")
    sys.exit()

if not (int(line[2]) >= 1 and int(line[2]) <= 31):
    print("False")
    sys.exit()

print(line[0].zfill(4) + "/" + line[1].zfill(2) + "/" + line[2].zfill(2))
```

###PHPの例

```php:php7.php
<?php
$date = trim(fgets(STDIN));

if( ! preg_match('/^([0-9]{1,4})\-(0[1-9]{1}|[1-9]{1}|1[0-2]{1})\-(0[1-9]{1}|[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]{1})$/', $date)){
    echo "False";
    exit;
}

// 前ゼロいれないと正しく出力されない…
$date = explode("-", $date);
$date = sprintf('%04d', $date[0]). sprintf('%02d', $date[1]). sprintf('%02d', $date[2]);

$obj = new DateTime($date);
echo $obj->format('Y/m/d');
```

## 参考にしたサイト

- http://chuckwebtips.hatenablog.com/entry/2016/05/14/000000
- http://php.net/manual/ja/class.datetime.php
- https://wepicks.net/phpsample-preg-date/

## お願い

誤りやスマートな回答方法など、お気づきの点があればぜひ教えてくださいm(_ _)m
Docker、ECS関係まとめ

## 概要

自分で書いたDocker関係の記事のリンク集ページ。

## リンク

### Docker

* [コンテナ利点メモ](https://qiita.com/k_hoso/private/a1ae5dc812c62611faa3)
* [Dockerコンテナ間でファイルを共有（マウント）する](https://qiita.com/k_hoso/items/fb37433c739e92848aba)
* [コンテナ間通信する（docker runから）](https://qiita.com/k_hoso/items/96139cffd5b3e4159526)
* [Dockerコンテナからホストにアクセスする（ホストのIPアドレス取得方法）for Windows
](https://qiita.com/k_hoso/items/40d2f18eccc29a204055)
* [Dockerコンテナからホストにアクセスする（ホストのIPアドレス取得方法）for Linux](https://qiita.com/k_hoso/items/cb073843192bbf54600b)

### AmazonLinux2

* [AmazonLinux2のDockerコンテナにPython3を入れる](https://qiita.com/k_hoso/items/bcd773bbfd260656e621)

### Docker Toolbox

* [DockerToolboxから見たホストOSのIPアドレスの調べ方](https://qiita.com/k_hoso/items/f395568848557c5dd230)

### ECS

* [コンテナ間通信する（ECS、Fargate起動）](https://qiita.com/k_hoso/items/5520aef93a4a63ffa0b3)
Dockerコンテナ間でファイルを共有（マウント）する

## 概要

コンテナA（参照される側）で共有したいディレクトリを、コンテナB（参照する側）でマウントして参照する。

簡単なやり方の説明としては、

* 参照される側はDockerfile内で `VOLUME` を指定。
* 参照する側は `docker run` する際に `--volumes-from` で参照される側のコンテナ名を指定する。

という感じ。

## 環境

```bash
$ uname -a
Linux ip-172-31-32-92 4.14.77-70.59.amzn1.x86_64 #1 SMP Mon Nov 12 22:02:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

$ docker --version
Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
```

## 実装

### 1.Dockerfile

Dockerfileを二つ用意する。
Dockerfile1が参照される側、Dockerfile2が参照する側。

Dockerfile1の方の `VOLUME` に注目。
`VOLUME` に指定されたディレクトリがそのままマウントした参照する側のコンテナに出る。

```dockerfile:Dockerfile1
FROM alpine:latest

WORKDIR /tmp/docker_mount_test
RUN touch hogehoge && \
    echo "this is hogehoge" > hogehoge

VOLUME /tmp/docker_mount_test
```

```dockerfile:Dockerfile2
FROM alpine:latest
```

### 2.docker build

普通にビルドするだけ。

```bash
docker build -f Dockerfile1 . -t test1
docker build -f Dockerfile1 . -t test2
```

こんな感じになる。

```bash
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test1               latest              b9bcae402c92        9 minutes ago       5.53MB
test2               latest              5cb3aa00f899        3 days ago          5.53MB
alpine              latest              5cb3aa00f899        3 days ago          5.53MB
```

### 3.docker run

下記の通り `docker run` する。
test2のコンテナの起動オプションに `--volumes-from` で参照される側のコンテナ名を指定する。

```bash
docker run -it --rm -d --name test1 test1
docker run -it --rm --volumes-from test1 --name test2 test2
```

test2の `docker run` でコンテナ側のシェルが立ち上がるので、Dockerfile1で `VOLUME` に指定したディレクトリ配下に生成したファイルを `cat` する。

```bash:Dockerfile2のコンテナ内で実行する
$ cat /tmp/docker_mount_test/hogehoge
this is hogehoge
```

という感じで、Dockerfile2のイメージから生成したコンテナから、Dockerfile1のイメージから生成したコンテナの中身が見えるようになる。
Scala の Future を Monix Task に変換する Tips

Scala の Future を Monix Task に変換したかった。
公式リファレンスにチュートリアル動画があったので視聴メモ。

https://monix.io/blog/2018/11/08/tutorial-future-to-task.html

# 準備

### Future を返す関数のサンプル

この関数を、如何にして Monix Task へ変換するかという点について解説する。

```scala
def sum(list: List[Int])(implicit ec: ExecutionContext): Future[Long] =
  Future(list.foldLeft(0L)(_ + _))
```

# 本題

### Task.fromFuture を使う

Future.apply が実行されるので遅延したい場合は使わないこと。

```scala
def sumTask(list: List[Int])(implicit ec: ExecutionContext): Task[Long] =
  Task.fromFuture(sum(list))
```

### Task.suspend もしくは Task.deferFuture を使う

suspend は defer のエイリアス なので suspend が Future を扱った場合、 deferFuture と同義となる。

##### Task.suspend

```scala
def sumTask(list: List[Int])(implicit ec: ExecutionContext): Task[Long] =
  Task.suspend {
    Task.fromFuture(sum(list))
  }
```

##### Task.deferFuture

```scala
def sumTask(list: List[Int])(implicit ec: ExecutionContext): Task[Long] =
  Task.deferFuture(sum(list))
```

### Task.deferFutureAction を使う

コールバックにインジェクトされた Scheduler を暗黙知として受け取る。
メソッドのシグネチャから ExecutionContext の暗黙引数が消えるは良さそう。

```scala
def sumTask(list: List[Int]): Task[Long] =
  Task.deferFutureAction { implicit scheduler =>
    sum(list)
  }
```

.runToFuture する際、 Implicit Parameter に Scheduler を渡して利用する。

```scala
import monix.execution.Scheduler.Implicits.global
sumTask(List(1,2,3)).runToFuture
```

### FutureLift を使う

Future → Task だけでなく他の非同期系の型変換をサポートしている。
※まだ、詳しく調べられていない。

##### FutureLift.from を使う

Task.from 同様 Future.apply は遅延しないことに注意。

```scala
def sumTask(list: List[Int])(implicit ec: ExecutionContext): Task[Long] =
  FutureLift.from(Task(sum(list)))
```

他の非同期系の型(cats.effect.IO)への変換は下記の通り。

```scala
def sumTask(list: List[Int])(implicit ec: ExecutionContext): IO[Long] =
  FutureLift.from(IO(sum(list)))
```

##### Task.deferAction と組み合わせて使う

Future.apply は遅延するし、シグネチャから ExecutionContext も消えた。

```scala
def sumTask(list: List[Int]): Task[Long] =
  Task.deferAction { implicit s =>
    FutureLift.from(Task(sum(list)))
  }
```

以上、Future → Monix.Task へのお引っ越しを検討中の方の参考になれば幸いです。

# おわり
Raspberry Pi Zero W にUSBスピーカーを接続する

```
# uname -a
Linux raspberrypi 4.14.98+ #1200 Tue Feb 12 20:11:02 GMT 2019 armv6l GNU/Linux
```

.asoundrcを新規作成

```
# cat ~/.asoundrc
pcm.!default {
    type plug
    slave.pcm "dmixer"
}

ctl.!default {
    type hw
    card 0
    device 0
}

pcm.dmixer {
    ipc_key 1024
    type dmix
    slave {
        pcm "hw:1,0"
    }
}
```

現在の状況確認

```
# cat /proc/asound/modules
 0 snd_bcm2835
 1 snd_usb_audio

# cat /proc/asound/cards
 0 [ALSA           ]: bcm2835 - bcm2835 ALSA
                      bcm2835 ALSA
 1 [MicroII        ]: USB-Audio - Audio Advantage MicroII
                      C-Media INC. Audio Advantage MicroII at usb-20980000.usb-1, full speed
```

```
# raspi-config

[7 Advanced Option] > [A4 Audio] > [1 Force 3.5mm ('headphone') jack] 

```

rebootして音声テストを実施

```
# aplay /usr/share/sounds/alsa/Front_Center.wav
```

参考
Raspberry Pi 3にUSBスピーカーをつなぐ
https://umiushizn.blogspot.com/2017/10/raspberry-pi-3usb.html
git merge の小さなサンプルメモ② conflict 

# メモ

- アカウントA
    - 	ブランチ（bugfix）切る
- アカウントB
    - 	編集、ローカルでコミット
    - 	Masterにpush
- アカウントA
    - 	編集、ローカルでコミット
    - 	Masterにch
    - 	pull
    - 	bugfixにch
    - 	merge bugfix
    - 	コンフリクト★
    - 	ファイルを修正
    - 	add
    - 	`git commit`
        - merge commit となる
    - push

全てのコミットが履歴となる

![ScreenClip.png](https://qiita-image-store.s3.amazonaws.com/0/50690/82e36c06-7866-afaf-3f30-2b8bc28fe737.png)

## 参考
git merge でのコンフリクト(競合)の解決方法まとめ | WWWクリエイターズ http://www-creators.com/archives/1938
定数の設定

##environment.rb

configの中にあるenvironment.rbというファイルは、ここにアプリケーションで共通して使う定数を記述しておいて置ける場所。

```environment.rb
BIRTH_YEAR_ARRAY = [*1930..Date.today.year]
BIRTH_MONTH_ARRAY = [*1..12]
BIRTH_DAY_ARRAY = [*1..31] 
```

このように、年は1930年から今年まで〜月は12月までだよ〜日にちは1~31日までだよ~ということをそれぞれの定数に格納している。

ちなみに [1..12]だと配列は展開できない「＊」が必要
<img width="315" alt="スクリーンショット 2019-03-11 23.42.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/265805/133732d2-61ec-eb8d-bc65-fcfb1fe7c1ea.png">


年は

```
[*1930..2019]
```

とかいても1930年から今年までの年を表示させることはできるが、毎年2020,2021と書き直さなきゃいけないので動的にかくとこうなる

```
[*1930..Date.today.year]
```



##form内での使い方

```
<%= form_with model: @user, local: true, :url => { :action => 'confirm' } do |f| %>
　　<h1>生年月日</h1>
　　<div class="select">
　　　　<%= f.label(:year) %>
　　　　<%= f.select :birth_year, BIRTH_YEAR_ARRAY.reverse, {:include_blank => "年"}, id: "user_birthday" %>
　　</div>
　　<div class="select">
　　  <%= f.label(:month) %>
  <%= f.select :birth_month, BIRTH_MONTH_ARRAY, {:include_blank => "月"}, id: 　　"user_birthday" %>
　　</div>
　　<div class="select">
　　  <%= f.label(:day) %>
　　  <%= f.select :birth_day, BIRTH_DAY_ARRAY,{:include_blank => "日"}, id: "user_birthday" %>
　　</div>
<% end %>
```




####selectの使い方
select(オブジェクト名, プロパティ名, タグの情報 [, オプション])

プロパティはオブジェクトに紐づくデータのこと
useMemoについて

UseMemoについての覚書です。

最初ドキュメントを見てuseCallbackとの違いがスッと入ってこなかったので、、
実際に使用してみたり、使用例とか見ると理解しやすいのですけどね。

公式ドキュメントにて `useCallback(fn, deps) ` と `useMemo(() => fn, deps)` は等しいよ、と言われており、コード上の差異はそんなにありません。

UseMemoもuseCallbackも第二引数で渡す `deps` の値が変更された際
中身が再評価されます。

ただ、 `useCallbackが関数を返す` のに対し
`useMemoは値を返す` という違いがあり、その違いが２つを差別化する基準となってます。

## useMemoの動き

useMemoはレンダリング中に第１引数で渡した関数を実行し、実行結果をキャッシュします。

```javascript
// fanctional component
...
  const memoDate = useMemo(() => {
    return Date() 
  }, [])
  
  return (
  	<div>date: {memoDate}</div>
  )

```

こちらは第２引数で渡した値が変更されない限り最初に実行された時と同じ結果を返します。
上の場合同じ日時を表示し続けます。
`第２引数が空配列となっており、第２引数の値の変更は起こらない` です。
なので `値が更新されずキャッシュされた初期実行時の値` を返し続けるわけです。

```javascript
// fanctional component
...
  const memoDate = useMemo(() => {
    return Date() 
  }, [hoge])


  return (
  　<div>date: {memoDate}</div>
  )

```

もし上のように第２引数に値を渡している場合は
レンダリング時以外にも、`第２引数のhogeが変更された時に再評価され、表示が変わります。`

## 所感
上の例だとあまりパッとしないかもしれませんが、画像処理などの複雑な計算をドラッグイベントの際に行う時など
useMemoを使えば低スペックPCでの動きが変わるのではないでしょうか。

`第二引数のdepsの指定漏れでハマる`ことがあるのでお気をつけくださいｍｍ

他のHooksについても追々書いていきます。
CodeBuildでのAWS CLI実行時に出るSNIMissingWarning対策

[CodeBuildの公式イメージ](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html)のうち、インストールされているPythonのバージョンが古いものを使うと、以下の警告が出力される。

```
SNIMissingWarning: An HTTPS request has been made, but the SNI (Server Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
SNIMissingWarning
```

この警告はPythonのバージョンが2.7.9より小さい場合に出るが、インストールされている（AWS CLIで使われる）Pythonバージョンを調べてみると以下の通りであった。

| image                      | Python Version |
| -------------------------- | -------------- |
| [aws/codebuild/standard:1.0](https://github.com/aws/aws-codebuild-docker-images/blob/master/ubuntu/standard/1.0/Dockerfile) | 3.7.2          |
| [aws/codebuild/ubuntu-base:14.04](https://github.com/aws/aws-codebuild-docker-images/blob/master/ubuntu/ubuntu-base/14.04/Dockerfile) | 2.7.6 |
| [aws/codebuild/docker:17.09.0](https://github.com/aws/aws-codebuild-docker-images/blob/master/ubuntu/docker/17.09.0/Dockerfile) | 2.7.6 |
| [aws/codebuild/docker:18.09.0](https://github.com/aws/aws-codebuild-docker-images/blob/master/ubuntu/docker/18.09.0/Dockerfile) | 3.4.3 |

特に理由がなければ、Ubuntu 18.04ベースのStandardイメージを使うのが良さそうである。
【意外と知らない】長いコマンド・ファイルを打つのを省略する方法

## 【意外と知らない】長いコマンド・ファイルを打つのを省略する方法
初心者向けの記事です。
ターミナルで、コマンドやファイル名を途中まで記入したところでtabキーを押すと、残りの文字を補完しくてれます。
そのディレクトリに`abc.txt`と`xyz.txt`というファイルがあったとします。

`$ ls a`
と記入してtabキーを押すと、
自動的に`$ ls abc.txt`となるはずです。

時間短縮に、ぜひ覚えておきたい機能です。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Nextcloudの管理用CLI「occ」詳細： ログ管理に関するコマンド群

# はじめに
NextcloudにはCLI環境として`occ`というものがあり、さまざまな設定、管理を行うことができます。 ここではoccで使える様々なコマンド群のうち、ログ管理に関するコマンド群についてまとめてみます。

※occ の使い方については、 [Nextcloudの管理用CLI「occ」コマンドについて](https://qiita.com/S_Katz/items/99b9319127d956b22e7b)の記事を参照ください。

# 環境について
ここで記載するoccを実行するNextcloudのバージョンは、2019年3月30日現在で最新の`15.0.5`を利用します。  
WebサーバはNginxを利用した環境で実施しております。ApacheをWebサーバとして利用している場合は、`sudo -u` のユーザIDを`apache`に読み替えてください。

# ログ管理に関するコマンド群
ログ管理に関するコマンドは以下のようなものがあります。

- log:file
- log:manage

## log:file
Nextcloudログの出力に関する設定を行います。オプションを何も指定しない場合はログ出力設定情報を出力します。

### 使い方
`log:file [オプション]`

#### オプション
- `--enable`
Nextcloudログの出力を有効にします。  
_# ログ出力はデフォルトで有効になっており無効にする手段が見つからないので利用することはないと思われます。_
- `--file=FILE`
Nextcloudログの出力先ファイルを絶対パスで指定します。出力先ディレクトリはあらかじめ作成しておく必要があり、このディレクトリに対してNextcloud実行ユーザ(=occ実行ユーザ)が読み書きできるように権限設定をする必要があります。
- `--rotate-size=ROTATE-SIZE`
Nextcloudログファイルをローテートするファイルサイズを指定します。ファイルサイズはバイト単位で指定しますが、`"k(K)"`(キロバイト)、`"m(M)"`(メガバイト)、`"t(T)"`(テラバイト)の単位も指定できます。`--rotate-size=0`とするとログローテートは行われません。ローテートした古いファイルは`"[ログファイル名].[数字]"`というファイル名になります。  
ログローテート処理はバックグラウンド処理で行われるため厳密にここに示したサイズジャストでローテートされず、若干大きいファイルサイズとなります。  
_※`logrotate`によるログローテーションの運用もあわせて検討しましょう。_

### 使用例
①現在のログ出力設定情報を出力する。

```
$ sudo -u nginx php /var/www/html/nextcloud/occ log:file
Log backend file: enabled
Log file: /var/www/html/nextcloud/data/nextcloud.log
Rotate at: 100 MB
```
②ログファイルの出力先を`/var/log/nextcloud/nextcloud.log`にする。

```
$ sudo -u nginx php /var/www/html/nextcloud/occ log:file --file=/var/log/nextcloud/nextcloud.log
Log backend file: enabled
Log file: /var/log/nextcloud/nextcloud.log
Rotate at: 100 MB
```
③ログファイルサイズが1GBを超えたらローテートする。

```
$ sudo -u nginx php /var/www/html/nextcloud/occ log:file --rotate-size=1g
Log backend file: enabled
Log file: /var/log/nextcloud/nextcloud.log
Rotate at: 1 GB
```

## log:manage
Nextcloudログの出力に関する詳細な設定を行います。オプションを何も指定しない場合はログ出力詳細設定情報を出力します。

### 使い方
`log:manage [オプション]`

#### オプション
- `--backend=BACKEND`
Nextcloudログ出力のバックエンド処理方法を設定します。設定可能なパラメータは以下のとおりです。
  - `file`
  - `syslog`
  - `errorlog`
  - `systemd`
- `--level=LEVEL`
Nextcloudログの出力レベルを指定します。設定可能なレベルは以下のとおりです(キーワード/数字のどちらでも指定できます)。
  - `debug (0)` (すべてのアクション、最も詳細なロギング)
  - `info (1)` (ユーザーログインやファイルアクティビティなどのアクティビティに加えて、警告、エラーをロギング)
  - `warning (2)` (警告(=処理が成功したものの潜在的な問題があるもの)、エラーをロギング)
  - `error (3)` (エラーをロギング)
- `--timezone=TIMEZONE`
Nextcloudログに記録する日時のタイムゾーンを指定します。指定するタイムゾーンは [PHPのタイムゾーン指定](https://www.php.net/manual/en/timezones.php) と同じとなります。

### 使用例
①現在のログ出力詳細設定情報を出力する。

```
$ sudo -u nginx php /var/www/html/nextcloud/occ log:manage          
Enabled logging backend: file
Log level: Warning (2)
Log timezone: UTC
```
②ログをsyslogとして出力する。

```
$ sudo -u nginx php /var/www/html/nextcloud/occ log:manage --backend=syslog
Enabled logging backend: syslog
Log level: Warning (2)
Log timezone: UTC
```
③ログ出力レベルを`info`にし、タイムゾーンを日本時間にする。

```
# sudo -u nginx php /var/www/html/nextcloud/occ log:manage --level=info --timezone Asia/Tokyo
Enabled logging backend: file
Log level: Info (1)
Log timezone: Asia/Tokyo
```

**★この記事は、[スタイルズ社のNextcloudサイト](https://nextcloud.stylez.co.jp/) の [Nextcloudブログ](https://nextcloud.stylez.co.jp/nextcloudblog)にも公開しております！**
Vue+Firebaseでタスク管理を作ってみた

ユーザ系子会社SEからWEB系プログラマに転職してから、勉強でしばらくVueをダラダラと触っていたが今朝[この記事](https://qiita.com/motoki4917/items/40386dd7fbd70987cc1d)の

>アウトプットに価値がある。

を読み思い立って未完成だがデプロイ＆投稿してみた。

#作ったもの
https://fluffy-task.web.app/#/signin
タスク管理サービス（仮
- スクラムボード
- タスクリスト
- Googleログイン

#動機
転職の前と後の職場でも、何かしらの作業進捗ツールを使っていたが、入力の理由がよくわからないカスタム項目だらけの面倒臭い仕様に対して抱いていた不満の解消。
要はは**ぼくのかんがえたさいきょうのつーる**

#使ったもの
- Vue
- Vuex
- Vue-router
- Firebase
- Buefy
- Muuri  

認証＋データベース＋ホスティングはFirebase、デザインはBuefy、スクラムボードの動きはMuuri。
個人開発なので手間と時間をかけないようにフレームワークを駆使しした。
とりあえずFirebaseによるサーバーレスは触っていて楽しい。

#反省点
当初は１ヶ月で形にする予定だったがQiitaを参考にために読んでいたら、あれもこれも試してみたいと手を広げて気がついたら４ヶ月経っていたので、具体的なゴールを決めて気になることはTodoで留めるべきだった。

#今後
やりたいことは次々頭に湧いてくるが、とにかくアウトプットを意識したいの。
開発中に嵌ったり解決できたらQiitaに投稿してみる。
湧いて出たアイデアは折角なので今回作ったものに記録してみる。

#追記
そういえば日記や報告書が苦手だった事を今更思い出したので、Qiita投稿をこんな感じでも続けて克服したい。
五十嵐響子画伯AIを作る その1 CNN

#はじめに
![head.jpg](https://qiita-image-store.s3.amazonaws.com/0/107045/6de18911-9592-5ef1-7bf7-b745de688154.jpeg)

五十嵐響子さんは「**味わい深い絵を描く**」ことで有名なアイドルです。これまでに公式でウサギとネコの絵を披露していますが、~~正直見わけられないので~~判別するCNNを組んでみました。

#サンプル
**6つ**しか見つかりませんでした。

|ソース|ラベル|
|:---|:---|
|モバマスN ジューンブライド|ウサギ|
|劇場369話4コマ目|ネコ|
|劇場369話5コマ目|ネコ|
|デレステログイン画面|ネコ|
|デレポ|ウサギ|
|アイプロアイテム「響子の特製オムライス」|ウサギ|

SSRあったかハートのウサギはあまりにひしゃげていたのでカットしました。ほとんどのサンプルがオムライスにケチャップで書かれたものなので、響子さんのお嫁さん特性がよくわかりますね。結婚したい。

#画像処理・水増し
7サンプルだけだとCNNどころかSVMすら学習させるのは難しいので、水増しします。

[参照文献](https://qiita.com/bohemian916/items/9630661cd5292240f8c7)を参考に、openCVで以下の処理を行いました。

* ガウシアンノイズ
* 上下左右反転
* 平滑化（フィルタサイズを5x5から14x14まで変化）

その結果こんな感じで5280枚まで画像を増やすことができました。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/107045/e15862e8-8bce-d8b1-14f0-849501d0c740.png)

#学習
読み込むときはグレースケールとしました。ケチャップだけを抽出したいので、thresholdをかけました。

マシンスペックがくそ雑魚なので、MNISTを参考に28x28x1を入力としました。

```python:cnn.py
def cnn():
    inputs = Input(shape=(28,28,1))
    xx = Conv2D(32,(3,3))(inputs)
    xx = Activation("relu")(xx)

    xx = Conv2D(32,(3,3))(xx)
    xx = Activation("relu")(xx)

    xx = MaxPooling2D(pool_size=(2,2))(xx)
    xx = Dropout(0.25)(xx)

    xx = Conv2D(64,(3,3))(xx)
    xx = Activation("relu")(xx)
    xx = Conv2D(64,(3,3))(xx)
    xx = Activation("relu")(xx)

    xx = MaxPooling2D(pool_size=(2,2))(xx)
    xx = Flatten()(xx)

    xx = Dense(512)(xx)
    xx = Activation("relu")(xx)
    xx = Dropout(0.5)(xx)

    xx = Dense(2)(xx)
    outputs = Activation("softmax")(xx)

    model = Model(input=inputs,output=outputs)

    model.compile(loss='categorical_crossentropy',
                  optimizer=keras.optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True),
                  metrics=['accuracy'])

    return model
```

#結果
test accuracyが100%になりました。ただ水増ししたとはいえ**サンプルが絶対的に少なすぎるので、これが過学習なのかどうかも判定するすべさえもありません**。響子さんにテストデータを描いてもらうしかないですね。

ちなみに、自分で書いた絵を判定させてみました。

![myfile.png](https://qiita-image-store.s3.amazonaws.com/0/107045/77297f9f-d170-2c1e-5271-3bcb72ce5411.png)

AI響子さん曰くこれは「**ネコ**」だそうです。僕はネコのつもりで描きました。

#ソース
github
https://github.com/bluepost59/kyoko_CNN
CSSで長方形の画像を丸く切り抜く方法 

Webサービスを作っていると
画像を丸く切り抜きたい時がある。

正方形の画像であれば"Border-radius:50%"で簡単に
丸く出来るのだが長方形の画像で上記のCSSを適用すると楕円形の
画像になってしまう。。。

正方形でない画像も真円で切り抜く方法はこちらのサイトに
詳しく書かれていた。
https://www.nishishi.com/css/trim-image-to-circle.html

ちなみにBackground-imageが表示されない時は
その要素にwidthとheightを指定してあげれば良い。

また、画像の中央で円形にくり抜きたい時は

```
background-position: center ;
```
とすれば中央でくり抜ける。

また、styleで

```
background-size:cover;
```

を指定してあげれば
以下の写真のように写真が拡大・縮小されて領域内に全体が収まるように処理される。

![無題1.png](https://qiita-image-store.s3.amazonaws.com/0/342318/1d41db68-fdc8-b1cd-205d-64e338fd041a.png)

↓

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/342318/7e260bce-8b79-ceda-937a-368eb4ccd3d7.png)
VSCodeでVagrantのMySQLを操作する

# はじめに
普段使っているVSCodeでSQL文を書いてその場で実行・確認できたらなーと思って、色々試したら何とかできたのでそれの \_φ(･\_･ です

# 好きなExtensionをいれる
- https://marketplace.visualstudio.com/items?itemName=formulahendry.vscode-mysql
- https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-database
- https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools

など

# SSHトンネルを手動で掘る
仮想環境内に用意したMySQLにアクセスするために、SSHトンネルを掘ります（ポートフォワーディング）。

```
# portやipはよしなに変更ください
$ ssh -N -L 3306:127.0.0.1:3306 vagrant@192.168.33.40
```

上手くつながると（応答がないように見えますが）プロセスを閉じるまでアクセスできるようになります。ターミナルを閉じても切れないようにバックグラウンドで実行するには `-f` オプションを指定します。

## 参考にさせていただいたサイト
- http://note.crohaco.net/2017/ssh-tunnel/
- https://nksg.org/archives/13

# Extensionで接続設定をする
あとは普通にMySQLのホスト・ポート・ユーザー名・パスワード・DBなどを指定し接続されれば成功です！！（もちろんVagrantは立ち上げておきます）

```
# 例
host: 127.0.0.1
port: 3306
username: root
password: 
database: app
```

# 終わりに
Sequel Proを使えば一発なんですが、やっぱり慣れているエディターでシンタックスハイライト・サジェスト・スニペット・フォーマットなど使えるのは気持ち良いですね...！
Timeパッケージを使って簡易ベンチマークを取ってみる

個人的にメモ。
原始的だが `time.Time` パッケージを使って、終了時間から開始時間をSubする。

```golang
func BenchFuncSeconds(f func() error) error {
	st := time.Now()
	err := f()
	if err != nil {
		return err
	}
	ed := time.Now()
	log.Printf("Time %v", ed.Sub(st))
	return nil
}
```

例えば、下記の関数を計測するとする。

```golang
func GetHelloList(name string, count int) []string {
	var list []string
	for i:=0;i<count;i++ {
		list = append(list, fmt.Sprintf("Hello %s\n", name))
	}
	return list
}
```

`BenchFuncSeconds`の引数は`(f func() error`なので`name string, count int)`を引数に受け取り、`[]string`を返り値に持つ`GetHelloList`は一見計測できないように見える。

が、下記のように即時関数内`func() error`で実行してやることで型の違いを気にせずに実行できるようになる。

```
func main() {
	_ = BenchFuncSeconds(func() error {
		_ = GetHelloList("Tarou", 99999)
		return nil
	})
}
```
トラブルシューティング1(Hyperledger-fabric)(docker)

Hyperledger Fabricによるアプリケーション開発を勉強しています。
P106～P133のブロックチェーンネットワークの構築でつまりやすいポイント

トラブル：Dockerのネットワークがバグで一つ多く自動で作成されていて、ネットワークができないというエラー

Removing network net_basic
ERROR: error while removing network: network net_basic id b40f9999db957527d1eb4371fe6a127945c4d376577f102bd77b9389301a3f1c has active endpoints

①docker network lsで状況確認
②docker network inspect　NAME名
それぞれ確認。特に、エラーであるnet_basic idを重点に
③docker network inspect net_basic id
→"Name": "ca.example.com"があり、コンテナと接続していることを確認
 "Containers": {
            "c6035605c93b24945bcb9639cf97d24c5987aad6584294388f8b4819e15bef6d": {
                "Name": "ca.example.com",
                "EndpointID": "e23e803e2acdc41dca87df77d114b6323c2511c15f2bebddaa2b37f24a62fc7f",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }　
④docker stop　ca.example.comで接続stop
⑤docker network rm docker　NAME名で削除。

エラー解決手法は、知っておくだけでも、いさという時に、便利なので記載します。
今後は、ブロックチェーン、パイパーレジャー、イーサリアムの記事を中心に記載します。
Pythonのpandasで加工したファイルのユニットテスト 例

# 概要

* [医薬品副作用データベース](https://www.pmda.go.jp/safety/info-services/drugs/adr-info/suspected-adr/0003.html)から取得したCSVファイルを使いpandasを用いたCSVの操作、その結果のユニットテスト用に作成
    * 医薬品、有害事象単位で症例をユニークにしたレコードを作成する。
    * 医薬品ごとに有害事象の件数を計算できるようにしたレコードを作成する。
* 作成した結果をユニットテストで確認できるようテストクラスも配置
* ソースは[github](https://github.com/snowpff14/pandastest)にて公開


## 使い方

1. データを[こちら](https://www.pmda.go.jp/safety/info-services/drugs/adr-info/suspected-adr/0003.html)から取得
    * ファイルサイズが大きいためgithubには加工したファイルをコミットしている
1. `data/drug.csv`に医薬品の情報(drugXXXXXX.csvをリネームする)を格納する。
1. `data/reac.csv`に有害事象の情報(reacXXXXXX.csvをリネームする)を格納する。
1. 実行すると`output`下に出力される。
    1. `caseCount.csv` は医薬品、有害事象の組み合わせで症例単位でまとめたもの例数計上用に重複を削除している。
    1. `count.csv` は医薬品、有害事象の組み合わせで症例単位でまとめたもの件数を数えるために重複もそのままにしてある。

## ユニットテスト

1. テスト用のデータは`test`下の同じ構成に配置している。
1. 現在の状態でテスト結果は一致するようにしている変更があった時には結果ファイルを必要に応じて修正を行う

## ソース説明

* `CreateFileBase`を継承したクラス内で処理を行うことで単体テストの結果比較を容易にしている。
* 各ファイルは`識別番号`.`報告回数`で結合できるようになっているのでまずは結合を行い必要な項目のみ出力している。
* `FileTestBase`は`unittest.TestCase` を継承しているのでこのクラスで比較処理は行うようにして呼び出し元はあくまでテスト対象の実行、結果の受け渡しのみを行う
* 今回はエクセルの対象は作っていないがcsvと同じ要領でエクセルの比較もできる
    * pandasを使ってエクセルファイルを加工するツールを作った際のテストなどに流用もできるはず・・・

## 応用

* 結果ディレクトリをテストケースごとに変えることでテストのパターンを網羅するできる
* 今後必要に応じて基底クラス部分は修正予定
reactで同じ条件で複数のプロパティーを分岐する

# 概要

reactのJSXの中で条件分岐に使う便利ツールです。

# 問題提起

react+jsxで、例えばあるボタンを、ユーザーの権限が無い時使用不能にし、かつクラスをつけて見た目も変えたいとします。多分こんな感じのコードになるんじゃないでしょうか？

```jsx
<button
  className={classNames('btn btn-primary', {deny: can('manage', 'guest')})}
  onClick={e => {
    if(can('manage', 'guest')){
      this.handleSendButton()
    } else {
      this.showAclError()
    }
  }}
>
  送信
</button>
```

このコードの問題点は同じ条件分岐`can('manage', 'guest')`が二箇所に書かれていることです。

これを一つのIF文で分岐することも可能ですが・・・

```jsx
{can('manage', 'guest') ? (
  <button
    className="btn btn-primary deny"
    onClick={e => this.handleSendButton()}
  >
    送信
  </button>
) : (
  <button
    className="btn btn-primary"
    onClick={e => this.handleSendButton()}
  >
    送信
  </button>
)}
```

今度はタグや子要素が二つ複製されて変更が面倒になります。

# 解決策

下記のようにかけるツールを作りました。

```jsx
<button
  {..._if(can('manage', 'guest'), {
    onClick: e => this.handleSendButton()
  }).else({
    onClick: e => this.showAclError(),
    className: 'deny'
  }).any({
    className: v => classNames(v, 'btn btn-primary')
  }).yield()}
>送信</button>
```

`_if()`の最初の引数がtrueだったら2番目の引数のオブジェクトが、falseだったら`else()`のオブジェクトがプロパティーに採用されます。`any()`には前段の`if/else/(elsif)`で採用された値を引数に関数が呼び出され、その返り値がプロパティーの値になります。関数を使って値を加工しつつマージするようなイメージです。

selectタグなんかは権限のないときは`mousedown`で`preventDefault`して警告を出したい時なんかもあります。そんなときはこんな風にもかけます。

```jsx
<select
  {..._if(can('manage', 'guest'), {
    onChange: e => this.handleChangeSelect(e)
  }).else({
    onMouseDown: e => this.showAclError(),
    onChange: () => {}, //valueがあってonChangeがないと警告がでるので
    className: 'deny'
  }).any({
    className: v => classNames(v, 'form-control')
  }).yield()}
  value={this.props.selected}
>
  <option value="foo">foo</option>
</select>
```

実装はこんな感じです。今回例にはあげてませんが`elsif`もあります。

```js
class ConditionalObject
{
  constructor(condition, props){
    this.conditions = []

    this.conditions.push({
      condition: condition,
      props: props
    })
    
    this.anyObject = {}
  }

  elsif(condition, props){
    this.conditions.push({
      condition: condition,
      props: props
    })
    return this
  }

  else(props){
    this.conditions.push({
      condition: true,
      props: props
    })
    return this
  }

  any(props){
    this.anyObject = props
    return this
  }

  _processAny(targetObject){
    const props = {...targetObject}

    for(var key in this.anyObject){
      // anyは関数。決定したpropsを引数に呼び出し上書きします。
      props[key] = this.anyObject[key](props[key])
    }

    return props
  }
  
  yield(){
    const result = this.conditions.find(cond => cond.condition)
    return this._processAny(result.props)
  }
}


export default function _if(condition, props){
  return new ConditionalObject(condition, props)
}
```

単純に、条件分岐で返すオブジェクトを変更する仕組み、ということでしょうか。classNameを想定して`any`は関数を渡すようにしたところが唯一の工夫ですかね。

関係ないけど`any`の名前は悩みました。`merge`, `default` `finally` `both` `either`とか・・・`any`も含め正直どれもピンとこなかったのでタイプ量で`any`にしたのが正直なところです。ネイティブな人だったら何にするんだろうか？あと念のためですが`elsif`はタイポではありません。
NodeでMarkdownをHTML化する

# 概要
タイトル通りの小ネタです。

- MD→HTML変換は `markdown` というライブラリで簡単にできます。
- 逆方向は `html-to-markdown` というライブラリを使うとできますが出力結果はいまいちでした。理由は、MDファイル内にHTMLが直接埋め込めるためです。

# MD2HTMLのコード

```js:md-to-html.js
const html = require('html')
const markdown = require('markdown')
const fs = require('fs')

main()

function main() {
  if(process.argv.length !== 3) {
    console.log("Usage: md-to-html.bat <markdown file>")
    process.exit()
    return
  }
  
  const mdFile = process.argv[2]
  console.log("Input File:" + mdFile)
  const contents = fs.readFileSync(mdFile, {encoding:'utf-8'})
  const output = html.prettyPrint(markdown.markdown.toHTML(contents))
  const outFile = mdFile + ".html"
  console.log("Outputing File: " + outFile)
  fs.writeFileSync(outFile, output, "utf-8")
  console.log("Completed.")
}
```

以下のバッチを作ってドラッグ＆ドロップすると変換されます。

```:md-to-html.bat
node ./md-to-html.js %1
```

# 逆方向（HTML2MD）

```js:html-to-md.js
const converter = require('html-to-markdown')
const fs = require('fs')

main()

function main() {
  if(process.argv.length !== 3) {
    console.log("Usage: html-to-md.bat <html file>")
    process.exit()
    return
  }
  
  const htmlFile = process.argv[2]
  console.log("Input File:" + htmlFile)
  const contents = fs.readFileSync(htmlFile, {encoding:'utf-8'})
  const output = converter.convert(contents);
  const outFile = htmlFile + ".md"
  console.log("Outputing File: " + outFile)
  fs.writeFileSync(outFile, output, "utf-8")
  console.log("Completed.")
}
```
Juliaでライブラリ本体で依存してるライブラリとテストコードで依存しているライブラリを分ける

# 背景
通常、Juliaで他のライブラリを使用する場合、```] add Hoge```で追加していきます。
この時、テストコードだけで使用するライブラリというのも存在すると思います。
(例えば、TestとかReviseとかですね)
ところで何かのライブラリを使用する場合、そのライブラリのテストコードを動かすことは少ないため、動かさないテストのために不要な依存関係をインストールすることが嫌な人もいると思います。
そんな人のために、ライブラリ本体で依存しているコードとテストで依存するコードを分け、テスト実行時にテストで依存しているライブラリがインストールされるようにしましょう。

# やりかた
Project.tomlを編集します。
ここではTestとReviseを分離します。

## Before
```
name = "CureMIDI"
uuid = "13f811c2-fe19-11e8-119b-d10f1cb6898b"
authors = ["YuK_Ota <whitenightwinter@gmail.com>"]
version = "0.1.4"

[deps]
FluidSynth = "7b5f247c-b83c-11e8-2667-b92b55f05ea5"
MIDI = "f57c4921-e30c-5f49-b073-3f2f2ada663e"
PortAudio = "80ea8bcb-4634-5cb3-8ee8-a132660d1d2d"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
RingBuffers = "f6d8bcc6-4e01-5431-93c4-9d6004abab90"
SampledSignals = "bd7594eb-a658-542f-9e75-4c4d8908c167"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
```

## After
```
name = "CureMIDI"
uuid = "13f811c2-fe19-11e8-119b-d10f1cb6898b"
authors = ["YuK_Ota <whitenightwinter@gmail.com>"]
version = "0.1.4"

[deps]
FluidSynth = "7b5f247c-b83c-11e8-2667-b92b55f05ea5"
MIDI = "f57c4921-e30c-5f49-b073-3f2f2ada663e"
PortAudio = "80ea8bcb-4634-5cb3-8ee8-a132660d1d2d"
RingBuffers = "f6d8bcc6-4e01-5431-93c4-9d6004abab90"
SampledSignals = "bd7594eb-a658-542f-9e75-4c4d8908c167"

[extras]
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Revise"]
```
3000番ポートを閉じた時のNginxの設定変更で、どハマリしてしまったのでメモ

外部からポートスキャンをされて、攻撃のターゲットにならないように、不要な3000番ポートを閉じたのですが、そのときのNginxの設定変更で2日間もハマってしまったので、一生忘れないようにするためにメモ！！

Nginxの設定ですが、当初は下記のような設定をしていました。

##設定

```vim
server {
  listen 80; #ポート番号を指定
  server_name ホスト名 #このホスト名に一致したリクエストの場合に、serverブロック（server {}）が適用される

  # nginx so increasing this is generally safe...
  keepalive_timeout 5;

  # path for static files
  root /var/www/rails/sample_app/public;

  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;

  location @app {
    # HTTP headers
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://IPアドレス:3000;　　#3000番ポートに中継して、Unicornにリクエストを転送
  }

  # Rails error pages
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/rails/sample_app/public;
  }
}
```

##エラー内容・問題
3000番ポートを閉じてからサーバーにリクエストを送って本番環境へのアクセスを試みると、Nginxの500エラーページが出ている。つまりUnicornまでリクエストが届いていない状態になっていた。

3000番ポートを閉じたと言っても、今まで本番環境へアクセスする時は80番ポート経由でアクセスしていたから、これまで使ってこなかった3000番ポートを閉じても影響は出ないはずでは。。。と2日間もハマってしまいました。

結論から言うと、外部アドレスにアクセスしようとしていたことが原因でした。

##リクエストがサーバーに届くまでの流れ

<img width="1008" alt="スクリーンショット 2019-03-31 14.18.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/298093/3f26309f-de01-fa3a-c1a2-71529973c39c.png">


この図の中で、私の理解が欠落していた部分は、DNSサーバーとルーターの存在でした。クライアントからのリクエスト送信先は、IPアドレスによって特定されます。
IPアドレスは人間にとっては見にくい表示形態なので、その多くはドメインを適用することで人間が見やすい文字列にしています。
裏を返すと、コンピュータからすると、ドメインの文字列はとても見にくくて、処理しにくい表示形態なので、ドメインではリクエスト送信先を特定することができません。なので、DNSサーバーに問い合わせて、リクエストとして指定された宛先であるドメインが示しているIPアドレスを特定します。いわばドメインをIPアドレスに変換しているようなイメージです。
IPアドレスが特定されると、ルーターを通して、外部ネットワークにデータが送信され、様々なルーターを経て最終的に、IPアドレスに示された送信先にデータが到着する、という流れです。

HTTPの仕組みについては、下記参照
https://chopesu.com/programing/http/

では、これを踏まえて私が陥っていた状況はどのような状況だったかを示しているのが、下記の図です。

<img width="1015" alt="スクリーンショット 2019-03-31 14.42.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/298093/39e270d5-84de-7c45-5aa2-0d4ad03cf1cd.png">



このように、Nginxが受け取ったリクエストを同一サーバー内のUnicornに転送するという設定をしているつもりでしたが、実際は外部アドレスに転送するという設定になっていました。
外部アドレスに転送するという設定にした結果、上記の図のように既に閉じられている3000番ポートでリクエストが遮断され、アクセスすることができない状況になっていました。

##解決策

これを解消する方法はいくつかありますが、今回は転送先であるUnicornが同じサーバーマシン内、つまりlocalhostにあることを利用して、下記のような転送設定にすることで無事に解決することができました！！

```vim

server {
  listen 80; #ポート番号を指定
  server_name ホスト名 #このホスト名に一致したリクエストの場合に、serverブロック（server {}）が適用される

  # nginx so increasing this is generally safe...
  keepalive_timeout 5;

  # path for static files
  root /var/www/rails/sample_app/public;

  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;

  location @app {
    # HTTP headers
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://localhost:3000;　
　　 # 3000番ポートを経由して、同一サーバーマシン内（localhost）にあるUnicornにリクエストを転送
  }

  # Rails error pages
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/rails/sample_app/public;
  }
}
```



仕組みを理解していないと、こんなに苦労するものかと思い知らされました笑
HDDを廃棄する際のデータ消去方法

Windows標準コマンドを使ってHDDの完全消去を試してみた記録。


## 結論

1TB以上のHDDに対して3回書き込みによる消去方法は時間がかかりすぎる（単純計算して、3TBで約1日）。

また、よく参考にされる *NIST(米国国立標準技術研究所)* のガイドラインにおいては、

> 2001年以降に製造されたATAディスクドライブ（15GB超）では、キーボード攻撃と実験環境室のどちらから媒体を保護するにも、媒体を一回上書きすることによる消去で十分である。
>
> (引用: [セキュリティ関連NIST文書 NIST SP 800-88：IPA 独立行政法人 情報処理推進機構][nist])

と記載されている。

よって、次のような1回書き込みによる消去を行うことを推奨。

* `diskpart` で `clean all`
    * オール0を1回書き込み
* HDD/SSDに組み込まれている *Secure Erase機能* を利用
    * **SSD** はこちらの機能を使用する

---

以下の文章は3回書き込みによる完全消去やってみたになります。
なので、読む価値はほぼないです……。


## HDDを完全消去したい

HDDを廃棄する際に困るのがデータの消去方法。
Windows標準コマンドの `cipher` を使えば米国防総省の定めている基準（3回書き込み）で完全消去（ワイプ）できるらしい。

`cipher` ではいくつかの制限があるため、次のような手順で進める。

1. HDDのパーティションを初期化
1. HDDまるごと1つのパーティションに
1. *NTFS* ファイルシステムでフォーマット
1. `cipher` でワイプ


## 詳細な手順

1. 廃棄するHDDのパーティションを初期化

    保護されたパーティションが残ったりしないように `diskpart` で初期化する。

    1. `diskpart` を管理者権限で起動
    1. `list disk` で対象のディスク番号を確認
    1. `select disk <NUM>` で選択
    1. `clean` でパーティション初期化


1. 廃棄するHDDすべてを使う1つのパーティションを作成

    1. `create partition primary` でパーティション作成

1. 廃棄するHDDをフォーマット

    ファイルシステムを **NTFS** にする

    1. `list volume` でボリューム番号を確認
    1. `select volume <NUM>` で選択
    1. `format fs=ntfs quick` でクイックフォーマット

    以上で `diskpart` 上の操作は終了なので `exit`

1. コマンドプロンプトなどで `cipher /w:<ドライブ文字>:` コマンドを実行

    対象が `Zドライブ` の場合

    ```cmd:cmd(管理者権限)
    cipher /w:z:
    ```

    時間計測したい場合は `powershell` 上で `Measure-Command` を用いる。
    自分の環境では以下のような結果となった。

    ```shell:powershell(管理者権限)
    $ (Measure-Command {cmd.exe /c "cipher /w:z:"}).TotalMinutes

    238.136201376667
    ```
    
    |IF |Capacity |Time |
    |:---:|:---:|:---:
    |USB3.0 |500GB |約4時間


## 参考

* [セキュリティ関連NIST文書：IPA 独立行政法人 情報処理推進機構][ipa]
* [Windowsでディスクの内容を完全に消去する | @IT][win-1]
* [MS-DOSコマンドで処理時間を計測する - 覚えたら書く][measure]
* [SSDをSecure Erase機能で安全に消去する][secure]
* [Tiny Core LinuxでHDDの完全消去（Secure Erase編）][secure-2]

[ipa]:https://www.ipa.go.jp/security/publications/nist/index.html
[nist]:https://www.ipa.go.jp/files/000025355.pdf
[win-1]:https://www.atmarkit.co.jp/ait/articles/0303/01/news003.html
[measure]:https://blog.y-yuki.net/entry/2017/11/01/130000
[secure]:https://qiita.com/nvsofts/items/f46c8a1b3541894ad382
[secure-2]:https://qiita.com/hachisukansw/items/c8cc9418c84d563bee29