OmniAICreator/Qiita-1.07M huggingface dataset:
Design Patterns in Python: Introduction

#What is a design pattern? 

Design patterns are widely accepted solutions to recurring problems.

#Why do we need them?

Reusing these patterns saves our time to reinvent the wheel and encourage us to adopt the best practices.

#Facts about design patterns
- language-neutral
- dynamic
- intentionally incomplete for possible customization

#Three major design patterns
- Creational : Polymorphism
- Structural : Inheritance
- Behavioral : Methods and their signatures

**Polymorphism:** 
1. relies on inheritance
2. Allows child classes to be instantiated and treated as the same type as its parent
3. Enables a parent class to be manifested into any of its child classes

# A Pattern Context
- Participants: classes
- Quality attributes: Usability, modifiability, reliability, etc
- Forces: various factors or trade-offs to consider
- Consequences: side effects

#Pattern Language
- Name: should be meaningful and memorable 
- Context
- Problem
- Solution: **Structure:** relationships among elements; **Behavior:** interactions
- Related patterns

#Links 
[Creational Patterns](https://qiita.com/Violet_Bing/items/abe6971534438df8480b)

[Structural Patterns](https://qiita.com/Violet_Bing/items/9c735799dd4a65dafe92)

[Behavioral Patterns]
(https://qiita.com/Violet_Bing/items/7d10b9c71dcc70aae430)
___
To be continued...
Ubuntu 18.04でAudexを使う

#Audexとは？
AudexはKDE向けに作られたオーディオCDのリッピングソフトです。Ubuntu向けのリッピングソフトで有名なものにAsunderがありますが、取り込み時にジャケット写真のダウンロードや手動付与を行うことが出来ず別途EasyTAGなどのソフトを利用する必要がありました。一方、Audexはジャケット写真の付与機能が含まれているとても便利なソフトです。便利なのですが、Ubuntu 16.04まで公式リポジトリに含まれていたもののそれ以降のバージョンでは利用できないという問題がありました。
Audex有能だったのにインストールできないよぉ～つらいな:cry:という人の助けになればと思います。

# How to install?
やることは簡単です。3つほどパッケージをダウンロードしてインストールするだけです。

## 必要なパッケージのダウンロード
### ブラウザから入れる場合
- [libkcompactdisc4](https://packages.ubuntu.com/ja/xenial/amd64/libkcompactdisc4/download)
- [libkcddb4](https://packages.ubuntu.com/ja/xenial/amd64/libkcddb4/download)
- [Audex](https://debian.pkgs.org/9/debian-main-amd64/audex_0.79-1+b1_amd64.deb.html)

libkcompactdisc4とlibkcddb4の2つはお好きなミラーサーバーからダウンロードしてください。たまに使えないものもありますがどれかは生き残っているでしょう。
Audex本体のダウンロードですが、リンク先中段にあるDownloadの項目にある.debパッケージへの直リンクを開くとダウンロードできます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322441/5ba74ee1-2cfa-2e6e-a941-72732f632039.png)
### wgetを使う場合
Kernel.orgからダウンロードしていますが、もしダウンロードできなければこちらも適宜ミラーサーバーを変更してください。
**libkcompactdisc4**
`wget http://mirrors.kernel.org/ubuntu/pool/universe/libk/libkcompactdisc/libkcompactdisc4_15.12.3-0ubuntu1_amd64.deb`
**libckddb4**
`wget http://mirrors.kernel.org/ubuntu/pool/universe/libk/libkcddb/libkcddb4_15.12.3-0ubuntu1_amd64.deb`
**Audex**
`wget http://ftp.br.debian.org/debian/pool/main/a/audex/audex_0.79-1+b1_amd64.deb`
## パッケージのインストール
ダウンロードしたパッケージをインストールしていきます。
GUI上のパッケージマネージャやdpkgでもインストールできると思いますが、問題が起こると面倒なのでgdebiを使うのが良いと思います。
`sudo apt install gdebi`

ここが重要なポイントなのですが、パッケージは上に記載したリンクと同じ順番でダウンロードしてください。Audexをインストールするにはlibcddb4が必須、libkcddb4をインストールするにはlibkcompactdisc4が必須なので順番が違うとインストールできません。

**libcompactdisc4のインストール**
`sudo gdebi libkcompactdisc4_15.12.3-0ubuntu1_amd64.deb`

**libcddb4のインストール**
`sudo gdebi llibkcddb4_15.12.3-0ubuntu1_amd64.deb`

**Audexのインストール**
`sudo gdebi audex_0.79-1+b1_amd64.deb`

##  インストール完了
インストールが完了すると以下のようなAudexが使えます。ちなみにMacじゃなくて見た目めちゃくちゃいじってあるUbuntu系OSです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322441/a0736cb8-b785-6513-7ef3-2c2ecc02b3c6.png)
excellで数値を文字列として表示

excelで[-a]と入力した際に[#NAME]となってしまったので備忘録。

##セルの書式設定→表示形式→[文字列]

上記で[-a]と素直に表示されるようになりました。
googleドライブしか使わねえよと腹を括っていたのですが、やっぱexcelも少しは出来ないとな。
WinSCPでタブを全て閉じたとき、終了させない

WinSCPの挙動が何か変わってしまって（？）、タブを全て閉じるとソフトが終了するようになってしまった。
設定画面のどっかでそんな雰囲気の文言を見たことあるけど、、、どこだ？！

「環境」-「ウィンドウ」-「その他」
![4a7550e91b484ad4705bc9c5f44ef312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28556/f71ef2f0-9002-098a-acad-d00e3d18a030.png)

”すべてのセッションを閉じてもウィンドウを閉じない”
ここだ！！:smiley:

コロナ状況下の停滞感で、必須じゃないことをする気持ちの余裕ができてきた:older_man:
AWS CDKで使用するSystems Managerのパラメータの作成方法

## はじめに
AWS CDKを使用する時、ARNなどをコードにベタ書きすると、セキュリティ面がいまいちなので、Systems Managerのパラメータストアにセキュアにしたい値を入れて使いたいなと思いました。

もともとはパラメータストアのスタックもCDKのデプロイ時にcontextとかから、渡して作成したいなと思っていたのですが、現状それはできなさそうです。

## じゃあどうすればいいのか？
それはAWSのドキュメントに書いてありました。
https://docs.aws.amazon.com/cdk/latest/guide/get_ssm_value.html#ssm_write
どうやらSystems Managerへのパラメータの登録はAWS CLIからのようです。つまりCDKからは厳しそうですね。

## パラメータ登録用のスクリプト
CDKでは「必要なパラメータのリストを一覧して、多くのパラメータを一気に登録する」ということができなさそうだったので、登録用のスクリプトを作成しました。

```create_parameters.sh
#!/bin/bash

#
# パラメータキーの一覧表示
#
key=("PARA1" "PARA2")
declare -a value
echo "登録が必要なパラメータキー一覧です"
echo
for ((i=0;i<${#key[@]};i++))
do
  echo "${key[i]}"
done

#
# パラメータキーの正誤確認
#
while :
do
  echo
  read -p "パラメータキー一覧は正しいですか？(y/n): " PARAM_CHECK
  case "$PARAM_CHECK" in
  [yY])
    echo
    echo "パラメータの値を入力してください"
    break
    ;;
  [nN])
    echo "パラメータキー一覧の編集をしてください"
    exit
    ;;
  *)
    echo "yかnのみ入力してください"
  esac
done

#
# パラメータ値の入力
#
for ((i=0;i<${#key[@]};i++))
do
  read -p "${key[i]}: " VALUE
  value[i]=$VALUE
done
echo
echo "入力した値の一覧です"
echo
for ((i=0;i<${#key[@]};i++))
do
  echo "${key[i]}: ${value[i]}"
done

#
# パラメータ値の入力内容確認
#
while :
do
  echo
  read -p "入力した値は正しいですか？(y/n): " VALUE_CHECK
  case "$VALUE_CHECK" in
    [yY])
      echo
      read -p "パラメータを登録するAWSプロファイル名を入力してください: " PROFILE
      break
      ;;
    [nN])
      echo "パラメータの値を入力し直してください"
      exit
      ;;
    *)
      echo "yかnのみ入力してください"
  esac
done

#
# パラメータの登録
#
echo
echo " パラメータを登録しています"

for ((i=0;i<${#key[@]};i++))
do
  aws ssm put-parameter --overwrite --name "${key[i]}" --type "SecureString" --value "${value[i]}" --profile $PROFILE
done
echo " 登録が完了しました。"

```

このshファイル内の`key`リストのところに登録したいパラメータキーを予め入力しておいて

```
$ sh create_parameters.sh
```
を実行し、表示された案内に沿って値を入力していけば、パラメータストアに値を登録することができます。（すでに登録されている場合は上書きされます。）
【ReactNative+Typescript】ローカルDBでRealmを使う

# 概要
`ReactNative`と`Typescript`のプロジェクトにローカルDBとして`Realm`をインストール・使用する際のメモ。
環境は以下の通り。

- node @10.15.0
- react-native @0.61.5
- typescript @3.5.3

# インストール

`node`のバージョンが`10.X`系にする必要がある。

```
install --save realm
```

※`react-native`のバージョンが`0.59`以下の場合は要`link`

## iOSの場合
要`CocoaPods`

```
cd ios
pod install
```

# 実装

```javascript
import Realm from 'realm'

// スキーマ名
const HOGE_SCHEMA_NAME : string = 'HOGE';

// スキーマ定義
const HOGE_SCHEMA : Realm.ObjectSchema = {
    // スキーマ名
    name : HOGE_SCHEMA_NAME ,
    // 主キー(省略可)
    primaryKey : 'prop1',
    // プロパティ
    properties: {
        // 型のみ指定
        prop1 : 'int',
        // 型と初期値を指定
        prop2 : { type : 'string', default : 'hoge' },
    }
}

// データIF
interface Hoge {
    prop1 : number,
    prop2 : string,
}

// DB操作開始
Realm.open({
    schema : [HOGE_SCHEMA]
}).then((realm : Realm) => {
    // write()でトランザクションを開始する
    realm.write(() => {
        // primaryKeyを指定しているならcreate()はupsertとして働かせることもできる(その場合は第3引数にtrue)を渡す
        realm.create(HOGE_SCHEMA_NAME , { prop1: 0, prop2 : 'test' });
        // 削除はdelete()もしくはdeleteAll()
    });
    
    // objects(schemaName : string)でデータを取得
    const datas : Realm.Results<Hoge> = realm.objects(HOGE_SCHEMA_NAME);
});

```

# 参考
- [Realm公式](https://realm.io/jp)
プログラマ脳を鍛える数学パズルQ03カードを裏返せ

#問題概要
100枚のカードを1回目は1枚おき、2回目は2枚おき・・・に裏返していって最後に裏返っているカードを求める。

#Code
```python
#Q03カードを裏返せ

cards0 = [-1]*100 #最初。1=表, -1=裏
cards = [-1, 1]*50  #2つ目
step = 3 #何枚おきに裏返すか

#step枚ごとにカードを裏返す。裏返すカードがなくなったら終了
while cards0 != cards:
    cards0 = cards[:]
    for i in range(step-1, len(cards), step):
        cards[i] *=  -1
    step += 1

#裏返っているカードが何枚目かを表示する
backs = [i+1 for i in range(len(cards)) if cards[i] == -1]
print(backs)
```

#参考
##配列の生成
```python
list1 = [0] * 3 
print(list1) # [0, 0, 0]

list2 = [0, 1] * 3
print(list2) # [0, 1, 0, 1, 0, 1]
```
参考：https://note.nkmk.me/python-list-initialize/

##配列のコピー

Pythonでは ~~配列のコピーは参照渡しなので~~ リスト型は**ミュータブル**オブジェクトで、~~コピーを作ったとき~~ 単純な変数代入ではオブジェクトのコピーを作らずにオブジェクトを共有するため、片方の変数からリスト内容を変更するともう片方の変数のリスト内容も変更される。
※ @shiracamusさんのコメントを元に訂正しました。ありがとうございました。

```python
a = [1, 2, 3]
b = a
b[2] = 4
print(b) #[1, 2, 4]
print(a) #[1, 2, 4]
```

~~値渡しをしたいとき~~ 独立したコピーを作りたいときはスライスを使う。

```python
a = [1, 2, 3]
b = a[:]
b[2] = 4
print(b) #[1, 2, 4]
print(a) #[1, 2, 3]
```

参考：https://qiita.com/hrs1985/items/4e7bba39a35056de4e73

##ミュータブルとイミュータブル
> オブジェクトによっては 値 を変更することが可能です。値を変更できるオブジェクトのことを mutable と呼びます。生成後に値を変更できないオブジェクトのことを immutable と呼びます。

https://docs.python.org/ja/3/reference/datamodel.html

ミュータブル：リスト、ディクショナリ、セットなど
イミュータブル：数値、文字列、タプルなど

どういうことかというと、イミュータブルなオブジェクトの値を変更しようとすると、新しいオブジェクトが生成される。ミュータブルなオブジェクトでは既存のオブジェクトの値が変更される。
そのため、変数をコピーした時の挙動が異なる。

```python:イミュータブルな例
a=b=1
print(id(a)) # 140716556333904
a=2
print(id(a)) # 140716556333936 ★新しいオブジェクトが生成される
print(b) #1 ★aの変更はbに影響しない
```

```python:ミュータブルな例
a=b=['hoge']
print(id(a)) #2667037271944
a[0] = 'fuga'
print(id(a)) #2667037271944 ★既存のオブジェクトが変更される
print(b) #['fuga'] ★aの変更はbに影響する
```

##リスト内包表記
```python
backs = [i+1 for i in range(len(cards)) if cards[i] == -1]
print(backs)
```
は以下と同じ

```python
backs=[]
for i in range(len(cards)):
    if cards[i] == -1:
        backs.append(i+1)
print(backs)
```
参考：https://note.nkmk.me/python-list-comprehension/
PHPでcsv(tsv)ファイルを読み込み・書き出しする方法

PHPでcsvファイルまたはtsvファイルの読み込み・書き出しする方法を紹介します。
どちらのファイルも手順と使用する関数は同じです。
(関数に指定するパラメータは一部異なります。)

■補足情報
csvファイル…データがカンマ(,)で区切られた形式のファイル。
tsvファイル…データがタブ(/t)で区切られた形式のファイル。

■手順
・「読み込み」の場合
1：fopen関数で読み込むファイルを指定する
2：fgetcsv関数でファイル内のデータを読み込む
3：fclose関数で読み込んでいたファイルを閉じる

~~~
<?php
//読み込み("r")でファイルを指定
$fo = fopen("FileName_r.csv", "r");

if (true == $fo) {
    //ファイル内の列を配列形式で$dataに格納する
    //tsvファイルの場合は「fgetcsv($fo, 0, "\t")」とする
    while ($data = fgetcsv($fo)) {
    //$dataに対する処理がある場合はここに記載
    }
}

//読み込んでいたファイルを閉じる
fclose($fo);
~~~

・書き出しの場合
1：fopen関数で書き込むファイルを指定する
2：fputcsv関数でファイルに書き込みを行う
3：fclose関数で書き込んでいたファイルを閉じる

~~~
<?php
//書き出し("w")でファイルを指定
$fp = fopen("FileName_w.csv", "w");

//csv(tsv)ファイルに配列形式の変数($data)をデータとして追加します
//tsvファイルの場合は「fputcsv($fp, $data, "\t")」とする
if (true == $fp) {
    fputcsv($fp, $data);
}

//書き出していたファイルを閉じる
fclose($fp);
}
~~~

読み込みと書き込みを同時に行う場合は、以下のようになります。

~~~
<?php
$fo = fopen("FileName_r.csv", "r");
$fp = fopen("FileName_w.csv", "w");

if (true == $fo) {
    while ($data = fgetcsv($fo)) {
    //$dataに対する処理がある場合はここに記載

        //$dataを列として書き出しファイルに追加
        if (true == $fp) {
	    fputcsv($fp, $data);
	}
    }

fclose($fo);
fclose($fp);
}
~~~
TLS 1.0/1.1 やめるとどうなるか

なんでやりたいのか
---
（もうすこし真面目に書きます・・・）
そもそも、やりたいことはTLS1.0/1.1をやめるサイトが増えている中、クライアントにはどんな画面が帰るんだろうか・・・　という疑問がスタートです。みんなやっているので、それを見ればいいんですが、やりたがりーなので。

ブラウザにTLS1.*の縛りを入れる
---
Google先生からIE、Safari、CromeでそれぞれTLS1.0/1.1をやめる方法が出てくるも、自分の環境ではその画面にたどり着けず。FireFoxだとかなり自由に操作できるってことで、FireFoxさんに犠牲になってもらいました。
`about:config`
とすると、詳細設定画面に飛べるので、
`security.tls.version.max 1 `
`security.tls.version.min 1 `
つまり、TLSの最高〜最低1.*ですって縛りを入れます。
![スクリーンショット 2020-03-28 12.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615025/5f965151-999b-ca06-f64a-bf6e94f3c057.png)

ブラウザはTLS1.0/1.1でしかアクセスできなくなったはずなので、お試しでJCBのサイトにアクセス。以下のようなエラーMSGが表示されて門前払いされました（成功ですね！）。
![スクリーンショット 2020-03-28 12.27.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615025/9132136d-5835-c6b8-9055-270c450c5355.png)

実験用のApache
---
Amazon Linux上のApacheはSSL化済み。TLSはALLにしているので！マークはつくものの接続は可能。
（この警告は、自己証明書を使っているため出力されているもの）
![スクリーンショット 2020-03-28 12.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615025/9b4987c0-7815-0acd-d353-134811790a77.png)
南京錠に「！」がついている。ちなみに、インスタンスは落としてるので、このIPには何もいません。
（ネギネギうるさいのは、Nginxを触ってた時のサンプルページなので気にしないで。。。　ネギは美味しい）
![スクリーンショット 2020-03-28 12.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615025/1aadf4ad-0f2a-8856-85c4-ea066df0dcab.png)

ApacheでTLS1.2のみ許容に変更する。
---
触るのは ssl.conf
旧）`SSLProtocol all -SSLv3`
新）`SSLProtocol -all +TLSv1.2`

それで、もう一度アクセス。
先ほど！であっても表示されたページが表示すらできなくなった。
（注意がいるのが、コンテンツ変更していないと、キャッシュクリアしないとサイトが”見えた”風になるので・・・）
![スクリーンショット 2020-03-28 12.27.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615025/b058bc42-e61b-a763-7b14-0b16963da8b7.png)

ログ上はどうなってる
---
で、その時のログはどうなっているんだよって気になりまして・・・ログを確認して見ました。

```title:ssl_error_log
[ssl:warn] [pid 3752] AH01909: (省略) server certificate does NOT include an ID which matches the server name
```
TLS1.*縛りでアクセスして怒られた時のエラー。。（ちょっとなにエラーなのかは調べ中）

```title:ssl_request_log 
(IPアドレス) TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 "GET / HTTP/1.1" 110 
```
TLS1.2が使える状態でアクセスが成功した時のログ。使用したCipherSuiteが出てくるっぽい。
まとめ
---
Apacheおじさんのデビュー戦ですけど、枯れた領域ですが勉強することが多いです。TLS1.*縛りで有名企業のHPにアクセスしてみると、いろいろバラツキがあって「へぇー」って思いました。
OMCでWordPressを監視する

Wordpressの運用監視されていますか？ レンタルサーバの標準機能を使う、SaaSだから気にしない、Zabbixで監視する、色々な選択肢がありますね。

ここでは、Oracle Management Cloudを使って、WordpressのアプリケーションとApacheやMySQLといったWordpressを構成するインフラの部分を監視する方法を紹介します。

ご存知の通りWordpressはPHPで記述されています。OMC APM(Application Performance Monitoring)は主にJavaや.NETで作成されたWEBアプリケーションを監視する機能でPHPを直接サポートしていません。
ただ、APMの機能の一部であるブラウザエージェントというJava ScriptをHTMLに直接埋め込むことで実際のユーザーのブラウザ操作やページリクエストの体感パフォーマンスを測定することできます。

また、OMC IM(Infrastructure Monitoring)でLinuxやApache, MySQLといったWordpressを構成するインフラ・リソースの稼働監視をすることもできます。

Wordpressにアクセスできない、レスポンスが異常に遅いという問題が発生した場合に、アラートで迅速な検知をし、どのレイヤーの問題なのか、原因特定に素早く対応するための活用が期待されます。

## APMのブラウザエージェントをWordpressで使う

- ブラウザエージェントのJava Scriptをすべてコピーする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/870dc918-f511-df55-1152-f43be4065b9b.png)

- WordPressにJava Scriptプラグインを追加し、コピーしたJava Scriptを貼り付けて、Page Headerに追加する
  以下は、Simple Custom CSS and JSプラグインの使用例 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/a057dba0-2b3f-0439-3cac-23e2de46d1c1.png)

- ブラウザエージェントを有効化した場合のAPMでの情報の見え方 ～ ページ一覧 ～
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/fb97809a-f9a1-25cc-877c-c316d4c331bc.png)

- ページ・アクセスの詳細情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/c7e1537d-438b-c430-cdca-329aa54fd212.png)

- ブラウザ上での実際のユーザ操作とレスポンスが記録される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/2c9ee133-99c3-a252-aca2-8a404dc8be9b.png)

## WordPressリソースの監視

- WordPressに対して定期的にアクセスしてヘルスチェックを行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/796ab911-0f23-f824-7c8e-1d0ae1cdf711.png)

- ヘルスチェックの結果。レスポンスが無い、実行時間が設定したしきい値を超えたらアラートで通知するなどで自動化できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/40ec90e0-5cbf-c300-5705-ceb5be5498df.png)

- OSの稼働状況
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/d6f7c7a7-fbed-25c4-09f5-98a19be73f52.png)

- Apacheの稼働状況
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/65e44674-247f-b530-fc37-d0575020b485.png)

- アラートの設定。Apacheのダウン検知、または特定の値のしきい値を超えた場合など
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b607d432-3ecc-4478-8684-70c459bf5667.png)

- 実際に通知されるアラートメール。レビュー詳細はOMCへのリンク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/2218d099-8065-d210-1641-2b650c57fdbb.png)

OSやApache等のミドルウェアを監視する場合はCloud Agentのインストールが必要です。Log Analyticsを組み合わせてログ分析も同時に行うとより多角的に監視できるかと思います。


Oracle Management Cloud関連の情報は[こちら](https://qiita.com/western24/items/1e44bfcaa77f3251a263)
【追記予定】Intellij ideaのショートカット比較

MacとWindowsでのIntellij ideaのショートカットの違いに困惑したので、個人的によく使うものだけをとりあえず一覧化した。
RubyMineやWebStormなんかもKeymap自体は同じなんじゃないかと思う。
まとめきれてないので追記予定。

|Action             |Mac      |Windows         |
|:-----------------:|:-------:|:--------------:|
|エディタタブを閉じる|command+W|Ctrl+F4         |
|設定               |command+,|Ctrl+Alt+S      |
|プロジェクト設定   |command+;|Ctrl+Alt+Shift+S |
|定義元へジャンプ   |command+B|Ctrl+B           |
|インテンション・アクションの表示 |shift+enter|Alt+Enter|
Microsoft Teams | 10分でできる Microsoft Teams を使った授業 | 課題の提出

関連記事は[**「Microsoft Teams の授業での活用」**](https://qiita.com/hisaho/items/12837a169bd6f1d90d5c)をご参照ください。

# はじめに

本記事では、Microsoft Teams を活用して授業を実施するための方法を解説いたします。
今回は **「課題の提出」**について説明します。

#課題の提出
- 学生の Teams の **[最新情報]** に課題が出されたことが通知されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/a459d81a-6430-2309-f8c6-8c7d8d471adc.png)
- では早速出された課題を解いていきましょう。**[View assignment]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/e090d8fe-6261-f912-12e9-f446b98599be.png)
- **[参考資料]**に添付されているファイル名の左の**[...]**をクリックし、**[ダウンロード]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/e55ecbf4-dfdd-40af-b46a-66582fd44359.png)
- PCのダウンロードフォルダにワークシートが保存されます。ダブルクリックすると Edgeブラウザが起動してPDFが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/99543bee-86b6-8015-9a61-5de9fb43ff97.png)
- Microsoft Edge ブラウザは、PDFの表示および手書き入力に対応しています。(**※新しい Edge ブラウザは、2020/04/07時点では手書き入力に対応していませんのでご注意下さい**。)　画面右上の**[ペンアイコン]**をクリックすると、手書き入力ができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/c215fc7f-df95-80fc-1eac-e818ccbebfab.png)
- **Surface GO + Surfaceペン** で実際に回答している[**動画を公開してますのでご覧ください。**](https://1drv.ms/v/s!AkVwRd2ThNyEh4lqo4kLi2Xv3wcmLA?e=yxJgOQ)。Surfaceペンは、ペンのお尻が消しゴムになっていますので、鉛筆と消しゴムを使うのと同じ感覚で利用することができます。
-　最後に画面右上の**[保存]**のアイコンをクリックし、ファイルを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/7f9580a2-9dcc-e595-3dfb-600d18800289.png)
- Teams の戻り、**[作業の追加]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/be9657e2-217d-55e9-a385-000e83d5970f.png)
- **[このデバイスからアップロード]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/b5244e10-b251-f595-37e6-d9e2ce093a86.png)
- **ワークシートファイル** を選び、**[開く]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/7335e910-1c53-09c4-e677-23253054930a.png)
- **[完了]** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/88817d4c-519a-3e4b-50e6-9b33491be3e5.png)
- **[自分の作業]** にファイルがアップロードされました。**[提出]** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/1c874a93-b4c3-26d6-7e55-074ab48cb577.png)
- 提出後、**[提出を取り消す]**こともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/02bf501a-39a0-a5dc-b5c5-829e4502ab0b.png)
- これで課題提出の一連の作業は完了です。

次回はマークシート方式の課題の作成に関して解説いたします。
Openpose 3D化に挑戦してみた話


##3D化の目的
・動作解析をするため

##3D情報を取得する方法
大まかに分けて2つ。
1. 複数のカメラを使用する。
　- 2つ以上の画像とカメラキャリブレーションが必要
2. 単眼カメラを使用する。
　- 機械学習による復元
　- 事前に3Dモデルの学習が必要

今回は2.の単眼カメラを用いた，機械学習手法の3D情報取得に挑戦しました。

##3d-pose-baselineの概要
教師データはHuman 3.6を使用。
Human 3.6はモーションキャプチャシステムで11人の様々な動作を計360万フレーム取得した，巨大な学習モデルである。

[A simple yet effective baseline for 3d human pose estimation](https://arxiv.org/pdf/1705.03098.pdf)

[3d-pose-baseline]
(https://github.com/una-dinosauria/3d-pose-baseline)

##windowsで3d-pose-baseline-vmdを正常に起動させるには
基本的には，miu様が書いてくださった，[MMDモーショントレース自動化への挑戦](https://qiita.com/miu200521358/items/fdedbca879cb079e407c#3d-pose-baseline) の手順に従えば，問題なく動くのですが・・・・。
技術的に嵌まった部分を共有したいと思います。
また、Openpose-1.5.0でも動いたので、紹介します。

＊Openposeの導入は省略

###①環境のセットアップ
最も大切なことは，Versionの確認。（この部分を怠るとハマる）
Versionの対応をすべて確認してからインストールする！

~環境例~（Openpose-1.5.0）
NVIDIA Corporation GeForce RTX 2080 436.48
CUDA 10.0
cudNN 7.4
tensorflow-gpu 1.13.1
python3.6
h5py

**＜GPUのドライバの確認＞**
Windowsであれば，タスクマネージャー起動→詳細→パフォーマンスで確認できる。
私のPCはNVIDIA社のGPUなので，
https://www.nvidia.co.jp/Download/index.aspx?lang=jp
から，Versionを確認。

**＜GPUとCUDAの対応＞**
①　対応確認
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600356/c3802ce4-a872-d636-a546-f1745fdbbfa7.png)
　　参考： https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

②　CUDA Version指定してインストール→ https://developer.nvidia.com/cuda-toolkit-archive

**＜CUDAとcuDNNとPythonとtensorflow-gpuの対応＞**
①　対応確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600356/02f6526c-981b-9b2c-29bf-14220bfcc70b.png)
　　参考https://www.tensorflow.org/install/source#common_installation_problems

②　cuDNN Version指定してインストール（アカウント登録必要有）
　　→https://developer.nvidia.com/rdp/cudnn-archive

③　tensorflow-gpu Version指定してインストール
　　→https://qiita.com/miu200521358/items/9b45c181c4fd39be9c21

　　1. Anaconda インストール
　　2. Tensorflowインストール
　　3. Tensorflow (GPU版）インストール　
　　4. "<font color="Blue">conda install tensorflow-gpu==1.13.1</font>" 入力 （conda install tensorflow-gpu==**Version番号**）

###②学習データの導入失敗(H36M)
学習データをダウンロードした時に，きちんとダウンロードできたかを確認する必要があります。
**checkpoint**の中身があるかどうか確認するべし。
私は空っぽだったため，エラーになりました。
もう一度やり直したら上手くいきました。

##3D化成功!!
あとはコマンドプロントの手順に従って実行するだけ！

立位→座位→立位動作を光学式モーションキャプチャとOpenposeで撮影し、比較してみました
カメラは正面から撮影しました。
![stickpicture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600356/fbfbbd97-d928-f4df-d0ef-ba85565e8d44.gif)
やはり機械学習での奥行き推定は難しいですかね、、
でも1台のRGBカメラでここまでできるようになったのは驚きです。
スマホ1台で動作解析できるようになる日は近いっ！！
次なる技術に期待！！
Windows10をHomeからProへアップグレードしたらライセンス認証が通らなくなっていた話

## 結論
サポートに電話しましょう:innocent:

## 前提
- windowsのバージョン：1809
- アップグレードはMicrosoft Storeから実施（14,000円弱掛かります）

## 何が起きたか
自宅のWindows10をHomeからProへアップグレードしたら以下の事象が発生

- ライセンス認証が通らなくなった
- エディションが「Enterprise」になっていた（謎）
- トラブルシューティングツールを実行しても改善されない

以下の様なエラーメッセージが表示されていました

```
有効なデジタルライセンスまたはプロダクトキーをお持ちでないため、このデバイスのWindowsをライセンス認証できません。有効なライセンスまたはキーをお持ちだと考えられる場合は、下の「トラブルシューティング」を選択してください。
エラーコード:0xC004F025
```

## 調べてみる
ひとまず↓でエラーコードの意味を調べてみることに
[Windows のライセンス認証エラーに関するヘルプ](https://support.microsoft.com/ja-jp/help/10738/windows-10-get-help-with-activation-errors)

んん、、？どこにも見当たらない、、？一般的なエラーじゃないの、、？

仕方がないのでGoogle先生に「windows10 ライセンス認証エラー 0xC004F025」と尋ねてみたところ、同じ様な事象で困っている人々が居ることが判明（しかも結構良くあることなのだとか）

## 解決方法
記事冒頭にある通り、サポートに電話しました。
事象を伝えるとプロダクトキーを教えてくれるので、それを「プロダクトキーの変更」から入力するとライセンス認証が通る様になります。

## さいごに
記事を書いたのが事象解決後だったのでスクリーンショットが取れませんでした。。。
非常に見辛い記事ですが、最後まで読んで下さってありがとうございます。
Yolo v3の物体検知中にアラート画面を出す

#物体検知中にアラート画面を出す

Yolov3を使用したリアルタイムの物体検知は出来たものの、
展示会用途だとそれだけではツマラナイのでそれに反応する何かも作りたい。
結果的には~~あまりビジネスにはならない~~多くのお客様が興味を持ってくださいました。

１、物体検知でひたすら検知物を表示
２、検知した物の中からスマホ（Cell Phone）を抽出
３、スマホを見つけたら黒猫が注意する
４、5秒後に猫は消える
５、ログはどんどん溜まるのでプログラム開始時に全て上書き


#ログ収集
まずは、yoloを動かして出たログをresult.txtに全てぶち込む。
teeにしたのは今回は出力画面も見せつつログ集めをしたかったから。（デモだから。）

./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights |tee result.txt

こんな感じで見つけたものをどんどん記録。
スマホは無いか？
![yolobase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/3e29a298-c341-89e1-c4e6-6291d18adf52.png)


Yolo3を動かすまでは前の記事
https://qiita.com/qiitaroi/items/9c86d5d48c7e30da8589

#Cell phoneの抽出と画面表示

ログを参照して終わりの15行からcell phoneを検知し、あれば猫画像を出力。

```
\#!/bin/sh
while true 
 do
  tail -n 15 ./result.txt >detect.txt  　　　　 #終わりの15行を抽出してdetect.txtに書き出し
  grep "cell phone" ./detect.txt >/dev/null　#cell phoneを抽出してnullへポイ
        if [ $? = 0 ]; then　　　　　　　　　　 #もし有ったらログ側にはecho メッセージと日付を表示
                echo "Black cat watching you."
                date
                timeout 5 eog cat1.jpg　　　　　#5秒間猫の絵を表示する
        fi
 sleep 2
done
```
いた！　スマホ発見！
![yolobase2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/0d5314f3-adf7-b5dc-69e1-ad0779698215.png)


スマホ見てる人はモニターの画面なんて見ないって！？
くっ　今度はパトランプとサイレンでも付けるか。。


---
単なる思いつきからの付け焼刃なので、ログの増大など課題はあるものの、
展示会の4日分は動いていたので良しとする！
PySpark in PyCharm

MacでPySparkをPyCharmで開発する方法について記載します。

# 概要
1. SparkをMacにインストール
2. PyCharmプロジェクトからPySparkを実行できるように設定します。

前提条件:

| 項 |備考|
|:--|:--|
| python3.7 | 私はPyCharmのプロジェクトにanacondaの仮想環境を使用しています。 |  
| Java8 | |
| Homebrew | |  

# 1. Sparkのインストール
terminalで実行  

```shell
$ brew install apache-spark

Updating Homebrew...
==> Downloading https://www.apache.org/dyn/closer.lua?path=spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz
==> Downloading from http://us.mirrors.quenda.co/apache/spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz
######################################################################## 100.0%
/usr/local/Cellar/apache-spark/2.4.5: 1,059 files, 250.9MB, built in 1 minute 45 seconds
```

## 環境変数の設定
.bash_profileに以下を追記します。
SPARK_HOMEのpathは上記のSparkの結果を参照してください。

```shell
$ echo 'SPARK_HOME="/usr/local/Cellar/apache-spark/2.4.5/libexec"' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$SPARK_HOME/bin' >> ~/.bash_profile
```

# 2. PyCharmの設定
PyCharmのプロジェクトを開いて、[Preferences]->[Project Structure]-> [+ Add Content Root]で以下のpathを設定します。  
"2.4.5"のバージョンは上記を参考に入力してください。

```
/usr/local/Cellar/apache-spark/2.4.5/libexec/python
```

画面の右上にある[+ Add Content Root]で設定します。
![spark-setting0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29280/0177b6bd-899c-3c07-32b2-0441731f5069.png)

[+ Add Content Root]でダイアログが表示されますが"/usr/local/・・・"を指定する方法は、"Macintosh HD"を選択した状態で、'/'のキーを入力すると
![spark-setting1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29280/63196f60-200e-2143-a454-0a863e4d38ae.png)

'Go to the folder:'が表示されるので、ここで上記のpathを入力してください。
![spark-setting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29280/8def3e02-e87d-ca91-2f82-57db3c34754e.png)

## PyCharmプロジェクトの再起動
PyCharmプロジェクトがSparkに接続するには、プロジェクトの再起動が必要になります。PyCharmを閉じて、再起動するとSparkに接続できます。  

# 開発
これでpysparkが使えるようになります。

```python
import pyspark
```

また、PyCharm Professional版であれば、Jupyter Notebookが使えますので、PyCharm + Jupyter Notebook + Sparkで開発することができます。

PyCharm + Jupyter Notebookは以下を参考にするとよいでしょう。  
[はじめてのPyCharm ＋ Jupyter Notebook（その１）](https://blog.jetbrains.com/jp/2019/11/30/2396)
僕のSystem.IO(VB)

自分用の備忘録

##使い方
####ファイル操作
#####ファイルを読み込む

```vb
'読み込み用でファイルを開く
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(path,encoding)
    'オプション
'path:操作するファイルのパス
'encoding:System.Text.Encoding.GetEncoding("文字コード")　読み取るファイルの文字コードを指定

'ファイルを1行読み込む
Dim Line = sr.ReadLine() 

```


#####ファイルに書き込む

```vb
Dim sw As System.IO.StreamWriter = New System,IO.StreamWriter(path,append,encoding)
    'オプション
'path:操作するファイルのパス
'append:Trueで追加、Falseで上書き
'encoding:System.Text.Encoding.GetEncoding("文字コード")　読み取るファイルの文字コードを指定

'ファイルに一行書き込む
sw.WriteLine(value)

```


#####ファイルを閉じる
```vb

sr.Close()
```


##番外編
文字の入力を受け取る

```vb
Dim txt As string = InputBox("文字を入力してください")
```
WIP: コロナウイルス 下でAppleのアプリ審査にどのくらい時間がかかるか試してみた。

### 2020/2月
　
自作アプリ完成　
・ アプリ名　PriLingo
アニメ「プリパラ」シリーズを題材にした語彙を収録する。日本語・英語・中国語（簡体字&繁体字）で閲覧・音声再生ができる。お気に入り登録ができる。

![IMG_7739拷貝.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/53dc4609-d11f-e7e1-214e-fcca77721db0.png)
![IMG_7740拷貝.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/ff2ff1c0-7612-0721-f4ac-6cdd25a23e19.png)
![IMG_7741拷貝.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/81b56e3d-ccbe-ed2e-5327-4256368e3232.png)


機能としては単純で、主にApp Storeアップロードを1人で全てやる事を目的として作成した。ただ単語が200種類ほど収録しており、それらの選定・それぞれの発音記号の記載、音声の作成などに一番時間を要した。音声ファイルは、Amazon Web Services の一つである[Amazon Polly](https://aws.amazon.com/tw/polly/)を使って生成した。

### 2020/3/8 Apple Developer Program メンバーシップ（個人） 購入

<img width="758" alt="截圖 2020-04-07 11.05.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/32b5df5b-624f-4cfb-d1f7-f14f3dd0f41f.png">

アプリが完成した段階で、App Storeにアップロードするためのメンバーシップを購入した。仕事ではアプリをアップロードした事があったが、個人ではなかったため購入していなかった。

元々持っているApple IDでメンバーシップを購入した。が、なぜかSafariで購入しようとすると、ログイン時の２ファクタ認証コードを入力する欄が表示されず、ログイン自体ができなかった。とりあえずGoogle Chromeでやってみた所、無事ログインが出来、購入する事ができた。

### 2020/3/15 App Store Connectにて審査に提出

<img width="775" alt="截圖 2020-04-07 10.47.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/ef7396dd-cd22-25c9-7006-b28d601c5632.png">

「提出されたアプリのうち５０%は２４時間以内に審査される」
「９０%以上は４８時間以内に審査される」

とのことだったが・・・コロナウイルスで時間がかかっているのか翌日・翌々日連絡はなし。

### 2020/3/22 ステータスが審査中になる

ちょうど一週間経ってやっと審査が開始される。やはりコロナウイルスの影響で時間がかかっている模様。

<img width="767" alt="截圖 2020-04-07 10.48.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/5514fa05-02cf-185b-ac41-8be70fcd8894.png">

### 2020/3/23 リジェクトされる

<img width="1429" alt="截圖 2020-04-07 10.35.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/39f2915d-5014-766d-6df1-65fc41a872c0.png">
<img width="1411" alt="截圖 2020-04-07 10.35.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392332/fbd8f3af-210e-3189-6bef-f622caac4765.png">

「Apple Developer Program account is currently under investigation」などと言っており、アプリそのもののみならず私のアカウントの正当性まで問題にされている模様。

このメッセージは最初にアプリを提出したアカウントでは比較的よくあることのようだ。場合によっては１ヶ月程度かかるとのこと。（参考：https://qiita.com/gureta/items/b21b264dfa95051e67bb ）しかもAppleからの文章に記載の通り、現状ではこちらからできることは何も無い。アプリを再提出することもやめてくれと書かれている。

### 2020/4/7 

いいかげん痺れを切らしてきたので、Appleにメッセージを送り、あとどれくらいかかりそうか尋ねてみた。

>Can I ask you how long it will take you to complete investigation of my account and the app I submitted? Though I know recent social situation, but I would be glad to know the rest of time you will need even roughly.

以下、続報をお待ちください。
[Node.js] メソッド使おうとしたらあるはずなのにないよって言われた

##環境
node：v8.11.3

## あかんプログラム

```javascript:nogizaka-suko.js
getHogeData: function(user_id, callback) {
    //なんかいろいろ
},
getAllUsers: function () {
    return new Promise(function (resolve, reject) {
        //いろんな処理する
        this.getHogeData(user_id, なんかコールバック);
        //いろんな処理する
    });
},


```

##解決方法
Promiseというより二重のfunctionで囲まれた状態でthis使っていたのがまずかったのでやめた
RailsでERBを直接使い、文字列として結果を取得する

#はじめに

Railsのviewではなく、erbの結果を文字列としてほしいケースが有ったので、その方法です。

パスにRails固有のコードを使っていますが、そこ以外はRailsじゃなくても使えます。



# ERBのインスタンス生成

``` ruby
file = File.read(Rails.root.join('app', 'views', 'hoge', 'fuga.html.erb').to_s)
erb = ERB.new(file)
```

といった形でERBのインスタンスを生成できます。

Railsじゃない場合は、

```ruby
file = File.read('/path/to')
```

みたいな感じですね。



# 結果の取得

```
result_text = erb.result_with_hash(hoge:1, fuga:2)
```

で結果の取得ができます。

引数に渡したハッシュが、そのままerb内でkeyを変数名、valueを値とするローカル変数として読み込まれます。



# あとがき

erbを直接使いたい状況、そこまで多くはないとは思いますが、もし必要な方の役に立てば幸いです。
【Rails5】rails_adminで多対多の関連付けを上手く編集する方法

#はじめに
一瞬でめちゃイケてる管理画面を作ってくれる`rails_admin`
今までCRUDそれぞれ画面編集してたのはなんだったんだ……と思う完成度です。

しかし、多対多の関連付けの時、毎回のようにエラーが出ました。


#出たエラー
ActiveRecord::HasManyThroughOrderError in RailsAdmin::Main#edit


#原因
色々試しましたが、Modelでの関連付け設定の順番が原因でした。


#構成
タイトルごとに複数のタグ。
タグごとに複数のタイトル。

title has_many tags
tag has_many titles

これを実現させるために、tag_mapsというテーブルを間に挟んでいます。

[tag_maps]
id
title_id
tag_id


#解決したコード

```ruby:model/title.rb
class Title < ApplicationRecord
  has_many :tag_maps
  has_many :tags, through: :tag_maps
end
```

```ruby:model/tag_map.rb
class TagMap < ApplicationRecord
  belongs_to :title
  belongs_to :tag
end
```

```ruby:model/tag.rb
class Tag < ApplicationRecord
  has_many :tag_maps
  has_many :titles, through: :tag_maps
end
```


ただ普通に記述してるだけなのですが、なぜか順番が逆だとエラーが出ました。


#オマケの注意点
今回のこれは、Rails5での解決策でした。
（Rails 5.2.4.2）

他のバージョンでは、ここ見たら参考になるかも……？
https://github.com/sferik/rails_admin/wiki/Associations-basics

あとrails_adminの編集画面で若干表示項目が変に見えるのは……まぁええでしょ。エラー出てないし


終わり
Vagrant でCentOS構築

#Vagrant でCentOS7構築
備忘録も兼ねまして、Vagrantを使ったCentOS構築を紹介していきます
（今更感。。。）

プログラミング勉強で何かを作る事はよくありますが
大切ですよね環境構築。。。ローカルで何か作るのもいいですがソースがごちゃごちゃしたり、設定変えて元に戻すのが面倒だったり。。。
自分はファイルを間違えて消してえらい事になったので。。。
仮想だったりOS再インストールできる環境で勉強、開発する事をお勧めします。。。

環境（使っているPC）
--------
MacBookPro

前提インストール
-------
Homebrew(https://brew.sh/index_ja)

構築したい環境
---------------
VirtualBoxとVagrantを使ってのCentOS構築

手順
-------------
まずVirtualBoxとVagrantをインストールするところから始まります
VirtualBox（https://www.virtualbox.org/）
Vagrant（https://www.vagrantup.com/）
ダウンロードしてインストールもいいですがMacを使っているのでせっかくだから
Homebrewを使った構築していきます。


まずvirtualboxがインストールできるか調べる

```
$ brew search virtualbox
==> Casks
homebrew/cask-versions/virtualbox-beta
homebrew/cask-versions/virtualbox-extension-pack-beta
homebrew/cask/virtualbox
homebrew/cask/virtualbox-extension-pack
```

Casksを使ってインストールできるからしいので実施

```
$ brew cask install virtualbox
```

続いてVagrant 

```
brew search vagrant
==> Formulae
vagrant-completion
==> Casks
vagrant                    vagrant-manager            vagrant-vmware-utility
```
インストールしたいのはvagrantなのでCasksで実施

```
$  brew cask install vagrant
```

インストールが完了したら任意のディレクトリを作成

```
$ mkdir Vagrant(任意のフォルダ名)
```
作ったフォルダに移動


```
$ cd Vagrant
```

設定ファイルを作成

```
$vagrant init
```

サイトを元にVagrantファイルを変更
多分ググったらすぐに出てくる
今回はCentos7
（https://app.vagrantup.com/centos/boxes/7）

```text:Vagrant
config.vm.box = "base"
```

この部分を

```text:Vagrant
#config.vm.box = "base"
config.vm.box = "centos/7"
```
こう変える（コメントアウトしなくても"base"ー＞”centos/7”に変えるでもOK）
書き換えたら保存して起動

```
$vagrant up
```

起動できたら接続

```
$vagrant ssh
```

接続できたらOK

```
[vagrant@localhost ~]$  
```

まとめ
---------
いかがだったでしょうか、はじめての投稿だったので
レイアウトで判りにくい部分もあるかもしれません。
はじめて勉強する、右も左もわからないそんな人に少しでも力になれればと思います。
[Rails]モデル、テーブル、カラムの作成と削除コマンド

# 本記事について
開発して行く中で
「あれ？マイグレーションファイルの作成コマンドってこんなんだっけ。」
のように、ド忘れしてしまうことがあります。
そのため、メモ代わりに書きたいと思います。


## DB関係

### モデル & テーブル作成

モデル & マイグレージョンファイル作成

````
rails g model モデル名(単数)

例 : userモデル
rails g model user
````
補足ですが上のコマンドで以下が作成されます。
1. モデルのクラスファイル
2. マイグレーションファイル
3. モデルの自動テスト
4. モデルの自動テストで使うfictureファイル

実行

````
rails db:migrate
````

### モデル削除

````
rails d model モデル名(単数)
````

### テーブルの削除
主な流れ

-　マイグレーションファイル作成
-　マイグレーションを編集
-　実行

例: users テーブルの削除
マイグレージョンファイルの作成

````
rails g migration DropTableUsers
````
マイグレーションファイルの編集

````2020xxxxx.rb
class DropTableUsers < ActiveRecord::Migration

  def change
    drop_table :users
  end

end
````

実行

````
rails db:migrate
````

### 既存のテーブルにカラムを追加

rails g Addカラム名Toテーブル名 カラム名:カラム型
の形でターミナルに入力しマイグレーションファイルを作成します。

例: usersテーブルにstring型nameカラムを追加

````
rails g migration AddNameToUsers name:string
````

実行

````
rails db:migrate
````

### 既存のテーブルのカラムを削除

rails g migration Removeカラム名Fromテーブル名 カラム名:テーブル名
の形でターミナルに入力しマイグレーションファイルを作成します。

例: usersテーブルのstring型nameカラムを削除

````
rails g migration RemoveNameFromUsers name:string
````

実行

````
rails db:migrate
````

# おわり
最後まで見ていただきありがとうございました。
サブネット(基本的なこと)〜個人的備忘録〜

AWSで仮想ネットワークを構築する際にVPCにサブネットを作ったので忘れないようにまとめます。
間違った部分があったらご指摘いただけると幸いです。

VPC(172.31.0.0/16)に
サブネットを３つ指定する
A　172.31.0.0/20
B　172.31.16.0/20
Cサブネットを作りたい時、
![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550166/2c4e9f80-0a6d-f83c-01ee-da9b8a876c4a.jpeg)

パソコン内では二進法で処理されているので十進法から直して考える。
IPアドレスは合計で32ビットまでの範囲を数字として持っているので（一区切り８ビット×４）
Bはこんな感じに。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550166/f632cede-f61a-8edd-7bd0-3cbb1fc03706.jpeg)
/20とあるので頭から２０ビット（赤文字）がネットワーク部、残りの青い部分がホスト部。
サブネットを変えるには赤文字のネットワーク部を変えなければいけない。
もしCを　255.240.17.1 としてしまうと
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550166/d781e0d6-033b-e730-4081-f4d66dd45b7d.jpeg)
こうなってしまう。そうすると赤文字のネットワーク部が変わっていないのでサブネットは別れない。
![b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550166/3338369f-183f-893d-4a86-ac3d0ef70843.jpeg)
そのためCは　255.240.32.1　にしてあげると
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550166/f4129c28-19ad-dcac-e028-8782e3149d70.jpeg)
と赤文字のネットワーク部を変えてあげることができる。


おしまい


参考
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典（CIDR）
https://wa3.i-3-i.info/word11989.html
2進数の変換方法
https://sci-pursuit.com/math/binary-number-conversion.html
axiosでリクエストせずにURLを生成だけする

oauth認証用のURLを生成だけしてクライアントに返したいときなど、リクエストはしないけどaxiosでクエリパラメタをURLエンコードしたURLを作りたいことがあります。
こんな感じでできます。

```
const axiosInstance = axis.create();
const url = axiosInstance.getUri({
    url: 'https://example.com',
    params: {
        hoge:"hogehoge",
        fuga:"あいうえお",
    }
});
console.log(url); // https://example.com?hoge=hogehoge&encoded=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A

```
Sign in with apple実装中に、サーバーサイド側でJWTを検証しようとしたところ、Signature verification raisedが発生する

iOSクライアントからJwt送信 -> Rails側でデコードをする場合に `Signature verification raised`が発生した
各種パラメーターは正しく与えているのにデコードに失敗してしまう
jwtの有効期限が切れたのかと思ったがそういうわけでもないようだった
結論、keysの正しいkidを選択していなかったことだった
Appleのサイトから証明書のjsonを取得すると、keysが２つあるのに気づいていた
確認したところ、デコードに使えるのは片方１つのみで、それはjwtの中に指定されている
正しいkeyのkidを指定したところ、うまく動くようになった
Jest encountered an unexpected token解決法

react-native-cameraを使ったアプリのテストをJestでする際、こんなエラーに遭遇した


      TypeError: Cannot read property 'Aspect' of undefined

      at Object.<anonymous> (node_modules/react-native-camera/src/Camera.js:425:113)
      at Object.<anonymous> (node_modules/react-native-camera/src/index.js:3:38)


他にもreact-native-unimodulesで

    Jest encountered an unexpected token

なんかが出たりする

結論から先に書くと、これらのエラーは

    jest.mock('{モジュール名}', () => '{クラス名}');

でモック化すると解決した。

react-native-cameraなら

    jest.mock('react-native-camera', () => 'Camera');

となる。

[Jest公式によると](https://jestjs.io/docs/en/tutorial-react-native#mock-native-modules-using-jestmock)、react-nativeに組み込まれたJestプリセットにはデフォルトのモックが付属しているものの、いくつかのコンポーネントにはそれが無く、ネイティブコードに依存しているためマニュアルでモック化する必要があるとかなんとか

正直Jestのモックとはそもそも何ぞや？というところからわかっておらず現状おまじないと化してるので、後で調べておきたい
Ubuntu 18.04 に XFce をインストールしてみる

Xojo IDE を Ubuntu 18.04 で動かしたときの日本語問題
「https://qiita.com/nanbuwks/items/b6eec25070661b73e3a2」
のテストのために　XFce をインストールしてみました。



# インストール作業


```

 sudo apt install -y xubuntu-desktop
```

途中、ディスプレイマネージャの選択が出てくるので、lightdmを選択する。

```


                    ┌────┤ lightdm を設定しています ├─────┐
                    │ Default display manager:            │ 
                    │                                     │ 
                    │              gdm3                   │ 
                    │              lightdm                │ 
                    │                                     │ 
                    │                                     │ 
                    │               <了解>                │ 
                    │                                     │ 
                    └─────────────────────────────────────┘ 
```                                                            

再起動したら、Xfceが使えるようになりました。
![スクリーンショット_2020-04-07_18-59-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e939a067-0162-5deb-d650-eeea613160e4.png)



# Xfce　自体の問題点

インストール後に気づいた XFce 自体の問題点

## 日本語の起動にコツがいる。

「半角/全角」キーで日本語変換が起動しない。画面右上の「入力モード」で設定すれば、それ以降は「半角/全角」キーで日本語変換が起動する。

## スクリーンキャプチャの問題

Alt+Print Screen　でアプリのスクリーンキャプチャが取れない。
Print Screenで画面全体のスクリーンキャプチャをクリップボードに入れても、Qiitaに貼り付けできない。
openpyxlのごく一部備忘録

# 概要
機能が多くて一覧化したほうが後々色々やりやすいってことで、列挙。
あくまでも自分で使ったもののみなのでこれで全部ではないです。
細かいところは[公式](https://openpyxl.readthedocs.io/en/stable/)を参照ください。

## 新しいブックを作る
ブックを作って1つシートも作る。
以降はこれをやってある前提。

``` python:
import openpyxl

book = openpyxl.Workbook()
sheet = book.active
```

## シート名設定

``` python:
sheet.name = "しーと"
```

## ブック保存

``` python:
try:
    book.save("book.xlsx")
except exception as e:
    # excelを開いているとPermission Error。他もあるかも。
finally:
    book.close()
```

## csvからエクセルを作る

``` python:
import csv

with open("file.csv", "r") as f:
    for l in csv.reader(f):
        sheet.append(l)
```

## セルに罫線を描く
この例はセルの外周に引く場合。
セル指定(num_row, num_column)はR1C1の数値(以下同様)

``` python:
from openpyxl.styles.borders import Side

border = openpyxl.styles.borders.Border()
border.top = Side(style='hair', color='000000')
border.bottom = Side(style='thin', color='ff0000')
border.left = Side(style='thick', color='00ff00')
border.right = Side(style='medium', color='0000ff')
sheet.cell(row=num_row, column=num_column).border = border
```

colorは16進数のよくあるRGB値。

既存の罫線を保持して一部のみ変更したい場合は

``` python:
border = copy(sheet.cell(row=num_row, column=num_col).border)
```
これで現罫線の状態を取得してから、上のやつで変更。

## フォント設定

``` python:
font = openpyxl.styles.fonts.Font()
font.name = 'フォント名'
font.size = 10
font.color = 'deadbeef'
# 特定セル
sheet.cell(row=num_row, column=num_col).font = font
# 値入力済範囲全体
for r in sheet:
    for c in r:
        sheet[c.coordinate].font = font
```

colorは16進数の以下略。

## セル幅設定
自動で調整するのはエクセル内部機能なので使えないようです。
それっぽくするにはカラムの内容から算出するしか無いみたい。

``` python:
column = openpyxl.utils.get_column_letter(num_column)
length = len(sheet.cell(row=num_row, column=num_column)
sheet.column_dimensions[column].width = length * 1.5
```

## 印刷設定
1行目を印刷タイトル、用紙向きを横、横ページ数を1、縦ページ数を無指定で印刷する場合。

``` python:
sheet.print_title_rows = '1:1'              # 印刷タイトル行
sheet.page_setup.orientation = 'landscape'  # 縦は'portrait'
sheet.page_setup.fitToWidth = 1
sheet.page_setup.fitToHeight = 0
sheet.sheet_properties.pageSetUpPr.fitToPage = True
```

## セル着色
塗りつぶしの場合はこれ、他のパターンも当然あります。

``` python:paint_cell.py
from openpyxl.styles.fills import (PatternFill, FILL_SOLID)
fill = PatternFill(fgColor='aabbcc', patternType=FILL_SOLID)
sheet.cell(row=num_row, column=num_column).fill = fill
```

fgColorは16進数(ry

## セル内文字寄せ
下、中央寄せの場合。

``` python:
align = openpyxl.styles.Alignment()
align.horizontal = 'center'
align.vertical = 'bottom'
sheet.cell(row=num_row, column=num_column).alignment = align
```

## フィルタ設定
セル指定がフィルタを適用するデータの範囲であることに注意。
この場合のセル指定はA1形式。

``` python:
sheet.auto_filter.ref = "B2:D10"
```

## カラム名の数値化
R1C1用にカラム番号を取りたいときはこれ。

``` python:column_number.py
num_column = openpyxl.utils.column_index_from_string('D')
```
Xojo IDE を Ubuntu 18.04 で動かしたときの日本語問題


Xojo はマルチプラットフォームでWin/Mac/Linuxで開発できる。

いいね！　と思って Linux で動かしたけれども Ubuntu で動かす Xojo IDE が辛すぎて仕方がない。


- 日本語編集時にInsertモードになっていない
- 日本語編集時にカーソル位置がずれる

このほか、遅いという問題が指摘されているが、もともとのUbuntu18.04をThinkPad X230 +　16MBytes Memory で使っていたときはさほど重いという感触はありませんでした。

# 環境

- Linux Ubuntu 18.04.4 LTS ( AMD64 )
- Xojo 2019r3.1

以下、Ubuntu 18.04 + XFce の組み合わせでの検証結果です。なお、標準の　Ubuntu18.04　と　Gnome 3 との組み合わせでも同様の問題が発生します。


# 日本語編集時にInsertモードになっていない



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/39aad048-dade-b50d-52cb-b076ffa1a731.png)

このようにあるところに日本語を挿入したいとします。カーソルを5と6の間において、日本語を入力すると上書きになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7df91aaa-30f6-9898-3e76-c2fb2a272102.png)


# 日本語編集時にカーソル位置がずれる

上のように入力したあと、カーソルを2と3の間におきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/39823f65-2b2a-05f8-204a-699d52b5c012.png)
ここに、日本語を入力しようとすると意図した場所ではないところに入力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bfe687fe-ef39-476a-27b4-a6db90344c5f.png)

# 参考資料
「Xojo memo・備忘録 - Atom Xojo LINUX IDE 激遅！ very slow!」
http://k2y1972blog.blogspot.com/2019/07/xojo-linux-ide-very-slow.html
XFce などを使うと調子がいいという話がありました。

上記の記事では、

> いろいろ試したが、lightdmをやめgdmを使い、unityをやめxfceにするとWinやMacに比べるとまだ遅いが見違えるくらいに動作する。

とありましたので、Xfceで試してみましたが日本語の問題は解決していないようです。
おうちハックで快適テレワークひきこもり生活

# にわか自宅警備員 爆誕!

ヒキコモリ自宅警備員となりはや一ヶ月。
今までのおうちハックは、

[おうちハックした自宅に2年すんでみたおはなし - Qiita](https://qiita.com/curtain6935/items/0fc7dc141f49fd1a48a4)

でしたが、こちらは平日昼間の不在を前提としていました。
というわけで、テレワーク版おうちハックです。

# テレワークの日と物理出勤の日を検出

いままで「有給休暇の日」を検出するのに使っていたiCloudのカレンダーを、今度は「テレワークの日」を検出するのにも使います。

iCloudのカレンダーに「今日はテレワーク」とか記入しておきます。
あるいはテレワークがデフォルト状態であれば「今日は物理出勤」でもいいでしょう。
そしてそのデータを元に、おうちハックで動くcronに「物理出勤の日は〇〇」といった制御をさせます。

iCloudのカレンダーはCalDAVで取ることが出来ます。
そのためには自分のCalDAVのURLを知る必要があります。

[GitHub - yukizumy/iCCalURI.rb: iCloudカレンダーのCalDAV URIを取得するRubyスクリプト](https://github.com/yukizumy/iCCalURI.rb)

こちらの方法でとることができます。

あとは多要素認証を回避できるアプリケーションパスワードを生成してCalDAVで叩けば、昔なつかしRFC5545形式のカレンダーとなります。
iCloudはなぜか時々変なエラーを出しますが、try catchで囲って多少の取れないエントリーは無視しても大勢に影響はありません。
繰り返しイベントや除外日が出るのですが、このへんはライブラリにまかせて処理すれば簡単にパースできます。

# テレワークのための通知

上記caldavで「今日はテレワーク！」と検出の上、テレワーク開始時刻と終了時刻にhueを点滅させます。
NO MORE 過重労働!
NO MORE 労働強化!

会社支給端末のvpn接続開始とかslackへの「おはようございます」投稿とかまでcronで自動化するのはまだ躊躇してますが、ステータス表示は自動で更新しています。

# 運動不足問題

テレワークの最大の問題は、運動不足。
新型コロナウイルスで何万人がこれから亡くなるのかは誰にも分からないのですが、世界では年間400万人が肥満に起因する疾病で亡くなっています。
コロナを回避できても肥満になってしまっては意味がありません。

ということで、fitbitを元に夕方に「お前このままだとブタになるぞ」と教えてもらうようにしましょう。

夕方、fitbit APIのtokenを手に

```
https://api.fitbit.com/1/user/-/activities.json
```

を叩いて、

```
echo "今日は $step 歩しか歩いていません。デブになりたくなければあと $more 歩、あるきましょう" | ssh mac say
```

とmacに喋ってもらいます。

ちなみに自分自身のログのみ粒度を細かく取る

```
https://api.fitbit.com/1/user/-/activities/steps/date/2020-04-01/1d/1min.json
https://api.fitbit.com/1/user/-/activities/distance/date/2020-04-01/1d/1min.json
https://api.fitbit.com/1/user/-/activities/calories/date/2020-04-01/1d/1min.json
```
という恐ろしいendpointもございます。
こちらでグラフを描画すると結構恐ろしいデータになります。

![fitbit-distance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204320/c1cd3e20-ff08-a39a-10fc-01935a1f8c19.png)

人間というのは気を抜くとすぐ体重増える生き物ですので、人の少ない時間に屋外ワークアウトを頑張りましょう〜

# お掃除問題

HMX-12ことお掃除ロボット。
以前は物理出勤した瞬間に動作させていたのですが、在宅だとそのタイミングがありません。
ゴミ屋敷に住んでいたら免疫力も何もありませんので、お掃除を頑張らせます。
テレワークの日は、お出かけを検出したら問答無用でHMX-12にお願いをかけます。

夜中に稼働させようとしたのですが、流石にうるさいので辞めました😅

# まとめ

Happy おうちハッキングひきこもり生活!

どんなにコロナがあってもコロナ**以外**の脅威がなくなったわけではありません。
おうちハックはコロナウイルス**そのもの**には無力かもしれませんが、おうちハックで心理的ストレスを軽減することは健康に繋がります。

出来ないことを嘆くのではなく、出来ることを頑張ることにより、災いを転じて福としていきましょう!

では皆様、ご武運を!
【情報共有】XDでは外部リンクを設置する機能がない(2020年4月時点)


【2022年1月11日更新】
やっとXDでもハイパーリンクを設置する機能が搭載されました。
[XD47 2022 年 1 月 11 日](https://www.adobe.com/jp/products/xd/features/whats-new.html#:~:text=XD47)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/73ffe63e-8b4a-96c1-a3db-d32afee6d664.png)

※ハイパーリンクはプレビューや共有のみで機能します（PDFやSVGに書き出してもリンクは入っていません）


---

私はデザインツール活用派で、簡単な資料なら最近はをパワポじゃなくデザインツールを使っています。ツールは「Figma」と「XD」を使っています。（個人的には「Figma」派ですが、仕事上は「XD」かな）

# XDでは外部リンクを貼れない
ふと、XDで外部リンクを入れたいときがあり「どこに機能があるのか」を探しました。
結果、2020年4月時点でも<font color="purple" size="">**XDでは外部リンクを挿入する機能はない**</font>様です。

# 参考サイト
以下がネタ元です。

* [Link to external URLs | Adobe XD: Feature Requests](https://adobexd.uservoice.com/forums/353007-adobe-xd-feature-requests/suggestions/12954396-link-to-external-urls)
4年前から要望が出てるんですね...私も希望します。

* [XDのリンクについてです | Q&Aフォーラム - chot.design](http://...)

# Figmaでは外部リンクを入れられます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/76f6208d-3c70-81b4-2c62-18a637a970db.png)

`Prototype`の画面で**Interaction**を`On Click`にするとURLの入力枠が表示されます。

なお、外部リンクはFigmaのプレゼン機能内のみで機能します（PDFやSVGに書き出してもリンクは入っていません）

# ChromeならURLな文字列を認識してくれる

たまたま知ったんですが...
「https：//qiita.com/」のようなURLな文字列をデザインツール上に表記し、PDFに書き出しました（デザインツールはXDでもFigmaでもOK。Figmaではリンクも貼っていません）
そのPDFをChromeで開いたら、ChromeはURLを認識し、ちゃんと外部サイトへリンクしてくれました
（FireFoxでも試したら、こちらはダメ）

以上です。
Railsチュートリアルメモ - 第14章

[メモの目次記事はこちら](https://qiita.com/yokohama4580/items/dedfd5510080273dc2a0)

[公式Railsチュートリアル第14章へのリンク](https://railstutorial.jp/chapters/following_users?version=5.1#sec-a_problem_with_the_data_model)

## サマリ
- モデルの複雑な関連付けの方法
    - 1つのテーブル`relationship`を使って、`follower`と`following`を管理する方法
- ネストしたルーティングの実装
- ajaxの実装

## ポイント
### テーブル名と異なるカラムをFKとして使用したい場合
#### 1対多の1側

```ruby
  # user.rb
  has_many :active_relationships, class_name:  "Relationship",
                                  foreign_key: "follower_id",
                                  dependent:   :destroy
```

#### 1対多の多側

```ruby
  # relationship.rb
  # follower_idカラムが存在している必要がある
  belongs_to :follower, class_name: "User"
```

### `has_many`と`belongs_to`について

#### `has_many`で指定できるパターン

```ruby
  # モデルの複数形 e.g. microposts
  has_many :microposts
  # 別名のシンボル、クラス名、FK
  has_many :active_relationships, class_name:  "Relationship",
                                  foreign_key: "follower_id"
```

- 関連付けとは別に、`has_many :hoge, through: :fuga, source: :foobar`を定義しておくと、こ配列``

#### `belongs_to`で指定できるパターン
デフォルトでは外部キーの名前を<class>_idといったパターンとして理解し、 <class>に当たる部分からクラス名を推測する
1. モデルのシンボル
2. 別名とクラス名

```ruby
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end
```

### ルーティングのカスタマイズ - ネストしたURLの設定

```ruby
  # /users/1/following や /users/1/followers 
  resources :users do
    member do
      get :following, :followers
    end
  end

  # /users/tigers
　resources :users do
    collection do
      get :tigers
    end
  end
```

### Ajaxの実装方法
- ローカル変数ではなくインスタンス変数への変更が必要
- viewには`form_for`の引数に`, remote: true`を追加する
- controllerには`respond_to`を追加する

```ruby
  def create
    @user = User.find(params[:followed_id])
    current_user.follow(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end
```

### アンパサンド（&）を使ったブロックの短縮表記

```ruby
# 以下は同値
[1, 2, 3, 4].map { |i| i.to_s }

[1, 2, 3, 4].map(&:to_s)

```

## 感想
- めちゃくちゃ時間がかかったがなんとか完走することができた
- チュートリアルとはいえtwitter風の動くアプリが完成したのは嬉しい
- まだまだ理解しきったといえる状態ではないので、3周目4週目をやりながら使いこなしていきたい