OmniAICreator/Qiita-1.07M huggingface dataset:
今更ながらGo言語を触ってみた(GO 1.13.6)

# Go言語を触りたかったきっかけ

kubernetesを構築・活用しているうちにカスタマイズしてみたい衝動があり、
Go言語でのみカスタマイズが出来ることと
軽量のWebApiを構築することが多々あり普段はPythonで実装していたが、
この際なのでGo言語を触ってみることにしました。
と言っても実務があるので、学習期間は3日しかありませんでしたが・・・。

## で、作ってみたもの

簡単にwebサーバーを立ち上げれるフレームワークを実装してみました。
内容的には下記のリンク先のREADMEにも記載していますが、
yamlファイルに諸々設定することでwebサーバーが起動します。
ビジネスロジックに集中出来るようにこのフレームワークを実装しています。

[httprouter_wrapper](https://github.com/ncs-nozomi-nishinohara/httprouter_wrapper)

## 躓いた点

`map[string]interface{}`の仕組みがいまいちわかりづらかったです。
`map[string]interface{}`からvalueを取得する際に型が思っている型にならなかったりしていたので、
`reflect`モジュールを使用して型を確認したりして実装しました。

```go:demo.go
// yamlファイルから読み込んでますがエラー処理は省いています。
var m map[string]interface{}
buf , err := ioutil.ReadFile("filename.yaml")
yaml.Unmarshal(buf, &m)
// valueの内容を取得したい為にValueOfで取得する。
v := reflect.ValueOf(m)
// 型の種類をKindメソッドで取得する。
k := v.Kind()
fmt.Print(k)
```

また、interface{}型については全ての型を受け入れれるのですが、
`map[string]interface{}`の値が`string`の時でも
cast時に`map[string]interface{}`でcast出来ず、`map[interface{}]interface{}`でcastしなければなりませんでした。
この辺りがまだあやふやなので実務が落ち着いた時にでももう少し調査しようと思います。

```yaml:test.yaml
test1:
  value1: value2
```

m変数にmap[string]interface{}が設定されているとして以下を実行すると

```go:demo.go
log.Print(m["test1"].(map[string]interface{}))
```

`panic: interface conversion: interface {} is map[interface {}]interface {}, not map[string]interface {}`
というエラーが発生し、エラーの内容の通り
`map[string]interface{}`を`map[interface{}]interface{}`に変換出来ないというエラーが出力されました。
エラーの通りに`map[interface{}]interface{}`でcastを行い、
keyを文字列で指定するとvalueを取得することが出来ます。

```go:sample.go
buf, _ := ioutil.ReadFile("test.yml")
var m map[string]interface{}
yaml.Unmarshal(buf, &m)
m1 := m["test1"].(map[interface{}]interface{})
// 念の為stringへcast
log.Print(m1["value1"].(string))
```

あとは、型アサーションぐらいですかね。
上記でも記載していますが、
`interface{}`型から別の型へcast(代入)する際の記述方法が
`.(T)`の記載方法で型変換(代入)が可能になります。

## まとめ

オブジェクト指向言語を扱うことが多いので、Classが存在せず、
`struct` `interface`でメソッドを記述したり、属性を与えることで
オブジェクト指向の様な記述をする必要があります。
パッケージ公開でも少し躓いてしまいましたのでまた手が空いたら記事にしようと思います。
AWS Sysopsアドミニストレーターアソシエイト資格に合格しました。

# はじめに
先週（1/17）ですが、AWS Certified SysOps Administrator - Associate (SOA)の試験に受かりましたので、勉強方法や試験での手応えについて記載しようと思います。

[※前回の記事（AWS SAAに受かった話）](https://qiita.com/kkino1985/items/85bcfa50686fcfe69c56)

# 勉強期間
資格取得に動き始めたのが2019年12月中旬頃（クリスマスの少し前ぐらい）でした。

勉強期間としては1ヶ月程になりますが、途中Azureの資格に浮気したり年末帰省して胃腸炎にかかってダウンしたりしたので、真面目に詰め込んだらもう少し早く取れたと思います。

自分は上記の通りSAAを取得済みだったので、その時の内容を思い出す＋アルファの知識を仕入れるだけで良かったですが、AWSを全く知らない人はクラウド固有の考え方含めて覚えることが多いのである程度の期間を取った方が良いです。
（色々な記事でも触れられていますが、SOAから入るとハードルが高いのでSAAから取ることをお勧めします）

# 獲得スコア
|受験日|スコア/合格点/満点|結果|
|:--|:--|:--|
|2020/1/17|731/720/1000|合格|

正直手応えはあったのですが、思ったよりぎりぎりでした……。

# 学習で使った教材

## AWS公式
AWSはアップデートが早く、書籍の内容が既に陳腐化している場合も多々あるので、基本的にはAWSが提供しているドキュメントやトレーニングが本命となります。

言わずもがなですが、試験ガイドにあるサンプル問題と模擬試験は必ずやりましょう。

あとはSOAのデジタルトレーニング（無料のeラーニング）も観ました。
（字幕なしの英語なのでハードルは高いですが、試験範囲のサービスを知るだけでもかなり有用だと思います）

今回一番お世話になったのは、やはりBlackbeltセミナーの資料（と動画）ですね。
SOAの場合、Cloudwatch、IAM、セキュリティ系（NACLとセキュリティグループなど）あたりが特に重要になります。
最低限、どのサービスがどんなことをやるためのものかはわかっていた方が良いです。これはSOAに限らずAWSの資格全般に言えることですが。
（例えば、GuardDutyとShieldとInspectorはそれぞれどんなサービスなのか、などなど）

https://aws.amazon.com/jp/aws-jp-introduction/

## 書籍
[「AWS認定アソシエイト3資格対策～ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター～」](https://www.amazon.co.jp/dp/B07TT1N73K/ref=cm_sw_em_r_mt_dp_U_L0gkEbGY6R68D)
Developerの資格取得も視野に入れていたので購入。
ただ、試験範囲にあるサービスについて概要程度のことしか書いていなかったのであまり役には立ちませんでした。（これからAWSを学ぶ人には有用だと思います）


## 問題集
[「AWS WEB問題集で学習しよう」](https://aws.koiwaclub.com)
SAAの時もお世話になったWEB問題集。
今回は試験までの日数が少なかったので、有料プランではなく無料分のみ活用しました。
（もし落ちていたら購入していたと思います）

[「WHIZLABS」](https://www.whizlabs.com/aws-sysops-administrator-associate/)
試験問題を販売している海外のサイト。
WEB問題集に比べて割安ですが、同じ理由で無料の問題（15問）だけ活用しました。
紹介していた記事では「Google翻訳で対応できる！」とあったものの、実際にやってみたらコピペ不可（そもそも右クリック不可）でやり方がわからなかったので、気合で英語のまま解きました。

# 試験を受けての所感
・試験時間は130分でしたが、文章をちゃんと読んで理解してから解くと意外とあっという間でした。（SAAの時は眠くてしょうがなかったですが、今回はそんなこともなく）
・サービスの目的（○○は何のためのサービスか、など）を問う問題はなく、「知っている前提」で設計や運用のベストプラクティスについて問う問題が出る
・セキュリティの問題は多かった気がする（その辺りのサービスの理解が不十分だったのでだいぶ減点されたと思います）
・S3バケットポリシーの定義内容を読み解いたり、ルートテーブルのstateを見て「どんな状態か」を問うような、そこそこピンポイントな問題もあったので、もっと実際に手を動かした方が良かった（なのでハンズオンやサービスのチュートリアルは一通りやるべきだった）

# 今後の予定
次はDeveloper（DVA）とクラウドプラクティショナーを取る予定です。（できれば今月中）
資格に限らず、今年は色々身に付けていきたいです（具体的にはコンテナやterraformなど）。

# 2020/1/24追記
これも多くの記事で触れられていることですが、AWSの認定資格に合格すると次回の試験・模擬試験は半額になるバウチャーがもらえるので、次の試験の際に活用すると良いです。
（自分は前回SAAに受かった分をSOAに適用し忘れて涙目になりました）
初学者によるプログラミングMemo　#18 フィボナッチ数列（メモ化）

#はじめに
今回はフィボナッチ数列のお話です
なお、本記述はMacにおいて、Railsでの開発を前提としています
また、まだまだひよっこですので、不備等ございましたらご指摘いただけると幸いです
＊追記
コメント欄に簡潔なコードがありますので、そちらもご覧ください
元の記述は自分が考えた軌跡として残しておきます

#目次
- フィボナッチ数列とは
- プログラムで解いてみる

##フィボナッチ数列とは
初項 = 1、第２項 = 1、第３項以降は、前項と前々項の和となる数列です
第３項は初項と第２項の和なので「1+1」で"2"となります
第４項は第２項と第３項の和なので"3"となります
また、フィボナッチ数列は黄金比とも関係してるので、知りたい方は調べてみてください
数列としては、「1,1,2,3,5,8,13,21,34,55,・・・」と続きます

この数列の第n項目は何になるかを求めたいと思います


##プログラムで解いてみる
では、プログラムで解いてみましょう
まずは、フィボナッチ数列がどういうものだったかを思い出しましょう

```.rb
fib(n) = fib(n-2) + fib(n-1)
```
第n項は前(n-1)項と前々(n-2)項の和でしたよね
しかし、初項と第２項は決まっています
付け加えましょう

```.rb
fib(n) = fib(n-2) + fib(n-1)
fib(0) = 1
fib(1) = 1
```

できました
このままではプログラムとしては成り立っていませんので、組み立てましょう

```.rb
def fib(n)
  if n == 0 || n == 1
    return 1
  else
    fib(n-2) + fib(n-1)
  end
end
```
できました

しかし、このプログラムには欠点があります
fib(4)で解説しましょう

```.rb
fib(4) = fib(3) + fib(2)
```

ですね
でも、fib(3)とfib(2)も求めないといけないですよね
そうすると

```.rb
fib(4) = fib(3) + fib(2)
fib(3) = fib(2) + fib(1)
fib(2) = fib(1) + fib(0)
```

こうなりますが、fib(3)の中にもfib(2)が入っていますね
そうするとこうなります

```.rb
fib(4) = fib(3) + fib(2)
  fib(3) = fib(2) + fib(1)  #fib(4)の中のfib(3)を求める式
    fib(2) = fib(1) + fib(0)  #fib(3)の中のfib(2)を求める式
  fib(2) = fib(1) + fib(0)  #fib(4)の中のfib(2)を求める式
```
ここで違和感というか、無駄が発生していることにお気づきでしょうか
fib(2)は２回、fib(1)とfib(0)は３回出てきています
nが小さい時はあまり問題がありませんが、n=30くらいになると、答えが返ってくるまでに時間がかかります
n=35で２秒ほどかかります
n=100では計算が終わらないようですので、実行はしないようにしましょう

###メモ化を使う
問題が発見されたので、変更しないといけませんね
使えないこともないコードならまだしも、n=100程度でギブアップするなんて使えないコードです
そこで、メモ化というものを使います
配列に入れてしまいましょう
メモ化の特徴としては、記憶領域と引き換えに、時間のコストを削減するというものがあります
いわゆるトレードオフをする必要があるということです

```.rb
F = []
def fib(n)
  if n == 0 || n == 1
    return 1
  elsif F[n] != nil #ここだけのプログラムであれば不要（関与しない）
    return F[n]
  else
    F[n] = fib(n - 2) + fib(n - 1)
  end
end
```
できました
変更点は、配列をつくって、それに入れている部分です
しかしこれでは数学的には間違っているので、対話型のプログラムにしつつ正しくしましょう

```.rb
F = []
def fib(n)
  if n == 0 || n == 1
    return 1
  elsif F[n] != nil 
    return F[n]
  else
    F[n] = fib(n - 2) + fib(n - 1)
  end
end

p "フィボナッチ数列の何項目が知りたいん？うちが教えたるで"

num = gets.to_i

if num >= 1
  p fib(num-1)
else
  p "ちゃんと入力しやん人はいややぁ"
end
```
できました
数学的な一般項はなかなか複雑ですが、プログラム上での一般項（？）はわかりやすくていいですね
LXDコンテナについて、lxc execコマンドでホストからコンテナ内の設定ができるのかを試したメモ書き【自分用】

# 概要
LXDコンテナの設定をホスト側から自動でできるのかを試してみたときのメモ書きです。LXDのセットアップが既に終わっていることが前提です。

# 環境
- ubuntu 18.04 on Virtualbox on Windows10 Pro
- LXD 3.18（snapでインストール）

# lxc execコマンド
lxc exec container_name bashなどと実行するとコンテナ内でコマンドを実行することができるので、入力したいコマンドをシェルスクリプトに書いたりしたら実行できるのかなーと思い試してみようと思います。

# 結果
いろいろ試行錯誤した結果、うまく動くコマンドと動かないコマンドがあるみたいです。単純にdockerなどのパッケージをインストールするためのコマンドを羅列しただけのスクリプトだったので、パイプとかを用いて工夫すればうまくいくかなーと思ったのですがうまくいきませんでした。

以下のようなコマンド実行しようと試みましたが、エラーが出たり途中で失敗したりでうまくいきませんでした...

```bash

lxc exec container_name -- sed -i.bak -e "s%http://[^ ]\+%http://linux.yz.yamagata-u.ac.jp/ubuntu/%g" /etc/apt/sources.list
lxc exec container_name -- ./xxxxxxx.sh
```

## ひとまず落ち着いた方法
ホストで実行するLXDコンテナの設定に関するコマンドを羅列したシェルスクリプトと、LXDコンテナ内で実行するセットアップ用のシェルスクリプトに分けて、それぞれホストとコンテナ内で実行します。もっといいやり方がないか探しています...ansibleとかを利用するといいんでしょうかね。

```bash
# host
./lxd-start.sh
lxc exec container_name bash
# container
./lxd_setup.sh
```

```lxd-start.sh
#!/bin/bash

lxc remote add --protocol simplestreams ubuntu-minimal https://cloud-images.ubuntu.com/minimal/releases/
lxc storage set default btrfs.mount_options user_subvol_rm_allowed,compress=lzo

lxc launch ubuntu-minimal:bionic u1804-sandbox -c security.nesting=true -c security.privileged=true
lxc config device add u1804-sandbox knowledge proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:8080 bind=host
lxc config device add u1804-sandbox codimd proxy listen=tcp:0.0.0.0:3000 connect=tcp:127.0.0.1:3000 bind=host
lxc config device add u1804-sandbox share disk source=/home/xxxx path=/root/share

sleep 10s
lxc file push lxd-setup.sh u1804-sandbox/root/
lxc exec u1804-sandbox -- chmod +x lxd-setup.sh
```

```lxd-setup.sh
#!/bin/bash

sudo sed -i.bak -e "s%http://[^ ]\+%http://linux.yz.yamagata-u.ac.jp/ubuntu/%g" /etc/apt/sources.list
sudo apt update
sudo apt -y dist-upgrade
sudo apt -y autoclean

sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update
sudo apt-get install -y docker-ce

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

docker -v
docker-compose -v
```
起動中のインスタンスからEBSボリュームのDeleteOnTermination設定を変更する。

起動中のEC2インスタンスのEBSボリュームのDeleteOnTermination設定を変更する手順。

通常、コンソールからだと、起動時のボリュームアタッチ時にしか設定できない。
そのため、あとから変更したい場合や、起動後にボリュームをアタッチした場合にはベットCLIから設定する必要があり、`aws ec2 modify-instance-attribute`コマンドで設定可能である。

```shell
# EBS作成
$ aws ec2 create-volume --availability-zone ap-northeast-1a --size 8 --volume-type gp2
$ aws ec2 create-volume --availability-zone ap-northeast-1a --size 8 --volume-type gp2

# EBSアタッチ
$ aws ec2 attach-volume --instance-id i-0cd13d242c52faxxx --volume-id vol-0c715576745bdbf9c --device /dev/sdb
$ aws ec2 attach-volume --instance-id i-0cd13d242c52faxxx --volume-id vol-0c589364244gmdl2a --device /dev/sdc

# 設定ファイルを作成
$ touch mapping.json 
$ nano mapping.json 
$ cat mapping.json 
[
  {
    "DeviceName": "/dev/sdb",
    "Ebs": {
      "DeleteOnTermination": true
    }
  }

# インスタンス終了時の挙動を反映
$ aws ec2 modify-instance-attribute --instance-id i-0cd13d242c52faxxx --block-device-mappings file://mapping.json

# マウントされていることを確認
$ df /dev/sdb
$ df /dev/sdc
```

EC2コンソールのナビゲーションペインからボリュームを選択し、3つ（インスタンス生成時のデフォルトのebs＋今作成したebs2つ）が`in-use`であることを確認。

EC2コンソールからインスタンスを終了。

再度EBSを確認すると1つのボリューム（削除設定をしなかった方のvol-id）のみが`available`で残っていることが確認できる。

なお、`mapping.json`ファイルとしないでコマンドのいオプションにずらずら書くことも可能。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/terminating-instances.html#preserving-volumes-on-termination
typescriptにおけるkeyupイベントの型

## この記事の概要

キーアップイベントを拾いevent.target.valueを指定したところ、
静的解析エラーになり、型を指定したら解決したのでその備忘録

## バージョン

- angular:8.0.0
- typescript:3.4.5
- eslint:6.8.0

## テンプレート

```html:sample.component.html
<input #hogeInput>
```

## 何も指定しない場合

```typescript:sample.component.ts
@ViewChild('hogeInput', { static: true })
input: ElementRef;

hugaFn() {
    const obs$ = fromEvent(this.input.nativeElement, 'keyup')
        .pipe(
            map(event => event.target.value));
}
```

<p>→「プロパティ 'target' は型 'unknown' に存在しません。」</p>

## eventの型を指定してみた

```typescript:sample.component.ts
map((event: KeyboardEvent) => event.target.value)
```

<p>→「プロパティ 'value' は型 'EventTarget' に存在しません。」</p>

## event.targetの型を指定してみた

```typescript:sample.component.ts
map((event: KeyboardEvent) => (event.target as HTMLInputElement).value)
```

解決:v:
Windows 10のChromeで文字認識(OCR)

Shape Detection APIの[TextDetector](https://wicg.github.io/shape-detection-api/text.html)で **Text Detection not implemented.** というエラーが出たのでメモ。

# 【重要】Windows 10にEnglishの言語機能(光学式文字認識)をインストール
日本語のWindowsには、Englishの言語機能は入ってないので注意が必要。
PowerShellを管理者権限で開く

```powershell
Add-WindowsCapability -Online -Name "Language.OCR~~~en-US~0.0.1.0"

# インストールできたか確認
Get-WindowsCapability -Online -Name "Language.OCR*en-US*"
```
https://medium.com/dataseries/using-windows-10-built-in-ocr-with-c-b5ca8665a14e

# ChromeのExperimental Web Platform featuresを有効化
[chrome://flags/#enable-experimental-web-platform-features](chrome://flags/#enable-experimental-web-platform-features)にアクセスし、Enabledに変更し、ChromeをRelaunch
![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/9dd16695-2a86-96bf-9e67-a4aa905a015f.png)

# 画像からOCR
画像を選択すると自動でOCRを行います。

<p class="codepen" data-height="512" data-theme-id="default" data-default-tab="result" data-user="04" data-slug-hash="QWwzmJq" style="height: 512px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Windows 10 Chrome OCR">
  <span>See the Pen <a href="https://codepen.io/04/pen/QWwzmJq">
  Windows 10 Chrome OCR</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# WebカメラからリアルタイムOCR
WebカメラからOCRを行います。リアルタイムでBoundingBoxが付きます。

**[Violation] Feature policy violation: camera is not allowed in this document.** で動かないので右上の **EDIT ON CODEPEN** を押して動かしてください。

<p class="codepen" data-height="640" data-theme-id="default" data-default-tab="result" data-user="04" data-slug-hash="LYEMoWj" style="height: 640px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Windows 10 Chrome Realtime OCR">
  <span>See the Pen <a href="https://codepen.io/04/pen/LYEMoWj">
  Windows 10 Chrome Realtime OCR</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

FullHD、フルスクリーンでOCRするサンプルもあります。
[https://codepen.io/04/pen/wvBRQYg](https://codepen.io/04/pen/wvBRQYg)

# まとめ

- 英数字や記号しか認識できませんが、Tesseract.jsよりも高速で精度が高いので追跡番号などを認識するのにおすすめです。
- オフラインで動作するので、Google VisionやAmazon Textractが使えない環境にもおすすめです。画像をクラウドにアップすると時間がかかりますが、エッジでやれば、高速でお金もかかりません。
Warning: Identity file ChatSpace.pem not accessible: No such file or directory. ec2-user@13.112.68.204: Permission denied (publickey).のエラーの解決例

# 1.エラーの内容
一度シャットダウンして日を置いて下記のコマンドをしようとしたらできませんでした。
エラー文は下記の通り

```
$ ssh -i ChatSpace.pem ec2-user@13.112.68.204
#ログインのコマンドを打ちました
Warning: Identity file ChatSpace.pem not accessible: No such file or directory.
ec2-user@13.112.68.204: Permission denied (publickey).
#ログインできないとのこと
```

# 2.原因と解決方法
原因はディレクトリを.ssh(pemファイルのある場所)でコマンドしていなかったからでした。
なので下記のコマンドでログインできます

```
$ cd .ssh
#ディレクトリを移動
$ ssh -i ChatSpace.pem ec2-user@13.112.68.204
#コマンドを打ち込む
```


# 3.このエラーで手が止まる理由
エラーを理解できなかった理由はpemファイルが何者でどういうコマンドか理解していなかったからでした。

まずpemとは「ただのファイル書式が決まった入れ物のことで、証明書、鍵をいくつでも含めることができるものです。つまり、鍵または証明書またはその両方」です。

この説明で理解された方も多いと思いますが'ssh -i ChatSpace.pem ec2-user@13.112.68.204'はec2-user@13.112.68.204のアプリケーションのpemファイルに情報をinsert(挿入)しますよという意味になります。

なのでpemファイルがない場所ではそもそも情報を追加などできませんのでタイトルのようなエラーが出てきます。

コマンドの内容を理解していれば現在のディレクトリが間違っているのだなと気づくことができます。
Jupyter学習ノート_008

# pythonでプログレスバーを簡単に実現できる

```sample_prb.py
import time
from tqdm import tqdm

#単純にスリープする
for _ in range(100):
    time.sleep(0.1) # 0.1秒をスリープする

#進捗を表示する
for _ in tqdm(range(100)):
    time.sleep(0.1)

for _ in tqdm(range(50)):
    time.sleep(0.1)
```
- 実行結果  
![progress_bar](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/89b74a4c-3f80-78ad-d5fa-463d662f4a40.png)
低予算・簡単構築で船の位置を受信してみよう

# はじめに
　私が学生の頃研究の一環で船舶の位置情報を無線機で受信して、そのデータを収集するシステムの開発を行っていました。
最近は得られた技術的知見を広めてないと感じたので、船舶の位置情報を取得する方法を紹介したいと思います。
***注意:本資料は昔研究ノートにメモしたことをベースに書いたものです。最新の環境で検証していないのでご注意ください。***

# 概要
　本資料では低予算・簡単構築の２点を重視した船の位置情報を取得するシステムの構築方法について説明します。

## 船舶の無線について
 航行する船同士の衝突を回避するために位置情報・船名等のデータをVHS帯の電波で送受信するAISというシステムがあります。
>![alt](https://www.furuno.com/img/technology/ais/basic/ais1_img02.gif)
参考：https://www.furuno.com/jp/technology/ais/basic/

AISの電波をデコードすると以下のようなNMEA形式の文字列で取得できます。

>
```
!AIVDM,1,1,,A,13u?etPv2;0n:dDPwUM1U1Cb069D,0*24
```
参考：https://rl.se/aivdm

# 使用機器
　以下の機器一覧は当時の私が所属していた機器を用いたものです。 
海外サイトから機器を安く仕入れる、アンテナの自作等をすればもっと安くなると思います。  

- Mac Book　Air(OS:Sierra)  
 一応Raspberry Pi 3 Model3(OS:Raspbian)で動作することも確認しています。  
高スペックなマシンは必要いらないので、もしかしたら初期のRaspberry Piでも動作するかもしれません。
- シェイクスピア - 5101センテニアルホワイト8' VHFマリンアンテナ  
マリン用のアンテナを扱っているメーカのAISアンテナをAmazonで購入しました。  
  当時の価格は**15,247円**と使用機器の中で一番高額でした。  
AISの利用周波数はCH87Bの161.975MHzとCH88Bの162.025MHzなので、それに対応したアンテナであること、耐塩仕様であることを満たせば自作して安くすませるのも手です。
- R820T2 & SDR+TCXO（温度補償型水晶発信器±0.5PPM）実装カスタムチューナー単品Blue［RTL2832U+R820T］［広帯域受信用］［High quality USB-CN］［RTL-SDR専用］  
電波を受信をPCの取り込めるように、RTL-SDRに対応したUSBドングルをAmazonで購入しました。  
 当時の価格は**5,850円**でした。  
受信中はUSBドングルの温度が上がってAISの周波数からズレてしまう現象が発生するので、TCXO(温度補償型の水晶発振器)があるものを選んでいます。  
TCXOが搭載していない方のUSBドングルは安く販売していますが、性能が悪すぎで使いもになりませんでした。  
- uxcell アダプタコネクタ　同軸ケーブル　MCXライトアングル　オスメス　RG316　20cm  
 AISアンテナとUSBドングルを繋ぐ変換ケーブルをAmazonで購入しました。  
当時の価格は**734円**でした。

PC以外の機器で総額**約2200円**となります。
マリン用で販売しているAIS受信機の値段はだいたい**2万円ほど**なので、それと比べるとかなり安く構築することができます。

# 構成図
![コメント 2020-01-26 163253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181903/3d687cf5-32f0-f462-1104-815b05941ed4.png)



# 環境構築
USBドングルで受信した電波から船舶の情報が取得できるように`rtl_ais`コマンドが使えるようにします。

```
# USBドングルに
$ brew update
$ brew install libusb

# rtl_aisコマンドを打てるようにする
$ git clone https://github.com/dgiardini/rtl-ais
$ cd rtl-ais
$ make
$ sudo cp rtl_ais /usr/local/bin
```

コマンドを実行してコンソール上にNMEAを表示してみましょう。

```
# デフォルトはローカルホストの10110ポートで送信ます。
sudo rtl_ais -R -n -S 1
```

# 地図上に表示させましょう。
NMEAだと船舶がどこにいるのか分かりませんので、OpenCPNを使って表示させてみましょう。
以下のサイトからダウンロードしてください。
https://opencpn.org/OpenCPN/info/downloadopencpn.html

OpenCPNの起動後、「preferences.. > Connections 」を選択して、以下のように設定します。

|Enable|Type|DataPort|Priority|Parameters|Connection|
|:---|:---|:---|:---|:---|:---|
|true|Network|127.0.0.0:10110|1|UDP|Input|

rtl_aisから出力したNMEAがOpenCPNで上手く入力することができれば、地図上に船舶を表示することができます。
![スクリーンショット 2017-11-24 10.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181903/03a0f5f3-a2b6-504c-45e5-4a6e08138449.png)

# 最後に
今回は研究ノートのメモを引っ張り出して、AISの受信環境の構築についてまとめてみました。
次回は、AISのNMEAの読み方について紹介したいと思います。
RAIDまとめ

自作PCやそれ関連に携わっていたり触ったことがある人は一度は聞いた事がある(と思う)`RAID`と呼ばれるもの。
それは一体何なのかを素人ながらまとめて行きたいと思う。
#RAIDとは
サーバー用のHDD等に用いられる技術であり、複数のHDDを組み合わせることによりサーバーに対する安全性の向上や大容量化、高速化を行う事ができる。
###なぜ大容量化や高速化ができるのか
・ 大容量化
→単純に複数のHDDを使用することになるため、全てのHDDの合計容量が使えるようになる(例外的なRAIDもあり)

・高速化
→HDD1台だけだと10秒かかるような書き込みであっても、複数台(今回は5台と仮定)使用することにより書き込みの分担を行い、2秒という短時間で書き込みが行えるようになる

#RAID構成
####RAID 0(ストライピング)
RAID0は大容量化と高速化に特化したRAID
よく一般的に聞いたりするのはこの構成だと思う。
複数台のHDDを一つのHDDとして認識し使用するため、データを分散させ高速な読み書きを可能にする。
また、全てのHDDの合算容量が使用できる容量でもある。
但し、複数台のHDDを一つのHDDとして使用しているため、一個のHDDでも破損や動作不良になってしまったら
データの復旧は困難とされている。

####RAID 1(ミラーリング)
RAID 1は安全性に特化したRAID
ミラーリングという名前の通り、メインとして使用するHDDのデータを全て別のHDDへ複製する
そのため、2台以上HDDが必要になってくるが実際に使用できるのは1台のみ。
但し、ミラーリングしたHDDとメインでのHDDが同時に壊れることがない限りデータが損失しない。

####RAID 5(パリティ付きミラーリング)
RAID 5は大容量化と高速化をしつつ、最低限の安全性を保持したRAID
このRAIDはHDDを最低３台必要とする。各々のHDDに復旧用の「パリティデータ」が生成される

`HDD1` : [データ1] [データ2] [パリティデータ5&6]
`HDD2` : [データ3] [データ4] [パリティデータ1&2]
`HDD3` : [データ5] [データ6] [パリティデータ3&4]

上記を見てわかる通り、1台のHDDは壊れてもパリティデータから復元が可能だが、
2台以上壊れるとデータ復旧が不可能になる。
だが、これによりRAID 0 には劣るが、高速化等が得られるようになる上に安全性も確保できるようになった。(但しパリティデータ分の容量が必要になったため、使用できる容量が多少減っている)

####RAID 6(ダブルパリティ)
RAID 6はRAID 5をより向上させたRAID
RAID 5では最低3台のHDDが必要だが、RAID 6では最低４台必要になってくる。

`HDD1` : [データ1] [データ2] [パリティデータ5&6]
`HDD２` : [データ3] [パリティデータ3&4] [パリティデータ5&6]
`HDD3` : [データ5] [パリティデータ1&2] [パリティデータ3&4]
`HDD４` : [データ4] [データ6] [パリティデータ1&2]

上記の通り、2台のHDDは壊れても大丈夫だが、3台以上はデータ復旧が不可能になる。

####RAID 10
RAID 10は[RAID 0]と[RAID 1]を組み合わせたもの。
HDDを最低でも4台必要とし、2台はRAID0で、もう2台はRAID1で稼働している。
そのため、各々１台の破損は復旧できるが、ミラーリングをしているHDDも壊れたらデータ復旧ができなくなる。

`HDD1` : [データ1] [データ3] [データ5]
`HDD2` : [データ1] [データ3] [データ5]

`HDD3` : [データ2] [データ4] [データ6]
`HDD4` : [データ2] [データ4] [データ6]

#結局どのRAID使えばいいん？
- 構築にかけれるお金
- 復旧にかけれる時間
- 信頼性や安全性をどれほどあげるか
- 速度や容量をどれほどあげるか

ここら辺を考えて構築したらいいと思う。

####RAID 0
とにかく速度と容量が欲しい。
ただ壊れて一切データ戻ってこなくても関係ない人はこれ。
####RAID 1
とにかく安全性が欲しい。
その代わり速度も容量も犠牲にするけど、費用も少なく抑えれるから、そういう人はこれ。
####RAID 5
費用はかけれないが、ある程度の安全と速度が欲しい。
####RAID 6
RAID5と同じ速度ではあるけど、費用はある程度確保できる。
ただ、もうちょい安全性が欲しい人はこれ。
####RAID 10
費用をバンバンかけれる代わりに安全性と速度が欲しい。
macOS CatalinaでErgodox EZのキーマップを書き換える

# はじめに
Catalinaになってから、書き換え用ソフトのTeensyが使えなくなってしまったので、代替方法を考える。

↓悲しみのTeensy
<img width="184" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360858/0bd21c5a-5300-4c5a-9332-ab5c401928b8.png">


想定としては、レイアウトの変更は、 [こちらのサイト](https://configure.ergodox-ez.com/) で十分な方。
つまり、hexファイルが手元にあって、それをErgodoxEZに書き込みたい人のためのメモ。


# コマンドラインツールのダウンロード

[こちら](https://github.com/PaulStoffregen/teensy_loader_cli)からコマンドラインツールをダウンロードします。

```bash
$ git clone https://github.com/PaulStoffregen/teensy_loader_cli.git
```

## 以下のエラーが出る場合

```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), 
missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

[こちら](https://qiita.com/nishina555/items/e23d73067a5cac182a63)の記事の通り、

```
xcode-select --install
```

を実行。
もしかすると、システム環境設定のソフトウェアアップデートにいるかも。

コマンドを実行すると、システム環境設定の通知が無くなったので、どちらでやっても同じ結果になる模様。

# コマンドラインツールのコンパイル

ディレクトリを移動してMakefileを書き換える。

冒頭の

```bash
OS ?= LINUX
#OS ?= WINDOWS
#OS ?= MACOSX
#OS ?= BSD
```

を、

```bash
#OS ?= LINUX
#OS ?= WINDOWS
OS ?= MACOSX
#OS ?= BSD
```

に修正。

で、おもむろにmake。

同じディレクトリに、`teensy_loader_cli`が生成されたはず。

# コマンドラインツールで書き換え

[こちら](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ergodox_ez)のqmk_firmwareのページに有るように、

```
$ ./teensy_loader_cli -mmcu=atmega32u4 -w 書き換えるファイル.hex
```

みたいな感じて書き換える。
状況がわかりやすいように、-vオプションを付けると良い。

コマンドを実行すると、ErgodoxEZのリセット待ちになるので、右側キーボードの右上にあるリセットスイッチを、ペーパークリップなどで押す。

押したら、

```
Found HalfKay Bootloader
Read "test.hex": 22552 bytes, 69.9% usage
Programming.................................................................................................................................................................................
Booting
```
となって、書き換え完了！
Macのlocalhost上で動作しているサービスへDocker内部から接続する方法

Docker Container内部で動作している環境からMac上で動作しているサービスへ接続することが出来ずハマったので、その解決方法をメモしておきます。
よくあるMacからDocker上のサービスへ接続するのとは接続方向が逆になりますのでご注意ください。

# 背景

VirtualBox上にNAT network interface1つを接続した状態で仮想Ubuntuサーバを立ち上げ、
そこへPostgreSQL(ポート番号:5432)を立ち上げました。
その後、VirtualBoxのPort Forwarding機能でHost:5432 Guest:5432 でForwardする設定をしました。
この状態であれば、MacへPostgreSQLクライアントをインストールして、`localhost:5432` へ接続することで仮想マシンで動作しているPostgreSQLへ接続可能です。
ところが、Mac環境をなるべく汚したくない私はpsqlコマンドをローカルにインストールすることを嫌い、PostgreSQLのDockerイメージを使って確認することにしました。
その際に接続できなくてハマりました。

# 解決方法

`docker run -it --rm postgres psql -U root -h host.docker.internal`

はい、結論から書くとこれが答えになります。
ポイントは、接続先をlocalhost:5432にするのではなく、`host.docker.internal:5432`にすることです。
どうやら、Docker Container上から見てローカル環境（Mac)のIPアドレスは、localhostと指定するのでは接続できず（おそらくDocker Containerそのものを指定してしまう？）、 `host.docker.internal` を指定する必要があるようです。
DockerはMac上の1プロセスとして動作するという理解をしているので、psqlコマンドを単体で実行するのと同じようなイメージでlocalhostを指定していたのでハマってしまいました。

# 参考情報など

公式: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
`I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST`

StackOverFlow: https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach
`Edit: If you are using Docker-for-mac or Docker-for-Windows 18.03+, just connect to your mysql service using the host host.docker.internal.`
自宅サーバーのススメ

#自宅サーバーのススメ
よくわからないですがQiita初投稿らしい..（書いた気になってるだけだった）

よく「自宅サーバー」と検索すると、
自宅サーバーからVPSに移行！とか、
自宅サーバーは危険！ すぐにやめるべき、
全然勉強にならない！っていう記事を見かけます。
でも、デメリットは何にでもあるものですよ、ね？
今回は布教も兼ねて、自宅サーバーにあんまりいい思いをしていないひとにとことん反論していこうと思います
※ちなみにこの記事も自宅サーバー(CentOS7 GUI環境）で書いてます
![Screenshot from 2020-01-22 23-21-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325374/979aadd0-6d61-06b6-f3df-fd7738496754.png)
##デメリット1「うるさい」
自宅サーバーは騒音を出すと嫌われがち。でも、最近のサーバー機やPCは、静音性重視で、
場所を考えて、音が広がらない用に配置すれば、全然気にならないと思います
（ラックサーバーは別問題）
##デメリット2「電気代が...」
自宅サーバー＝ウェブサーバーだと思っていませんか？
サーバーや仮想化の勉強をする為に、24時間365日起動しておく必要なんてないと思います。
私も自宅サーバーは24時間つけっ放しではありません。
24時間つけっ放しするのであれば省電力な電源を買った方が幸せになれます
##デメリット3「VPSのほうが良さそう」
VPSは安定を求めるなら重要かもしれませんが、
**VPSは固定費がかかります**よ、
ウェブサービスとか人気ブログとかならまだしも、実験用や勉強用のVPSに、
**24時間起動してある意味、**ほんとにあります？
私はVPS借りても1ヶ月に3回ぐらいしかログインしませんが。
##デメリット4「セキュリティーが...」
インターネットに接続されている機器は**ほぼすべて**攻撃を受けています。
これは、windowsやLinuxでも一緒ですし、VPSも自宅サーバーも**同じように狙われています。**
実際、自宅サーバーを10時間放置してたら**1万件の**不正なログイン試行がありました
もうここまで来ると、自己責任だと思います。
##デメリット5「燃えそう」
サーバー専用機ならまだしも、**ノートPCを24時間連続稼動**させたらそりゃ燃えますよ。
勉強のためなら、やはり24時間ではなく、
**使うときだけ**起動するべきだと思います
railsサイトマップをサーチコンソールに送る方法

route.rb

```
get 'sitemap', to: redirect('https://s3-ap-northeast-1.amazonaws.com/バケット名/sitemaps/sitemap.xml.gz')
```

sitemap.rb

```
SitemapGenerator::Sitemap.default_host = "サイトのurl"
SitemapGenerator::Sitemap.sitemaps_host = "https://s3-ap-northeast-1.amazonaws.com/#{ENV['S3_BUCKET_NAME']}"
SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/'
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
  ENV['S3_BUCKET_NAME'],
  aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
  aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  aws_region: 'ap-northeast-1'
)

SitemapGenerator::Sitemap.create do

  add posts_path, changefreq: 'daily'
  
  posts = Post.published
  posts.find_each do |post|
    add post_path(post), lastmod: post.updated_at
  end
end

```

herokuに環境変数を設定する。

search console
ドメイン/sitemapで登録
UISearchBarのキャンセルボタンをアニメーション付きで表示したい話

UISearchBarをタップして編集状態中だけキャンセルボタンを表示したいと、
ちょびっと悩んだので備忘録として書いときます。

↓こんな感じのやつ
![qqytl-ojzlm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542129/ad6d45db-b35f-7f6e-dc42-8b66beb6c2c0.gif)

# アニメーション無しの場合

showsCancelButtonを使うことで表示の制御はできますが、アニメーションはありません。

```swift
searchBar.showsCancelButton = true
```

# アニメーション有りの場合

setShowsCancelButtonを使いましょう

```swift
searchBar.setShowsCancelButton(true, animated: true)
```

# 実装例

コピペをこよなく愛する者たちへの贈り物です😘

```swift
import UIKit

class  ViewController: UIViewController,UISearchBarDelegate {

    @IBOutlet weak var searchBar: UISearchBar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // デリゲート設定
        searchBar.delegate = self
    }

    // 検索バー編集開始時にキャンセルボタン有効化
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar){
        searchBar.setShowsCancelButton(true, animated: true)
    }
    
    // キャンセルボタンでキャセルボタン非表示
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
        searchBar.setShowsCancelButton(false, animated: true)
    }
    
    // エンターキーで検索
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
        searchBar.resignFirstResponder()
        searchBar.setShowsCancelButton(false, animated: true)
    }
    
    // 入力された文字出力
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        print(searchText)
    }
}

```
emotion で The pseudo class ":nth-child" is potentially unsafe when doing server-side rendering. Try changing it to ":nth-of-type".

Next.jsとemotionで次のようなエラーがでた

```
The pseudo class ":nth-child" is potentially unsafe when doing server-side rendering. Try changing it to ":nth-of-type".
```

`:nth-child` はSSRでundafeらしい。なんでたかが`:nth-child`がunsafeなの？と思ったけどどうやら

- https://github.com/emotion-js/emotion/issues/1178

このissueをみてるかんじ、兄要素として `<style>` が挿入されることがあるそうな。解決策については

- https://emotion.sh/docs/ssr

公式のドキュメントのSSRのページにのっています

SSRではない場合、このエラーを非表示にしたい事はあると思うんだけど

- https://github.com/emotion-js/emotion/pull/1209#issuecomment-462035404

この記述が必要らしい

```js
span:nth-child(2) /* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */ {
  animation-delay: 0.2s;
}
span:nth-child(4) /* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */ {
  animation-delay: 0.4s;
}
```

うーん、流石にちょっとこれは普通につけられるのであれば、クラスつけたほうがいいんじゃない？となっちゃいますね……
goss advent calender2019反省会的な何か

(*'▽')[goss advent calender2019](https://qiita.com/advent-calendar/2019/goss)お疲れ様でした
おつかれさまでした(´･ω･`)

え、この形式でやるの？(´･ω･`)
(;'-')ダメですか？

（´・ω...:.;::..
(;'▽')ちょ、冒頭で逃げないで

まあ好きにしたまえ(´･ω･`)
(;'-')ありがたきしあわせ


Advent Calenderを書き始めたきっかけ
-----------
なんでAdvent Calender2019書き始めたの？(´･ω･`)
(*'-')2019年は積極的にOutputはしようと考えていて、その一つとしてAdvent Calender参加をしました

gossにしたのは？(´･ω･`)
(;'-')書けそうな持ちネタの中で割と投稿登録がなかったのでいけるかなーと

goss Advent Calender2019のカレンダー自体作った人は別の人だよね(´･ω･`)
(;'-')実質乗っ取った状態なのはちょっと気にしてます。とはいえ白紙よりは良いかなーと思いまして


Advent Calenderのネタ作り
-------------------
gossもやるって決めて勉強したわけではないのね(´･ω･`)
(*'-')一応ある程度実務的に使った上で内容まとめた感じですね

Manual読めばOKくらいの内容も多いよね(´･ω･`)
(;'-')公式は英語ですし、日本語情報だとちょっと使ってみた、くらいなのでまずは使おうと思えるように情報増やすのが大事かなと
(*'-')でも使ってみた上での留意点とかも混ぜるようには心がけたつもりです

記事は投稿した日に書いてるの？(´･ω･`)
(*'-')記事タイトルと見出しを列挙したようなプロットリストを先にざっと起こして、そこから順次下書きして投稿ですね。

(;'-')下書きストックが何本もあった時もあれば、使い切ってせっせと書いてる時もあります

プロットリストってどういうの？(´･ω･`)
(*'-')一般的かはわかりませんが、インデント付き箇条書き形式で内容の要約をずらっと書きました。この時点で書いておきたい留意点はほぼ全部書いています。

ほほー(´･ω･`)
(*'-')その上でリストを並べなおして1本分の記事にして下書きしてます。

Excelでも使って書いてたの？(´･ω･`)
(*'-')Google Keepのチェックリストを使いました。チェックはしませんが、1段インデントつけられるのと後から行の並べ替えが出来るのと、ちょっとした時間でスマホで書けるので。

へー(´･ω･`)
(*'-')記事書くときはQiita編集画面と別のWindowでGoogle Keepのページ開いて見ながら書いてました。

ああ、スマホとブラウザでGoogle Keepの内容共有してるのか(´･ω･`)
(*'-')ですです


投稿する上での苦労したこと
-------------------
この辺りは書くの大変だったとかある？(´･ω･`)
(;'-')この12月は暇する予定だったのが急遽仕事が入って時間取りづらかったのが一番大変でしたね。

だから歯抜けた投稿ペースなのか(´･ω･`)
(;'-')出かける時にノートPC持っていって、カフェとかでちょこちょこ書き進めてたりとかしてました。

スタバでマックですか(´･ω･`)
(;'-')コメダでDELLですね

なにそれ新しい(´･ω･`)
(;'-')土地柄コメダ珈琲店は店舗多いのと、今持ってるノートPCが昔間に合わせで買ったDELLというだけです。

庶民派アピール(´･ω･`)
(;'-')ただの準備不足です

Qiita使う上で、とかはないの？(´･ω･`)
(*'-')別のブログサービスも使ったことあるので、そこまで苦労はないです。むしろ便利でした。

(*'▽')もっと言えば記載失敗してた箇所を編集リクエストで読んだ方に直して頂いたりしてありがたかったです。


投稿で工夫した点
----------------
この辺は工夫したとかはある？(´･ω･`)
(*'-')長くなりすぎないのと、あまり深堀しないことですかね

そのこころは？(´･ω･`)
(*'-')チュートリアルではなく読み物なので、一つの内容に文字数割くと話が進まないので、さっくり書いて読みやすくなるようにはしてました。

この記事長くない？(´･ω･`)
(;'-')しっかり反省しているということでここは一つ...。あとは余計なチャチャ入れを省けば短くなります。

ひどいはなしもあったもんだ(´･ω･`)


ぼくもっとgossのこと知りたい(´･ω･`)
(;'-')別記事でやれればと思います。もしくは書いてください。

これ使えばサーバテストはばっちりだぜ！的なYAMLファイルないの(´･ω･`)
(;'-')私が欲しいくらい


Advent Calender書き終わってみての感想
-----------------
終わってみての感想があればどうぞ(´･ω･`)
(;'-')疲れました

でしょうね(´･ω･`)
(;'-')昔はもうちょっと筆進んだ気がするんだけどなあ

歳ですね(´･ω･`)
(;'-')そうですね


先生の次回作にご期待ください(´･ω･`)
(;'-')やる機会があれば、で


エピローグ
-------------------
ところでぼくは誰？(´･ω･`)
(;'-')某所ブログで使ったキャラに出張頂きました。元になった実在本人には未承諾です。

ひどいはなしもあったもんだ(´･ω･`)
(;'-')広い世界にデビューできたということでここは一つ

ところでこの反省会記事は必要？(´･ω･`)
(;'-')これで書き手が増えればという願いを込めて

本当は？(´･ω･`)
(;'-')書きたかっただけ
基本情報技術者　テクノロジ系　第7章 セキュリティ②

昨日に続いて
書き続けて行きます。

# 暗号方式

## 共通鍵暗号方式

復号化と暗号化する鍵を共通にしておく方式

利点: 処理が高速になる
悪天: 相手の数だけ必要になるため鍵の数が膨大になる
　　　総数: n(n-1)/2

### AES
共通鍵暗号方式のアルゴリズム
AES-128 が128ビット
AES-256 が256ビット
使用となり
多いほど安全性が増します。

## 公開鍵暗号方式
ペアとなる2種類の鍵を使用して
暗号化と復号化を行います。

### 公開鍵
他人に使ってもらうための鍵

### 暗号鍵
自分だけの秘密にするための鍵

### 使用例

#### 情婦の秘匿
公開鍵で暗号化、秘密鍵で復号化

#### 署名
秘密鍵で暗号化、公開鍵で復号化

### 公開鍵暗号方式

#### RSA
素因数分解を利用した方式

#### 楕円曲線暗号
RSAよリも短く
RSAと同等

## セション鍵暗号方式
2種類の鍵暗号方式の利点を組み合わせた方式
ハイブリット暗号方式とも言います。

平たくいうとセション鍵で
共通鍵暗号方式を行っているだけですが

セション鍵そのものを公開鍵暗号方式で
暗号化しているので
安全性が高いということです。
メディアクエリ_HTML&CSS_20200118

<https://bitsofco.de/how-calc-works/>
<https://coliss.com/articles/build-websites/operation/css/how-calc-works-by-ire.htmla>
【calc（）】
CSS関数
加算、減算、乗算、除算が可能

width: calc(100% - 50px);
幅いっぱいから50px引いた幅を指定

width: 33.33%;
↓
width: calc(100% / 3);

HTML
<br class="u-display__pc">
CSS
media (max-width: 670px) {
 .u-display__pc {
  display: none;
 }
}
画面幅が671px以上の場合には改行を行う。
画面幅が670px以下の場合には改行を行わない。
これにより、スマホなどで表示を行う際に綺麗に枠に合わせた文字出力が行われる。

CSS
position: fixed;
メニューの画面上部固定などに使える

transform: rotate();
要素を回転表示する(使い方わからない)
CorDappを自作してみる。(contract作成まで)

# 記事の概要
Cordaの公式ドキュメントに沿って、CorDappを自作してみた。
この記事では、[前回](https://qiita.com/kzt_tateyama/items/049391b542014e05f3f9 "前回")の続きとしてcontractを作成する所までを記載する。

# 公式ドキュメント
https://docs.corda.net/_static/corda-developer-site.pdf
(主に第5章 「Getting started developing CorDapps」と第6章「KEY CONCEPTS」に沿って実施。)

# contractの概要
1.「contract」とは？
contractは、「statesをどのように作成し、展開するか」を定義したオブジェクト。
各トランザクションの正否はcontractの内容に従って判断される。また、入力側のstatesと出力側のstatesのcontractが
すべて有効とみなされる必要がある。

2.contractの記述について
contractコードは、任意のJVM言語で記述できる。(Java/Kotlinなど)

# contractの実装
CorDappを公式ドキュメントの「5.2.3 Step Three: Creating contracts」に倣ってコーディングしてみる。
ちなみに、プログラミング言語はKotlin。

```Kotlin:CarContract.kt
package com.template.contracts

import com.template.states.CarState
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.Contract
import net.corda.core.contracts.requireSingleCommand
import net.corda.core.contracts.requireThat
import net.corda.core.transactions.LedgerTransaction

class CarContract : Contract {
    companion object {
        const val ID = "com.template.contracts.CarContract" ※1
    }

    override fun verify(tx: LedgerTransaction) {　※2

        val command = tx.commands.requireSingleCommand<Commands>().value ※3

        when(command) { ※4
            is Commands.Issue ※4 -> requireThat { ※5
                "There should be no input state" using (tx.inputs.isEmpty()) 
                "There should be one input state" using (tx.outputs.size == 1)
                "The output state must be of type CarState" using (tx.outputs.get(0).data is CarState)
                val outputState = tx.outputs.get(0).data as CarState
                "The licensePlateNumber must be seven characters long" using (outputState.licensePlateNumber.length == 7)
            }
        }
    }

    interface Commands : CommandData {
        class Issue : Commands
    }

}
```

※1：contractを一意的に識別するためのIDを動的に生成する。(「companion object」は1つのクラスに1つだけ宣言可能なオブジェクト)
※2：LedgerTransactionをオーバーライドする。
※3：「command」にLedgerTransactionのrequireSingleCommandの値を設定する。
※4：whenで「command」を判定。「Commands.Issue(新しく資産状態を発行するクラス)」である場合、後続の処理に遷移する。
※5：requireThatに、トランザクションの定義を記述する。ここで定義されているのは以下の内容
　　5-1：入力stateは未入力であること。
　　5-2：出力stateは1つであること
　　5-3：出力stateのデータ型は、CarStateであること。
　　5-4：出力state中の「licensePlateNumber」の長さは7であること。

# 終わりに 
次回はflowの作成から再開する予定。
DJI TelloでOMPLを用いた自律飛行ドローンのナビゲーション - 6.5. octomapのインストール

DJI Tello等ドローンの自律飛行を実現するには、3D環境でナビゲーション経路を計画としてOMPL（Open Motion Planning Library）を試してみます。

# 目次
1. [OMPLのインストール](https://qiita.com/k-koh/items/4f7e441d1225e6580f82)
2. [OMPLの基礎](https://qiita.com/k-koh/items/9933cd29599c859cac45)
3. [OMPL.appの入門](https://qiita.com/k-koh/items/fe1f05313045ed729c8b)
4. [OMPLの使用](https://qiita.com/k-koh/items/3a8b372537aa29e17863)
5. DJI Telloの使用
    1. [DJI Telloのフロントカメラのcamera_calibration](https://qiita.com/k-koh/items/094631646931ea5bc2bb)
    2. [Visual SLAM ORB_SLAM2 用のカメラキャリブレーションYamlファイルの作成](https://qiita.com/k-koh/items/b524fc175198e701bdff)
    3. [DJI Telloのカメラ でVisual-SLAMのORB-SLAM2 を動かしてみた](https://qiita.com/k-koh/items/98b5f079f784b22dcd01)
6. navigationスタックの使い方
    1. [Turtlebot3 NavigationをGazebo Simulationで動かしてみた](https://qiita.com/k-koh/items/1a4fbc175ca37be6206b)
    2. [Turtlebot3 Navigationでmap_fileの代わりにSLAMを使用](https://qiita.com/k-koh/items/1ec9097e4afedd0b43ca)
    3. [ARdroneのシミュレーターをGazeboで動かす](https://qiita.com/k-koh/items/feccbaee7c11c43c3ab4)
    4. [AirSimのシミュレーターを動かす](https://qiita.com/k-koh/items/52122fb5e96336ac8d33)
    5. [octomapのインストール](https://qiita.com/k-koh/items/c9a3a87e043934456842)　← いまココ
    6. [単眼カメラでORB_SLAM2から3D point clouodの生成](https://qiita.com/k-koh/items/1e069c9dda43b85e2fa0)
    7. [point_cloud2から3D octomapの生成](https://qiita.com/k-koh/items/01e34f353487eb8a6e26)
7. OMPLで3D 経路計画
    1. [状態空間環境のセットアップ](https://qiita.com/k-koh/items/e19ac08bb0a16975081e)

## 動作環境
- Ubuntu 18.04
- ROS Melodic
- Tello EDU

# octomap

## octomapのインストール
```console
$ sudo apt-get install libqt4-dev qt*-qmake libqglviewer*
$ git clone https://github.com/OctoMap/octomap.git
$ cd octomap
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
```

## octovisでサンプル地図を表示
```console
$ cd octomap
$ bin/octovis octomap/share/data/geb079.bt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/c16b7d38-d25e-229a-090c-7f282e73fc7e.png)

## ros packageのインストール
```console
$ sudo apt-get install ros-melodic-octomap
$ sudo apt-get install ros-melodic-octomap-msgs
$ sudo apt-get install ros-melodic-octomap-ros
$ sudo apt-get install ros-melodic-octomap-rviz-plugins
```

## fclのインストール
```console
$ git clone https://github.com/flexible-collision-library/fcl.git
$ cd fcl
# use same version with libfcl-dev
$ git checkout 0.5.0
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
```

## Compile with fcl
in package.xml

```
<depend>fcl</depend>
```

in CMakeLists.txt

```
find_package(fcl REQUIRED)

include_directories(
 include
 ${fcl_INCLUDE_DIRS}
)

target_link_libraries(xxx
  fcl
)
```

Prev: 6.4. [AirSimのシミュレーターを動かす](https://qiita.com/k-koh/items/52122fb5e96336ac8d33)
Next: 6.6. [単眼カメラでORB_SLAM2から3D point clouodの生成](https://qiita.com/k-koh/items/1e069c9dda43b85e2fa0)
クラスについて

#用語
||説明 |    
|:-----------------|------------------
| プロパティ|クラス内の変数 | 
| メソッド|クラス内の関数 |
| クラス|メソッド、クラスの集まり（設計書） |
| インスタンス|クラスから生成されるもの|
| オブジェクト|インスタンスメソッド |

#アクセス修飾子
・どこからメソッド、プロパティがどこからアクセス可能かを示す修飾子
・アクセス修飾子を指定しないと、publicの扱いになる

|種類  |説明  |
|---|---|
|public　 |どこからでもアクセス可能  |
|private  |クラス内のみアクセス可能  |
|protected  |クラス内とそノクタスを継承した子クラスからアクセス可能  |

#インスタンス
・クラスをもとにしてものを作ること
・インスタンス化したら基本的に変数に代入する

```php:インスタンス作成
$変数名 = new クラス名（引数）
```

#アロー演算子
・インスタンスのプロパティやメソッドにアクセスするには、-> を使う

```php:クラスの定義
class Car {

    public $name;//初期値指定可能
    public function drive() {
        echo '走ります';
    }
}

// Carクラスのインスタンスを作成
$prius = new Car();

//プロパティにアクセス、代入、呼び出し
$prius->name = 'aqua';
echo $prius->name;// aqua

// インスタンスした（drive）メソッドへアクセス
$prius->drive();// 走ります
```

#this
・クラス内のプロパティ、メソッドにアクセスできるインスタンスメソッド
・staticメソッドでは使えない

```php:this
class Car {

    private $state = '走ります';

    public function drive() {
        //プロパティにアクセス
        return $this->state;
    }
}

$prius = new Car();
echo $prius->drive()// 走ります
```
#static(静的プロパティ)
・クラスのプロパティ、メソッドを`static`と宣言することで、クラスのインスタンス化無しでアクセス可能
・静的プロパティは->で呼び出せない
###self
・自クラスのプロパティ、メソッドへのアクセス
`self::`
クラス内の自身のインスタンスを生成
`new self`

```php:静的プロパティ
class Car {

    public static $name = 'aqua';

    public static function drive() {
        echo '運転';
    }
    public static function enjoy() {
        //自クラスのメソッド、プロパティにアクセス
        self::drive();
        self::$name;
    }
}
echo Car::$name;// aqua
Car::drive();// 運転

Car::buy();// aqua運転
```
#対応表

||インスタンスプロパティ|インスタンスメソッド|静的プロパティ|静的メソッド|
|--:|--:|--:|--:|--:|
|外部から|$a->name|$a->name()|クラス名::$name|クラス名::$name|
|インスタンスメソッド内から|$this->name|$this>name()|self::$name|self::$name()|
|静的メソッド内から|×|×|self::$name|self::$name()|

#コンストラクタ
・オブジェクトを生成するうえで必要なパラメータや、そのクラスのオプションなどを引数として受取り、プロパティにセットするという役割を果たす。

```php:コンストラクタ
class Car {

  private $name = '';
  //引数をコンストラクタで受け取る
  public function __construct($name){
    //受け取った値をプロパティとして保存
    $this->name = $name;
  }
  
  public function getName(){
    return $this->name;
  }
}

$a = new Car('aqua');
echo $a->getName();// aqua
```
#継承
・同じような処理を二度三度定義し直すのお回避するためにあるコード再利用の仕組み
・親クラスのプロパティ、メソッドが全て引き継ぎ
・引き継いだものは`public`、`protected`なものに限定してアクセス可能
・外部からのアクセスは`public`のみ

```php:BはAの継承クラスである定義
class B extends A { } 
```
#finalキーワード
・fainalキーワードをしたメソッドは継承された派生クラスでオーバーライド（子クラスで親クラスのメソッドを再定義）出来なくする
Anaconda(python 3.7)でspyderが起動できない問題を解決する

#はじめに
データサイエンスの講座に参加した時にspyderを使う機会があったのだが
受講者の中でなぜか自分だけspyderを起動できなかった。
一応解決したのでメモ

#症状
spyderを起動時に
**カーネルを開始中にエラーが発生しました**
と表示され、起動できなかった。

#環境
OS:Windows 10
[Anaconda python 3.7](https://www.anaconda.com/distribution/)(2020/1/22時点の最新版)

#解決策
1. 一度Spyderを終了し、**管理者として**Anaconda promptを実行
2. `conda update --all`を実行
3. 色々updateされるので、updateが完了されたら終了
4. spyderを起動すると正常に立ち上がるはず

管理者として実行するのがポイント
そのまま実行するとupdateが途中で失敗してしまう。

#最後に
実はspyderの[GitHub](https://github.com/spyder-ide/spyder/issues/10400)に解決策載ってたんですが、**管理者として実行**の記載が無かったのでメモとしてこちらに書いておきました。
【Git】fatal: protocol error: bad line length character: usag の解消方法

# はじめに

develop ブランチが更新されたので、pull しようとしたら、
`fatal: protocol error: bad line length character: usag` 
が発生しました。
なかなか解決できず、2時間ほど時間を無駄にしました。

最初に結論からいうと、

###.gitconfig を見直そう！！！！

# 環境

- macOS Catalina バージョン10.15.2
- git 2.21.1

# やったこと

- .bashrc の見直し（効果なし）
- git のアップデート（効果なし）
- 対象のブランチを削除して、取得し直す（効果なし）
- プロジェクトを clone し直す（効果なし）
- 仮想環境で clone してから ローカルに持ってくる（効果なし）
- .gitconfig を見直す

# .bashrc の見直し（効果なし）

参考文献より、

> ググってみると、リモート先のサーバーにsshでログインする時に表示されるメッセージが悪いとか、
> ssh関連で、.bashrcとか.zshrcとかの設定を見なおしたよ、というような内容が多い。

でした。
ただ、自分の Mac の Terminal は fish を使っています。
bash も zsh も使っていません。

念のため、.bashrc を確認しましたが、何も書かれていませんでした。
さらに念のため、.bashrc を消してみましたが、改善しませんでした。

# git のアップデート（効果なし）

git のバグかと思ったので、 git のアップデートしました。
mac で HomeBrew を使用している方は、下記のコマンドでアップデートできます。

```shell
brew update
brew install git
```

XCode の CommandLineTools での git を使っている方は、 which コマンドで path が合っているか確認しましょう。

```shell
which git
# /usr/local/bin/git となっていれば OK
```

これでは改善しませんでした。

# 対象のブランチを削除して、取得し直す（効果なし）

今回は develop ブランチを pull しようとしたときに発生しました。
なので、 develop を削除して、取得し直そうと思いました。

```shell
git checkout master
git branch -D develop
git checkout -b develop origin/develop
```

これでももちろん改善せず。

# プロジェクトを clone し直す（効果なし）

この際ヤケクソです。
プロジェクトを新たに clone することにしました。

```
git clone https://github.com/<ユーザー名>/<プロジェクト名>.git
```

ここでも、`fatal: protocol error: bad line length character: usag` が発生しました。
そこで、git そのものがバグっていると気づきました。

# .gitconfig を見直す

```shell
rm ~/.gitconfig
touch ~/.gitconfig
git config --global user.email example@example.com
git config --global user.name example
```

と、.gitconfig を削除して、name と email を設定し直しました。
これで、エラーが発生しなくなり、clone も pull もできるようになりました。

# 最後に

どのタイミングでバグったのが気になるところですが、無事解消することができました。

# 参考文献

[[エラー] bad line length character: Sysl - KayaMemo](http://kayakuguri.github.io/blog/2014/07/28/git-heroku-error/)
JConsoleがlocalで接続できないとき


知りたい情報をドストレートに射抜いてくれる日本語記事は検索しても出てこなかったので記します。

**解決の助けになった記事(英語）**
https://community.oracle.com/thread/1177644
#現象
jconsoleなるJavaのプロセスを監視するものを使う必要が生じたので、常駐してるJavaプロセスにローカルでアクセスしにいったところ、４つあるうち１つのプロセスだけアクセスできなかった。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571578/54dcb4a7-3ac9-f892-2ce0-7a9f640a2d2f.png)
ローカルなのになんで失敗するの？接続が成功しませんでした？


#対処法
目的の*jar*ファイルに監視するオプションを付与してあげるとJconsoleで監視できるようになった。
例）コマンドプロンプトでJMXで監視するオプションを付与して実行する。

```console:コマンド(win10)
java -Dcom.sun.management.jmxremote -jar 目的のjar.jar
```
普段、意識することはなかったですが監視対象にするにはオプションを付ければいいのですね。
逆に成功した他のプロセスは誰かが起動時にオプション付けるようにbat組んでくれてたんでしょうね。
#JMXとは？（番外編）
[参照元：Oracleの公式ドキュメント](http://otndnld.oracle.co.jp/document/products/wls/docs103/jmxinst/understanding.html)　いわく
>「Java Management Extensions (JMX) は、Java アプリケーションをモニタおよび管理するための仕様です。 」

JMXガイド↓　~~まとめようと思ったけどめんどくさかった~~
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/management/agent.html
【R】 文字列から半角括弧を削除したい

# 1. 趣旨

**タ イ ト ル 通 り**

スクレイピングしたテキストなど、R上の**文字列データから半角括弧を削除したい**って時にどうするべきか、書いておきます。

# 2. サンプル文字列

```R
moji <- "(今夜はカレー)だと思う。"
moji
[1] "(今夜はカレー)だと思う。"
```

ここから半角括弧を削除して`今夜はカレーだと思う。`という文字列に仕上げたいです。

基本的な方針は、`gsub()`を利用して、括弧を空のテキストに置き換えます。
ただ、**半角括弧はメタ文字なので、一工夫が必要です**。

# 3. 削除してみよう

試行錯誤しているうちに、いくつか方法を見つけたので、お好きな方法でどうぞ。

## 方法1：クラスを利用する

```R
> gsub("[()]","", moji)
[1] "今夜はカレーだと思う。"
```

この大括弧`[]`で囲われた部分を「クラス」と呼びます。
クラスは、囲われた部分の中のどれか1文字とマッチングするのですが、この中だと**ほとんどのメタ文字が文字列として扱われる**ようです。
半角括弧`()`も例によって、クラス内ではメタ文字ではなく普通の文字列として扱われるので、半角括弧を削除できるということですね。

## 方法2：正統派の正規表現を用いる

```R
> library(dplyr)
> gsub("\\(", "", moji) %>%
  gsub("\\)", "", .)
[1] "今夜はカレーだと思う。"
```

こちらは正規表現をゴリゴリに利用した方法です。
注意点は、**「バックスラッシュ」を「2つ」重ねて使うこと。**
普通のスラッシュを使ったり、バックスラッシュが1つだけだったりすると、エラーが出ます。


## 方法3：正規表現を無効化する
```R
> library(dplyr)
> gsub("(", "", moji, fixed = TRUE) %>%
  gsub(")", "", ., fixed = TRUE)
[1] "今夜はカレーだと思う。"
```

最後は、**「ええい、正規表現なぞ知らねぇ！」**という方向けの方法。
引数に`fixed = TRUE`を指定すると、クォーテーション`""`内の正規表現を完全無視して、文字列として扱ってくれます。
デメリットは、正規表現を無視するので、正規表現を用いた詳細な文字列検索や置換ができなくなること。

# 4. まとめ

個人的には**方法1**か**方法2**がオススメです。

特に方法1は、コードが短くて済むのがいいです。
ただ、最もベーシックかつ応用が利くのは方法2だと思います。

とはいえ、最終的な結果は変わらないので、しっくり来る方法でいいと思います。

おしまい。
これを勉強してみた！！

初投稿で緊張しております。
今更なのですが。。。
初心者なのでお許しください。

・pwdとは、carrrent directly(現在のディレクトリ)のpath(道筋：コンピュータ内のアドレス）を表示する。

・ls　とは、そのディレクトリとファイルが入っているのか確認する。
メモ帳とMSEDGEだけでSlickを呼び出し、スライドショーを作りました。

#プログラミングの学習環境の話
今日はJQuery(超便利なライブラリ）の学習の一環として、Slick（スライドショーを作成するのに便利なプラグイン）を使ってスライドショーを実装する予定だったのですが・・・
教科書『いちばんやさしいJavaScriptの教本』

・学習用PCでソフトをインストールしてはいけない
・プラグインダウンロードもだめっぽい

学習場所の上記のルールのせいでかなり！苦労しました。
そもそもプログラミングの学習をすることを想定したPCを使っていませんからね・・・
てか教本は推奨ソフトインストールさせる場面が多すぎ！！
てことで、WindowsPCに最初から入っているPCにある

・メモ帳
・Microsoft　EDGE

だけで学習してる私が、JqueryとSlickを何とか呼び出して実装する話です。

#やり方の要約
・HTMLファイルのheadにSlickのCDN（プラグインやライブラリがアップロードされているところ）のURL（css)を貼り付ける。
・headにSlickのTheme。cssファイルがあるURLを貼り付ける（今回やってみたら失敗したので割愛）
・BODYタグ終了の直前にJqueryのURLを貼る
・その下にSlickのjsのURLを貼り付ける。
・jsファイルを呼び出す


#Head部分に貼り付けるURL

```
<link rel="stylesheet" type="text/css" href="http://cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick.css"/>
// 他に各自cssファイルとかGoogleフォントとか呼び出してくださいな
```

#Scriptタグのあたりに貼るURL

```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick.min.js"></script>
// この後JSファイルを読み込ませる
```

これであとは教本なり学習サイトなりに書いてあるSlickの使い方を見れば、各種ライブラリ、プラグインをダウンロードしたときと同じように使えるはずです。
但し体裁は整ってないけど・・・SlickのTheme.cssが読み込めないから・・・
上記URLを探すのに参考にした記事はこちらです、助かります。
https://qiita.com/wifeofvillon/items/0d1f6844533c7bed95c8
⛰【Vue.js】MariaDBのJSON型カラムから取得したデータの指定の値を変数名で取り出す為にパースする

## 環境
Vue.js 6.12.0
PHP 7.3.10
Laravel 6.5.0
MariaDB

## やりたいこと

MariaDBのに下記のようなデータが格納されていてそれをLaravelのAPIで取得する。
その内のcontentカラム（JSON型）のデータからdata_kindの値を判断基準として条件分岐を行い、
valueの内容である「テストの内容です🐾」や「赤文字で強調する！！」や円周率をVueの<tenplate>で表示する為にJSONをパースする

|id|content|del_flg|
|:------------------:|:------------------:|:------------------:|
|1|{"data_kind": "1", "value": "テストの内容です🐾"}|0|
|2|{"data_kind": "2", "value": "赤文字で強調する！！"}|0|
|3|{"data_kind": "3", "value": "円周率を表示"}|0|
|4|{"data_kind": "4", "value": "削除済み😭😭😭"}|1|

## やったこと

下に全体で色々書いてますが一番重要なのは下記のパース部分です
これが無いとJSONではなくJSONの形をしたただの文字列としてデータが扱われるので値を取り出すことができません

```parse部分
          // 取得データをforEachで全てJSON.parseにかける
          res.data.recordList.forEach(value => {
            value["content"] = JSON.parse(value["content"]);
          });
```

#### 全体

```Hoge.vue
// テンプレ部分
<template>
  <section class="container">

    <div v-for="data in tableData" :key="content.id">
      <!-- 通常表示 -->
      <div v-if="data.content.data_kind === '1'">{{ data.content.value }}</div>
      <!-- クラスを付けて装飾を変更 -->
      <div v-else-if="data.content.data_kind === '2'" class="redBold">{{ data.content.value }}</div>
      <!-- 円周率を表示 -->
      <div v-else-if="data.content.data_kind === '3'">3.141592653589323846....</div>
    </div>

  </section>
</template>

// データ取得とパース部分
<script>
export default {
  data() {
    return {
      tableData: []
    };
  },
  methods: {
    getContent() {
      axios
        .get("/api/getContent", {
          params: {
            delFlg: 0
          }
        })
        .then(res => {
          // 取得データをforEachで全てJSON.parseにかける
          res.data.recordList.forEach(value => {
            value["content"] = JSON.parse(value["content"]);
          });
          this.tableData = res.data.recordList;
        });
    }
  },
  mounted() {
    this.getContent();
  }
};
</script>

// 装飾
<style lang="sass" scoped>
.redBold
  color: red
  font-weight: bold
</style>
```