OmniAICreator/Qiita-1.07M huggingface dataset:
シェルスクリプトの実行

#シェルスクリプトとは
シェルによって解釈・実行される一連の処理を記述したスクリプト。狭義では、Unixシェルで用いられるスクリプト言語を指します。

「スクリプト(script)」は「台本」という意味で、コンピュータに実行させたい処理を記述してコンピュータを動かせます。

この台本をテキストデータで用意したものがシェルスクリプトです。コマンド・インタプリタとも呼ばれています。

#シェルスクリプトの使い所
- 定期作業の自動化
- 作業の記録
- 複数コマンドをまとめて処理

#シバン

```shell

#!/bin/bash

echo "Hello World !"

exit 0

```

先頭に指定した #! で始まる「シバン」と呼ばれる文字列は、スクリプトを実行するためのインタプリタを指定しています。つまり、「このシェルスクリプトは bash によって解釈・実行されます」と、宣言するためのものです。

これは決まり文句のようなものなので、必ず 1行目に指定しなければなりません。


#シェルの実行（ホームディレクトリに作成したhw.shを実行する場合）
主に3通りの方法があります。

- bashコマンドで実行  
 bash コマンドに引数として実行するシェルスクリプトのファイル名を指定する方法。  
→この場合、ファイル名だけを指定して実行できるのは、そのファイルがカレントディレクトリにある場合のみ。ファイルが別のディレクトリにある場合は、絶対パスもしくは相対パスで指定しなければなりません。

  ```
  bash /home/[ユーザー名]/hw.sh
  ```
  
- コマンドとして直接実行  
シェルスクリプトを (ls や cat のように) コマンドとして直接実行するためには、主に以下の 2つの条件が必要。  

1.ファイルのパーミッションに実行権が付与されていること  
（ls -lで実行権の確認→ファイル所有者にxがなければchmodコマンドで付与する必要あり→chmod +x ファイル名（実行権の付与））  
 
2.シェルがファイルの場所を特定できること

```
/home/[ユーザー名]/./hw.sh
```

3. PATHを通して実行

```
export PATH=$PATH: /home/[ユーザー名]/

cd /home

bash hw.sh
export PATH=$PATH: /home/[ユーザー名]/
 
cd /home
 
bash hw.sh
```

通常、プログラムを実行する際には、絶対パスを指定して実行する必要があります。

ここで、絶対パスではなく「PATHを通す」ことにより、そのPATH直下に存在するプログラムを、プログラム名だけで実行できるようになるのです。

しかし、OSを再起動すると、上記コマンドで設定したPATHの内容は消えてしまいます。永続的にPATHを設定したい場合は、対象ユーザーのホームディレクトリ直下にある「.bash_profile」と呼ばれるファイルに追記することが一般的です。

参照：https://udemy.benesse.co.jp/development/system/shellscript.html
非同期処理とは

<h1>はじめに</h1>

非同期処理の理解がないとAPIを扱えないので一旦概念を整理。

ここでは二つの処理のことをそれぞれ、**タスクA / タスクB**と呼ぶ。

<h1>同期処理とは</h1>

タスクA / タスクBの具体的な処理を↓とする。

**【タスクA】
ミッション①：サーバーにデータのリクエストを送信
ミッション②：サーバーからデータを受け取ってブラウザに表示**

**【タスクB】
ミッション①：タスクAで受け取ったリクエストをもとに、データベースからデータを呼び出す
ミッション②：データベースから呼び出したデータをレスポンスとしてタスクAに返す**


同期処理の場合、タスクAは①でサーバーにリクエストを送ると、タスクBの①②の処理が完了するまで、<br/>自身のミッション②を実行できない。つまり、タスクAを一旦中断することになる。

タスクBで重い処理があった場合、それが完了するまでユーザーは何もできない状態になり、<br/>離脱に繋がってしまう。

そこで**非同期処理**の登場。

<h1>非同期処理とは</h1>

非同期処理は、タスクBの処理完了を待たずに、タスクAを進めてしまう処理のこと。

これにより、タスクBの処理が完了するのを待たずに、ユーザーは他の操作ができるようになるため、<br/>前述の「何もできない状態」は解消される。

しかし、タスクBから返されるデータを用いてタスクAのミッション②を実行したい場合、
非同期処理だとデータがない状態でタスクAが進んでしまうため、エラーに繋がってしまう。
（今回の場合、ブラウザに表示するデータがない状態でタスクAのミッション②が実行されてしまう。）

ゆえに、タスクBの処理完了を待ってから、<br/>タスクAを実行させるという非同期処理の順序を制御する必要がでてくる。

非同期処理を制御する具体的な方法として下記がある。　
＊今回は非同期処理の概念整理なのでこの部分の詳細は割愛。

**・コールバック関数
・Promise
・async/await**

これらを用いて、処理の順序をコントロールすることが、非同期処理では必要となる。

<h1>まとめ</h1>
この辺りの非同期処理の概念的な理解があった上で、Promiseやasync/awaitを学ぶと理解が進む。
cronで毎日ファイルのバックアップを取る/ミラーリングファイルを用意する


数値計算の結果をためる場合は、環境はそれほど重要ではなくて、計算結果のファイルが大事で単一のHDDにそれがあるだけでは心もとないということがよくある。できれば、異なる筐体(というか物理的に異なるディスク)にバックアップを用意したり、ミラーリングしたファイルを用意できると、安心感が増す。
Linuxで定期的な処理は、cronで実現できる。cronでは、その実行頻度を分刻みから、月刻みまで指定することができる。
ここで、**日単位**でバックアップ/ミラーリングを取ると結構都合がよい。ファイルの冗長性というか、オリジナルディスクが物理的に壊れたときのファイルの救出可能性を考慮すると、バックアップ/ミラーリングの頻度は高いほど良い。一方で、計算機上で手動で作業をしていると、度々ファイルを誤って消してしまうミスが起きる。この時、頻度が高いバックアップ/ミラーリングを取っていると、そのバックアップ/ミラーリング先も瞬時に同期してしまって、そのミスに気付いたときには手遅れになってしまう。もし、日単位のバックアップ/ミラーリングをしていれば、ファイルの消去に気づいたときにそうしたファイルはバックアップ/ミラーリング先に残っている可能性が極めて高い。逆に週単位で、バックアップ/ミラーリングを取っていると、元のディスクが物理的に壊れたとき、進捗が一週間前に戻ってしまうことになり、これは結構痛い。一方で、日単位でバックアップ/ミラーリングを取っている場合は、失う進捗は一日分で済む。
このようなわけで、バックアップ/ミラーリングは短すぎても長すぎても短所が顕在化する。この辺の定量的な感覚は人に依るとは思うけれども、私の感覚では日単位でとるのがベストバランスのように思える。
と言うわけで毎日バックアップ/ミラーリングをするという処理をcronでどう実装するかをまとめる。頻度を低くしたり、高くしたりしたければcronの設定を適宜変えればよい。

# cronの設定
基本となるコマンドはcrontab。例えば`crontab -l`で、今現在登録されている定期実行処理が表示される。事前に設定していなければ`no crontab for hogehoge`と標準出力が返ってくるはず。
crontabへの定期実行処理の追加は`crontab -e`でも出来るらしい。他のオプションとしては`cron.conf`という登録用ファイルを用意して、そこに追加する方法もある。好みの都合で、私は後者を採用した。
毎日4:00AMに`backup.sh`を実行する設定は以下の設定ファイルで実現できる:

```:cron.conf
0 4 * * * /root/cronfiles/backup.sh
```
この`/root/cronfiles/backup.sh`の前のスペースで分かれた五つの欄はそれぞれ、分、時、日、月、曜日になっていて、`*`が挿入されている箇所は任意の整数値に実行される。例えばこの個所を`* 4 * * *`だと毎日午前4時台に**毎分**処理が実行されることになるので、注意。
このファイルを準備して`crontab cron.conf`で登録される。`crontab -l`で登録されていることが確認できる。

参考にしたページ
[cronを用いたコマンドの定期実行 - アメリエフのブログ](https://staffblog.amelieff.jp/entry/2018/07/06/150851)
[定期実行の手法3パターンとその活用例 - Qiita](https://qiita.com/shuntaro_tamura/items/c759bc318859a1203211)

## トラブルシューティング
### スクリプト内のいくつかのコマンドが使えない
[cronの環境変数について - Qiit](https://qiita.com/positrium/items/a2de9af6c5b4d06b504e)にもあるとおり、かなり限定的なところにしかpathが通っていないよう。全体の設定をいじっても良いが、私のケースでは該当のスクリプト内で`export PATH=/path/to/be/reffered:$PATH`として、明示的に必要なpathを追記した。


# `backup.sh`の中身
バックアップを取りたい計算機のホスト名をここでは`hoge001`とする。バックアップを取る際には、もちろん`hoge001`の中で異なるディスクにrsyncをしても良い。ここでは、`hoge001`でnfsサーバーが動いていることを使って、nfsクライアント側の筐体でこれを`/hoge001_home`にread-onlyでマウントした状況を考える。
こうするメリットとして、read-onlyオプションによって、同期元のファイルを原理的に編集できなくする点が挙げられる。同じ筐体の中でrootアカウントでファイル操作をする場合は、こうした形で制限をかけるのは難しい。nfsでのマウントを介することで、サーバー側ではreadとwriteを許可しても、クライアント側でread-onlyを選ぶ(`/etc/fstab`に適宜記載)ことで安全性を高めることができる。
サンプルのスクリプトファイルは以下の通り:

```bash:backup.sh
#!/bin/bash
DATE=`date +'%Y_%m_%d'`
#rsync -avn --delete /hoge001_home /backup/ #For dry run
rsync -av --delete /hoge001_home /backup/ > /root/cronfiles/backup_log_files/"backup_log_$DATE.log"
```
このスクリプトを実行すると、rsyncをアーカイブモード(`-a`オプション)で処理の情報を書き出す(`-v`オプション)で同期をする。`--delete`がついているので、同期元で消えたファイルは同期先でも消去され、ミラーリングになっている。
三行目の`#`でコメントアウトされたものは追加で`-n`オプションがついている。これはdry-run用のオプションで、このコマンドを実行した際に、実際には**ファイルへの操作は行わずに**、具体的にどのファイルが同期されるのか、どのファイルが消去されるのかを標準出力で教えてくれる。例えば標準出力をテキストに書き出しておいて`deleting`などのキーワードで検索を書ければ、消してしまっては困るファイルが表示されて、事前にそれに気付けるかもしれない。
二行目の変数`DATE`に日付を代入してあり、標準出力に同期をとった日付の情報を付け加えている。
このスクリプトはcronから実行するには多分実行権限が継いでいる必要があるので、`chmod 755 backup.sh`で実行権限を付与する。
「これさえ読めば理解できる」Vuexの使い方

##どんな人に読んでほしいか
SPAでアプリを作ってて、ログイン認証とか実装したいけど、Vuexの使い方がよくわからんぞ！って方に読んでいただきたいです。

## Vuexとは
難しい話をすっ飛ばすとVue複数のコンポーネント間使えるグローバル変数を用意するためのライブラリです。(めっちゃ誤解を招く)
一応公式では、「Vue.jsアプリケーションのための状態管理+ライブラリです」だそうです。

## 最初に用語一覧と説明
記事読んでて用語がわけわからなくなったらここに戻ってきてください。

* ステート(State)... Vue.js全体で使えるグローバル変数
* ゲッター(Getters)... どのコンポーネントでも使えるcomputedプロパティ的なやつ
* ミューテーション(Mutations)... ストアの値を変更することを許された唯一の存在(語弊あり、本当はここから以外でも変更できます。でもこのルールに従って書いたほうが、可読性と保守性が上がります。)
* アクション(Actions)...非同期処理を書く場所。ex.外部APIとの通信を行って、ミューテーションを呼び出す時。

## ステート(state)

Vue.jsで全体で使えるグローバル変数的なやつです。ここに登録したプロパティはVue.js全てのコンポーネントから以下の形でアクセスできます。
例

```javascript:store.js
state: {
    count: 100
}
```

```vuejs:something.vue
 this$store.state.count   <!-- 100って出力される -->
```

## ゲッター(Getters)
ゲッターとは全てのコンポーネントから利用できる算出プロパティです。
算出プロパティってなんやねんって人は[こちら](https://public-constructor.com/vuejs-computed-property/)
では実例を交えて解説していきます。
とあるコンポーネントに以下の算出プロパティを実装しているとします。

```vuejs:something.vue
computed: {
    countLessThanTwo() {
　　　　　　return this.$store.state.count < 2 
          
    }
}
```

上記の処理を他のコンポーネントでも利用したくなったとします。通常では他のコンポーネントでも上記の算出プロパティをコピペして実装しなければならないのですが、ゲッターズを使えば

```vuejs:store.js
getters: {
    countLessThanTwo:  state => state.count < 2
}
```
と登録をしておいて、他のプロパティで使い方時に

```
this$store.getters.countLessThanTwo
```
とするだけで全てのコンポーネントで利用できます。

## ミューテーション(Mutations)
ミューテーションとは、ステートの値を変更することができる唯一の存在。同期処理しかかけない！！！！！（これ大切）
※別にミューテーション外でも変更できるけど、ミューテーションのみから変更するのがベター。この方が可読性と保守性が上がるから。

```javascript:store.js
mutations: {
    increment(state, number) {
         state.count += number
    }
}
```

第一引数にはstateを入れます。第２引数以降は好きな引数を入れます。
あとは使いたいコンポーネント側で、

```vuejs:something.vue
methods: {
    this.$store.commit("increment", 2);
}
```

のようにすれば利用できる！

## アクション(Actions)
アクションとは、非同期処理を書く場所。
以下のように使う

```javascript:store.js
actions: {
    incrementAsync(context, number) {
          timeSetout({
          context.commit('increment', 2) 
          }, 1000)
     }
}
```

ちなみにアクションを実行するときは、

```
this.$store.dispatch('increment', 2)
```

のように実行する。
気軽に svn サーバ立てて post-commit

# First

ちょっと相談されたので，かんたんな環境を作ってみたのでメモ．

* 自社内でホストする SVN サーバをさくっとたてたい・・(要望 1)
* コミット時にいろいろゴニョゴニョしたい・・(要望 2)
* 検証環境もさくっとたてたい・・(要望 3)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112500/74f7444b-5adc-529c-cc2b-b660feda5625.png)


いまどき，社内ホスト SVN なんていう時点でいろいろお察しだが，まぁそうおっしゃらずに．ニーズがあること自体は否定できない．
そういうわけで，さくっとたてて post-commit とかで遊べるものを作った．本記事はその解説である．
実装は [youknowcast/svn-docker-wrapper](https://github.com/youknowcast/svn-docker-wrapper) を見てほしい．

# Usage

Subversion 込みの Docker イメージとして [elleFlorio/svn-docker](https://github.com/elleFlorio/svn-docker) を利用させてもらっているので，そっちも解決しつつ引っ張ってくる．

```bash
$ git clone git@github.com:youknowcast/svn-docker-wrapper.git --recursive
```

docker-compose で起動する．
※ docker-compose 等の導入については割愛する

```bash
$ docker-compose up -d
```

`http://localhost/svnadmin` にアクセスすると iF.SVNAdmin というツールが立ち上がって GUI で最低限の設定ができるみたい．
事前にコンテナ内にはいって `htpasswd` で設定しない限りはユーザは `admin/admin` なので，この設定でログインする．

GUI 上で以下の要領でリポジトリとユーザ，それらの紐付けを行う
1. Repositories > Add で適当なリポジトリを追加(e.g. test)
2. Users > Add で適当なユーザ追加(e.g. youknow)
3. Access-Paths で `1` `2` で追加したリポジトリとユーザを紐付け．権限は Read & Write にする

登録した諸情報をもとに local で svn checkout する．
※ Bulk でユーザ登録する場合はたぶん `svnadmin` でなんかやりようがあると思います．

```bash
$ svn co --username youknow http://localhost/svn/test
```

## post-commit の有効化

post-commit を有効にする

```bash
$ cp -p svn/{repository}/hooks/post-commit.tmpl svn/{repository}/hooks/post-commit
# 振られているはずだが，一応権限も振っておく
$ chmod +x svn/{repository}/hooks/post-commit
```

いろいろ出力して遊んでみる

```bash
$ cat /home/svn/test/hooks/post-commit
(略)

REPOS="$1"
REV="$2"
TXN_NAME="$3"

# 引数で渡ってくる情報のチェック
echo "$REPOS $REV $TXN_NAME" >> /home/svn/test/logs
# `svnlook` でとれそうな付帯情報のチェック
svnlook info $REPOS >> /home/svn/test/logs

# もとの mailer 設定については使わない場合はコメントアウトしておきましょう．
#mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
```

上記の例でいくと，例えば以下のような情報がとれる．
ちょっと拡張すれば checkout -> gcc -> ./a.out くらいの簡易 CI コードは書けるでしょう．
試しにコミットしてみると以下のような感じで動作しているのが確認できる．

```bash
$ cat /home/svn/test/logs
/home/svn/test 5 4-4  # ★ $REPOS $REV $TXN_NAME
youknow               # ★ コミットユーザ
2021-02-07 17:13:41 +0000 (Sun, 07 Feb 2021) # ★ 時刻
17                    # ★ ログメッセージの文字数
youknow changed       # ★ コミットメッセージ
```

# 参考
svn-docker(very useful)
https://github.com/elleFlorio/svn-docker

svn-docker 同梱の iF.SVNADMIN の初期設定については以下が参考になった．
http://www.voycn.com/article/docker-ellefloriosvn-server-ifsvnadmin-anzhuangyushiyong

post-commit については以下を参考にした．
https://qiita.com/toshiro3/items/e69e9df146b9af5b9094
Gatsbyで「hot-update.json timed out.」に出会った

#環境
node : 12.19.0
npm : 6.14.8
Gatsby CLI version: 2.12.111
Gatsby version: 2.24.83
テンプレート：gatsby-starter-hello-world

#エラー内容

```
$ npm run develop
```
で起動すると以下のエラーが発生する。

`Unhandled Rejection (Error): Manifest request to /xxxx.hot-update.json timed out.
XMLHttpRequest.request.onreadystatechange`
-要約-
Manifestへのリクエストがタイムアウトになり、ホットリロードできない。

#解決方法
`package.json`の以下の部分を書き換えた。

```json
[変更前]
"develop": "gatsby develop"
[変更後]
"develop": "gatsby develop -p 8080"
```
今回は`8080`番にしたが空いている任意のポート番号で良さそうです。
#原因
~/gatsby-starter-hello-world/webpack/bootstrap:41

```js

  38 | if (request.status === 0) {
  39 | 	// timeout
  40 | 	reject(
> 41 | 		new Error("Manifest request to " + requestPath + " timed out.")
  42 | ^);
  43 | } else if (request.status === 404) {
  44 | 	// no update available
```
bootstrapがなんか言ってることは分かるんですが理解できていません。
分かる方がいればリンクでもいいのでコメントお願いいたします。

#参考
https://yasutomo.hatenablog.com/entry/2018/10/16/190750
curl -d @file.json でファイルのデータを送れないときの場合の対処法。

#解決方法
```
curl 　-d '@file.json'
```
このようにシングルコーテーションで囲うことで解決しました。


#エラー
```
curl -X POST -H "Content-Type: application/json" -d @file.json https:~~~
```
と実行すると、

```
分配演算子 '@' を使用して式で変数を参照することはできません。コマンドの引
数として使用できるのは '@file' だけです。式で変数を参照するには、'$file' を使用してください。
```

と表示され、うまくいかない。
DataFrame obeject operation to use python library pandas

##1.overview
this is python library pandas to output csv files.
how to use DataFrame object and replacement DataFrame index by dict.

##2.sample


```sample.py
import pandas as pd

input_csv_file_path = <input_csv_file_path>
output_csv_file_path = <output_csv_file_path> 


def no_list_to_multiple_list(no_list):
    return [index * 2 for index in no_list]


if __name__ == '__main__':
    input = pd.read_csv(filepath_or_buffer=input_csv_file_path , encoding='ms932', sep=',')
    no_list = csv_input['no'].values.tolist()
    multiple_list = [no_list_to_multiple_list(no_list) for _ in no_list]
    dic = dict(zip(no_list, multiple_list))
    input['no'].replace(dic, inplace=True)
    input.set_index(['index'], inplace=True)
    input.to_csv(output_csv_file_path)
```
PHP参照渡しとforeach

## 初めに

記事を読んでいただきありがとうございます。
一月に未経験で就職したヤマウチです。
ここでは僕が勉強の中で関心を抱いたことに関して、アウトプット感覚で記事を書います。
記事に関するフィードバック等いいただけると幸いでございます。

## 今回の記事について

さて、今回の記事についてですが、題名にもあります通り「PHP参照渡しとforeach」について私なりにまとめましたので共有させていただきます。
この記事を読み進める前に[PHP 参照渡しを試しに使ってみたよって話](https://qiita.com/MitsukiYamauchi/items/78a5eb6698c19a55f4c4)を読んでいただけますと幸いです。

## foreach構文
早速foreach構文に関する注意点をご紹介します。

 ```php
$numbers = [1, 2, 3, 4];

foreach ($numbers as &$number) {
    $number = "「{$number}」"; 
}

echo '<pre>';
var_dump($numbers);
echo '</pre>';

// 結果
// array(4) {
//   [0]=>
//   string(7) "「1」"
//   [1]=>
//   string(7) "「2」"
//   [2]=>
//   string(7) "「3」"
//   [3]=>
//   &string(7) "「4」"
// }
```

上記のようにforeach構文で要素変数を参照すると、ループ内で値を書き換えることができます。
しかし、次に紹介するようなケースでは注意が必要になります。

```php
$numbers = [1, 2, 3, 4];

foreach ($numbers as &$number) {
    $number = "「{$number}」"; 
}

foreach ($numbers as $number) {
    echo '<pre>';
    echo $number;
    echo '</pre>';
}

// 結果
// 「1」
// 「2」
// 「3」
// 「3」
```
初めに内容を書き換えた変数を再度ループ内で表示させてみました。
見て頂くとわかる通り、`$numbers[3]`結果が、`$numbers[2]`の値と重複しており、最終要素の参照がうまくいっていません。うまくいっていないというよりかは、ループ内でどういったことが起っているのかを紐解いていくと必然とも言えます。

## foreach構文の中身をより詳しく
foreach構文の中身を分解して表示させてみます。

```php
$numbers = [1, 2, 3, 4];

$number = &$numbers[0]; // $numberが、$numbers[0]の別名となる
$number = "「{$number}」";

$number = &$numbers[1]; // $numberが、$numbers[1]の別名となる
$number = "「{$number}」";

$number = &$numbers[2]; // $numberが、$numbers[2]の別名となる
$number = "「{$number}」";

$number = &$numbers[3]; // $numberが、$numbers[3]の別名となる
$number = "「{$number}」";

// ---------------------------------------------------------
// 上記ループを抜けた時点で$numberは、$number[3]を指したままである。
// そのため、二回目のループでは次のようなことが起こる。
// ---------------------------------------------------------

$number = $numbers[0]; // $numbers[3] = $numbers[0] 同じ意味
echo $number;
// 結果
// 「1」

$number = $numbers[1]; // $numbers[3] = $numbers[1] 同じ意味
echo $number;
// 結果
// 「2」

$number = $numbers[2]; // $numbers[3] = $numbers[2] 同じ意味
echo $number;
// 結果
// 「3」

$number = $numbers[3]; // $numbers[3] = $numbers[3] 同じ意味
echo $number;
// 結果
// 「3」
```
二回目のループの最後をもう少し詳しくわかりやすく説明すると、
三回目で`$numbers[3] = $numbers[2]`としているので、実質三回目は
`$numbers[2] = $numbers[2]`といったことになる。
初めてですと意味わからなくなりますよね。。。（我高卒也）

## 解決策

### ループ終了後unset()
参照渡しのループが終了後、値の変数をunset()で破棄することにより、参照を解除できます。


```php
$numbers = [1, 2, 3, 4];

foreach ($numbers as &$number) {
    $number = "「{$number}」"; 
}

unset($number);

foreach ($numbers as $number) {
    echo '<pre>';
    echo $number;
    echo '</pre>';
}

// 結果
// 「1」
// 「2」
// 「3」
// 「4」
```

## まとめ
foreachで参照渡しを使用した際の挙動に加え、参照渡しについての理解を深めることができました。
ですが、参照渡しを利用しなくても良い場面で利用してしまうとかえって混乱を巻き起こす原因となることもありますので、現代において非推奨とされるケースが多いです。
ですので、実際に業務で使う際には、当たり前ではありますがきちんと挙動を把握した上で使用すること及び、他者に混乱を招くことがないような記述を心がけていきたいと思います。
【Mac】ディレクトリ下のnode_modulesを全削除するコマンド

自分はこれで30GBの容量確保に成功しました。

## コマンド

* <font color="red">カレントディレクトリ以下のnode_modulesが全て削除されます。適切なディレクトリで実行してください。</font>
* <font color="red">コマンドを改変する際は自己責任でお願いします。</font>

```sh
find ./ -name "node_modules" | xargs rm -rf
```

管理者権限はつけない方がいいですが、`permission denied` が出る場合は自己責任でお願いします。
1ヶ月で統計検定2級に合格した勉強法

#概要
こんにちは、初投稿です。
2021年1月某日、統計検定2級に合格したのでその勉強法について書きたいと思います。


#目次
-　前提
-　使用した参考書
-　勉強法
-　受験の流れ
-　結果と感想

#前提
まず勉強する前の僕の状態を端的に述べると以下の通り
・高校で数Ⅲまで学習した理系大学生
・統計学に関してはほぼ知識なし
・機械学習に興味があり、統計学的知識が必要になったので受験

#使用した参考書
①日本統計学会公式認定　統計検定2級対応　統計学基礎
②日本統計学会公式認定　統計検定2級　公式問題集2017～2019(過去問)
③日本統計学会公式認定　統計検定2級　公式問題集2014～2016(過去問)



#勉強法
まず①の日本統計学会公式の統計学基礎を用いて勉強しました。
統計学基礎の読むべき内容としては210ページほどで以下のような構成になっています。
・第1章　データの記述と要約
・第2章　確率と確率分布
・第3章　統計的推定
・第4章　統計的仮説検定
・第5章　線型モデル分析
・第6章　その他の分析法
・第7章　付録

僕はこの本の第1章から6章を2週間でかけて理解しながら読みました。
1章に関しては比較的スムーズに理解できました。しかしこの章の理解が先の章の土台になります。
2章～4章は統計検定の最頻出分野であるのでしっかり理解しました。確率分布について期待値と分散を暗記していれば問題を解く上で楽になります。特に正規分布と標準化については式は意味を理解しといた方がいいと思いました。3章と4章はセットで考えました。というのも3章がわかれば4章もできます(笑)。ただし推定と検定の違いについては意識しました。あとどこでどの確率分布を使用するのかをしっかり覚えました。後から思い返してもここの勉強法が一番重要だったと思います。
5章は回帰直線と一次元分散分析とRについて理解しました。回帰直線については第1章で触れていたのでスムーズに理解できました。一次元分散分析はみなさんご存じの「統○の時間」さんにお世話になりました。正直ここが一番難しかったので統○の時間さんには本当に感謝しています。しかし今から思えば2級の試験は選択解答で計算もしやすく工夫されていたので、試験で解く分にはそんなに難易度はそんなに高くない気はしました。Rは慣れが重要です。僕はネットで統計検定のRについて調べて慣れました。
6章は主に適合度の検定と独立性の検定です。この章は比較的短く、そこまで難しくはないのでこの2つの検定は容易に理解できると思います。
題名の通り2週間で統計検定2級に合格したのですが、この本中心に勉強した最初の2週間は平均して毎日2時間は勉強しました。この最初の2週間は特に重要だったと思います。

そして後の2週間で②③の過去問を解きました。過去問を解いては間違えた分野の復習を統計学基礎で行うというアウトプットとインプットの繰り返しです。おそらく一番最初に2018年6月の過去問を解いたのですが、正答率は50%後半くらいだったと思います。合格率が60%であったことと、正直この時点で合格できるだろうと思っていたこともあり、かなり焦りました。過去問を初めて解いた感想としては割と細かいことも聞かれるんだなと思いました。当たり前のことですが統計学基礎にのっている内容はどれも出る可能性があると考えといた方がいいです。このときの僕はどうせ太字のところばかりだろという考えだったので過去問を解いてみて考えを改めました。

その後は過去問演習を繰り返し4年分解きました。正直3年分で良かったのですが、2014～2016の過去問を買ってしまったこともあり記念に解きました。この頃には正答率が70～85%で安定していました。このころには正直やる気がなくなっていて、年末年始ということもあり、あんまり勉強していませんでした。しかし、心の底では勉強しないといけないという焦りがあり、怠けと焦りの間で葛藤していました。そこで勉強からの解放を夢見て受験を決意しました。

#受験の流れ
僕はCBT受験というパソコンで解答するという方式で受験しました。自分で受験会場を選択し、日時を指定して申し込みを行いました。運が良く近所に受験会場があり、すぐに受験できる日程があり助かりました。ちなみに受験票はありませんでした。

#結果と感想
76点で合格しました。合格基準点が60点前後なので、高くもなく低くもないといった中途半端な点数です(笑)。
受験会場に行くと他にも2人受験者の方がいましたが、試験時間が違ったので統計検定2級の受験者ではなさそうでした。筆記用具も時計も必要なく、会場の方からペンとラミネート加工された紙と確率分布の付表が手渡され、それらを用いて試験に臨みました。受験した正直な感想として、CBT受験ということもあり過去問とは少し異なりました。詳細については控えますが、過去問が解けていれば対応可能です。僕は過去問より解きやすい印象でした。あとパソコンの画面から問題文を読むということで、問題が読みにくいことを警戒していましたが、そこまで気にはなりませんでした。試験時間は5分ほど余りましたが、最後まで確認を行いました。試験を終えると、軽いアンケートに答えた後に結果が表示されました。一応合格であったので大満足です。欲を言えば80点取りたかったな...。

今から思うことは2級の試験は思っていたよりも簡単でした。最悪丸暗記でも乗り切れると思います。僕は2級を終えて準1級の勉強を始めたのですが、難易度は比べものにならないくらいというのが正直な感想です。ここで統計学の洗礼なるものを受けることになりそうです。しかし、2級の知識が完璧になれば準1級の勉強も少しは楽になるのではないかと思ったので、もう一度2級の範囲を復習しようと思い、自分自身を思い出す意味でこの記事を書きました。また準1級について書こうと思います。
Laravelでお気に入り機能

## はじめに
サービスの概要としては、本のデータがあって、user機能があって、userは本にブックマーク（お気に入り機能)をつけることができるという感じです。


##実装
```php:Book.php
 public function bookMarks(){
        return $this->hasMany('App\BookMark');
    }
```
```php:User.php
 public function bookmarks(){
        return $this->hasMany('App\BookMark');
   }
```
```php:BookMark.php

  public function book(){
        return $this->belongsTo('App\Book');
    }

    public function user(){
        return $this->belongsTo('App\User');
    }
```
関連はこのような感じになってます！

```php
@if (Auth::check())
    @if ($bookmark)
    <form action="{{action('BookMarksController@destroy',$book->id)}}" method="POST" class="mb-4" >
    <input type="hidden" name="book_id" value="{{$book->id}}">
    @csrf
    @method('DELETE')
        <button type="submit">
          ブックマーク解除
        </button>
    </form>
    @else
    <form action="{{action('BookMarksController@store')}}" method="POST" class="mb-4" >
    @csrf
    <input type="hidden" name="book_id" value="{{$book->id}}">
        <button type="submit">
         ブックマーク
        </button>
    </form>

    @endif
  @endif
```

これは本の詳細ページなのですが、ブックマークしてたら「ブックマーク解除」ボタンが表示され、していなかったら「ブックマーク」ボタンが表示されるようにif文をかけてます。

```php:BookMarksController
<?php

namespace App\Http\Controllers;
use App\BookMark;
use App\Book;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;

class BookMarksController extends Controller
{
    public function store(Request $request)
    {

        $bookmark = new BookMark;
        $bookmark->book_id = $request->book_id;
        $bookmark->user_id = Auth::user()->id;
        $bookmark->save();


        return redirect()->route('book.show',[$request->book_id]);
    }

    public function destroy(Request $request, $id) {
        $book=Book::findOrFail($id);

        $book->bookmarks()->delete();

        return redirect()->route('book.show',[$request->book_id]);
    }
}
```
次にコントローラーです。storeはシンプルにリクエストで渡ってきた値を代入しているだけですね。 destroyの方はまず本のデータを取ってきて、紐付いているブックマークを削除という形です。destroyの方はもっと良い書き方がありそうですが。。。
mysql_config not foundとでたときの対処法

M1Macを買って色々とセットアップしてたらエラーがでたので。

## pipでmysqlclientをインストールしようとしたらmysql_config not foundとでる。

### やること

```
brew install mysql-connector-c
```


インストールできたら、

```
echo 'export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"' >> ~/.zshrc
export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"
which mysql_config
```
でパスを通して、whichが叩けることを確認。

```
chmod 777 /opt/homebrew/opt/mysql-client/bin/mysql_config
```

でパーミッションを変更。（パスはwhichを叩いたときにでてくるパスとなる）

`vi` で開いて。

```
libs="$libs -lmysqlclient"
```

を

```
libs="$libs -lmysqlclient -lssl -lcrypto"
```

に変える。

それで保存してもう一回mysqlclientを入れるpip installコマンドを叩けば無事にインストールできる。

幸せいっぱいですね。
VRアプリをつくりたい#1【環境構築】

## はじめに

この記事の最終目標は**VRアプリ**の作成
とりあえず自分用に開発環境の構築方法などを残す
最初はwindows環境のちにmacOS環境でも開発環境を構築したい

## unityhubのインストール
これはそこらへんに記事が転がっているので省略

## unityのインストール

ここから記事によって使用しているunityのバージョンが違う(だいぶ前に触った時は2018だった気が)
とりあえず参考にしている記事に従い**「2019.4.12」**を使用
(2020~はバグがあるみたい、知らんけど

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/224ef95b-1a62-2f5f-0145-0cd7ecb583b7.png)

モジュール追加にはAndroid Build Support と Android Build Support のタブを開いたところにある Android SDK & NDK Tools、OpenJDK にすべてチェックを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/d6a54cd2-9d98-2657-5eb3-42a8eaf0ee0c.png)

同意画面が出るので後は適当に

## プロジェクト作成

インストールが終わったら**3D**を選択、プロジェクト名は適当に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/a7517753-f955-fed9-f633-8facb71b72ac.png)

プロジェクト画面が立ち上がったら色々と設定をしていく　　
→**・Build Setting**
　　　まずはAndoroidにプラットフォームを変更、テクスチャ圧縮形式を**ASTC**
→**・Project Setting**
　　　Player > Other Settings > Graphics APIs の Vulkan を削除
　　　Color Space を Linear
　　　Minimum API Level を**Android 6.0 ‘Marshmallow’ (API level 23)**

ここまでで設定はだいたい終わり

## Oculus Integarionをインポート

**・そもそもOculus Integarionとは**
　Oculus統合パッケージ
　VRのコアとなる機能、コンポーネント、スクリプト、およびプラグインのためのオールインワンソース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/41fa7211-d611-5847-3b4e-99dfdb54e5c6.png)
(インポートする前にAvatarの欄はチェックを外す必要になることが少なく、とても重いらしいので)


## さらに設定

**Project Setting**から**XRPlug-inManagement**をインポート
oculusにチェックを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/ceab2383-0622-3cb4-52cb-5d7ce87166bf.png)

**これで環境設定は終わり**

## いろいろ触ってみた


いろいろ触って作ってみました　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087181/5c4be192-d481-f612-1785-0bfed53fd54a.png)

今回移動操作をスティック移動にしたが結構酔う
VRの移動方法って大体がテレポートだけどやっぱりテレポートが正解っぽい

またオブジェクトの当たり判定など考えるのはやっぱり難しい
刀のオブジェクトを配置するための土台を配置したが、当たり判定を忘れていて永遠に下に落下していった

**とりあえず今回は終わり**
**環境構築わかりずらいところはブラッシュアップしていく(つもり)**
PowerShellでマニアックなデータ加工をする("十人十色" => "人十色")

# コード

文字をソートして重複を消す。"十人十色" => "人十色"。

```powershell
function uniqsortString($str){
  $arr = [regex]::Matches($str,".{1}").value | sort -Unique
  return $arr -join ""
}
```

# 漢字を対象にすると

[**国立国語研究所(2004)『分類語彙表増補改訂版データベース』(ver.1.0)**](https://github.com/masayu-a/WLSP)から
漢字熟語を抜き出す。また、構成する漢字の列を追加する。
さらに、[,,,]のような区切りを追加してファイル保存する。

```powershell
# 文字列を重複無しソートにする  [十人十色] => [人十色]
function uniqsortString($str){
  $arr = [regex]::Matches($str,".{1}").value | sort -Unique
  return $arr -join ""
}

$csv |
# 漢字のみで構成されたものを取り出す
  where{$_.col14 -match "^([〇\u3400-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF])+$"} |
#  2文字以上で重複なし
  where{$_.col14.length -gt 1} | Sort-Object -Property col14 -Unique |
# idと分類と熟語を抜き出す。構成漢字列を付加する。
  %{echo ("["+ $_.col1 +","+ $_.col5 +","+ $_.col6 +","+ $_.col7 +","+ $_.col14 +","+ (uniqsortString $_.col14) +"]," )} >> jukugo_uniqsort.txt
```

## 解説

- `sort -Unique` 配列等をソートして重複を消す。sortはSort-Objectのエイリアス
- `[regex]::Matches($str,".{1}").value` 文字列を1文字ずつの配列にする
- `$arr -join ""` join == 文字列配列をまとめて1つの文字列にする。(""を区切り文字にする)
- `$str -match "^([〇\u3400-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF])+$"` 文字列が漢字のみであればtrue
- `Sort-Object -Property col00` オブジェクトをcol00という要素でソート
- `echo (文字列)` オブジェクトを並べると改行されてしまうので、文字列にしてまとめてからechoした


## 補足
col14に単語が入っていて、それが漢字のみの熟語の行のみとってきてます。
要らない列は省いてます。
追加した列は重複無しでソートされた熟語です。構成する漢字が似通ったものを探すために便利なのでくっつけました。
メモ書き記事です。
Raspberry piでwineを動かしてみるメモ(2021年版)

<font color="red">
2021/11/22　追記
現在はWineもPi-Appsでインストール出来、手動でインストールする必要はないようですので、この記事の手順は古いものです。
今からWineをラズパイにインストールしたい人は下記のサイトを参照することをおすすめします。
</font>


https://raspida.com/wine32-rpi4

# 概要

*nixでWindowsアプリを動かすwineをraspberry piで動かすにはx86エミュレータを経由する必要があるためかなり面倒そうだったが、
最近はBox86というx86エミュレータがあるようで、導入が楽そうだったので試してみたメモ。

参考: [How to Install Box86 and Wine on Raspberry Pi OS](https://www.youtube.com/watch?v=OT17OQNiGcA)(英語、Youtube動画)

# インストール

概要にも書いたとおり、まずx86エミュレータとして[Box86](https://github.com/ptitSeb/box86)をインストールする必要があるが、
[Pi-Apps](https://github.com/Botspot/pi-apps)経由でインストールするのが一番手軽そう。

## Pi-Appsのインストール

```
git clone https://github.com/Botspot/pi-apps
~/pi-apps/install
```
でインストールできる。sudoによるパスワード入力の必要があります。


## Box86のインストール

Pi-AppsがインストールされていればデスクトップにPi-Appsのアイコンがあるはずなので、ダブルクリックして起動。
実行方法を聞かれるので「端末で実行する」を選んでおく。
カテゴリがいくつかあるので「Tools」を選び、アプリの一覧から「Box86」を選んで下の「+」をクリックするか、
「Box86」をダブルクリックして下の「+install」をクリックするとインストールを開始します。
こちらも途中sudoによるパスワード入力の必要があります。

## wine・winetricksのインストール

[参考](https://www.youtube.com/watch?v=OT17OQNiGcA)(英語、Youtube動画)の丸パクリですが・・・

```
cd ~/ダウンロード
wget https://dl.winehq.org/wine-builds/debian/dists/buster/main/binary-i386/wine-devel-i386_5.21~buster_i386.deb
wget https://dl.winehq.org/wine-builds/debian/dists/buster/main/binary-i386/wine-devel_5.21~buster_i386.deb
dpkg-deb -xv wine-devel-i386_5.21~buster_i386.deb wine-installer
dpkg-deb -xv wine-devel_5.21~buster_i386.deb wine-installer
sudo mv wine-installer/opt/wine-devel ~/wine
sudo ln -s ~/wine/bin/wine /usr/local/bin/wine
sudo ln -s ~/wine/bin/winecfg /usr/local/bin/winecfg
sudo ln -s ~/wine/bin/wineserver /usr/local/bin/wineserver
```

```
cd ~/ダウンロード
wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
sudo chmod +x winetricks
sudo cp winetricks /usr/local/bin
sudo apt-get install cabextract -y 
```

# wineを初期化する

```
box86 wine wineboot
```


# winetricksを使えるようにする

<font color=red>
※通常は下の作業をしなくてもwinetricksは動くようです。
</font>

winetricksはそのままだとなぜか素の状態のwineやwineserverをそのまま呼び出そうとして実行に失敗する<font color="red">ことがある</font>ので、
もしそうなった場合はBox86経由で呼び出してもらうように工夫する必要がある。

上記の通りインストールした場合、PATHが通っている/usr/local/binのwine、wineserverは~/wine/bin内のwine、wineserverのシンボリックリンクになっているはずなので、

box86経由で実行するよう以下のシェルスクリプトに置き換える

```shell:wine
#!/bin/sh
box86 ~/wine/bin/wine "$@"
```

```shell:wineserver
#!/bin/sh
box86 ~/wine/bin/wineserver "$@"
```

これで、wine、wineserverが自動的にBox86経由で実行されるようになる。

ちなみにwinetricksは```BOX86_NOBANNER=1```をつけないとエラーで動かない模様

```
BOX86_NOBANNER=1 winetricks dotnet20sp2
```

# 日本語表示

とりあえず、モナーフォントをインストールすればいい模様

```
BOX86_NOBANNER=1 winetricks fakejapanese_ipamona
```
【初見の方向け】ロボット・ IoT開発で使われているMQTT通信。概要把握からPython実装まで紹介。

[記事はこちらに移動しました。](https://tro555-engineer.com/2022/02/05/%e3%83%ad%e3%83%9c%e3%83%83%e3%83%88%e3%83%bb-iot%e9%96%8b%e7%99%ba%e3%81%a7%e4%bd%bf%e3%82%8f%e3%82%8c%e3%81%a6%e3%81%84%e3%82%8bmqtt%e9%80%9a%e4%bf%a1%e3%80%82%e6%a6%82%e8%a6%81%e6%8a%8a%e6%8f%a1/)
Electron で ES Modules を使う。

# 概要

`Node.js`が`ES Modules`(以下`ESM`）をサポートするようになったので、`Electron`のメインプロセスでも`ESM`を使いたいというニーズが[当然のように出てきました。](https://github.com/electron/electron/issues/21457)
そこで[`Electron`のクイックスタートガイド](https://github.com/electron/electron-quick-start)を改変して、メインプロセス(`main.js`) で`ESM`をインポートできるようにやってみましたのでその方法を紹介します。ただし今のところ少し問題があるので、補足2を読んだ上で実際に使うかどうかは判定してください。

# 準備

[Electron Quick Start](https://github.com/electron/electron-quick-start)をクローンしてそのフォルダに入ります。

```
$ git clonen https://github.com/electron/electron-quick-start
$ cd electron-quick-start
```

# 手順

### package.json を変更します。

```package.json.diff
-  "main": "main.js",
+  "main": "main.cjs",
+  "type": "module",
+  "build": {
+    "asar": false
+  },
```

* スタートアップファイルを main.js -> main.cjs に変更します。

* `"type": "module"`を指定することで拡張子が `js` のファイルのモジュールシステムが`ES Modules`になります。

* 拡張子が`cjs`のファイルはこの指定に関係なくモジュールシステムが`CommonJS`になります。

* `build`オプションで`asar`を`false`にします。これをやらないと`electron-builder`で`build`したモジュールがどうもファイルを見つけてくれないようです。（補足2を参照）


### main.cjs というファイルを以下の内容で作ります。

```main.cjs
global.require = require
global.__dirname = __dirname
import( './main.js' )
```

`CommonJS`の中でも[Dynamic Importは使える] (https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import)ので、これを使って`main.js`を読み込みます。

`require, __dirname`はモジュールの中では消えてしまうので、`global`に退避します。[他にも消えるものがあります](https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs)ので必要な場合は同様に`global`にセットしてやればいいでしょう。

# テスト

### モジュールのサンプルを作ります。

```sample.js
export const X = { A: 'B' }
export default { 1: 2 }
```

### main.js でこのサンプルを読み込んで表示してみます。

```main.js.diff
+ import D, { X } from './sample.js'
+ console.log( D, X )
```

### 実行

```
$ npm start

> electron-quick-start@1.0.0 start
> electron .

{ '1': 2 } { A: 'B' }
```

# 補足1

`require`をグローバルに退避しないで、以下のように`ESM`の中で新しく作るやり方もあります。

```
import { createRequire } from 'module'
const require = createRequire( import.meta.url )
```

# 補足2

`asar`を`false`にして`build`するとソースが丸見えになってしまいます。そのせいか以下のような推奨されていませんというメッセージが表示されます。
そのうち`asar`がデフォルトの`true`でもビルドしたモジュールがちゃんと動くようになってくれることを祈ります。

```
  • asar usage is disabled — this is strongly not recommended  solution=enable asar and use asarUnpack to unpack files that must be externally available
```
Eclipseのtomcatで実行すると文字化けするときの対応 

#はじめに
Eclipseからtomcatを起動してテストしていたとき、ファイル出力の文字コードをShift_JISにする方法がわからずハマったので、その時の対応を書きます。

#やり方
通常、文字コードはJVMを起動するときの引数で指定します。EclipseでJVMの引数を与えるには以下のように設定します。

Eclipseのメニューからウインド→設定を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292064/b4a24e01-e9f6-24cc-b7d8-e28fea397e64.png)

設定画面のtomcat→JVM設定を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292064/d7cedd0c-4499-9bc9-a8e9-d2c17522de62.png)

追加ボタンを押します。出てきたダイアログに「-Dfile.encoding=MS932」と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292064/ccb3c855-42ff-bca4-09bd-639d79f51887.png)

#パラメータの「MS932」の意味は？
javaでShift_JISをこのように指定します。MS932はShift_JISにマイクロソフトの拡張を加えたものなので、完全にMS932=Shift_JISというわけではないです。その辺の事情は以下が詳しいです。

Shitf-JisとMS932の違い
https://weblabo.oscasierra.net/shift_jis-windows31j/

#その他
以下を参考にしました。

デフォルトエンコーディング変更方法
https://www.javadrive.jp/start/encoding/index4.html
1.WSL環境構築

# 概略
WSL=Windows Subsystem for Linuxとは、LinuxをWindows上でネイティブ実行するための互換レイヤーです。
難しい事書きましたが要はWindows上にLinuxのネイティブ環境を構築して自由に操作できますという事です。
本環境の使用用途・メリットとして思いつくだけでも下記のようなことが考えられます。

- Windows上でネイティブに実行するため、ホスト型・ハイパーバイザー型仮想環境のようにメモリを切り分ける必要がないく、無駄なメモリを消費する事が少なくなる。
- WSL上からWindowsのコマンド操作が可能・また逆にWindows上からWSLのコマンド操作が可能
- 開発・テスト環境が無い段階（提案・要件定義・基本設計フェーズ等）でも本番環境に近いプロトタイプ・サンプルの作成・提供が可能となる。
- 環境の違いによる設定の違いがほとんどなくなる

ここではWSLで使用するLinux OSのインストール、初期設定、及び起動時に必要な設定、操作に便利なツールのインストールについて記載します。
環境イメージは下記の通りとなります。
![WSL in Windows環境俯瞰図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96681/93d51505-3782-4386-e4b4-5457add47e5b.png)

---

# 使用した環境

Windows10 Pro Intel Core i7-8650U
実装RAM 16.0 GB

---

# 目次
[アーキテクト技術者・構成管理者・リモート開発者のためのローカル開発環境構築ガイド](https://qiita.com/boss_ape/items/c33408df7557801d0183)
**1.WSL環境構築**
[1.1.WSLインストール・初期設定](https://qiita.com/boss_ape/items/6f1e1f731b5385f4b31a)
[1.2.ConEmu・Nyagosインストール・設定](https://qiita.com/boss_ape/items/015feebc6e3a77311e01)
[1.3.Windowsドライブマウント設定](https://qiita.com/boss_ape/items/6ba3a846e45b2ebe24c9)
[1.4.Google Driveマウント設定](https://qiita.com/boss_ape/items/74bcad7441417c331205)
[1.5.WSLでのsystemctl設定](https://qiita.com/boss_ape/items/3d30dd651b93fdbbb3a5)

---

[アーキテクト技術者・構成管理者・リモート開発者のためのローカル開発環境構築ガイド](https://qiita.com/boss_ape/items/c33408df7557801d0183) < 前 **1.WSL環境構築**  次 > [1.1. WSLインストール・初期設定](https://qiita.com/boss_ape/items/6f1e1f731b5385f4b31a)
アーキテクト技術者・構成管理者・リモート開発者のためのローカル開発環境構築ガイド

# 前書き

Windows10を開発PCのOSとして開発に必要な各種サーバを含めて1台のPCで動作させることを目指して「オールインワンローカル環境」を構築します。

- Windows WSL内に開発用サーバ環境を構築
- Windows内に開発・試験環境を構築
- CI/CDサーバ・プロビジョニングサーバに接続できる場合は必要に応じて簡単にサーバにある最新モジュールをデプロイ、また、開発用最新データをDBにインポートできる環境を構築

※本ページは目次です。すいません。すべてを一度に公開はできませんので1年（目標）かけて記載します。その間、告知なしに内容を修正・変更することがありますが、ご了承ください。

---

# 目的・指針

ローカル環境は下記を指針とし、目指して構築していきます。

- サーバ機能をオールインワンですべてPC端末内で稼働させ、極力スタンドアローンで実行可能とします。
- 環境を構築する手順はDevOpsの観点から極力複雑な操作を廃し単純なコマンド・ボタンクリックで構築可能とすることを目指します。
- プログラミングと同様にローカル環境でインフラの調査設計・単体テスト・構築ができます。
- プロダクト環境はAWSを想定しています。AWS CLIでローカルDocker⇔AWS ECS設定の自動連携が可能となります。
- 最終的には営業担当者・開発担当者が自身で端末PC内に構築可能な状態にし、ネットワークのつながらない環境・リモート環境でも開発を継続できる、サンプル動作環境を自由に持ち運びプレゼンテーション等で動作している状況を見せることができる様にすることが最終目標です。

---
# ローカル環境概略

ローカル環境の最終イメージは以下の通りWindows内に独立したLinux OSを構築し、更にそのLinux OS内にサーバ機能を導入します。
下図にある通り、Windowsの各種ドライブはLinux側に自動でマウントするため、ネットを介してのファイルコピー等の必要がないのでデプロイその他の速度が大幅に向上します。また、逆にLinux側のファイルもWindows側から
Linuxでの各種service起動・shell実行はwsl.exeを使用してWindowsタスクスケジューラに設定すればWindowsマシン起動時等に実行することも可能です。

## ローカル環境俯瞰図
![オールインワン開発環境俯瞰図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96681/7d05902b-392c-3d1a-dd50-5a64863e7ec5.png)

---
# 目次
1. [WSL環境構築](https://qiita.com/boss_ape/items/a30ebffde989d622be0a)
 1. [WSLインストール・初期設定](https://qiita.com/boss_ape/items/6f1e1f731b5385f4b31a)
 1. [ConEmu・Nyagosインストール・設定](https://qiita.com/boss_ape/items/015feebc6e3a77311e01)
 1. [Windowsドライブマウント設定](https://qiita.com/boss_ape/items/6ba3a846e45b2ebe24c9)
 1. [Google Driveマウント設定](https://qiita.com/boss_ape/items/74bcad7441417c331205)
 1. [WSLでのsystemctl設定](https://qiita.com/boss_ape/items/3d30dd651b93fdbbb3a5)

1. [Git / GitHubによる環境ファイル管理](https://qiita.com/boss_ape/items/25cc648beb2519d5e1da)
 1. [GitHub登録](https://qiita.com/boss_ape/items/aa2e5da904add70639d6)
 1. [gitインストール・設定](https://qiita.com/boss_ape/items/c9155659d8d474f3c8b6)

1. [Docker in WSL環境構築](https://qiita.com/boss_ape/items/fe48e4d7b69e83bed7c8)
 1. [Docker / docker-compose インストール・初期設定](https://qiita.com/boss_ape/items/f35a1362fe56f755e44c)
 1. Docker環境構成検討
 1. DockerによるMySQL(RDBMS)サーバ構築
 1. DockerによるGo言語(API)サーバ構築
 1. DockerによるVue.js(UI)サーバ構築
 1. DockerによるNginx(Web)サーバ構築
 1. docker-composeによる簡易オーケストレーション

1. 本番環境に相当するオーケストレーション
 1. Kubernetesインストール・設定
 1. KubernetesによるDocker構築
 1. Portainerによるクラスタ管理

1. 自動構成管理
 1. DistroLauncherインストール・設定
 1. DistroLauncherによるWSL環境イメージ作成
 1. Ansibleインストール・設定
 1. AnsibleによるWSL環境構築自動化

1. WSL内開発環境整備
 1. DB Backup
 1. DB Restore
 1. APサーバコピー構築
 1. APサーバCI/CD
 1. サーバ自動起動・停止

1. 開発アプリケーション(Windows)設定
 1. A5mk2インストール・設定
 1. VSCodeインストール・設定

## 番外

1. 各リモートサーバへのSSHログイン・端末設定

1. X Windowへのリモートデスクトップでの接続

1. AWS CLI インストール・設定

1. AWS S3マウント

## 検討

1. 環境内ツール類のブラウザアプリGUI化

## Tips

1. WSLのマウントについて

---

**アーキテクト技術者・構成管理者・リモート開発者のためのローカル開発環境構築ガイド**  次 > [1.WSL環境構築](https://qiita.com/boss_ape/items/a30ebffde989d622be0a)
PowerToysでCapsLockとShift+CapsLockを入れ替える

# PowerToys

> Microsoft PowerToys は、パワー ユーザーが Windows 10 エクスペリエンスを調整および合理化して生産性を向上させるためのユーティリティ セットです。

https://docs.microsoft.com/ja-jp/windows/powertoys/

GitHubで公開されており、2021年2月8日現在、x64がサポート対象になっています。
svgファイルやmdファイルがプレビューで見られるようになったり、
MacのSpotlightみたいな機能「PowerToys Run」が追加されたり、
『パワーユーザーじゃなくても、欲しい人いるんじゃね？』っていう機能を提供しています。

そんな機能の中の１つ「Keyboard Manager」を使って、USキーボードでのCapsLockとShift+CapsLockを入れ替える設定をし、使いやすさを感じたので備忘録も兼ねてここに記します。

## 設定

1. PowerToysの設定を開き、Keyboard Managerのメニューを開きます。
2. キーの再マップで「Caps Lock」を「VK240」にします。
3. ショートカットの再マップで「Shift(Left) + VK240」を「Caps Lock」にします。

以上です。

## 注意

単押しの機能を入れ替えるのではなく、キーそのものを入れ替えるので、CapsLockと何かを組み合わせている場合（している人いるんですかね？）、Shift+Caps+○○ になります。

## 余談
karakaram様が公開している「alt-ime-ahk」を普段から使っています。
> 『WindowsのAlt空打ちで日本語入力(IME)を切り替えるツールを作った - karakaram-blog』
> https://www.karakaram.com/alt-ime-on-off/
> 
> 『Releases · karakaram/alt-ime-ahk · GitHub』
> https://github.com/karakaram/alt-ime-ahk/releases

以前までは、これに加えて「ULE4JIS」を使用していました。
> 『ULE4JISの詳細情報 : Vector ソフトを探す！』
>  https://www.vector.co.jp/soft/winnt/util/se476294.html

これは、JIS環境でUSキーボードを使うためのエミュレータですが、CapsLockをJISキーボードと同じ挙動にしてくれるので重宝していました。しかし、動作しなくなることがあり、アプリの再起動が必要な時がありました。

エミュレータが止まればJIS環境でUSキーボードを使っているわけですから、記号などがうまく打てなくなります。それが煩わしく、いつからかCapsLockを捨てULE4JISを使うことをやめてしまいましたが、PowerToysに出会ってCapsLockを捨てなくてよくなりました。これで触れただけで知らぬ間に大文字に！？なんてことがなくなりました。

alt-ime-ahkも挙動がたまに怪しいので、CapsLockでの切り替えに慣れようと思います。ただ、alt-ime-ahkはトグルではなく、各altに英or日が割り振られているのがメリットなので離れることはできないんですよね...
PythonでChord Diagramを描画する

#はじめに
本記事ではPythonでChord Diagramを描画する方法を紹介します。
初投稿、メモ書きレベルなので至らない部分はご了承ください。
#Chord Diagramとは？
データ同士の相互関係を視覚的に分かり易く描画できる図です。
データは円周上に配置され相互関係は線で描画されます。
また線の太さは重要度に比例します。
#環境
Python3.7.6
Jupyter Lab　
(Jupyter Notebookでは動作はしますがChord Diagramが描画されませんでした)

#Chord Diagramの描画

```sample.py
from chord import Chord
#データ名
names = ["AAA","BBB","CCC","DDD","EEE"]
matrix = [
[0,5,6,4,7,4],
[0,5,6,4,7,4],
[0,5,6,4,7,4],
[0,5,6,4,7,4],
[0,5,6,4,7,4]
]
Chord(matrix,names).show()
```
#実行結果
![8aa278f0f34b54315ffe6ed2fe9acd74.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533083/7c18f3c4-ac55-e09a-86c9-0d183d622abd.png)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533083/adef7b40-0bac-e2a0-ba28-dfa94c4d2a67.png)
マウスオーバーで確認することもできます。
![bfa5fa2bf487592b9ebb24e3ac704cd7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533083/e48f20c8-bb44-ba10-302f-9175572dc2a3.gif)

#終わりに
普段R言語で書いていましたがPythonでもっと楽に書けないかなと悩んでいたので備忘録として書きました。

#参考
chord pypl https://pypi.org/project/chord/
Oracle Cloud [OCI]: DBCSへのscpでPermission Deniedが発生する場合の解決方法

プロビジョニング直後にDBCSへscpでファイルを送信する際、デフォルトの設定で/home/oracle　へデータを転送したい場合はPermission Deniedが発生します。
scpで接続するためには、転送先のフォルダおよび、公開鍵に権限設定を付与する必要があります。

この方法を実施すると、他のOSユーザも自由にファイルを配置できてしまうため、一時的にセキュリティが弱くなってしまいますが、サイズの大きいファイルを/home/oracle配下へ直接転送したい場合などのためにまとめています。
/home/oracle 配下にscpでファイル転送を行う方法をまとめています。

なお、/tmp　配下は下記の手順を実行せずとも、scp通信が可能です。

###デフォルト設定でscpでファイル転送した結果
下記のエラーが発生します。

```terminal
scp -i /Users/ipaccho/ssh-key-YYYY-MM-DD.key /Users/ipaccho/*.* opc@xxx.xxx.xxx.xxx:/home/oracle
scp: /home/oracle/apex_20.2.zip: Permission denied
scp: /home/oracle/ords-20.4.1.013.1644.zip: Permission denied
```


■参考にさせて頂いた記事
<a href="https://qiita.com/youcune/items/2f427979403771f2e03a">SSH で Permission Denied となる傾向と対策
</a>

##作業手順
1.DBCSの設定変更
　1-1./home/oracleのパーミッション変更
　1-2.opcユーザのssh関連ディレクトリ、およびauthorized_keysのパーミッション変更
2.動作確認

###今回使用したサービスと技術
・OCI Database Cloud Service
・scp

###著者の環境
Mac OS X 10.15.7

##1.DBCSの設定変更
###1-1.opcユーザのssh関連ディレクトリ、およびauthorized_keysのパーミッション変更
scpでファイルを転送するためには、/home/opc/.sshを700,/home/opc/.ssh/authorized_keysを600にする必要があります。
デフォルトでは、/home/opc/.sshは700ですが、/home/opc/.ssh/authorized_keysは644になっています。

opcユーザで接続先DBCSのauthorized_keysのパーミッションを644から600へ変更します。

```terminal
chmod 600 /home/opc/.ssh/authorized_keys
```
###1-2./home/oracleのパーミッション変更
oracleユーザのパーミッションをデフォルトの700から757へ変更します。
７５７にすると、他のOSユーザも/home/oracle配下に自由にファイルが配置でき、見ることができるため注意が必要です。

```terminal
sudo chmod 7５7 /home/oracle
```
なお、/home/opc のパーミッションを757にしてしまうと、下記のエラーが発生してしまうので要注意です。

```terminal
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
lost connection
```

##2.動作確認
著者の環境から下記スクリプトでファイルを送信しました。

```terminal
scp -i /Users/ipaccho/ssh-key-YYYY-MM-DD.key /Users/ipaccho/*.* opc@xxx.xxx.xxx.xxx:/home/oracle
apex_20.2.zip                                 100%  229MB   8.8MB/s   00:25    
ords-20.4.1.013.1644.zip                      100%   71MB   8.7MB/s   00:08  
```

エラーなく送信が完了しました。

##参考

■cloud-init公式マニュアル
<a href="https://docs.oracle.com/ja-jp/iaas/Content/Database/Concepts/overview.htm#Bare">ベア・メタルおよび仮想マシンのDBシステム</a>

###再掲
■参考にさせて頂いた記事
<a href="https://qiita.com/youcune/items/2f427979403771f2e03a">SSH で Permission Denied となる傾向と対策
</a>
ファイルシステム とは

## 勉強前イメージ

ext4 とか xfs とか？
聞いたことがあるけど、何かはしらん。
なんとなくパーティションごとにフォーマットするファイルの形式ってイメージ？

## 調査

### ファイルシステム とは

ファイルシステムとはOSとは独立しており、ファイルシステムの上にOSが乗ってるような状態です。

### OSとファイルシステムの関係性

OSをインストールする際に、HDDをファイルシステムにフォーマットします。
この `フォーマット` というのは初期化のイメージがありますが、
インストールするOSが認識する形にHDDの構成を作り変えることをいいます。
ファイルシステムはインストールするOSによってある程度決まっており、
windowsであればNTFS、linuxであればXFSやext4などというふうに
ファイルシステムにも種類があります。

![ファイルシステムUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/91ad2422-1c27-4900-8d29-f57449330c15.png)

### ファイルシステムの種類

#### FAT

歴史が古く、MS-DOSでも使用されていたファイルシステムです。
拡張性が乏しく様々な制限があります。
FAT32が流行っていましたが、最大記憶領域が2TBまでしか扱えず、
大容量データ向けに実質容量制限がない `exFAT` が普及しています。
Windows と MacOS で使用可能です。

#### NTFS

Windowsで使用されているファイルシステムで、FATにはなかった暗号化などの昨日が追加されています。
WindowsXP以降で普及しており、データ領域の破損もしづらいとのことです。
Windows のみ使用可能です。

#### HFS

HFSは Mac OS標準フォーマット と呼ばれており、
Mac OS X以降では機能が拡張されて、HFS+になり、Mac OS拡張フォーマット と呼ばれる様になりました。
MacOS で使用可能で互換性はありません。

#### ext

extended file systemの略で、linuxで昔から使用されているファイルシステムです。
ext1 から ext4 まで存在し、各バージョンの互換性はある程度保たれています。

#### XFS

こちらもext同様、linuxで使用されているファイルシステムで
extより大規模なデータに適しています。
NASはこのファイルシステムを使用されていることが多く、
XFSのファイルシステムでWindows や MacOSから中身を見ることはできません。

## 勉強後イメージ

OSで読める形にHDDの構造を変えるってことか。

## 参考

- [ファイルシステムについて｜データ復旧](https://www.rescue-center.jp/explanation/filesystem/type.html)
- [【図解】初心者向けファイルシステムの基礎知識〜仕組み, OSとの関係, アクセス権との連携〜](https://milestone-of-se.nesuke.com/sv-basic/architecture/os-and-filesystem/)
[Ruby on Rails] 　ストロングパラメータの使い方について

地味にめちゃくちゃ大事なストロングパラメータについて自身の備忘録として書いて行きたいと思います。



### ストロングパラメータとは一体何？
指定したキーを持つパラメーターのみを受け取るように制限するものです。


**ストロングパラメータ**を使用する理由は、
受け取る パラメーター を制限しなければ、仕様以外のパラメーターも使われてしまうためです。
この状態だと、意図しないデータの更新をされる可能性が発生します。

　　


ストロングパラメータの定義には
**requireメソッド**と、**permitメソッド**を組み合わせて使用します。


##requireメソッド
送信されたパラメーターの情報を持つparamsが、使用できるメソッドです。 requireメソッドは、パラメーターからどの情報を取得するか、選択します。
ストロングパラメータとして使用する場合は、主にモデル名を指定します。


####params.require(:モデル名)  
＊ 取得したい情報を指定する
＊ 基本はモデル名でそれ以外のキーも使うことが可能らしいです。



##permitメソッド
requireメソッドと同様に、paramsが使用できるメソッドです。 permitメソッドを使用すると、取得したいキーを指定でき、指定したキーと値のセットのみを取得します。


####params.require(:モデル名).permit(:キー名, :キー名) 
 ＊取得したいキーを指定する
permitメソッドでparams.requireの内容からキーを指定すると、それ以外のキーがあっても値を受け付けません。
　　

実際にやってみたいと思います。

#####【例】
まずはcreateコントローラー内に
item_paramsを定義してあげます。

![スクリーンショット 2021-02-08 0.14.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/8891423c-a6b6-a3d5-5d31-ff8077d8795a.png)

こちらがparamsの中身だとして、
![スクリーンショット 2021-02-08 0.36.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/a33ddc7a-1955-0bc7-3c53-1f9babb41396.png)



実際に入力して見ると
![スクリーンショット 2021-02-07 23.57.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/db4a3db6-7490-f9d3-e888-96a39dd6b3b4.png)

こんな感じに代入できます。
paramsの中身は**ターミナル**や**binding.pry**で確認可能です。
　　
　  
ストロングパラメータを使う際には、プライベートメソッドを使います。
##privateメソッド
これは簡単に説明すると、クラス外から呼び出すことが不可になるメソッドです。
　　
こちらでストロングパラメータの完成です。
これで特定のキーを受け取ることができるようになりました。
![スクリーンショット 2021-02-08 0.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/424c49a2-86ca-6cf4-8fd4-9ab3713e541d.png)


　　
自分はまだまだ駆け出しエンジニアなので、間違った記述等ありましたら、ご指摘、ご教示のほどよろしくお願い致します。
【GeoGebra】JavaScriptで実行する便利な関数

## はじめに
[こちらのリファレンス](https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_API)の一部を訳したものです。これらの関数の使い道としては

- ボタンが押された時に特別な処理を実行させるアプリ
- [こんな感じ](https://dev.geogebra.org/examples/html/example-api.html)のGeoGebraが埋め込まれたwebページを作成する

だと思います。教材アプリを作る分にはよっぽど使わない機能ですが、少し高度(特別な)処理を使いたい時に活躍するイメージです。つまり何が言いたいかというと「GeoGebraを始めたいけど何から始めれば...」という人向けではないです。
## コマンド

### evalCommand(String cmdString)
与えられた文字列を、GeoGebra の入力バーに入力されたときに評価されるのと同じように評価します。コマンドの評価が成功したかどうかを返します。
GeoGebra 3.2 からは、複数のコマンドを \n で区切ることで、一度に複数のコマンドを渡すことができるようになりました。

```javascript
ggbApplet.evalCommand('(0,0)')
```
**ボタンを押した際に動くようにするためには`ggbApplet`を冒頭につける必要があります。**
上のコードをボタンが押されたときの設定欄に書き込むと、(0,0)の点が追加されます。詳しくは[それ単体の記事](https://qiita.com/Hyperbolic_____/items/c64805717b7a2359cb63)を参考にしてください。
### evalCommandGetLabels(String cmdString)
evalCommand() と似ていますが、戻り値は、作成されたオブジェクトのラベルをカンマで区切ったリストを含む文字列となります。

```JavaScript
var label = ggbApplet.evalCommandGetLabels('(0,0)');
alert(label);
```

### evalCommandCAS(String string)
CASとはComputer algebra system: 数式処理システムの略称です。詳しくは[こちら](https://ja.wikipedia.org/wiki/%E6%95%B0%E5%BC%8F%E5%87%A6%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)
この関数では文字列を GeoGebra の CAS に渡し、結果を String として返します。

```JavaScript
var CAS = ggbApplet.evalCommandCAS('Circle(A,B)');
alert(CAS);
```
ボタンのスクリプト記述内に上のコードを書き込み、実行すると画像のようにCASによって導かれた方程式がアラート表示されます。
表示させる役割を果たしているのは`alert()`というJavaScriptの関数です。
![スクリーンショット 2021-02-07 19.12.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/c4ba54ae-5774-4dcf-07ca-de9d7602b60e.jpeg)

###setUndoPoint()
取り消しポイントを設定します。evalCommandのアクションを元に戻すことができるようにしたい場合に便利です。
GeoGebraソフト単体で動くサンプルが作れませんでした。
「一つ前に戻る」みたいな挙動ができそうです。


## オブジェクトの状態を設定する
オブジェクトの状態とは

- ユーザーから操作できないように固定されている
- 見えない
といったことを指しています。

### deleteObject(String objName)

```JavaScript
ggbApplet.deleteObject('A');
```
Aというオブジェクトが既に存在している時に消去することができます。

### setVisible(String ObjName, boolean)
引数に用いたオブジェクトの見える/見えないを設定できます。

```JavaScript
ggbApplet. setVisible('A', false);
```

### setLabelVisible(String ObjName, boolean)
引数のオブジェクトのラベルの見える/見えないを設定できます。

```JavaScript
ggbApplet. setLabelVisible('A', false);
```

### setFilling(String objName, double filling)
面積の透明度を設定します。線は設定できませんでした。

```JavaScript
ggbApplet. setFilling('t1', 0.7);
```

## オブジェクトの情報を取得する
オブジェクトの座標や透明度といった情報を取得します。

### getXcoord(String objName)
指定した名前のオブジェクトの直交座標を返します。オブジェクトが点やベクトルでない場合は 0 を返します。
Y座標、Z座標についても同様なので、割愛します。

```JavaScript
var x = ggbApplet.getXcoord('E');
alert(x);
```

### getObjectType(String objName)	
与えられたオブジェクトの型を文字列で返します。

```JavaScript
var t = ggbApplet.getObjectType('E');
alert(t);//point
```

pointやcircleなどの種類を返してくれます。これ結構使えそう。

## アプリそのものの構成
リセットやユーザの操作を制限するための処理を加えることができます。

### reset()
全てのオブジェクトを消去し、はじめの状態にします。

```JavaScript
ggbApplet.reset()
```

### undo()
ユーザーが最後に行った動作を取り消しできます。
### redo()
ユーザーが最後に行った動作を繰り返し実行できます。
propsのvalueのデフォルト値はtrue

next.jsのチュートリアルをやっていてたら、propsのvalue値を省略して書いてあるところがあった。

「そんなことができるのか！？」
「next.jsの仕様なのか！？」

と思って調べてみたところ[reactの公式](https://reactjs.org/docs/jsx-in-depth.html#props-default-to-true)にありました。

propのvalueを省略した場合、trueになるようです。以下の2つは同じことを意味してます。

```react
<MyTextBox autocomplete />

<MyTextBox autocomplete={true} />
```
公式的には、省略することは非推奨。

理由は、es6のオブジェクトのvalueの省略に見えてしまうため混乱するから。
`{foo}`って書いてあったら、`{foo: true}`よりも`{foo: foo}`を普通はイメージするよね！

ってことらしい。
MySQLのストレージエンジンについて

## MySQLのストレージエンジンについて
### ストレージエンジンとは?
- SQL文を受け取って結果を返すデータベースエンジン部分　⇨ つまりテーブルにデータを書き込んだり読みだしたりするプログラム
- 複数の種類があり、データの取得方法、保存方法、処理方法がストレージエンジンによって異なる
- MySQLの場合、テーブル毎にストレージエンジンを分けられる
![img](https://thinkit.co.jp/images/article/0608/1/1/1_zoom.gif)

> 上図ではMySQLサーバ内の構造を中心に図示しており、複数のストレージエンジンがプラグのマーク付きで示されています。そして、複数のストレージエンジンの配下にユーザデータファイルやログファイルを持つファイルシステムが記されていることがわかると思います。  このようにストレージエンジン部分がモジュール化されたアーキテクチャは、アプリケーションの特性の違いによって適したストレージエンジンを使用できるといったメリットを生みます。
>
>   またアプリケーション開発者は、図1の上部にあるConnector APIを通してMySQLにアクセスするため、ストレージエンジンの違いを意識する必要はありません。

#### ストレージエンジンの種類
| ストレージエンジン |                         概要                          |
| ------------------ | :---------------------------------------------------: |
| MyISAM             | MySQL標準のストレージエンジンとして使用される(旧標準) |
| InnoDB             | 行ロックとトランザクションをサポートする(現在の標準)  |
| Memory             |             メモリ上にテーブルを配置する              |
| Merge              |            複数のMyISAMテーブルを統合する             |
| Archive            |            圧縮したデータベースを使用する             |
| Federated          |           リモートのデータベースを参照する            |
| NDB                |             クラスター構成にて使用される              |
| CSV                |             データファイルにCSVを使用する             |
| Blackhole          |               ダミーテーブルを使用する                |

##### 対応エンジン確認方法
```
SHOW ENGINES;
```

##### ストレージエンジン確認方法
```
SHOW TABLE STAUS WHERE NAME = [テーブル名] \G;
```
#### 代表的なストレージエンジン
- MyIsam
- InnoDB
 
##### MyIsamエンジン
- 旧デフォルトストレージエンジンでバランスが良かったらしい
- トランザクション非対応
- レコードレベルのロックをサポートしない　⇨ 故にロックの粒度がテーブル単位になる
- クラッシュセーフでない　⇨ なんらかの事情によりプロセスがダウンしたり、マシンが電源毎落ちた場合、再起動後に元の状態に戻って処理を再開できない
- クラッシュしやすく、Innodbよりも復旧にかかる時間が長い
- リードは早いので参照が多いテーブル構成だとInnoDBよりパフォーマンスが高い

##### InnoDBエンジン
- 現在のデフォルト
- トランザクション対応
- クラッシュセーフである
- ロックの粒度がレコード単位　⇨ ロック方法を指定できる（[参考記事](https://blog.kamipo.net/entry/2013/12/03/235900)）

テーブル毎にストレージエンジンを変更できるが、それが必ずしも良いわけではなく、バックアップとサーバーの調整が難しくなるため十分な検討が必要

#### テーブル移行
- MyISAMからInnoDBに変更するのは注意が必要　⇨ [詳細な注意点](https://qiita.com/SuguruOoki/items/fbaed055611b9416e4cc)
  
##### 参考記事
https://qiita.com/arutemyan/items/b75d240f2f5b7da98a4a
https://qiita.com/SuguruOoki/items/fbaed055611b9416e4cc
https://qiita.com/at_1016/items/33186523cfc20fb58675
https://www.dbonline.jp/mysql/myini/index4.html
Apple Developer Programへ登録ありとなしの機能の違い

■共通
https://developer.apple.com/
Apple Developer -> Acount -> ログイン

![スクリーンショット 2021-02-07 23.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136142/3d0f83b5-4d7d-ce42-dd9d-2e374fc5854f.png)


■Apple Developer Programへ登録されている時だけ表示されるメニュー

![スクリーンショット 2021-02-07 23.45.29 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136142/b871ea6c-ab61-baa4-84d1-979f72e5b9b1.png)

![スクリーンショット 2021-02-07 23.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136142/1edf5114-563f-b978-8026-d90af586c8e6.png)