OmniAICreator/Qiita-1.07M huggingface dataset:
初心者がRuby on Rails チュートリアル（第４版）を初めてみた

[Ruby on Rails チュートリアル（第４版）](https://railstutorial.jp/chapters/beginning?version=5.1#sec-bitbucket)で学習しながら備忘録として投稿していきたいと思います。

# 用意するもの
・Mac Book Pro 2015
・学ぶ意思

# 開発環境
・MacBook Pro(Retina, 13-inch, Early 2015)
・プロセッサ 2.7 GHz デュアルコアIntel Core i5
・メモリ 8 GB 1867 MHz DDR3
・macOS Catalina Ver.10.15.4
・AWS Amazon Cloud9 
・GitHub 

ぶち当たった壁
・GitHubレポジトリとの紐付け
・git initするディレクトリのミス（アプリのrootではなくrootでget initしてた）
modified:   .bash_history無限ループ
・GitHubにpushしようとしたがgit initし直したので整合性が取れずエラー
error: failed to push some refs to 

壁にぶち当たりながらもググりながらなんとか１章終了
Laravelでモーダル画面から関連した投稿の削除機能を行う

LaravelでCRUD掲示板を作成していた際、モーダルウィンドウから投稿を削除するかユーザーに選択してもらい削除機能を実装しようとしたがかなりハマったのでメモ。

## 原因
HTML側から記事の投稿IDを引数に選択してなかったこと。
JS側で処理が呼び出された際にどの投稿IDかわからずずっと一意の投稿IDのみが選択されていた。

## 行ったこと
モーダルを投稿の数だけ配列で回して用意した
JSを呼び出す際に引数を指定してJSと紐付けた

##コード
```php:main.js

let modalMenu = false;

//HTMLからの引数から投稿IDを取得
let editModal = function(id) {

//.editModal-投稿IDと一致するものを定数に格納
 let checkForm = document.querySelector('.editModal-' + id);
 scrollTo(0,0);
 if(modalMenu === false) {
   checkForm.style.display = "flex";
   modalMenu = true;
  }
 else if(modalMenu === true) {
   checkForm.style.display = "none";
   modalMenu = false;
  }
}

```

```html:index.blade.php
@foreach($posts as $post)
<div class="post-frame">
			<div class="top-picture">
				<img src="{{ asset('images/image.jpg') }}">
			</div>
			<div class="user-tweet">
				<p>{{ $post->text }}</p>
				@if (!empty($post->file))
					<p><img src="{{$post->file}}" width="200px" height="200px"></p>	
				@endif
				<div class="user-information">
					{{ $post->name . " " . $post->created_at}}
				</div>
				<div class="link">
					@if ( Auth::id() === $post->user_id )
                    <!-- deleteModalの呼び出し引数に投稿IDを指定する -->
					<label onclick="deleteModal({{$post->id}})">削除</label>
					<label id="edit-form" onclick="editModal({{$post->id}})">編集</label>
					@endif
				</div>
			</div>
		</div>
<!-- JSからモーダルに呼び出される側、edit-modalがmodalの本体 editModal-(投稿ID)で投稿とモーダル画面を紐付けをしている -->
	<div class="edit-modal editModal-{{ $post->id }}">
		<div class="modal-content">
			<h2>投稿編集</h2>
			<form method="POST" enctype="multipart/form-data" action="{{ url('users/posts/update/') }}/{{$post->id}}">
				@csrf
				<textarea name="text" cols="30" rows="10"></textarea>
				{{ $post->id }}
				<div class="line-right">
	                <!-- モーダルを閉じるボタン(関数名と一致させないとモーダルが閉じません) -->		
            		<button type="button" class="left-button" onclick="editModal({{ $post->id }})">キャンセル</button>
                     <!-- 送信ボタン -->
					<button type="submit" class="right-button" onclick="editModal({{ $post->id }})">保存</button>
				</div>
			</form>
		</div>
	</div>
@endforeach

```
Aurora Severless Data API を使ってみての気づき

# この記事は何？
Aurora Severless Data API を利用した開発活動中に気づいたことを随時記載します。
Data API については、昨年（2019年）に東京リージョンでリリースされたばかりであるため、日本語の情報が少ない状況です。この記事が今後利用される方のお役に立てば幸いです。


# RDS 利用環境

- リージョン：ap-northeast-1
- ロール：サーバーレス
- エンジン：Aurora PostgreSQL

# Aurora Severless (PostgreSQLエンジン)を使ってみての気づき


#### :one: 最小キャパシティーを１Aurora Capacity Unit (ACU) から設定できるのはMySQLエンジンのみ。
PostgreSQLエンジンの最小キャパシティーは２ACU。
「[Amazon Aurora Serverless が 1 ユニットのキャパシティーと新しいスケーリングオプションのサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/04/amazon_aurora_serverless_now_supports_a_minimum_capacity_of_1_unit_and_a_new_scaling_option/)」という発表を聞いて、選択するエンジンに関わらず１ACUから設定できると考えていたのですが

>MySQL と互換性のある Aurora Serverless DB クラスターの最小キャパシティーを 1 Aurora Capacity Unit (ACU) に設定できるようになりました。

　　とのことです :innocent:


#### :two: プレースホルダーに渡す値のデータ型が少ない。ARRAY型、JSON型は２０２０年５月時点で非サポート。
[ExecuteStatementアクション](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html)の公式ドキュメントを読むと、リクエストシンタックスには一見ARRAY型をサポートしているような記載がありますが、次の注意書きがありました。

> :information_source: Note
Array parameters are not supported.

　気になったので試しに、boto3からプレースホルダーへARRAY型の値を渡すようにExecuteStatementを実行したところ、「Array parameters are not supported」エラーが発生しました。調べたところ、GitHubでも [Issues](https://github.com/aws/aws-sdk-js/issues/2993) として Open になっており、**AWSのエンジニアが次のようにコメントしていることから今後ARRAY型をサポートするものと考えます**。

>The SDK team has already things set up, its up-to the service team the time they take to implement it. Will update if they implement the feature.

　ワークアラウンドな対応となりますが、**次のような記述をすることでARRAY型のプレースホルダーへ値を渡すことが可能です**。

```python
tags = ['tag1', 'tag2']

rds_client = boto3.client('rds-data')
parameters = {
    'secretArn': 'your_secret_arn',
    'resourceArn': 'your_resource_arn',
    'sql': INSERT INTO sample_tbl (id, tags) VALUES (:id, :tags::text[]),
    'parameters': [
        {'name':'id', 'value':{'stringValue': '001'},
        {'name':'tags', 'value':{'stringValue': '{' + ','.join(tags) + '}'}}
    ],
    'database': 'your_database_name',
}

response = rds_client.execute_statement(**parameters)
```

#### :three: トランザクションのタイムアウト値は３分。
[BeginTransactionアクション](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_BeginTransaction.html)の公式ドキュメントによると、**発行したトランザクションIDが使用されない場合、トランザクションは３分間でタイムアウトします**。コミットされる前にタイムアウトする場合は、自動でロールバックが実行されます。
また、**一度使用されたトランザクションは最大２４時間有効**で、２４時間後に自動で終了し、ロールバックが実行されます。

> :warning: Important
A transaction can run for a maximum of 24 hours. A transaction is terminated and rolled back automatically after 24 hours.
A transaction times out if no calls use its transaction ID in three minutes. If a transaction times out before it's committed, it's rolled back automatically.
arduinoでの電圧判定（アナログ入力から電圧計算）とステアリングスイッチ１

##arduino で電圧は分圧回路で抵抗を介すれば、わりと正確に計れるという記事がある。
しかし、実際にarduino初心者である自分など、そう簡単にうまくいかないことがあった。
##ステアリングスイッチでオーディオ操作およびハンズフリー操作のボタン類
![IMG_7230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/f6792016-56cd-5790-2f21-1a2e41b892bc.jpeg)

これらのボタンは抵抗値が変化するだけなのでこれを電圧の変化を作り出して利用すればいいのではと考えたが。ただそう簡単でもなかった。

分圧回路の解説で計算式があるが、なるべくなら無駄に電流を流したくはない。
####そこで最初にＲ１の抵抗（下記図）を9K程度でテストした
![nano分圧イメージ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/2e4dc738-79c1-d592-2465-1d42e941abd9.png)
その結果抵抗値がもっとも低くなるCALLボタン（1）とVOL UPボタンで差が小さくなり、さらに電源が入るたびに数値が変化することに気づいた。最初ブレッドボードの接触に何か問題があるのかと疑ったが、どうもバッテリー電圧もDC-DCコンバーターの出力も安定しているようだった。
つまり列ＡとＣとＤは時間をおいて計っただけで、回路図の抵抗値やかけている電圧は同じであるにもかかわらず列Ｄでは値がちょっとずれている。もしかしたらDC-DCコンバーター出力で微妙に出力電圧が違ってしまっている可能性はあるかもしれない。
![電圧グラフ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/f0c001ca-49da-f82b-037f-a0ea8d6831b7.png)
####抵抗値を5.4Kにして再度計測した結果
![電圧グラフ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/171afdce-639a-dda6-8a77-7655c91e8563.png)
> グラフには電圧とあるが実際の正確な電圧ではない。analogRead()の読みとり値をただ判断しやすい数値に置き換えているだけである。
##しかし毎回安定しない問題が
車両のバッテリーはパナソニックで新品に交換してからあまり日はたっていないし、エンジンアイドリング時も14V以上ある。出力電圧が入力電圧の変化によって変化しているようには見えず。DC-DCコンバーターを疑い悩んでいるうちにarduino mini proでの実際に使用するチップで実装を始めていて、結局テストもより小型のarduino miniへ
![IMG_20200428_232323_672.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/529c6c17-566e-a5fe-c814-b8039775de87.jpeg)
（画像は別のプリント基板を流用）
ミニでのテストすると今までのnanoでのデータ
はすべて無効になるほど値が変化
抵抗値がありあわせで合わせたのでやや変化していることともともと正確な電圧計算ではなかったが
そこですぐプログラム中の判断の値を再調整し接続するたびに変化は少なくなったが、DC-DCコンバーターが発熱していることに気づく。
どうも壊したらしく取り替えるがやはり発熱が気になる。そこで電流を測るがLCDディスプレイ接続していて52.3mA程度
![IMG_20200505_125315_753.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/376bbdb2-7cc1-17e0-8102-a8191a3be078.jpeg)
DC-DCコンバーターがおかしい。→　すでに販売中止
これ5枚１組で買ったと思うがどうも信用できない。動く基板のやつもあるようだが
##DC-DCコンバーター基盤を別のものに入れ替え。
より小型になって設置が難しくなったが動かしてみると発熱まったくなし
![IMG_20200507_173018_210.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200517/03a2fcce-da07-2d8b-213f-46e831d756b9.jpeg)
少し大きめの真ん中に移っているものがだめなDC-DC
5個１セットでのこり４つ写っているのが今回使用したDC-DC
5Vのところショートして微調整できるようになっていたが、5Vでは最大で4.3Vにしかならず、8Vをショートさせて微調整すると最低電圧が4Vちょっと以下になったのでそれで5.3Vくらいにする
これで再度車でテストするが、そのときはリレーと連動させて、それぞれのボタンでLEDを光らせるようにしようと思う。
（次回また続き投稿予定）
Hyper-vで仮想化マシンを作成する（一時ファイルから再作成）

###仮想化マシン作成後にダウンロードファイルを自動的に削除しないことです。
下図の１行目は１６Ｇの「windows開発環境評価バージョン」のダウンロードファイルです。
![temp_big_size.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/462ffbc5-3ff9-646c-adbe-4f8847100dfe.png)

###解凍したイメージファイルから再インストールする

![unzip_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/29cc4b7d-79df-49f2-0cb9-def793a7a107.png)

###接続成功したデスクトップ
![success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/03990f0b-e3bd-1dcf-daf6-b433832e9a1e.png)

今後はlinuxの仮想マシンも作って、wsl2とhyper-v両方経験したいです。
![wsl2_docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/ff5cb0bb-df87-ead5-403f-df780fdde4a1.png)
【初心者向け】10行以内のスクリプト(7.bashでsqlite3のテーブルからcsvを出力するスクリプト

### 【初心者向け】10行以内のスクリプト(7.bashでsqlite3のテーブルからcsvを出力するスクリプト)
pythonで色々なライブラリを使えば、「少ないコードでもちょっとした事が出来て、少なければ5行程でもちょっとしたスクリプトが作れ、便利だな。」と思ったので、pythonやその他、コマンドを羅列しただけのものも出てくるかも知れませんが、10行程のスクリプトを不定期で投稿してみようと思います。

**第7回**として、<font color=blue>bashでsqlite3のテーブルからcsvを出力するスクリプトを投稿したいと思います。</font>


少し古いデータですが、ダウンロードしてあったfredの為替相場のcsvを格納したsqlite3から、select文を発行してカンマ区切りで表示してみようと思います。

***


### 1.sqlite3のテーブルからcsvを出力するスクリプト

【環境】
Linux: debian10
sqlite3: version 3.27.2
bash: 5.0.3

sqlite3で、カンマ区切りで出力する方法は、「sqlite3のコマンドとして.mode csv」他に、「-separator」というオプションで、区切り文字を指定出来る様です。

とすると、以下の様な構文になると思うのですが、色々と試してみたところ、
**【2】の外部ファイルをパイプでsqlite3に渡すやりかたが良い様に思いました。**

【1】sqlite3 (-separator ,) sqliteファイル名.sqlite3 "sql文、若しくはコマンド"
【2】echo '.read 「sqlを記述した外部ファイル」' | sqlite3 -separator , 「データベースのファイル名」

sqlを記述したファイルを読んで抽出するのですが、殆どがコメントです。
データベースの定義や複数行でインデントした外部のsql文を除けば、<font color=blue>sqllite3の操作は一行というシンプルさです。</font>
抽出結果を保存する場合は、リダイレクトするだけです。

データ・ベースに相当するsqliteのファイルは、カレントディレクトリに「dexjpus.sqlite3」としました。
以下の様に、日付と相場の2つのカラムからなる、時系列データです。

sqlite> .schema
CREATE TABLE t_dexjpus(
  "DATE" TEXT,
  "dexjpus" TEXT
);
sqlite> 

スクリプトは、ターミナルから実行しました。

```terminal:bash,sqlite3

#!/usr/bin/env bash
#####################################
# sqlite3のテーブルからcsvを出力するスクリプト
# sqlite3: version 3.27.2
# bash: 5.0.3
# sqlite3:ファイル名: dexjpus.sqlite3
# sql記述ファイル: select_tbl.sql
# sqlite3 (-separator ,) sqliteファイル名.sqlite3 "sql文、若しくはコマンド"
# csv出力: -separator ,
# #
#####################################

# ファイル名
db_file=dexjpus.sqlite3
#echo '.read select_tbl.sql' | sqlite3 -separator , dexjpus.sqlite3

# echoでsqliteのコマンド「.read」でsqlを記述した外部ファイルを読む
# パイプでsqlite3にフィールセパレーターに「,」を指定
# データが格納されたファイルを開く
echo '昇順で10件'
echo '.read select_tbl_asc.sql' | sqlite3 -separator , $db_file
echo ''
echo '降順で10件'
echo '.read select_tbl_desc.sql' | sqlite3 -separator , $db_file

```

### 2.sql文の読み込みを見てみると
<font color=blue>外部ファイルは、一行で記述しても良いのですが、一応、改行をしながら記述しています。</font>
「echo '.read select_tbl_asc.sql' | sqlite3 -separator , $db_file」として、
以下のsql文を読み込みました。
このデータは取引が無い日の相場は、ピリオドが入っている様です。

**それ以外で、昇順で10件を検索してみました。**


```sql:sqlite3

select 
* 
from t_dexjpus 
        where dexjpus is not '.'        
        order by dexjpus asc 
        limit 10; 
```

**降順で10件検索の別のファイルも読んでみました。**

```sql:sqlite3

select 
* 
from t_dexjpus 
        order by dexjpus desc 
        limit 10; 

```

実行した結果

```terminal:bash

$ sh sqlite3_rev_csv.sh > out.txt

$ less out.txt
昇順で10件
2016-08-18,100.0700
2016-08-23,100.2000
2016-08-17,100.2400
2016-08-19,100.2400
2016-08-22,100.2500
2016-08-16,100.2800
2016-09-26,100.3400
2016-09-27,100.3600
2016-08-24,100.5000
2016-09-28,100.5700

降順で10件
2015-06-05,125.5800
2015-06-08,125.0800
2015-08-11,124.9000
2015-08-05,124.8400
2015-06-01,124.6400
2015-08-06,124.6000
2015-06-04,124.5600
2015-08-10,124.5500
2015-08-18,124.3900
2015-07-30,124.3800

```

<font color=blue>sqliteの「.read」を使って、外部にsql文を記述する事で、再利用がしやすく、また複雑なsql文に対応出来そうです。</font> 

sqlite3は、shellの他、python等の言語からも接続しやすく、またファイルベースで手軽に使え、機能も豊富になっている模様。
<font color=blue>スマートデバイスや今後のIoTの普及を視野に入れると</font>今後、益々重要なものになりそうに思います。


**以上、7.bashでsqlite3のテーブルからcsvを出力するスクリプトでした。**
FactoryBotでのsequenceでつまずいたのでメモ

# sequenceとは
ユニークなデータを生成するためのメソッド。

モデルで一意性のバリデーションを定義指定た場合、

```
user1 = FactoryBot.create(:user)

user2 = FactoryBot.create(:user)
```
はuserの属性が一意性のバリデーションに引っかかってしまい、生成することができない。

だが、ファクトリで

```
# emailにバリデーションがかかっている場合
sequence(:email) { |n| "exmple#{n}@example.com" }
```
こうすることで、このファクトリが呼び出されるたびに、nの部分に数字が一つずつ増えて入るため、一意性が保たれる。
そのため、生成することができる。

```
user1 = FactoryBot.create(:user)
# emailは"example1@example.com"

user2 = FactoryBot.create(:user)
# emailはexample2@example.com"
```

# つまずいたこと

モデルスペックで一意性を検証するitを作成した。

```user_spec.rb

let(:user) { FactoryBot.build(:user) }
let(:duplicate_acount_id_user) { FactoryBot.build(:user, :duplicate_acount_id_user) }
# 省略

it "acount_idは一意でなければ無効であること" do
    user.save
    expect(duplicate_acount_id_user).to_not be_valid
  end

#省略
```

ファクトリ

 ```user.rb
factory :user do
    name { "user" }
    sequence(:acount_id) { |n| "www#{n}" }
    
  trait :duplicate_acount_id_user do
        name { "user2" }
        acount_id { "www1" }
    end
```

モデルスペック内ではuser.saveでuserが呼び出されて、sequenceによりそのuserのacount_idは"www1"になると思っていたので、トレイトの方は、acount_idを同じにするために"www1"と設定した。

だが、 bin/rspecで確かめると

```
# エラー文
Failure/Error: expect(duplicate_acount_id_user).to_not be_valid
```
が出た。

これにつまずいてしまった。

# 確かめてみたこと
focusをつけて単体で実行してみたら通った。

つまり、単体では最初にsaveされたacount_idが"www1"にちゃんとなっているということ。また、モデルのバリデーションも機能してるということ。

なので、全体で実行したらどのようになってるのかを見てみた。


```
it "acount_idは一意でなければ無効であること" do
    user.save
    # expect(user)にすることする事で、エラーになり、エラー文でuserの属性の値を見ることができる
    expect(user).to_not be_valid
  end
```
実行してみたら、acount_idが、"www15"になってた。

ということはuser.saveで読み込まれたuserのは"www14"だということである。（多分）

# なぜつまずいたか

1つのexampleが終わるたびにデータが削除されるのと同じように、ファクトリのデータもそのつどリセットされるものだと思っていたため。どうやらsequenceのカウントは継続されているっぽい。

# 解決法

saveする前にacount_idを指定。
ファクトリのトレイトの方のacount_idも変えた。

```user_spec.rb

let(:user) { FactoryBot.build(:user) }
let(:duplicate_acount_id_user) { FactoryBot.build(:user, :duplicate_acount_id_user) }
# 省略

it "acount_idは一意でなければ無効であること" do
    user.acount_id = "wow"
    user.save
    expect(duplicate_acount_id_user).to_not be_valid
  end

#省略
```


```user.rb
factory :user do
    name { "user" }
    sequence(:acount_id) { |n| "www#{n}" }
    
  trait :duplicate_acount_id_user do
        name { "user2" }
        acount_id { "wow" }
    end
```

通った。

トレイトやシークエンスを使う必要もないと思うが、練習のために使ってみた。
AWS SAA資格取得~データベースサービス編①~

今日はAWSのデータベースサービスについてまとめていきたいと思います。

#RDS(Amazon Relational Database Service)とは
⇨マネージド型のリレーショナルデータベース。
下記のデータベースエンジンをサポートしています。
・Amazon Aurora（1/10のコストで商用データベースと同等の可用性を実現）
・PostgreSQL（ビジネス、モバイルアプリケーションを実行するオープンソースのリレーショナルデータベース）
・MySQL（人気高め！コスト効率○）
・MariaDB（MySQLからフォーク）
・Oracle Database（高いシェアがある商用DB）
・Microsoft SQL Server（高いシェアがある商用DB。Windowsとの親和性○）

★マネージドなデータベースサービスの特徴について★
・最初からデータベースがインストールされている状態のためすぐにデータベースが利用可能。
・データベースサーバが動作しているOSや、データベースソフトウェアのパッチの適用はAWSが行う。
・自動バックアップが可能
・データベースのスケールアップ、スケールアップはAWSの機能を利用して行うことができる。

#RDSの特徴
#####パッチ適用の管理負荷軽減
曜日や時間帯をメンテナンスウィドウで指定するだけでAWSが自動でパッチを適用する。
セキュリティに関わるパッチがリリースされた場合は早急に対応する必要がある。
緊急のパッチ適用はメンテナンスウィドウで設定した時間とは関係なくユーザのシステム利用を調整・対策が必要

#####バックアップと復元
標準設定の場合1日1回自動バックアップが実施され、データベースとトランザクションログが取得されます。
データベース（データベースインスタンス）のバックアップにはストレージボリュームの
スナップショットを作成し、データベースインスタンス全体を取得します。
保存期間の設定は最大で35日間分を保存することが可能。
また自動ではなく手動で任意の時間に取得することも可能

もちろん復元も可能でRDSの復元方法は２通り
⇨通常の復元：スナップショットからデータベースインスタンスを復元
⇨ポイントインタイムリカバリ：バックアップのデータベースとトランザクションログが残っている範囲内の特定の日時時点にデータを復元

#####マルチAZ
RDSのマルチAZはRDSを複数のAZの構築することをさす。
Aurora以外のRDSデータベースではマルチAZのデータベースインスタンスを作成すると、
RDSはマスターのデータベースインスタンスを自動作成してくれ、
別のAZにあるインスタンスにデータ複製をしてくれる。
シングルAZの場合はバックアップを利用して復元しなければいけない。復元にも数分かかってしまう。
このことからマルチAZにすることで**耐久性と可用性が向上する。**

| 　　　　　　　     |             可用性 |      スループット増    |        レイテンシー   |
|:-----------------|------------------:|:------------------:|:------------------:|
| スケールアップ             |              ー |        ○ |　　　　ー
| マルチAZ          |            ○ |       ー       |　　　　ー
| リードレプリカ             |              ー |        ○        |　　　　ー
| プロビジョンドIOPS               |                ー |         ○         |　　　　○

#####リードレプリカ
マスターデータベースと同じデータベースを複製し、読み取り専用として構築したものをリードレプリカという。
リードレプリカを利用することにより読み取り頻度の高いデータベースを増設でき、
パフォーマンスの向上に繋げられる。


続きはAWS SAA資格取得~データベースサービス編②~
iOSでCustom URL Scheme活用

iOSでは「cm-app://」という文字列で、またこの文字列のあとにvalueを設定することによって、特定のAppを起動でき、また、特定のvalueによりAppを起動できる。

最近、地震が多いので、頻繁にアクセスするYouTubeの「強振モニタ放送24LIVE」様の「【地震・災害】強震モニタ マルチウィンドウ ライブ（配信地点：長崎 - 24時間放送）*」をiOSのスクリーン上にWeb Appのように設置することを実施した。
* https://www.youtube.com/watch?v=cwPFbQuyvRo

Apple Configurator 2を起動し、

Webクリップ
→ラベル「強振モニタ」（→表示名）
→URL「youtube://cwPFbQuyvRo」

と設定するだけ。これをAirDrop等でiDeviceに送信し、プロファイルをインストールすることで完了。
Jupyter Notebookで脚注を書く方法


Jupyter Notebookでの脚注(footnotes)の書き方を探すのに時間がかかったのでメモとして残します。

なお、脚注とはこれ→[^1]のことです。Qiitaだと```[^1]```と```[^1]: 脚注内容 ``` のように書き表すことができますが、Jupyterだとうまくいきません。


## 作り方
HTMLコードを埋め込むことで作成します。

```
①脚注の挿入箇所で
あいうえお[<sup>1</sup>](#id_01)かきくけこ[<sup>2</sup>](#id_02)。

②脚注を記述する箇所で、
<span id="id_01">1に対応した脚注の内容</span>
<span id="id_02">2に対応した脚注の内容</span>
```
これにより以下のようになる。
![footnotes.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208553/e8878b41-82a0-27fc-e871-0f03f34a25f6.jpeg)

①の添字をクリックすると、②の記述箇所にページがスクロールされます。
id_01の箇所は内部的なidなので自由に決められます。



(以上)


ソース：
[ENH: allow Markdown footnotes #1287
](https://github.com/jupyter/notebook/issues/1287)

[^1]: これが脚注です。
BootStrapを適用する方法

###環境
BootStrap v4.3

#解決方法
```hoge.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
```

headタブの中にコピペしてね。
念のために[BootStrap公式ドキュメント](https://getbootstrap.com/docs/4.3/getting-started/introduction/#css)で調べてみて。

超初歩だけど忘れがち。俺は忘れてた。
Tera Termに見るWEBエンジニアのIoTエンジニアとしてのキャリア形成

#Tera Termマクロ組める奴は尊敬されるネットワーク業界

最近、こういうTwitterを更新してます。
https://twitter.com/FseFull

ほぼギャグなのですが、
プログラマーやネットワークエンジニア等、IT業界と言えどお互いをあまり知らない業種を色々経験してきたので、その時に感じた事を思い出しながらTweetしてます。

そこで一つ言える事。
###ネットワークエンジニアはプログラミングできない人が多い
これはマジです。
めちゃくちゃ最先端で世界的に注目を集めてるプロジェクトの人たちですらプログラミングが出来ない人が散見されます。
（逆に現状のネットワークエンジニアに所謂プログラミングは求められません）
だから今自分がいるような運用業務チームレベルでは、Tera Termのマクロができるだけで重宝されます。
Tera Termのマクロは単純なスクリプト言語で、
プログラマーなら一番最初に練習するレベルのもの。
こんな感じです。
http://ttm.jimba.ddo.jp/adiary.cgi/teraterm/0148

ただ今までは簡単な処理ばっかりで、あんまりちゃんと書いたことなかったんですが、今日同僚からこのサイトを教えて貰いました。
このサイトを読んでると、Tera Termマクロでもなかなかの事ができるんだな～と社会人13年目にして感慨深いです。

###ただ、今後プログラミングができないネットワークエンジニアは居場所がなくなる説
を割とマジで思っています。
理由はSDNとIoTですね。
プログラム書いている人目線でIoTを切ると、
「プログラミングが出来る人が物理レイヤーを操作できる世界」
の到来です。
なので、今まで機械工学や所謂本物のエンジニア（プログラマーをエンジニアと呼ぶ今の風潮止めましょう）の人たちもプログラミングを覚えないといけない世界がやってきます。

###WEBエンジニアのキャリア形成にCCNA
またコロナの影響でプログラミングを覚える人が増え、WEB開発界隈の競争は今後激化すると思います。
ITスタートアップへの投資も鈍ってきましたし、エンジニアを高収入で雇える仕事の絶対数は一時的に減ると思いますし、今までの技術に執着していてもジリ貧です。
そんなWEB界隈の人へお勧めがIoTエンジニアへの転職です。
どうやるか？
CCNA覚えれば良いです。手始めに。
OSI参照モデルから勉強しましょう :)
【RSpec】変数を使いたい時はlet

#はじめに
RSpecのテストで変数を書くと、rubocopに怒られた。のでその対処について。

#怒られ方

>Defining constants inside of specs can cause spurious behavior. It is almost always preferable to use `let` statements, anonymous class/module definitions, or ? stub_const (convention:Airbnb/SpecConstantAssignment)

letを使えって言われている事はわかる。。

> spec の中で定数を定義すると、スプリアスな動作を引き起こす可能性があります。ほとんどの場合、let文、匿名のクラス/モジュール定義、またはstub_const を使用することが望ましいです。

うんうん、スプリアスね。

google翻訳だと、`spurious behavior`で、偽りの行動。でした。
要は意図しない変数化になるで、という事かな。

#letを使う
もともとは、RSpecの中で、このように書いていた。

```ruby
  API_KEY = Rails.application.credentials.api[:API_KEY]
```

これを、最終的に

```ruby
  let(:api_key) { Rails.application.credentials.api[:API_KEY] }
```

この様に変えました。
呼び出すときは、

```ruby
 headers = {
    'Authorization': "Bearer #{api_key}",
 }
```
この様に普通に変数として呼び出せます。

#letを使うことのメリット
- テストに使う変数をletでコードの上の方で記述してしまうことで、itの中の検証部分が見やすく、わかりやすくなる
- もし、beforeの中に普通に変数として定義すると、テストケースの中で使われない変数があった場合も、生成されてしまうが、letであれば、遅延評価で必要なときだけ呼ばれる。

などなど、、
詳しいことはすべてこちらから教えて頂きました。
[RSpecのletを使うのはどんなときか？（翻訳）](https://qiita.com/jnchito/items/cdd9eef2ed193267c651)



###終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
Seed Fu の API を使用する際の Tips


Seed Fu の rake タスクではなく、API を使用する際のアレコレです。

# Seed Fu の インストールや基本的な使用方法

[公式ドキュメント](https://github.com/mbleigh/seed-fu)を参照。

# Tip1: `rake db:seed` された場合にも Seed Fu を実行させる。

`db/seeds.rb` に Seed Fu を使うように書いておくと、 間違って `rake db:seed` された場合にも Seed Fu が実行されるため便利だと思います。
その場合、以下の2点に気をつける必要があります。

## 1. fixture_path を設定

README には Fixtureファイルを探すパスのデフォルトは `db/fixtures` と `db/fixtures/#{Rails.env}` と記載されていますが、
これはrakeタスクを実行した場合のデフォルトです。
`SeedFu.seed` APIを使用する場合のデフォルトは `db/fixtures` です。
そのため、Rails.envに応じたFixtureファイルを使い分けたい場合には fixture_path の設定が必要です。

## 2. FILTER を変換

環境変数を用いて `FILTER=users,articles` のように適用するファイルを指定できますが、この環境変数の値をそのままAPIに渡しても期待通りに動きません。
正規表現に変換する必要があります。

---

以上の2点を踏まえた具体的な記述例は以下の通りです。

```ruby:db/seeds.rb
paths = [Rails.root.join("db/fixtures"), Rails.root.join("db/fixtures/#{Rails.env}")]

filters = ENV["FILTER"].presence && /#{ENV["FILTER"].gsub(/,/, "|")}/

SeedFu.seed(paths, filters)
```

参考: https://github.com/mbleigh/seed-fu/blob/v2.3.9/lib/tasks/seed_fu.rake#L27

# Tip2: FILTER の指定はファイル名の一部でOK

環境変数 `FILTER` で指定した文字列は正規表現に変換されて、ファイル名とマッチするか判定されます。
そのため、ファイル名の一部だけを指定しても部分一致するファイルが実行されます。
ファイル名の順番で実行されるため、ファイル名の先頭に連番をつけているケースが少なくないと思いますが、そのようなケースでは例えば `FILTER=01,02` のような指定ができます。

前述の通り、正規表現として使用されるので、頑張れば除外するファイル名を指定することもできます。`FILTER='^(?!users)'` で「 `users` で始まるファイル以外」ということになります。

# Tip3: Fixture ファイルの中で FactoryBot を使用する。

Seed Fu でも FactoryBot を使用できます。
しかし require や include が必要な場合には少し気をつける必要があります。
Fixtureファイルは API を呼び出した場所と同じコンテキストで実行されるため、require や include もそこで行う必要があります。

```ruby:db/seeds.rb
require "factory_bot_rails"

include FactoryBot::Syntax::Methods

SeedFu.seed
```

これで Fixtureファイル内でもFactoryBotのメソッドを使用できます。(include しなくても `FactoryBot.attributes_for` のような形式であれば使用できます)

```ruby:db/fixtures/users.rb
User.seed(
  :id,
  attributes_for(:user, id: 1, name: "Alice"),
  attributes_for(:user, id: 2, name: "Bob")
)
```

# Tip4: 共通で使用するメソッドを作る

前述の FactoryBot と同様ですが、API を呼び出した場所にメソッドを定義したり、別ファイルに書いてそれを require すると、各Fixtureファイルで使用することができます。

```ruby:db/utils.rb
def triple(num)
  num * 3
end
```

```ruby:db/seeds.rb
require_relative "./utils"

def double(num)
  num * 2
end

SeedFu.seed
```

```ruby:db/fixtures/users.rb
User.seed(
  :id,
  { :user, id: 1, num1: double(2), num2: triple(3) }
)
```

# Tip5: シードデータのプリントを抑制する。

`rake db:seed_fu` を実行すると、標準では以下のような内容が出力されます。

```sh
== Seed from /path/to/app/db/fixtures/users.rb
 - User {:id=>1, :name=>"Alice"}
 - User {:id=>2, :name=>"Bob"}
```

データのプリントを抑制したい場合、 `SeedFu.quiet = true` をセットするとファイル名まで出力されなくなります。
そこで各Fixtureファイルでファイル名を出力するようにします。
ちなみに、Fixtureファイルは文字列として読み込まれ、evalされます。そのため `puts "== #{__FILE__}"` のように `__FILE__` を使用できません。
代わりに `filename` を使用することができ、 `puts "== Seed from #{filename}"`　と書けば各ファイルの正しいファイル名が出力できます。
ただし `filename` は公式のものではなく、evalされた場所でたまたま見えているローカル変数（メソッド引数）です。そのため将来のアップデート等で参照できなくなる可能性があります。

https://github.com/mbleigh/seed-fu/blob/v2.3.9/lib/seed-fu/runner.rb#L46
DBの正規化

* 正規化　更新や、追加、削除がしやすいようにデータベースを設計する。無駄な繰り返しを避ける。
* ☆ この従属関係（あるaカラムの値が決まった時、bカラムが一位に定まるならbはaに従属している）を表してた図から正規化できる。矢印のでどころと矢印先のカラムをテーブルに分ける。
	* 仕入れ先、商品、入荷日、入荷数
	* 仕入れ先、住所、代表者名
	* 商品、一個あたりの金額、備考
	* 代表者、代表者連絡先
	

![代替テキスト](https://ferret-one.akamaized.net/images/5c4001477f0ebd040f010436/original.gif?public=true
)
	* 主キー（primary key）　レコードを一意に特定できる
	* 部分従属　主キーが複数ある場合、主キーの一部の要素だけで決まるカラムを部分従属であるという
	* 推移従属　主キーじゃないものに従属。上の図だと代表者に連絡先が従属している
* 基本的にこの部分従属と推移従属を別テーブルに分ければ正規化の完了
[参考　データベースの正規化](https://oss-db.jp/dojo/dojo_info_04)
	
* インデックス
	* 並べるに近いことをして、DB検索が早くなる。
	*  インデックスを設定しないと
		* 順番に並んでるわけではないので検索に時間がかかる
	* インデックスのでメリット
		* 種類が少ない、レコード数が少ない場合は検索スピードはかわらないし、インデックスをつける計算をする分時間が遅くなる場合もある。
* トランザクション
	* 「ここからここまでワンセット」な処理単位。
	* 分割できない一連の流れ。
 *振替を例にとる*
・Aの口座から-5万円して（update文）
・ Bの口座に+5万円する（update文）
これらの処理は、一つが成功して、一つが失敗したらまずい。なので二つとも成功した時だけ、確定（コミット）をする。
どちらかでエラーが発生したときは処理をする前にもどる。（ロールバック）
mac miniにlinux mintをインストール

手元にDVDも8GBのUSBもなかったので、SDカードでできるかやってみた。

# インストール先PCスペック
mac mini(mid 2010)

# インストールしたOS
linux mint(Cinnamon)

# インストール手順
## 1. それぞれのisoをダウンロード
[ダウンロードlink](https://linuxmint.com/download.php)

## 2. SDカードにisoをマウント
```
$ diskutil list
→マウント先を確認。ここでは「/dev/disk2」
$ diskutil eraseDisk MS-DOS MINT /dev/disk2
$ diskutil unmountDisk /dev/disk2 
$ cd ~/Downloads
$ sudo dd if=linuxmint-19.3-cinnamon-64bit.iso of=/dev/rdisk2 bs=32m
$ 
```

## 3. mac miniにインストール
SDカードを挿して、optionを押しながらmacの電源起動。
起動ディスク選択画面となり、なぜかSDカードが2つ現れた。
うち1つを選択。
start linux mintを選択。
すぐに立ち上がる。デスクトップにあるinstall linux mintのアイコンを押すと、インストールが開始される。
RStan導入について

RStan導入について
===
## いんとろ
「時系列分析と状態空間モデルの基礎 RとStanで学ぶ理論と実装」の第6部3章で使用するRStanの導入について備忘録(自分用)。

> 07May'20: Written

## 導入環境
OS: Mojave (version; 10.14.6)
R version: 3.6.3 (2020-02-29)
R Studio version: 1.2.5033

## 手順
1. C++コンパイラの導入
2. 古いバージョンのRStanを消去
3. RStanパッケージをダウンロード
4. 動作確認

## C++コンパイラの導入
Stanの実行にC++のコンパイラが必要なので適宜入れる。
CRANのサイトからclang-7.0.0.pkgをダウンロードしてインストールした。
https://cran.r-project.org/bin/macosx/tools/

## 古いバージョンのRStanを消去
古いバージョンのRStanを消した。
RStudioのコンソールから、以下のコマンドを実行した。

```gherkin
remove.packages("rstan")
if (file.exists(".RData")) file.remove(".RData")
```

## RStanパッケージをダウンロード
以下のコマンドを実行した。

```gherkin
install.packages("rstan", repos = "https://cloud.r-project.org/", dependencies = TRUE)
```
https://cloud.r-project.org/


## 動作確認
動作確認のため二項分布を描いてみた。

```gherkin
library(rstan)

x <- rbinom(n = 100, size = 20, prob = 0.8)
binomial_test <- "
      data {
      int N;
      int n;
      int x[n];
  }
  parameters {
      real<lower=0, upper=1> p;
  }
  model {
      x ~ binomial(N, p);
  } "
d <- list(N = 20, x = x, n = length(x))
fit <- stan(
      model_code = binomial_test ,
      data= d)

stan_hist(fit)
```

結果は以下。
![](https://i.imgur.com/Msqt0Ct.png)

上手くかけました。



## 参照
・Macでrstanの実行環境を用意する
https://sonnamonyaro.hatenablog.com/entry/2019/11/16/092734

・RStan Getting Started
https://github.com/stan-dev/rstan/wiki/RStan-Getting-Started

・Stanを利用した二項分布のパラメーター推定 二項分布
https://stats.biopapyrus.jp/bayesian-statistics/stan/binomial.html
[Node][npm] sudoなしでMacOS/Linux に npm packeage をインストール



# Install `npm` packages globally without sudo on macOS and Linux

`npm` installs packages locally within your projects by default. You can also install packages globally (e.g. `npm install -g <package>`) (useful for command-line apps). However the downside of this is that you need to be root (or use `sudo`) to be able to install globally.

Here is a way to install packages globally for a given user.

###### 1. Create a directory for global packages

```sh
mkdir "${HOME}/.npm-packages"
```

###### 2. Tell `npm` where to store globally installed packages

```sh
npm config set prefix "${HOME}/.npm-packages"
```

###### 3. Ensure `npm` will find installed binaries and man pages

Add the following to your `.bashrc`/`.zshrc`:

```sh
NPM_PACKAGES="${HOME}/.npm-packages"

export PATH="$PATH:$NPM_PACKAGES/bin"

# Preserve MANPATH if you already defined it somewhere in your config.
# Otherwise, fall back to `manpath` so we can inherit from `/etc/manpath`.
export MANPATH="${MANPATH-$(manpath)}:$NPM_PACKAGES/share/man"
```

If you're using `fish`, add the following to `~/.config/fish/config.fish`:

```sh
set NPM_PACKAGES "$HOME/.npm-packages"

set PATH $NPM_PACKAGES/bin $PATH

set MANPATH $NPM_PACKAGES/share/man $MANPATH  
```

If you have erased your MANPATH by mistake, you can restore it by running `set -Ux MANPATH (manpath -g) $MANPATH` once. Do not put this command in your `config.fish`.

---

Check out [`npm-g_nosudo`](https://github.com/glenpike/npm-g_nosudo) for doing the above steps automagically

---

NOTE: If you are running macOS, the `.bashrc` file may not yet exist, and the terminal will be obtaining its environment parameters from another file, such as `.profile` or `.bash_profile`. These files also reside in the user's home folder. In this case, simply adding the following line to them will instruct Terminal to also load the `.bashrc` file:

```sh
source ~/.bashrc
```

---

See also: `npm`'s documentation on
["Fixing `npm` permissions"](https://docs.npmjs.com/getting-started/fixing-npm-permissions).


# 原文

https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md
Linuxのアーカイブと圧縮（tar と gzip）


## アーカイブと圧縮
複数の`ファイルやディレクトリ`をまとめた`ファイル`のことを**アーカイブ**（書庫）と呼ぶ。

また、アーカイブするときに`アーカイブファイルのサイズを小さくする`ことができれば、ファイルを転送・保存するときのデータ量を抑えることができる。

この小さくする処理を**圧縮**と呼ぶ。

## ファイルをアーカイブする
ファイルをアーカイブするためにLinuxでは`tarコマンド`を使用する。

###↓練習用ファイルの作成

```
$ mkdir dir1
$ touch dir1/file-{1..5}.txt
```
###↓確認

```
$ ls dir1
file-1.txt file-2.txt file-3.txt file-4.txt file-5.txt
```

##アーカイブファイルの作成

###↓書式
`c`はcreateの意味で、新しくアーカイブファイルを作成する時に指定する。
`f`はfileの意味で、新しく作成する`アーカイブファイル名`を指定するために必ず必要

```.sh
tar cf <アーカイブファイル> <アーカーブのファイルパス>
```

###↓dir1ディレクトリをアーカイブする

```.sh
$ tar cf dir1.tar dir
```
※tarコマンドは歴史的経緯から引数に`-`を付けない。ただし`-`を付けても同じ挙動になる。

##アーカイブファイルの内容確認

###↓書式
`t`はlistの意味。
`f`はfileの意味で、新しく作成する`アーカイブファイル名`を指定するために必ず必要

```.sh
tar tf <アーカイブファイル> <アーカーブのファイルパス>
```

###↓内容を確認

```.sh
$ tar tf dir1.tar
dir1/
dir1/file-1.txt
dir1/file-2.txt
dir1/file-3.txt
dir1/file-4.txt

```

##アーカイブの展開
アーカイブファイルを展開して元のファイルやディレクトリを取り出すには、`x`オプションを利用する。

###書式
`x`はextract（抜く、抜き取る）のxを表す。

```.sh
tar xf <アーカイブファイル>
```

###↓アーカイブを展開する
アーカイブから元のファイルが復元できるかどうか確かめるために、dir1ディレクトリをいったん削除してからアーカイブを展開する。

```
$ ls
dir1  dir1.tar

$ rm -rf dir1          ←元のディレクトリ削除
$ tar xf dir1.tar      ←アーカイブを展開
$ ls dir1              ←確認
file-1.txt  file-2.txt  file-3.txt  file-4.txt
```

##ファイルを圧縮する
###gxipコマンド
`gzip`はファイルの圧縮・展開を行うためのコマンドである。
`gzip`で圧縮したファイルには慣習として、`.gz`という拡張子を付ける。

####書式

```.sh
$ gzip <圧縮元ファイル>
```

下記はテスト用として、`psコマンド`でプロセス一覧を表示した結果を`ps.txt`というファイルに出力リダイレクトして作成したものである。
`ps.txt`のファイルサイズは`約9.6キロバイト`ある。

```
$ ps aux > ps.txt
$ ls -lh
-rw-rw-r--. 1 vagrant vagrant  9.6K May  7 19:07 ps.txt
```
####gzipコマンドで圧縮してみる
```
$ gzip ps.txt
$ ls -lh
-rw-rw-r--. 1 vagrant vagrant 2.3K May  7 19:07 ps.txt.gz
```
ご覧の通り約2.3キロバイトに圧縮された。
また、`ps.txt.gz`という（圧縮された）新しいファイルが残り、元の`ps.txt`というファイルが**削除される**。

####圧縮ファイルを展開してみる。
圧縮ファイルを展開するためには、`-dオプション`を指定する必要がある。

```
$ gzip -d ps.txt.gz
$ ls -lh
-rw-rw-r--. 1 vagrant vagrant 9.6K May  7 19:07 ps.txt
```

この時も、圧縮時と同様に展開されたファイルのみが残り、圧縮ファイルは削除される

###その他のファイルを圧縮するコマンド
gzipコマンド以外にもファイルを圧縮するコマンドがある。

####bzip2コマンド
特徴として、**gzip形式よりも圧縮率が高く、データ量をより小さくできる。**ただし、圧縮・展開にかかる時間はgzipより長いため、`時間よりファイルサイズを重視`する場合に使われることが多い。
####zipコマンド
zipはtarやgzipと違ってあーカーブと圧縮を同時に行う。なので、**複数のファイルやディレクトリをまとめて一つのファイルに圧縮できる**。
なお、`zipコマンド`は標準ではインストールされていないので、使用するにはインストールする必要がある。
##参考
新しいLinuxの教科書
【C#】var dynamic objectについて簡単にまとめてみた

#C#の型#
C#をよく書く方なら当然のことだと思いますがC#の型は大きく分けて3種類あります

- 参照型
- 値型
- どちらでもない型

###参照型###
参照型はオブジェクトではなくオブジェクトの参照のみ持った型です

- クラス型
    - object
    - dynamic
    - string
    - 配列
    - デリゲート型
    など
- インターフェイス型 など
###値型###
実際にオブジェクトのすべての値を持つ型です

- 構造体型
    - bool
    - char
    - int
    - double
    - decimal など
- 列挙型 など

###どちらでもない型###
ポインタ型ですobject型と相互変換することができない型であり、参照型にも値型にも含まれない

#varはどこに行ったのか?#
varというものがC#にはあります
題でもvar dynamic型 object型について簡単にまとめてみたなんて書いたあるのに、出てないなんてどういうことだ！
と思う方がいると思いますが
**varは型ではありません**
varは型推論を行うキーワードです、なので型としての**実態は存在しません**、
なのでIL上にもvarなんて型はありません。
#dynamic型について#
 dynamic型は動的に型を付ける型です
つまり、コンパイル時に型情報を確認しないのです
そのため思った動きをしなかったりするので
基本的には**使わないことをおすすめします**
では、なぜdynamic型があるかというと Python や Ruby のような動的型付けをする言語を.NET Framework上で動かすことなどを目的に追加されました。
#object型#
object型はすべてのクラスの継承元となっています。
そのためobject型はすべての型でキャストできます
また、自分で作った型もすべて指定しなければobject型の継承になります。
なので.GetTypeメソッドなどはすべての型で使えるのですね。
#最後に#
var、dynamic objectについてまとめてみました
似ている型に感じますが全然違う型であります、特にdynamic型はむやみに使うことを避けましょう
Vuexをめちゃくちゃざっくり理解する

Vue.jsの概要はふんわり理解している前提です。

# 概念図
![概念図](https://vuex.vuejs.org/vuex.png)

# Vuexの役割
ストアの状態を管理する。
コアコンセプト（State, Getters, Mutations, Actions, Modules）ごとに定義する。

# ストアって何
コンポーネントをまたいで共通に使用するデータ。
Vuexのストアはリアクティブに扱える。

# Vuexを使うコンポーネントの役割
Vuexで状態管理されているデータを参照したり、状態を変更するイベントの発火を定義する。
コンポーネントから直接状態を変更したり処理したりはできない。
（一応機能としてはできるけど設計的に好ましくはないから極力使わない。）

# コアコンセプトのざっくりとした役割
|コアコンセプト|役割|
|:-:|:--|
|**State**|Vuexで状態管理するデータの定義|
|**Getters**|State用の算出プロパティ|
|**Mutations**|Stateの状態変更の定義|
|**Actions**|Mutationsを発火させるイベントの定義|
|**Modules**|役割やモジュールごとに分割して定義する機能|

# コアコンセプトのもう少し詳しい役割
## State
Vuexで状態管理するデータの定義。
一つのコンポーネント内で完結するデータであればわざわざVuexを使う必要はない。
例えばショッピングサイトのカートの中身とか。

## Getters
Stateの状態によって毎回計算させるようなデータがある時に役立つ。
コンポーネント内でいうところの算出プロパティみたいなもの。
例えばToDoリストの未完了項目を取得するとか。

## Mutations
Stateの状態変更の定義。
Stateの状態変更はmutationsで定義されたものでしかできない。
例えばToDoリストに追加や削除がある場合とか。

## Actions
Mutationsを発火させるイベント処理の定義。
コンポーネントからStateの状態を変更するときはここから発火させる。
コンポーネント内でいうところのmethodsに近い。
StateにかかわりのあるイベントはmethodsではなくActionsに定義する。
一つのコンポーネント内で完結するイベントの場合はStateに定義されたデータを使ってないはず。

## Modules
Storeは基本的に「./store/index.js」で定義する。
State、Mutationsなどをそれぞれ別ファイルに分割して管理することができる。
「state.js」「mutations.js」などを「index.js」に読み込ませて使う。
また、State～Actionsまでをセットにして、機能ごとに分割することもできる。
「./store/moduleA/index.js」「./store/moduleA/index.js」などを「./store/index.js」に読み込ませて使う。
それぞれの機能ごとに名前空間を独立させたりもできる。

# 補足
## Vuexを使わなくても状態管理って実現できるのでは？
できるけどpropsの定義を常に気にしなきゃいけなかったり、管理が複雑になりやすい。
ごく小規模ならVuexを使わない方が管理しやすいかもしれない。
Vuexを使わずに[ストアパターン](https://jp.vuejs.org/v2/guide/state-management.html#%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E7%8A%B6%E6%85%8B%E7%AE%A1%E7%90%86%E3%82%92%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8B)を自分で実装するのも一つの手。

## コンポーネントからMutationsを発火させればActionsいらないのでは？
Actionsに定義した方が構成がわかりやすいだけで、使わないと動作しないとかではない。
Mutationsでイベント処理も一緒にやってもいいけど、分けた方がわかりやすい。
シンプルな機能の場合、わざわざActionsに定義すると冗長になる場合もあるから、公式ガイドでも使用を許可してる。
ただし、非同期処理はMutationsでは使えないからActionsを使う。

# 参考
[Vuex とは何か？ | Vuex](https://vuex.vuejs.org/ja/)

[状態管理 — Vue.js](https://jp.vuejs.org/v2/guide/state-management.html)

[VuexのMutationとActionの切り分け - Qiita](https://qiita.com/frost_star/items/4620957fce888150e4cc)

[改めて学び直すVuex - Qiita](https://qiita.com/nasum/items/d17c0a628e6c32616b85)

[Vuexのアクションを理解する](https://junpeko.com/vuex-actions/)
Web Speech APIでSSMLのテスト

Web Speech API で SSML を含むテキストの読み上げを試みました。しかし現状ではサポートされていないようです。

"test" を「ハロー」と読み上げる例です。（うまくいきません）

<p class="codepen" data-height="300" data-theme-id="light" data-default-tab="result" data-user="7shi" data-slug-hash="WNQMggp" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Web Speech APIでSSMLのテスト ">
  <span>See the Pen <a href="https://codepen.io/7shi/pen/WNQMggp">
  Web Speech APIでSSMLのテスト </a> by 七誌 (<a href="https://codepen.io/7shi">@7shi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

↑ エラーになる場合は一度 [CodePen](https://codepen.io/) を開いてから、この記事をリロードしてください。

以下の記事のサンプルを改造しました。

* [Web Speech API で読み上げ位置を取得](https://qiita.com/7shi/items/43452dcd34e57100fc3c)

# Chromium 系

Chrome と Edge では次の挙動を示しました。

* ローカルエンジン (Windows): タグが無視され「テスト」と読み上げ
* オンラインエンジン: タグもテキストとして読み上げ

オンラインエンジンはブラウザの開発元のサービスに紐付いており、日本語は以下の通りです。

* Chrome: Google 日本語
* Edge: Microsoft Nanami Online (Natural) - Japanese (Japan)

※ もしかして Nanami は[窓辺ななみ](https://ja.wikipedia.org/wiki/%E7%AA%93%E8%BE%BA%E3%81%AA%E3%81%AA%E3%81%BF)と関係があるのでしょうか？（アニメ声ではないですが）

# Firefox

Firefox ではオンラインエンジンはなく、ローカルエンジンのみです。

* ローカルエンジン (Windows): タグもテキストとして読み上げ

同じローカルエンジンを使用しても Chromium 系と挙動が違います。

# SAPI

Windows ローカルのエンジンを SAPI で使用すると、SSML が認識され「ハロー」と読み上げます。

```text
wintts -i test.ssml
```

挙動が違うことから、ブラウザはローカルエンジンに SSML を含むテキストを直接渡しているわけではないようです。

使用している wintts は以下の記事で作成したコマンドです。

* [PythonでWindows 10の音声合成を使用する](https://qiita.com/7shi/items/a5fb03406e0626b4f138)

SAPI での SSML の使用については以下の記事を参照してください。

* [SAPIで発音を指定する](https://qiita.com/7shi/items/51017b4b268f66e11c42)
UnityとOculusIntegrationをアプデしたらOculus RiftにGame画面が映らなくなった

# 概要

Unity2018.2.20f1 → Unity2018.4.22f1 に、OculusIntegrationをバージョン不明 → 16.0 にアップデートした。すると Editor でゲームを実行しても OculusRift に Game 画面が映らなくなってしまった。(今までは動いてた)また、Oculus Go 用にビルドして `adb install` しても平面アプリケーションとして実行されてしまった。

Oculus Integration のアプデにミスってしまったのかと思ったが、意外とシンプルな問題だったのでメモ。

# 検証

下記コードで検証したところ、そもそもVRが有効化されてないように見えた。

```csharp
public class CheckEnableVr : MonoBehaviour
{
    private void Start()
    {
        Debug.Log("VRが有効になってるのかの検証をする");
        Debug.Log(XRSettings.loadedDeviceName); // ""
        Debug.Log(XRDevice.isPresent); // false
        Debug.Log(XRSettings.enabled); // false
    }
}
```

# 解決策

ふと Console を見たら、「Package Manager から Oculus Desktop を入れろ」と書いてあったので、Package Manager から `Oculus Android` と `Oculus Desktop` を導入したら Oculus Rift と Oculus Go で正常に動作した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44388/11aab49c-59e2-567c-2453-7de6d281751d.png)

どこかのバージョンから Unity (もしくは OculusIntegration) に組み込まれなくなったのだろうか。
(ソースが見つけられなかったので、知ってる方いらっしゃったらご教示頂けますと幸いです)

# まとめ

OculusIntegration のアプデ作業で多くのエラーが出て対処していたため、本事象も複雑な問題では無いかと捉えてしまい余分な時間を取ってしまったが、無事に解決出来てよかった。
Oculus 開発はもう一度公式ドキュメント見ておいたほうが良さそうだと思った。
pfSenseでパッケージインストールができなかった件

#事象

ある環境でpfsenseを設定後、追加パッケージをインストールしようとしたが失敗

なんかリポジトリのpkg.pfsense.orgが名前解決できない
コマンドラインでnslookupを実行するも解決できない

他端末でpkg.pfsense.orgの名前解決を試みたが、できなかった

ネームサーバかなんかが一時的にしんでるのかな？と思い、1日以上放置するも解決せず

#原因
SRVレコードだと・・・

```
nslookup
> set type=srv
>  _https._tcp.pkg.pfsense.org
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
_https._tcp.pkg.pfsense.org     service = 10 10 443 files01.netgate.com.
_https._tcp.pkg.pfsense.org     service = 10 10 443 files00.netgate.com.

Authoritative answers can be found from:
```


pkg.pfsense.orgの実際のAレコード解決先はfiles00.netgate.comとfiles01.netgate.comらしい
どうも今回の環境だと参照しているdnsサーバでsrvレコードが正常に解決できないっぽい

#解決方法
dnsサーバの設定等で解決できるようにするのが一番なんだろうけど、今回環境のdnsサーバはこちらでいじれるものではなかったし
めんどくせーので/usr/local/share/pfSense/pkg/repos/pfSense-repo.confを直書き換えてしまう

```
FreeBSD: { enabled: no }

pfSense-core: {
  url: "pkg+https://pkg.pfsense.org/pfSense_v2_4_5_amd64-core",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/local/share/pfSense/keys/pkg",
  enabled: yes
}

pfSense: {
  url: "pkg+https://pkg.pfsense.org/pfSense_v2_4_5_amd64-pfSense_v2_4_5",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/local/share/pfSense/keys/pkg",
  enabled: yes
}
```

↓

```
FreeBSD: { enabled: no }

pfSense-core: {
  url: "pkg+https://files00.netgate.com/pfSense_v2_4_5_amd64-core",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/local/share/pfSense/keys/pkg",
  enabled: yes
}

pfSense: {
  url: "pkg+https://files00.netgate.com/pfSense_v2_4_5_amd64-pfSense_v2_4_5",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/local/share/pfSense/keys/pkg",
  enabled: yes
}
```


URLの処を下記通り修正
pkg.pfsense.org
↓
files00.netgate.com

正常にパッケージがインストールできましたとさ
ドメインを跨ぐJavaScriptでのCookie設定にはpathの指定をお忘れなく

# 結論
JavaScriptを使ってフロントエンドからCookieを設定する場合には、pathの指定が必須である。
そうしないと、ブラウザによって動作がまちまちになってしまう。

# 概要
ドメインを跨いでCookieを設定する要件で開発を行っていた。
`login.example.com` でCookieでフラグを設定して、 `pay.example.com` で設定したCookieを読み出したいという仕様。



`*.example.com` ドメイン以下でCookieを呼べるようにしたいので、
下記URLで、`jquery-cookie` を使ってCookieを設定。

login.example.com/member/sign_up.php

```html
<script>
    function setLpFlagCookie() {
        $.cookie('newUserFlag', 1, {domain:"example.com"});
    }
</script>
```

# 症状
`pay.example.com` にアクセスした際に、
FirefoxではCookieが送信されるが、ChromeではCookieが読み出されない。

Firefoxのブラウザ開発者ツールを見るとCookieが設定されているが、ChromeではCookieは無いものとして扱われる。

# 原因

Pathの指定をしていないので、Chromeでは `member/` がPathとして設定されてしまう。
言い換えれば、`*.example.com/member/*`でのみCookieが有効と設定される。

Pathを指定しない場合はデフォルトで`/` が設定されるだろうと思っていた。

# 解決策
Cookieを設定しているところで、Pathに"/"を指定することでルートディレクトリ以下を指定する。

```html
<script>
    function setLpFlagCookie() {
        // pathの指定を追加！
        $.cookie('newUserFlag', 1, {domain:"example.com", path: '/'});
    }
</script>
```


# 参考
ブラウザごとの挙動については、ここのブログによくまとまっている。
https://please-sleep.cou929.nu/cookie-path-behavior-difference-of-browsers.html
PythonでLiNGAM

# PythonでLiNGAM


> 統計的因果探索で利用されるモデルの1つのLiNGAMについて、Pythonでの使用法のメモ(自分用)。
> 今回はパッケージ化されているものを使用。

> 07May'20: Written

 
## はじめに
現在、因果探索アプローチに用いられるLiNGAMはRおよびPythonで実装されている。
> いろいろなLiNGAMモデルのR and/or Python
> https://sites.google.com/site/sshimizu06/lingam

今回はその中でもPythonを使用したものを動作確認までみていく。

## 導入環境
OS: Mojave (version; 10.14.6)
Python: 3.7.6
JupyterLab: 1.2.6

## 手順
1. パッケージのインストール
2. Graphvizの整備
3. 動作確認

## パッケージのインストール
Terminalでインストールは以下。

```
$ pip install lingam
```

## Graphvizの整備
このままJupyterLabを起動して実行しようとしても、因果グラフの描画のときにErrorを起こしてしまう。
そこでそれを回避するために、描画に使用するGraphvizをアンイストールし、その後python-で再インストールする。
これによりJupyterLabでも描画が可能になる。

Terminalで以下。

```
$ conda remove graphviz
$ conda install python-graphviz
```

## 動作確認
今回はチュートリアルを用いてみていく。

### GitHubからファイルのダウンロード
以下のサイトの「Clone or Download」からローカルに落とす。
https://github.com/cdt15/lingam


### JupyterLab起動
どんな方法でもいいが以下のように実行した。

Terminalで以下。

```
$ jupyter lab
```

### 「examples」からテキトーにUpload
落としたファイルの中の「examples」から、今回は「utils.ipynb」を使用。
なので、JupyterLab上にこれをUploadする。

### 動かしてみる
基本的には読み込んだノートブックをCellごとにRunしていき動作確認する。

## 参照
- LiNGAMのGitHub
https://github.com/cdt15/lingam
- LiNGAMのPythonパッケージでのTutrial and API reference
https://lingam.readthedocs.io/en/latest/index.html
- LiNGAMのプロジェクトサイト
https://sites.google.com/site/sshimizu06/lingam
JavaScriptでiPhone風電卓を作ってみた

JavaScriptを学習したのでアウトプットとしてiPhone風の簡易電卓を作成してみました。
メンターに指導してもらいながら、制作期間は約1週間ほどかかりました。
改良の余地はあると思いますが、公開します。
スマホで見るとiPhone風ではなくなっていますがご了承くださいませ。

#機能
* iPhone8の電卓を模倣
* 計算結果が10桁以上の場合、エラー表示
* ACで数字全てクリア、Cで入力中の数字クリア



入力桁数はいまのところ制限がかかっていません。
今後、余力があれば修正予定です。
(2020/05/09 入力桁数制限追加。やや変な部分もありますがご了承ください。)



#リンク
* ソースコード：
[GitHub](https://github.com/N0S0/iPhoneCalc.git)
* ここでお試しできます：
[iPhone風簡易電卓](https://N0S0.github.io/iPhoneCalc/)
wxPythonをUbuntu20.04 on raspberry pi 4でビルド


# 概要
ubuntu 20.04 on raspberry pi 4でとあるPythonアプリを動かそうとしたらwxが無いぞと怒られました。wxとは何だと思い調べるとwxPythonのことです。そこでwxPythonをインストールしました。

# やったこと

pip本体は対応するパッケージが存在せず、wxPython本家サイトのソースコードからのビルドもうまく行かずでした。

[このサイト](https://krhb.hatenablog.com/entry/2019/04/30/234953#ImportError-No-module-named-wx%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC)で紹介されている方法が参考になりました。

紹介されている手法

```
$ pip install -U \
    -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-16.04 \
    wxPython
```

や、ubuntuバージョンを変えた

```
$ pip install -U \
    -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 \
    wxPython
```

では途中でエラーでした。が、ここで使われているソースコードhttps://files.pythonhosted.org/packages/cb/4f/1e21d3c079c973ba862a18f3be73c2bbe2e6bc25c96d94df605b5cbb494d/wxPython-4.1.0.tar.gz
を自分でビルドしたら成功しました。

```
$ wget https://files.pythonhosted.org/packages/cb/4f/1e21d3c079c973ba862a18f3be73c2bbe2e6bc25c96d94df605b5cbb494d/wxPython-4.1.0.tar.gz
$ tar xvf wxPython-4.1.0.tar.gz
$ cd wxPython-4.1.0
$ python build.py etg sip build build_py
$ python build bdist_wheel
$ pip install dist/wxPython-4.1.1a1-cp36-cp36m-linux_aarch64.whl
$ python -c "import wx;print(wx.__version__)"
4.1.1a1
```
DIGAに音楽ファイルを入れてYAS-408で聴く

#関連機材
YAMAHA MusicCast BAR 400 YAS-408
Panasonic DIGA DMR-BRX2000
Windows10 PC

#サマリ
YAMAHAのサウンドバーYAS-408を購入。
本機はNASの音楽ファイル再生に対応しており、
これを機にNASも買おうと思ったが、元々持っていたDIGAで事足りた。

主な作業は、
・DIGAのNAS機能を有効化(取扱説明書通りに実施)
・Windows10PCから音楽ファイルを配置
・YAMAHAのスマホアプリMusicCastで音楽ファイルを選択して再生
だが、Windows10PCからのDIGAアクセス時につまづいたのでその記録。

対策をまとめると下記2点
①WindowsのSMB1.0を有効化　★1 参照
※SMB1.0は脆弱性を持っているので自己責任で。
②ネットワークドライブにDIGAを追加 ★2 参照


#つまづきポイント詳細
DIGA取扱説明書の「パソコンから本機にデータを保存する」通りに進めたが、
ファイルブラウザで"ネットワーク"を表示してもコンピューターの欄にDIGAが出てこない。

うちのDIGAが古いのが原因と思われるが、
DIGAのファイル共有プロトコルはSMB（Server Message Block)のVer 1.0という最も古いバージョンのみ対応している様子。
SMB1.0はWindows10 では一定の条件で無効化されてしまうので有効化する。

####WindowsのSMB1.0有効化 ★1
[プログラムの追加と削除]
↓
[プログラムと機能]
↓
[Windowsの機能の有効化または無効化]
↓
[SMB 1.0/CIFS ファイル共有のサポート]の下の
[SMB 1.0/CIFS クライアント]
のチェックボックスを有効化
↓
PC再起動を促されるので再起動

これでSMB1.0が有効になる。


####ネットワークドライブ にDIGAを追加 ★2
ファイルブラウザからDIGAにアクセスできるように、ネットワークドライブにDIGAのディレクトリを追加する。

[コンピュータ]
↓
[ネットワークドライブの割り当て]
↓
フォルダー を下記フォーマットで指定して、完了
\\\XXX.XXX.XXX.XXX\USER_area
※XXX.XXX.XXX.XXXはDIGAのIPアドレス
↓
DIGAで事前に設定しておいたパスワードを入力

これでWindowsのファイルブラウザ上にDIGAのUSER_areaディレクトリが表示されるようになる。
この配下に、好きなフォルダ構成で音楽ファイルを配置する。

#音声ファイルの再生方法
MusicCastアプリで音楽ファイル指定するだけ。

音声ソース画面で[Server]を選択
↓
[DMR-BRX2000]
↓
[HDD]
↓
[音楽]
を選択すると、USER_areaディレクトリの中身が参照できるので、
音声ファイルを選択すれば再生可能。
javascriptでアルファベットから数値へ変換する

列のアルファベットを数値へ変換したいタイミングがあったので。

```js:アルファベットから数値へ
// アルファベットを数値へ変換(順番に)
function convertToInt(a) {
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return alphabet.indexOf(a) + 1 ;
}
```

2020年5月27日追記：コメントでいただいた記載の方がスマートに感じたので、配列→文字列へ変更
CSSの擬似要素（content）を多言語化する

## はじめに
Railsアプリのi18n(tメソッド)をJSでも使用できるようにしています。
CSSの擬似要素(content)を多言語化したかったのですが、style内でjavascriptは使えないのでどのように実装するか悩みました。

## 解決策
JQueryのappendで擬似要素を追加しました。

```html:test.html
<div class="myclass">質問</div>
```

```javascript:test.js
const required = I18n.t('helpers.required')
$('head').append(`<style>.myclass:before { content: "${required}" }</style>`);
```
Emacsのvue-mode等のpackage-installに失敗する場合

# 環境
Ubuntu: 18.04
Emacs: 25.2

# 状況
Emacsでvue-modeをpackage-installでインストールしようとした時に以下のようなエラーが出てインストールできませんでした。

```
Required package 'mmm-mode-0.5.5' is unavailable.
```

最初は上記のようなメッセージが出ていたので、依存関係の問題かな？と思いましたが、mmm-modeのインストールも含めてpackage-installが動かないことがわかりました。
そしてよくよく見たらEmacsで以下のようなメッセージが出ていました。

```
Failed to verify signature archive-contents.sig:
No public key for 066DAFCB81E42C40 created at 2020-05-05T00:00:00+0000 using RSA
Command output:
gpg: Signature made Wed May  5 00:00:00 2020 UTC
gpg:                using RSA key C433554766D3DDC64221BFAA066DAFCB81E42C40
gpg: Can't check signature: No public key
```

どうやらGNU ELPA package manager用のGPG keysが無い？古い？ようです。

# 対処方法
よって、以下のコマンドでインポートを試みます。
※ オプションは--receive-keysでも--search-keysでも似たような動きをしました。

```bash
$ gpg --homedir ~/.emacs.d/elpa/gnupg/ --receive-keys 066DAFCB81E42C40
gpg: error searching keyserver: Server indicated a failure
gpg: keyserver search failed: Server indicated a failure
```

うーん、失敗しました。Key Serverが見つかってなさそうなので、指定して実行してみます。

```bash
$ gpg --keyserver hkp://keyserver.ubuntu.com:80 --homedir ~/.emacs.d/elpa/gnupg/ --receive-keys 066DAFCB81E42C40
gpg: data source: http://162.213.33.9:80
(1)     GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org>
          3072 bit RSA key 066DAFCB81E42C40, created: 2019-04-23
Keys 1-1 of 1 for "066DAFCB81E42C40".  Enter number(s), N)ext, or Q)uit > 1
gpg: key 066DAFCB81E42C40: public key "GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
```

インポートできた模様です。
もう一度package-installしたらうまく行きました。

# 参照
GNU ELPA - gnu-elpa-keyring-update
https://elpa.gnu.org/packages/gnu-elpa-keyring-update.html
自然言語処理系解析器インストールまとめ

## はじめに

へいしゃのデータ分析関係の新卒研修で、自然言語処理を中心としたテーマで実習を行いました。
その際に各自然言語処理系のツールのインストール方法をまとめたので、ここでも紹介することにする。

## インストール方法まとめ

[How to Install Natual Language Processing Tools](https://ayukiyoshida.github.io/tips/nlp/install_tools/) にまとめてあります。

### 2020/5/30 追記

@KoichiYasuoka さんにいただいたコメントを元に以下のツールに関するインストール方法も追記しました。

* [GiNZA](https://github.com/megagonlabs/ginza)
* [Camphr](https://camphr.readthedocs.io/en/latest/index.html)
* [Stanza](https://stanfordnlp.github.io/stanza/)
* [UniDic2UD](https://github.com/KoichiYasuoka/UniDic2UD)
テスト技法を選択する際の様々な要素（基準）

## テスト技法の概要
一般的には以下の技法が多く採用されています。
どれも有名な技法で探せば情報は見つかるため、ここではリンクを貼る形とします。

* [ブラックボックステスト](https://hnavi.co.jp/knowledge/blog/white-box-test/)
* [ホワイトボックステスト](https://hnavi.co.jp/knowledge/blog/white-box-test/)
* [グレーボックステスト](https://hnavi.co.jp/knowledge/blog/white-box-test/)
* [経験ベーステスト(エラー推測、探索的テスト、チェックリストベースドテスト等)](https://webrage.jp/techblog/testing_by_experience/)

上記のテスト技法を採用するにあたり、何を基準に選択するか？が本記事の主題です。以下の項にまとめます。

## テスト技法を選択する際の様々な要素（基準）
以下の要素（基準）が挙げられます。
特筆すべきもの（*）は本項の下部に注釈を入れます。

* コンポーネントまたはシステムの種類
* コンポーネントまたはシステムの複雑性
* 規則や標準（*）
* 顧客または契約上の要件（*）
* リスクのレベル（*）
* テストの目的
* 入手可能なドキュメント（*）
* テスト担当者の知識とスキル（*）
* 利用できるツール
* スケジュールと予算（*）
* 開発ライフサイクルモデル
* ソフトウェアの想定される使用方法
* テスト対象のコンポーネントまたはシステムに関してテスト技法を使用した経験
* コンポーネントまたはシステムで想定される欠陥の種類

#### 規則や標準
開発組織内で開発標準や規則があれば基本的にはそれに倣います。

#### 顧客または契約上の要件
顧客との契約上、「ホワイトボックステストのみを行うこと」「ブラックボックステストのみを行うこと」等といった、契約上の決まり事があり顧客からそれを要求されているのであれば基本的にはそれに倣います。

#### リスクのレベル
リスクが顕在化した時の影響度が高い機能は優先的にかなり手厚く行い、リスクの低い機能は優先度を下げて行う、といったアプローチをとることがあります。

#### 入手可能なドキュメント
テスト設計のインプットとなる要件定義書や設計書といったドキュメントの有無によっては、テストが困難な場合もあります。そのため、できる範囲でのテストとするか、それ同等のドキュメントを作成しそれをインプットにしてテスト設計を行う必要があります。

#### テスト担当者の知識とスキル
特に[経験ベーステスト(エラー推測、探索的テスト、チェックリストベースドテスト等)](https://webrage.jp/techblog/testing_by_experience/)は、テスト実施者の経験やスキルに依存します。そのため、テスト実施者の経験やスキルを考慮してその技法を採用するかどうかを決める必要があります。

#### スケジュールと予算
テストの時間や予算を充分に確保することができない、といったこともプロジェクトでは発生します。そういった場合は限られた時間と予算で最大限の効果を得ることができる技法を採用する必要があります。

以上です。