OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】LibreOffice Writer関連

Microsoft Office を使うのが以下の理由で面倒になってきたので、LibreOffice に移行しつつあります。

* ライセンスを購入したくない
* ライセンスを移行するのが手間
* OS関係なく同じ操作できるオフィスソフトを使用したい
* Googleドキュメントのようなブラウザありきのソフトは使用したくない



<br>

# ショートカット関連

## 直前の操作を繰り返す

### 方法
`Ctrl` + `Shift` + `Y`

> `ツール(t)` → `カスタマイズ(C)...` → `キーボード` から別のキーに割り当て可能

# フォント関連

## デフォルトのフォントやサイズを変更したい

### やること

LibreOffice Writerのデフォルトのフォント「游明朝」とサイズ「10.5 pt」を変更する。

### 方法

1. 「ツール(T)」 → 「オプション(O)」をクリック。

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/c0257070-8beb-be63-503b-2c80c99ada08.png)

2. 「LibreOffice Writer」 → 「規定フォント(...)」を開く。

* 英数字の変更：「西欧諸言語」をクリック
* 日本語の変更：「アジア諸言語」をクリック

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/cefff2c0-b507-630e-c30f-ff8340ac5ad6.png)

3. 使用したいフォントやサイズを設定する。<br>変更後は「適用(A)」または「OK」をクリックすれば完了。

* ここでは「MS UI Gothic」に変更しています。

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/0fca5624-e0dd-4304-c3da-f968aa6e33a8.png)



## 文字の間隔（字間）を変更したい

### やること

見出しや本文などの「文字の間隔（字間）」を変更する。

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/e4c802a2-c893-09eb-3bc4-3a4d5f2f8295.png)

### 方法

1. 「書式(O)」 → 「文字の書式(H)」をクリック。

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/3407f357-49b9-d364-adb0-e95c8c615894.png)

2. 「位置」タブ → 「間隔」項目の数字を変更し、OKをクリックして設定完了。

* 下図では字間を「32 pt」に設定

![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/5d8067b3-bd9e-14fa-0cab-8acaa8cea00d.png)



<br>



# レイアウト関連

## 「余白」を変更したい

### やること

下図のように、本文以外の「余白」幅を変更する。

![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/6072c080-a945-40c0-13b9-1c12ee6413e4.png)

### 方法

1. 「書式(O)」 → 「ページレイアウト(P)」をクリック。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/c1702797-dfef-4320-dbc2-53a4ec72e954.png)

2. 「ページ」タブを開き、「余白」項目の数字を変更する。<br>その後に「適用(A)」または「OK」をクリックすれば完了。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614920/fd99385e-9ec5-61b7-73bb-be56050b5275.png)
console出力の同じ行を更新する

# tl;dr
`readline`ライブラリの`cusorTo()`を使うと、consoleの同じ行を更新することができます。

# 説明
パッケージインストール時などにconsoleの同じ行が更新されて経過が表示されることがありますが、Node.jsで実現できます。

### 普通のconsole.logの場合

```JavaScript
let time = 0;

setInterval(() => {
  console.log(`time: ${++time}`);
}, 1000);
```
実行結果

```
time: 1
time: 2
time: 3
time: 4
...( 以下、略 )...
```

### readlineを使った場合
※`readline`はNode.jsに標準でバンドルされています。

```Javascript
import readline from 'readline'

let time = 0

setInterval(() => {
  readline.cursorTo(process.stdout, 0);
  process.stdout.write(`time: ${++time}`);
}, 1000)
```

実行結果(5秒後)

```
time: 5
```

以上。
Apache spark master の指定で勘違い

Apache spark には、そのアプリケーションをどの環境で実行させるかを指定するための設定値として、master(master URL)というものがあります。
その目的に合わせて指定する必要があるので、それぞれのモードをまとめておきたいと思います。

##### 1.ローカルモード
1つのインスタンス(driverプロセス)で処理を行います。
実行中の spark アプリケーション上の ExecutorID には、driver という表記しか存在せず、分散処理では Executor が担当する計算処理もすべてこのインスタンスで処理されます。
アプリケーションの単体テストで指定されることをよく見かけます。
master URL には "local" と指定するが、その指定の仕方によって、実行時に作成されるスレッド数などに影響があります。

|  値  |  スレッド数  |  最大試行回数(n回以上何らかのタスクが失敗するとジョブが失敗と見なされる) |
| ---- | ---- | ---- |
|  local  |  １  |　１　|
|  local[2] |  ２  |　１　|
|  local[*] |  cpuのコア数と同じ |　１　|
|  local[*,3] |  cpuのコア数と同じ|　３　|

##### ２.ローカルクラスターモード
ローカル環境において所謂、疑似分散モードで処理を行います。
実際に使われている場面を見ることが少ないのですが、単体テストで上手く使えれば、パフォーマンスの向上につなげられるかもしれません。

|  値  |  Executor数  | cpu コア数 |メモリサイズ |
| ---- | ---- | ---- | ---- |
|  local-cluster[2,2,1024]  |  2  |　2　|　1024　|

##### ３.yarn client モード
yarn によるリソース管理の元で実行します。
ただし、driver プロセスはクライアント側のプロセスとして実行されます。
アウトプットを素早く確認するための対話モードやデバッグに向いているため、開発中に指定することがあります。

|  値  |  補足  |
| ---- | ---- |
|  yarn-client  |Yarn Resource Managerの場所は、Hadoopの設定ファイルで指定するため、マスターURLにIPアドレス等は指定する必要がない　|

##### ４.yarn cluster モード
yarn によるリソース管理の元で実行します。
driver プロセスもYarn管理下の アプリケーションMaster 内で実行されます。
driver プロセスに異常が発生した場合に自動的に再割り当てされるため、本番環境で実行するのに適しています。

|  値  |  補足  |
| ---- | ---- |
|  yarn-cluster |Yarn Resource Managerの場所は、Hadoopの設定ファイルで指定するため、マスターURLにIPアドレス等は指定する必要がない　|

##### ５.Spark Standalone Cluster モード
SparkにはHadoopやリソース管理のYarnなしで、ローカルで簡易クラスターを実行させるためのモードが用意されています。
Sparkのクライアントに付属している Master と Worker を起動させることで、そのクラスターを作成することが可能です。
ローカルで動かすという点では、ローカルモードと同じであるため、間違えやすい。
実際、Spark Standalone Cluster を構築しているにも関わらず、ローカルモードで動かしているという勘違いを何度か経験しています。
ローカルクラスターモードは、1台のサーバ上で複数のExecutorを動作させるモードで、Spark Standalone Cluster モードは、複数のサーバ（コンテナ）に亘って複数のdriver もしくはExecutorを動作させます。
そのため、HadoopやYarnの環境はないけれど、少数のサーバで簡易クラスタを構築させたい上では使用できると思われます。

|  値  |  補足  |
| ---- | ---- |
|  spark://ホスト:ポート |ホストにはホスト名もしくはIPアドレスを指定する。ポートはデフォルトで7077　|

※Yarnの他に Apache Mesos など他にもリソース管理する仕組みがあります
PythonのListにDict型データを中身を変えながら追加する

#python でListにDict型データを入れていきたい
Python初学者です。既出かもしれませんが自分がちょっと詰まったので、メモとして残しておきます。どなたかの参考になれば幸いです。

Classを作り、その中の関数で毎回外部からデータを取ってきて、Dictデータを書き換えながらListに格納しようとしたのですが、返ってきたリストが全て同じデータになってしまう。
例えば以下のように

```
class Logic():
  def __init__(self):
    self.sample_dict ={"イチゴ":0, "バナナ":0, "オレンジ":0}

#例えば外部からデータを取ってきて辞書の中身を変えるような関数
  def plus_func(self, n):
    if n==0:
      self.sample_dict["イチゴ"]=100
      self.sample_dict["バナナ"]=200
      self.sample_dict["オレンジ"]=300
    else:
      self.sample_dict["イチゴ"]=500
      self.sample_dict["バナナ"]=900
      self.sample_dict["オレンジ"]=4000
    return self.sample_dict
```
とクラスを作り

```
logic = Logic()
sample_list=[]

sample = logic.plus_func(0)
sample_list.append(sample)
print(sample_list)

sample = logic.plus_func(1)
sample_list.append(sample)
print(sample_list)
```
これを実行すると以下のように中身が同じListなってしまいます。

```
[{'イチゴ': 500, 'バナナ': 900, 'オレンジ': 4000}, {'イチゴ': 500, 'バナナ': 900, 'オレンジ': 4000}]
```

##DictのCopyを渡しましょう
pythonではリストは参照わたしになると習いました。要するに上のコードだと同じsample_dictのIDをListに渡してしまっているため、そのIDの内容が変わるたびに全てのListの中身が更新されてしまうんですね。
なので、上のようにしたい場合は毎回Dict.copy()をしてやって参照IDを変えてから格納しなくてはいけないのですね。。。勉強になりました。

```
logic = Logic()
sample_list=[]

sample = logic.plus_func(0)
sample_list.append(sample.copy())
print(sample_list)

sample = logic.plus_func(1)
sample_list.append(sample.copy())
print(sample_list)
```
これで以下のように出力されます。

```
[{'イチゴ': 100, 'バナナ': 200, 'オレンジ': 300}, {'イチゴ': 500, 'バナナ': 900, 'オレンジ': 4000}]
```

以下の方の記事に詳しい解説が書いてありますのでリンクを貼らせていただきました。
[リストのコピーでハマった話](https://qiita.com/kokorinosoba/items/e9ab9398af5b44d2ac9a)
Streamlitで作成した株価アプリをWEB公開した（キャッシュ説明あり）

# Streamlitで作成した株価アプリをWEB公開した

株価アプリは前回作成したものを使う → [Streamlitを使って株価データをグラフ表示した](https://qiita.com/morita-toyscreation/items/04d9c77dfb596aa2b5a8)
デプロイ先はCloudRunを使う

## キャッシュ化

このままWEB公開するとBigQueryアクセスが多くなるのでキャッシュ化を行う
`@st.cache`デコレーターを付けることで返り値をキャッシュする
`@st.cache`は引数種類別にキャッシュする
2回目以降はキャッシュを使いBigQueryにアクセスしない
`allow_output_mutation`をTrueにすると返り値が変わってもエラーにならない

```Python
@st.cache(allow_output_mutation=True, suppress_st_warning=True)
def _get_stock(stock_no: str, start_date: str, end_date: str):
    ....
```

## Docker環境準備

Dockerfile作成
Cloud Runで動かすのでポート8080に設定する

```Dockerfile
FROM python:3.7.4

WORKDIR /app
ADD . /app

RUN apt-get update && apt-get clean;
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

ENV TZ Asia/Tokyo
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV GOOGLE_APPLICATION_CREDENTIALS /app/config/xxx.json

EXPOSE 8080

CMD streamlit run --server.port 8080 app.py
```

ビルド

```
$ docker build -t kabu-analysis .
```

起動

```
$ docker run --name kabu-analysis \
-p 8080:8080 -v ~/Sites/kabu-analysis/:/app -it --rm kabu-analysis
```

## Cloud Run へのデプロイ

### ビルド

DockerイメージをCloud Buildにビルドする
`kabu-analysis`はイメージ名

```
$ gcloud builds submit --tag gcr.io/weekend-hackathon/kabu-analysis
```
![screencapture-console-cloud-google-cloud-build-builds-region-global-1bc7f5ee-1855-46f3-b9ae-ad57bbbc1581-2021-01-31-21_39_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/dd9c9f93-0fbe-20e8-48df-bffee2590bf2.png)

### デプロイ

Cloud Run を使いビルドしたイメージをデプロイ

```
$ gcloud run deploy kabu-analysis --project=weekend-hackathon --image=gcr.io/weekend-hackathon/kabu-analysis --region=us-central1 --platform=managed --no-allow-unauthenticated
Deploying container to Cloud Run service [kabu-analysis] in project [weekend-hackathon] region [us-central1]
✓ Deploying... Done.
  ✓ Creating Revision...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [kabu-analysis] revision [kabu-analysis-00003-wuq] has been deployed and is serving 100 percent of traffic.
Service URL: https://kabu-analysis-leopsotyca-uc.a.run.app
```

### 権限追加

```
$ gcloud run services add-iam-policy-binding kabu-analysis  \
> --region=us-central1 --member="allUsers" --role="roles/run.invoker" --platform=managed
Updated IAM policy for service [kabu-analysis].
bindings:
- members:
  - allUsers
  role: roles/run.invoker
etag: BwW6MhTA8fg=
version: 1
```

URLにアクセスしサイトが表示されれば完了
[https://kabu-analysis-leopsotyca-uc.a.run.app/](https://kabu-analysis-leopsotyca-uc.a.run.app/)

![screencapture-kabu-analysis-leopsotyca-uc-a-run-app-2021-01-31-22_21_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/c19d2cab-ae9f-2f26-6af4-6cdb4ddc6472.png)

---
次回は詳しく可視化した株価グラフを作成していきます
いいね！と思ったら LGTM お願いします :clap::clap::clap:
「連番」を弄りたいならperlの範囲指定演算子が最強

# はじめに

名前に「連番」を含むようなファイルやディレクトリやデータを作りたい局面は少なくなかろう。perlの範囲演算子を使えば、pythonやシェルスクリプトや、増してやCなどの超回りくどいループ処理を書かなくても、ワンライナーで瞬殺である。


# 範囲演算子とは

perlにおける範囲演算子は、`..`または`...`の形をとり、「リストコンテキスト」においては、演算子の前後の式を開始点と終了点とした連続した値をもつ要素からなるリストを返す[^1]。

[^1]: 「スカラコンテキスト」では全く異なる機能を示すが、本記事では触れないことにする。

リストコンテキストとは、perlのソースにおいて、結果がリストで返ってくることが期待される処理が行われている個所のことを指す。例えば、@aへの入力処理、foreachループでの制御変数の定義などがこれに該当する。

とりあえず、やってみよう。

```
@a = 0..9;
print @a;
```
結果は、`0123456789`となる。

ここまではまあ、「へー、そう」以外の感想は出てこないだろう。だが面白いのはこれからだ。

# 文字でも範囲指定できる

前例を少し変えてみる。

```
@a = '00' .. '09';
print join("\n", @a);
```

結果はこうなる。

```
00
01
02
03
04
05
06
07
08
09
```

このように、perlの範囲演算子は文字列データを扱うことができる。

もっとがっつり文字列を弄ってみよう。

```
@a = 'a'..'d';
print @a;
abcd
```

さらに凝ったことをやってみる。長さが2文字以上の文字列を与えるとどうなるだろうか。

```
@a = 'aa' .. 'bc';
print join("\n", @a);
```

```
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
an
ao
ap
aq
ar
as
at
au
av
aw
ax
ay
az
ba
bb
bc
```

# こんな感じで実用する

たとえば、こういうのはどうだろう。
「大量のファイルを収めるために`data01`から`data99`までのサブディレクトリをさっさと作りたい。」
範囲演算子を利用すれば、ワンライナーで楽勝である。

```
perl -le 'map {print "mkdir data$_"} "01".."99"' | sh
```

# 参考

[perlop - Perl の演算子と優先順位 - perldoc.jp](https://perldoc.jp/docs/perl/perlop.pod)
Backlog APIで課題一覧を取得・加工して出力する方法

Backlog APIとは？
バックログの各種情報をhttpリクエストにより取得し、レスポンスをJSON形式で受け取ることができるBacklog公式のWebAPI
バックログ自体、View(HTML)からこのAPIをたたく仕組みで動いていると思われる
APIの場合便利なのは、受け取ったJSONを任意のプラグラミング言語にて配列操作し加工・出力することができること
もちろん標準機能でも高度な検索機能を持っているが、例えば「プロジェクトごとの月内のみの工数を知りたい」などの標準機能にない機能を開発することができる
![backlog_api利用の概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32299/16ed8cb6-390a-1450-c86c-c93402168288.png)
実際にBacklogAPIを叩いてみるサンプルは下記の通り

```php:issues_list.php
<?php
$hostname = '*****.backlog.jp';    //対象backlogのドメインを入れてください
$apiKey = '******************************'; //API keyを入れてください
$proj_id = getProjectIdFromKey($argv[1],$hostname,$apiKey); //PHPコマンドの第一引数にプロジェクトキーを設定
$from_date = $argv[2];//PHPコマンドの第2引数に取得開始更新日付を設定 例）php issues_list.php HOGE-1 2021-01-01
$cnt = 0;
$result = array();

while(1){
  $offset = $cnt * 100;
  $params = array(
  'projectId[]' => $proj_id,
  'count' => 100,
  'offset' => $offset,
  'updatedSince' => $from_date,
  );

  $headers = array('Content-Type:application/x-www-form-urlencoded');
  $context = array(
    'http' => array(
    'method' => 'GET',
    'header' => $headers,
    'ignore_errors' => false
    )
  );

  $url = 'https://'.$hostname.'/api/v2/issues?apiKey='.$apiKey.'&'. http_build_query($params, '', '&');
  $response = file_get_contents($url, false, stream_context_create($context));
  //echo $response;
  # レスポンスを変数で扱えるように変換
  $json = mb_convert_encoding($response, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
  $json = json_decode($json, true);
  if(count($json) < 100){
      $result = array_merge($result, $json);
      break;
  } else {
    $cnt++;
    $result = array_merge($result, $json);
  }
}
foreach($result as $value) {
  //例として、第一引数でしていしたプロジェクトの、第二引数で指定した日付以降に更新された課題の課題キーと課題名を出力
  echo $value["issueKey"];
  echo $value["summary"]."\n";
}


function getProjectIdFromKey($projectKey,$hostname,$apiKey){
  $cnt = 0;
  $result = array();

  while(1){
    $offset = $cnt * 100;
    $headers = array('Content-Type:application/x-www-form-urlencoded');
    $context = array(
      'http' => array(
      'method' => 'GET',
      'header' => $headers,
      'ignore_errors' => false
      )
    );

    $url = 'https://'.$hostname.'/api/v2/projects/'.$projectKey.'?apiKey='.$apiKey;
    $response = file_get_contents($url, false, stream_context_create($context));
    //echo $response;
    $json = mb_convert_encoding($response, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    $json = json_decode($json, true);
    if(count($json) < 100){
        $result = array_merge($result, $json);
        break;
    } else {
      $cnt++;
      $result = array_merge($result, $json);
    }
  }
  return  $json["id"];
}
?>
```
このファイルを配置したディレクトリ内で、下記のコマンドを打てば、プロジェクト名「HOGE」の、2021-01-01以降に更新のあった課題一覧が取得できる。

```
php issues_list.php HOGE 2021-01-01
```
レスポンスのJSONがどのようなものかは、issues_list.phpの下記の行のコメントアウトを外すことで確認することができる。

```
  //echo $response;
```
JSONのレスポンスを確認しながら、issues_list.php内の下記のforeach文で課題ごとに欲しい情報を表示させれば、各種集計表に必要な内容のみを表示させることができる。例えば課題の課題キーと課題名のみを一行ずつ出力したい場合は下記のようになる。

```
foreach($result as $value) {
  echo $value["issueKey"];
  echo $value["summary"]."\n";
}
```
基本はこれだけ。あとは言語で普通に用意された文字列加工や条件分岐、加減算などで欲しい情報を修正すればよい。
【Udemy学習応援】おすすめJavaScriptコース紹介　感想

#Udemyのコース名
The Complete JavaScript Course 2021: From Zero to Expert!
Created by Jonas Schmedtmann
Last updated 1/2021
https://www.udemy.com/course/the-complete-javascript-course/

#感想
全体を通して、丁寧で分かりやすい説明です。
内容は、本当に未経験の人にも優しく教えてくれる感じで無理なく着いていける感じですね。
英語は多少クセがあるが、聞き取りやすいし、難しい単語も出ないです。

実はこのコースはだいぶ前から購入していて途中だったのですが、2021年ver.になって内容が新しくなっていました。（なので、また１から始めます）
JavaScriptも更新がありますし、どんどんモダンな開発にアップデートされていくのでこういった内容更新は非常に助かりますね。
また3日前に講座内容更新してくれているようなのでどんどん良いものになっているようです。

皆さんもぜひ購入して学習してみてください。

Happy coding!
【Udemy学習応援】おすすめJavaScriptコース紹介　概要

#Udemyのコース名
The Complete JavaScript Course 2021: From Zero to Expert!
Created by Jonas Schmedtmann
Last updated 1/2021
https://www.udemy.com/course/the-complete-javascript-course/

#コース概要
Udemyで最も売れているJavaScriptコースです。

JavaScript学習で必要な内容がすべて入っていますね。すごい！
IDEの使い方から始まり、プログラミングの基礎的な条件分岐処理や関数の扱い方など本当に助かる内容を学ぶことができています。

具体的な内容は以下の通りです。
・JavaScript基礎（変数、if文など条件分岐の書き方、関数、配列、ループ処理など）
・ES6+などモダンな開発について（アロー関数など）
・オブジェクト指向
・JavaScriptの非同期処理（API利用やAJAXなど）
などなど

68時間分もの講義動画内容がありますので、なんだか得した気分になりますね。
【Udemy学習応援】おすすめKotlinコース紹介　感想


#Udemyのコース名
The Complete Android Kotlin Developer Course
Created by Hussein Alrubaye
Last updated 11/2020
https://www.udemy.com/course/the-complete-kotlin-developer-course/

#感想
初歩的なことからゲーム開発やSNS開発など進んだ内容も含まれていて、素晴らしいですね！

淡々と進んでいく感じがよいですね。着実にコース内容を理解した上で進めます。
アプリを作ることよりもコードを書くことをベースにして始まるので、Web開発経験者からするとわかりやすい気がします！

インストラクターはニューヨークでソフトウェアの学位をとった方のようで、非常に論理的な説明をしてくれます。
英語については、イスラム系特有のアクセントがややありますが、だいたい分かりやすいです。

ちなみに使っているIDEは、JetBrains社のIntelliJ IDEAです。
自分はIntelliJ IDEAについては未経験だったので、IDEのインストールから教えてくれてとても参考になりました。
【Udemy学習応援】おすすめKotlinコース紹介　概要


#Udemyのコース名
The Complete Android Kotlin Developer Course
Created by Hussein Alrubaye
Last updated 11/2020
https://www.udemy.com/course/the-complete-kotlin-developer-course/

#コース概要


Kotlinでの開発を初歩的内容から発展的な内容まで網羅しています。
個人的には、IF分の分岐処理など実践的な学びができています。
もちろん、アプリをつくることを中心としたコースもよいのですが、こういったコーディング部分に着目したものも非常に参考になりました。

また、センサー関連のアプリにも触れるようでなかなか奥が深い講座ではないでしょうか。

具体的な内容は、
スクラッチ開発、最初のアプリ開発
変数、計算、関数、ループ処理、オブジェクト指向
アプリ開発、ゲーム開発
データベース処理
などなど


以下がこの講座の開発するアプリの内容です。このボリューム凄くないですか？！
Find My Age App.
Tic Tac Toe Local App.
Calculator App.
Pokémon Game App.
Zoo App.
Restaurants App.
Find Sunrise time App.
My Notes App.
Tic Tac Toe using Firebase App.
Facebook App using Firebase.
MediaPlayer App.
Alaram App.
Notification Channel App.
Light sensor App.
Nimbuzz vibrate.
Find My Phone App.
Twitter App using Php + MySQL.
【初心者】Amazon Macie を使ってみる

# 1.目的
- セキュリティ関連サービスを一通り復習している。一度も触ったことの無かった Amazon Macie について、チュートリアルレベルの確認を行い概要を理解する。

# 2.Amazon Macie とは（自分の理解）
- S3に含まれる機微情報(電話番号、クレジットカード情報など）を検出できるサービス。

# 3.やったこと
- 検査対象のバケットを作成し、サンプルデータを含むファイルを保存する。
- MacieのJobを作成して検出処理を行い、結果を確認する。

# 4.構成図

![macie-図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ca02a23b-5cfa-abbc-a61f-092466427729.png)

# 5. 作業手順
## 5.1 事前準備
- 空のS3バケットを作成する。
- 機微情報っぽいデータを含む日本語及び英語のサンプルファイルをアップロードする。それぞれファイル形式はcsvとxlsxとする。（内容は同じ）

``` English-namelist.csv/.xlsx
Name,Phone,email,credit card
Taro Yamada,03-1111-2222,yamada-taro-test@gmailgmailtest.com,1111-2222-3333-4444
Jiro Yamada,03-1111-3333,yamada-jiro-test@gmailgmailtest.com,1111-2222-3333-5555
```
``` 日本語名簿.csv/.xlsx
名前,電話,メール,クレジットカード
山田太郎,03-1111-2222,yamada-taro-test@gmailgmailtest.com,1111-2222-3333-4444
山田次郎,03-1111-3333,yamada-jiro-test@gmailgmailtest.com,1111-2222-3333-5555
```

![macie01a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/63000c88-f9c9-2a8f-e23f-8e3cb840045f.png)

## 5.2 Macie jobの作成

Macie の jobを作成する。

- Step1: 検査対象S3バケットの選択
 - 前の手順で作成したバケットのみを指定する。
![macie02a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f67fb502-ed55-29e0-6c07-39c7ca1c9d77.png)

- Step2: 選択したS3バケットの確認
 - 選択したバケットが正しいか確認する。
![macie03a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/9813077d-80c5-8f42-f01b-8e5f5797f05d.png)

- Step3: スコープの指定
 - 今回は「ワンタイムジョブ」（1回のみ実行）を選択する。

![macie04a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/050e326c-e98d-5ca9-07ee-ac06da86ab0c.png)

- Step4: カスタム識別子の指定
 - 今回は特に指定せず、Macieのデフォルト設定でどこまで検出できるのか確認する。
![macie05a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/09d295be-102f-dfd6-bfde-020eecf8e89a.png)

- Step5: 名前の設定
 - jobの名前を設定する。
![macie06a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/8ea6fd70-ab1b-635f-fe55-75a32776270f.png)

- Step6: 設定の確認
 - jobの設定内容を確認して実行する。
![macie07a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/39f1309b-946b-f00e-5238-aebf49a7ae9a.png)

## 5.3 Macie jobの結果確認

- 左メニューの「ジョブ」から、ジョブ名を指定して結果を確認する。

![macie10a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/71460795-76ce-4335-fa3a-eb507899a0fb.png)

- 以下の結果となっている。
 - 英語版の2つのファイルから機微情報を検出。
 - それぞれのファイルに対して「『Brazil Phone Number』が2個含まれている」という結果が出た。(ブラジルでも03-xxxx-xxxxのように電話番号を表記するのだろうか、、）

![macie11a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ba22c757-009a-063f-5c51-c511b2542827.png)

- データのどこが検出対象となったのかをjsonで確認できる。ファイルの2,3行目の2列目のレコードであり、まさに電話番号が書いてあるフィールド。
![macie12a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ff342c7e-f526-991d-c802-fa1879837080.png)


# 6.所感
- まだ日本語対応もしていないようであり、試しに使う分にはよいが、「これで正式に監査を行う」とするには少し早いかなと感じた。
【Udemy学習応援】私のUdemy活用内容

Udemyキャンペーン中なのでUdemyの記事を書きます！

#なぜUdemyをしようと思ったか
私は以下のような流れでUdemyを始めました。

＜流れ＞
新しい分野を業務で扱いたいができるかわからない
↓
まずはUdemyで触れてみる
↓
もっとやる（or無理そうならやめとく）
↓
開発能力を身に着ける
↓
実際の業務に活かす（挑戦できるように会社内で発信）

Udemyは、実践的かつやりたいことを学ぶことができているところが気にっています！
KotlinやJavaScriptなど業務であまり触れていないけどやってみたい言語をIF文の処理など基礎的な内容から学べているのでだいぶ助かります👍

Udemyでの学習を通してスキルを身に着け、会社に貢献できるレベルまでになることが業務やキャリアにおいても大事かと思います。
ポートフォリオなど実際に自分で開発した内容を見せるのも有効かと思いますし、まずはチャレンジあるのみですね！

また英語の講座は英語の勉強に非常に良いのでお勧めです。
英語プレゼンの参考にもなっていますし、海外のエンジニアとの交流にも使えるような英語表現にあふれています。
非常によい学びとなっています。

Udemyスマホアプリも使いやすいですし、日々の隙間時間に勉強できます。
コツコツやれば業務にもプラスになりますし、ほんとにやる価値ありです✊

#実際に受講している講座たち
The Complete JavaScript Course 2021: From Zero to Expert!
https://www.udemy.com/course/the-complete-javascript-course/

The Complete Android Kotlin Developer Course
https://www.udemy.com/course/the-complete-kotlin-developer-course/

iOS & Swift - The Complete iOS App Development Bootcamp
https://www.udemy.com/course/ios-13-app-development-bootcamp/

The Complete 2021 Web Development Bootcamp
https://www.udemy.com/course/the-complete-web-development-bootcamp/
Spring BootでJPQLのIN句をLISTでの書き方

###検索機能などで実装することがあると思われるSQLのIN句

Ajaxを利用して、一覧テーブルの絞込検索機能を実装しました。その際にステータスによってチェックボックスで絞り込むような場面がありました。

```javascript
// 送信するステータスIDの例
statusList = [2,3]
```
この値を利用して

```java
SELECT * FROM 〇〇 WHERE △△ IN (2,3);
```
のようなSQLを作りたかったのですが、SQLとJPQLは書き方が違うんですよね。

ですがさすがJPQLといいますが、便利ですね。簡単でした

###JPQLでのIN句の書き方

```java

IN List型のプロパティ名

```
これだけで、IN句を作成できます。


###大まかな流れのイメージ

####1. HTMLのnameで配列名を指定

```html
// Thymeleafを利用してhtmlは作成したので、th:valueでvalueをセット
<input name="statusList[]" type="checkbox" th:value="${status.id}">
```

####2. javascriptでチェックされたやつのvalueを取得

```javascript
var statusList = []; // ここにチェックされたvalueの値を格納
$('[name="status[]"]:checked').each(fuction(){
  // 一つずつ格納していく
  statusList.push(this.value);
});
```

####3. Ajaxで送信

```javascript

let data = [
statusList : statusList,
]

$.ajax({
  url : // 略
  method : 'POST',
  dataType : json',
  data: JSON.stringify(data), // ここにstatusListが入ってるんですね
  contentType : application/json',
})
.done( function (response) {
// 略

```

####4. Controllerの引数で受け取る

```java

@PostMapping
@ResponseBody
public String search(
@RequestBody List<Integer> statusList // これで受け取れる
){ // 略


// ラッパークラスを利用している場合
// 引数には
@RequestBody SearchForm searchForm

```

```java:SearchForm.java(ラッパークラス）

public class SearchForm{

  private List<Integer> statusList; // Ajaxで送られてくるjsonのkey名に一致させる
  private String name;
  // その他フィールド

  // setter, getter略

}

```

ちゃんとこの中のフィールドに格納してくれます。
【blender 2.9】カラーミックスとは

# 動作環境
本記事の動作環境は以下の通りです。

 
| 項目             |               環境 |
|:-----------------|:------------------|
| OS               |         Windows 10 | 
| Blender          |               2.9 |

#カラーミックスとは

参考：[https://docs.blender.org/manual/ja/latest/render/shader_nodes/color/mix.html](https://docs.blender.org/manual/ja/latest/render/shader_nodes/color/mix.html)

その名の通り、オプションによって選択されるブレンドモードでカラーをミックスするノード

![color_mix_node.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/5bc063fe-27bf-0f52-cb13-12930976503d.png)


#乗算

その名の通り乗算。
係数を1にするのが慣例。
係数が大きいほど純粋な掛け算。

以下の式のイメージ。(あくまでイメージ)

出力画像 = 画像1 × (画像2/255 + ( 1 - 係数))

ただし、(画像2/255 + ( 1 - 係数)) > 1 のとき、画像2/255 + ( 1 - 係数) = 1


参考：[カラーノード一覧](http://oldrookie.info/2016/11/01/blender-node%E3%80%80%E3%82%AB%E3%83%A9%E3%83%BC%E3%83%8E%E3%83%BC%E3%83%89%E3%81%AEmix-rgb%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B/)
参考：[乗算の使用例](https://bookyakuno.com/multi-normal-map-texture/)
参考：[フォトショップでの乗算の仕組み](https://itstudio.co/2017/04/28/6638/)

#あとがき
必要に応じて更新するかも。
乗算に係数って何？って思ったのが始まり。
AWS CLIでS3 objectsへメタデータを設定する

# はじめに
[TeQA](https://teqa.net/)というサービス開発を通して得た知見を記載していこうと思います。
TeQA内で使用しているserverless framework componentsを用いたデプロイとS3の設定についてです。

# serverless framework componentsでのwebsite deploy
[serverless framework components](https://github.com/serverless-components/website)を用いて、websiteをビルドしS3へのデプロイを行っています。
serverless framework componentsは下記のようなserverless.ymlのみを配置し、ドメインネームのみ申請すればonelineで、S3の設定やデプロイなど多くのことをやってくれるすごいやつです。

```yml
component: website
name: hoge
stage: dev
inputs:
  src:
    src: ./src
    hook: yarn build
    dist: ./build
    domain: ${custom.${stage}.domain}
  region: ap-northeast-1

custom:
  dev:
    domain: hoge.com
  test:
    domain: test.hoge.com
  prod:
    domain: hoge.com
```

そのため、React用のアプリケーションをCreate-React-Appで作成し、上記のserverless.ymlを配置し、ドメインネームを取得すれば、

```
$ serverless deploy --stage dev
```
で、すぐにAWS上にデプロイ可能です。

ただ使っていく中でプロダクション向けには、別途設定しなければならない箇所が出てきました。

# S3へのメタデータ設定が付与できない
S3でSPAを配置するときは、ブラウザ側の読み込み速度を考慮しcache-controlなどのメタデータを付与したいものです。
ただ、serverless frameworkではそのようなS3オブジェクトへの細やかな設定付与はどうやらできないようなので、別途スクリプトを用意してやる必要があります。
S3への配置でキックされるLambda関数等を用意してもよいのですが面倒なので、今回はaws cliでシェルスクリプトを書いてしまいます。
下記が完成形になります。

```sh
#!/bin/bash

BUCKET_NAME="hoge"
PROFILE_NAME="profile"
CACHE_CONTROL="max-age=xxxxxxx"

for key in $(aws s3 ls $BUCKET_NAME --recursive --profile $PROFILE_NAME  | sed -E 's/[\t ]+/ /g' | cut -d " " -f 4); do
	ContentType=$(aws s3api head-object --bucket $BUCKET_NAME --key $key --profile $PROFILE_NAME | jq '.ContentType')
	# echo $ContentType | sed 's/"//g'
	aws s3 cp s3://$BUCKET_NAME/$key s3://$BUCKET_NAME/$key --metadata-directive "REPLACE" --content-type $(echo $ContentType | sed 's/"//g')  --cache-control $CACHE_CONTROL --acl public-read --profile $PROFILE_NAME	
done
```

簡単に解説していくと、

```sh
aws s3 ls $BUCKET_NAME --recursive --profile $PROFILE_NAME 
```
これでawsのbucket内のオブジェクトkeyを取得します。
その後に、s3apiのhead-objectを用いて、serverless deploy時に自動設定されるcontent-typeを取得します。

```sh
aws s3api head-object --bucket $BUCKET_NAME --key $key --profile $PROFILE_NAME 
```

最後に、取得したcontent-typeと定義したcache-controlでS3 objectを上書きしていきます。

```sh
aws s3 cp s3://$BUCKET_NAME/$key s3://$BUCKET_NAME/$key --metadata-directive "REPLACE" --content-type $(echo $ContentType | sed 's/"//g')  --cache-control $CACHE_CONTROL --acl public-read --profile $PROFILE_NAME
```

aws cliでs3 objectに対してcache-controlをつける際は、REPLACEオプションのみを受け付ける仕様で、さらにREPLACEオプションをつけてしまうと既存のメタデータが全て上書きされてしまいます。
そのためこのように

- 既存のメタデータ取得
- 既存のメタデータと追加したいメタデータを付与してobject更新

という少し手間がかかる方法で更新しています。

# おわりに
serverless frameworkですが、Serverlessなものに特化して非常に使い勝手位の良いフレームワークになっています。
AWSでインフラ構成だとcloud formation/terraformになりがちだと思いますが、サーバーレス系のマネージドサービスを小さく素早く使うには充分なものだと思いました。
0オリジンの配列でインデックスの数値の四則演算の仕方

# 概要
0オリジンのインデックスの掛け算のやり方を知らなかったので調べました。

## やり方
下記の0オリジンの配列を例にして説明します。

```ruby
array = [1,2,3,4]
```

### 足し算
- インデックスの数値にただ足すだけ

例: インデックス0にプラス2をするとき

```ruby
index = 0
index = index + 2

# インデックス0にある要素1から2つ進んだ箇所にある3を返却する
puts array[index]
=> 3
```

### 引き算
- インデックスの数値からただ引くだけ

例: インデックス2から1を引くとき

```ruby
index = 2
index = index - 1

# インデックス2にある要素3から1つ戻った箇所にある2を返却する
puts array[index]
=> 2
```

### 掛け算
- インデックスの数値に1を足して掛け算をし、その結果から1を引く

例: インデックス0に2を掛けるとき

```ruby
index = 0
index = (index + 1) * 2 - 1

# インデックス0にある要素1、つまり1オリジンで考えると1番目に2を掛けて得られる2番目の要素2を返却する
puts array[index]
=> 2
```

### 割り算
- インデックスの数値に1を足して割り算をし、その結果から1を引く

例: インデックス3に2で割るとき

```ruby
index = 3
index = (index + 1) / 2 - 1

# インデックス3にある要素4、つまり1オリジンで考えると4番目を2で割って得られる2番目の要素2を返却する
puts array[index]
=> 2
```

# 終わりに
もし間違っていたら遠慮なく教えてもらえればと思います。
VSコード内でemmetを有効にする2021.01.29

VSコードでは予測変換機能（emmet）が標順で使用出来ます。
例えば、HTML内で

```test.html
div
```
と打ち、tab　キーを押すと

```
<div></div>
```
と、予測変換されます。

HTMLおよびCSSはVSコードの標準としてemmetという機能が使えるようになっているからです。
一方で.erbファイルではemmetが有効になっておらず予測変換機能が使用出来ません。
HTML,CSSと同様に使いたいと思っている方も多いのではないでしょうか。
そこで、今回はVSコードで、erbファイルもemmetが有効にする方法を挙げてみます。
#目的
VSコード内でerbファイルのemmetを有効にする
#条件
バージョン： November 2020 (version 1.52)

#内容
**バージョンの確認**
1. 上部メニューバーの　”Help”　を選択
2. ４番目のリスト　"Release Note"をクリック
3. 「November 2020 (version 1.52)」　を確認
（本バージョン以外は検証しておりません）

※動画参考
https://gyazo.com/517dea73b388d304a6408777a69d8097

**setting.jsonへ移行**
1. command + ,　で Settings を開く
2. Search settings　に　"json"と記入
3. Launch 内の　Edit in setting.json　をクリック
4. setting.json　内にいることを確認

**setting.jsonの内容を変更**
最後の2つの項目を修正します。

1.emmet.excludeLanguagesを"markdown"とする

```setting.json
    "emmet.excludeLanguages": [
        "markdown"
    ],
```

2.emmet.includeLanguagesを以下の通り編集

```setting.json
 "emmet.includeLanguages": {
        "erb": "html",
        "vue": "html"
    }
```
以上でerbファイルでもemmetが有効になると思われます。
以下参考動画では、test.html.erbで予測変換機能が実行されているものとなっております。
皆様の参考になれば、幸いです。

※参考動画
https://gyazo.com/0812cb736f9cc43162e2f78c9692b453
Declaring TypeScript global variable types

We may declare a Node.js global variable in this way:

```ts
declare module NodeJS  {
  interface Global {
    foo: string
  }
}
```
After placing this in a `d.ts` file within the workspace, TypeScript could infer that `global.foo` is of `string` type. This is the so-called [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) trick. And for Browser environment, we can extend the `IWindow` interface in the same way.
bulma column編

# 注意書き
自分用のメモなのでかなり雑です。初めてbulma使うので<a href="https://bulma.io/documentation/overview/">公式サイト</a>を適当にまとめとく。英語は大嫌いなので超ガバ翻訳です。間違えてたら教えてください。
[公式](https://bulma.io/documentation/columns/basics/)

# column
<dl>
<dt>basic
<dd>まず横に並べたい内容をcolumnsでかこってcolumnで一つずつ書く。特に指定しなければ均等の幅になる。

<dt>size
<dd>1~5分の1~5まで指定できる。例えば一つを画面の1/3にしたいならis-one-third。念のため英語で数字も書いておく。<br>
<strong>分子</strong> one,two,three,four,five<br>
<strong>分母</strong> (half),third(s),quarter(s),fifth(s)、分子が2以上なら複数形、指定してないところは均等に分けられる。<br>
またis-数字 (数字は1~12)とすると数字/12の幅が割り当てられる。<br>
<strong>is-narrow</strong>これを使うと必要な分だけスペースをとってくれる。そのほかは埋めるようにスペースを割り当てられる。公式見たほうがわかりやすい。

<dt>responsiveness
<dd>-mobile,-tablet,-desktop,-widescreen,-fullhdで端末ごとに違うsizeに出来たりする

<dt>Nesting
<dd>ネストもできる。<a href="https://bulma.io/documentation/columns/nesting/">公式</a>見たほうが早い

<dt>gap
<dd>それぞれの間のスペースも調整できる。is-gaplessとかだとスペースがなくなる。











　　
</dl>
Laravelでhiddenに埋め込んだオブジェクトを復元する

あるアクションメソッドでBladeに使用した値をそのまま次の画面のコントローラに引き継ごうとしたら困ったのでメモ。
String型の場合は問題ないのだが、オブジェクトの場合そのままは引き継げない。

例えば

class名がEloquantObjectで
プロパティとして
id = 3
user_roma = tarou
user_name = 太郎
phone = 99-1234-5678

みたいなインスタンスを受け渡すとして、

```php5:PostController
$eloquant_obj = EloquantObject::find(3);
$param = ['eloquant_obj' => $eloquant_obj]
return view('sample.view')->with($param);
```
みたいな感じでBladeに送り込んで、

```html:sample.view.blade.php
<ul>
  <li>{{ $eloquant_obj->user_roma }}</li>
  <li>{{ $eloquant_obj->user_name }}</li>
  <li>{{ $eloquant_obj->user_phone }}</li>
</ul>

<input type="hidden" name=eloquant_obj value="{{ $eloquant_obj }}">
```
という感じで、このページでオブジェクトの中身を表示したあと、また次のコントローラのためにhiddenに埋める。
これを取り出すには以下のようにする。
 
```php5:RestoreContrloller      
 $eloquant_obj = New EloquantObject();
 $eloquant_obj->forceFill(json_decode($request->eloquant_obj,true));
```

まず、空のインスタンスをNewで用意する。
で、これにhiddenの値を書き込むんだけど、そのままでは入らない。
hiddenにオブジェクトを埋めこんだ時に、自動的にjsonに変換されているので、
json_decodeで復元する。
さらにfillするのに配列にしないといけないので、json_decodeの第二引数をtrueにする。

ここで、falseにするとオブジェクトになるんだけど、なぜかEloquantモデルのオブジェクト出ないとBlade(コントローラ内でも)でプロパティが取り出せない。
つまり、<li>{{ $eloquant_obj->user_roma }}</li>とか書くとproperty of non-object みたいなことを言われてエラーになる。
自分はここでハマりました。

そのため、上記のように一旦配列にデコードしたあと、元のクラスのインスタンスにフィルして復元する必要があります。
またfillではなく、forceFillにしないとオートインクリメントの項目が入ってこなくなります。
(モデル側で$fillableに加えればできそうですが、その場合は他の箇所で危険になりそう。)
YAMAHA RTX830 で transix IPv4接続(固定) を GUIで設定してみよう

`YAMAHA` `RTX830`がついにわが家にやってきました。

"[transix IPv4接続(固定)](https://www.mfeed.ad.jp/transix/staticip/)"サービスでの設定した結果です。このリンク先にもある[【設定例10：IPv4 over IPv6 IPIPトンネル接続 インターネットマルチフィード株式会社 transix IPv4接続（固定IP）】](http://www.rtpro.yamaha.co.jp/RT/docs/ipip/index.html#setting10)の通りで実際に接続可能です。しかし、久しぶりのYAMAHAルータなので、コマンドもお母つきません。入力ぽしゃったり、LUA入れるのを失敗したりしそうです。なるたけ、GUIで設定できないかなと、Web画面をポチポチしてたら、ほとんどGUIで設定できました。

今回はその記録です。

# YAMAHA RTX830 で transix IPv4接続(固定) を GUIで設定してみよう

管理系は置いといて、接続だけに的を絞ったら「詳細設定」部分だけで設定可能です。

## プロバイダー接続

ここでは`IPv6 IPoE接続 (WAN)` から `IPv4 over IPv6 トンネルの設定`で`「v6プラス」固定IPサービス`を指定します。`transix` の名前がいちいちありませんが気にしません。これを選択します。これが、いわゆるIPIPトンネル設定です。

もちろん、「光電話の契約」有無についても正しく指定くださいね。

![Screen Shot 2021-01-31 at 22.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/9ef92aa3-9a38-0e7c-edba-0883e3be6478.png)

プロバイダから入手した情報を、ここにそのまま入れていきます。気をつけるとこがあるとすれば、`インターフェースID` の省略形 `::feed` のような入力ではエラーが出ました。ファームウェアのバージョンにもよるかもしれませんが、個々でエラーが出たら `0000:0000:0000:feed` とフルで入力しましょう。

## LAN

ここでは、「IPアドレス」の部分で、 IPv4でのお宅の LAN側のルータアドレスを入れておいてください。

## ルーティング

放置

## NAT

放置

## セキュリティ

ここはお好きにどうぞ。IPv4ルールを入れたければ、`TUNNEL1`というインタフェースが増えているはずなので、そちらで設定ください。デフォルトで設定追加するかどうかも聞いてきてくれます。YAMAHAデフォルトのアレを入れておいてほしければ、それを入れておけば十分かと。

## DNS

ここも、デフォルトでリカーシブサーバになっているので、これですんでしまいます。

![Screen Shot 2021-01-31 at 22.15.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/e25af0c4-7ed2-f791-cdde-31c9e0eb3627.png)

## DHCPサーバー

IPアドレスの割り当て範囲に変更が必要であれば、ここを指定しましょう。

## メール通知

お任せです。

# これで終わりなのか

はい、これだけで接続設定終わりです。

ここまでGUIで設定すると、先に紹介した YAMAHAの設定例の LUAスクリプトまでちゃんとしっかり入っています。実際には一つだけ不足していたものがありましたので、これだけ追加しました。

```
lan linkup send-wait-time lan2 5
```

あと個人的なところでは、DHCPでの固定IPが一部有りましたので `dhcp scope bind 〜`を使っていますが、必須ではありませんね。

GUIだけでも結構いけてんじゃん。すごいじゃん。やるじゃん。久しぶりの YAMAHA でしたが、GUIが良くなってて感動です。
Udemyで営業事務が機械学習を学んでみた

#Udemyをはじめたきっかけ

この秋に転職して製造業の営業事務になったのですが、そこは当たり前に手書FAXで情報がやりとりされる世界でした。
誰も金額や原価のデータを見られない・・・分析もできない・・・
私がちゃんとデータをとって、分析もできるようにならなくては！と勉強をはじめました。

#学習した講座
どうやらデータ分析にはPythonが便利らしいと知ったので、
ひとまずさらっと勉強してみたいなと思っていたところで出会ったのがUdemyでした。

2５時間以上の学習動画がこの値段って詐欺か？まあ多少失敗してもいいかと購入。

【世界で34万人が受講】データサイエンティストを目指すあなたへ〜データサイエンス25時間ブートキャンプ〜
https://www.udemy.com/course/datascience365/

この講座ではデータ分析とは、データサイエンスとは何かを網羅的に学ぶことができました。
具体的な内容は

・データサイエンスとは何か
・どのような業務を行うのか（職種の分類など）
・データサイエンスで使用するツール

といった門外漢への解説にはじまり、分析についても

・確率や記述統計の基礎知識（高校や大学でしっかり学んでいる人は必要ないかな）
・推測統計
・回帰分析
・ロジスティック分析
・クラスター分析

そして、ディープラーニングやビジネス上での実践についても知ることができました。

#Udemy学習のメリット

Udemy学習のメリットは以下の三つだと思います。

####30日間返金保証があるので、購入してみて内容が合わなければ返品することができる
これは全く知識のない状態から学習をはじめた私にはとても良かったです。
最初は何を学べば良いのかわからず、思っていた内容と異なるものを購入してしまうこともありましたが
購入後30日以内であれば返金してもらえました。

####先生に直接質問ができる&メッセージを送ることができる
どうしても解らないことは先生が質問に答えてくれるので、挫折することなく取り組むことができました。
また、受講が終了した時には、内容のリクエストを聞いて頂けたりもします。

####他の人の質問が見られる
受講途中には、他の受講生さんのQ&Aもとても参考になりました。
自分の疑問を既に解決してくれているようなQ&Aはもちろん、さらに一歩踏み込んだ質問をしている受講生さんも沢山おられるので、一人で本を読むよりも多くの気づきを得ることが出来ます。
受講される際は、Q&Aまで熟読されることをお勧めします。
サーバーエンジニア(Java)が、AWS認定資格を取って職務領域を広げた話

## エンジニアとしての幅を広げるために、インフラ(AWS)を出来るようになると決めた
サーバーサイドのビジネスロジックを書くのをメイン業務としてやってきたが、**このままではエンジニアとして出来る領域が広がらず頭打ちになるという焦り**が自分の中であった。
エンジニアとしての領域を広げるにあたって、フロントエンド/クライアント(iOS/Android)に広げる手もあるが、**インフラ(クラウド)周りに広げるのが、今の仕事や知識と親和性が高い**と思い、 AWSの理解を深めることにした。

## 取り組むなら短期間で、定量的な目標を1つ達成する
新しい技術を学習にあたって、**長期的にじっくりやろうと思うと必ず失敗**する。
学習に対する熱量は日を追うごとに原則下がっていくし、普段の業務においても忙しい日も多い。
AWSの理解を深めるに当たって、**3ヶ月未満で達成出来る目標かつ達成したことを定量的に把握出来る目標**を立てることにした。

### 資格取得は目指しやすい定量的な目標
認定試験は目標として定量的であり、試験日があるため期間も限定して取り組める。
受験日を決めてしまえば〆切駆動型で集中して勉強することになるため、短期間でインプットが出来るためコスパが良い。

国内だけの資格はテンションが上がらないが、AWSの公式資格であれば世界共通なのでテンションが上がる。

#### AWS ソリューションアーキテクト アソシエイトを取得することにした
##### AWS ソリューションアーキテクト アソシエイトとは
[AWS 認定 ソリューションアーキテクト – アソシエイト](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)はざっくり言うと、インフラ構築系の知識を問われる試験である。
各ジャンルごとにアソシエイト、プロフェッショナルの2段階レベルが用意されており、アソシエイトの方が入門資格である。

##### 取得することで得られる知識レベル
サービス名を聞いた時、

 - どのようなサービスか分かる
 - どのような課題に対して使うべきか分かる

状態におおよそなれる。

実務で作業するには知識として足りないが、プロダクトのインフラをどうするべきか議論する和に加われる知識が付く。



## 業務に実際に活きた話
### 知識が増えて議論に加わりやすくなった
資格を取る前は、エンジニア同士の議論の中でAWSのサービス名が出た時、そもそも何のサービスなのかも分からず、どのような課題にどうアプローチする提案をしているのかさっぱり分からなかった。
資格を取った後は何の話をしているかおおよそ分かるようになり、議論されている内容が分かるようになってきた。
インフラ周りを理解する最初のステップとして、AWS認定試験は有用だったと思う。

### プロダクトのレスポンス速度の向上/インフラコスト削減を実現
一通り勉強した上で自分が業務で関わっているプロダクトを見返した時、改善の余地に気付くことができた。
インフラエンジニアに相談を持ちかけて見たところ、**感じていた課題だったが、ビジネス要件としてどうするべきかまでは提案できず改善できていなかった**とのことで、是非一緒に改善しましょうとなった。
**普段ビジネスロジック側を触っていたエンジニアがインフラも勉強したことで生まれた相乗効果**だったと思う。
具体的に改善されたのは以下の2つ。

#### EC2/RDSのアベイラビリティゾーンに改善の余地がある
masterを片方のゾーンに寄せて、待機系を逆のゾーンにおけばレスポンス速度と冗長性を担保出来る。
実際に適用したところ、平均のレスポンス速度は大きく下り目に見えて改善された。
レスポンス速度がユーザー体験に直接影響するサービスだったため大変喜ばれた。

#### インスタンスサイズに調整の余地がある
実際にサーバーを運用して見ているメトリクスを踏まえると、インスタンスタイプを下げられる
RDSのインスタンスタイプを下げ、月2桁万円単位の費用削減につながった。

### 資格取得のために勉強したこと
#### Udemyでのインプット
[Ultimate AWS Certified Solutions Architect Associate 2021](https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c02/)でざっと動画を流しみて、理解の浅いところを探した。
動画にして24時間ととても長く簡単に挫折するので、全部見ようと思わない方が必要なところだけに時間を使える。
ある程度分かったところで問題集を解くことにした。

#### 問題を繰り返し解く
今回の**最終ゴールは試験で合格点を超える**ことなので、問題を繰り返し解いて精度を上げた。
問題集は[AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト - アソシエイト](https://amzn.to/3tfTTuu)を使った。

##### 状態目標
参考書一冊分の例題を、

 - 全て解ける
 - それぞれの選択肢がなぜ違うか説明できる

状態であれば、合格点に到達できる。
学習する本を広げず、**一冊を完璧に仕上げる**のが一番コスパが良い。

### 合格した際の最終スコア
上記勉強方法で1-2ヶ月ほど勉強して望んだところ、
合格ライン720点に対し788点である程度余裕を持って受かることが出来た。

スコアの計算方法は謎が多く、

 - 点数は100〜1000点の間で表示される(0点はないということ？)
 - 配点は均一でない

らしい。7-8割解けたら安心ということかな。

#### おまけ:選択肢で迷った時に指針になる考え方
試験は選択肢問題なので、消去法で絞り込むと残り2つで悩むことが出てくる。
**多分っこっちだけど、こちらも間違いとは言えない**のような問題が私はいくつか出てきた。
その際**正当する確率を上げる考え方**があるので紹介する。

##### AWSは優秀であり、最適なサービスを用意している
AWSの認定試験である以上、AWSの良いところ、特性が前面に出た問題となっている。認定試験といえど、一種の宣伝の要素もあるように思える。

その観点でいうと、**オンプレで使っているユーザーがAWSに移行できないユースケースはまず出題されないし、必ず最適なサービスが用意されている**

ことを踏まえた選択肢が正解になる。

##### サーバーレスを使うべき場所はサーバーレス
ざっくりいうと、負荷が読めない、サーバー管理者が十分に立てられない場合はサーバーレス一択になる。
問題文を読んで厳密に考えていくとRDSでも要件を満たせそうな問題も出てくるが、課題に対して適切なサービスを選ぶのが間違いない。
ROSの勉強　第3弾：配信者と購読者の混合

# #プログラミング ROS< 配信者と購読者の混合 >

##はじめに
1つの参考書に沿って，ROS(Robot Operating System)を難なく扱えるようになることが目的である．改めて初めから学び，復習も兼ねながら学習を進めていくこととする．その第3弾として，配信者と購読者の混合を扱う．

##環境
#####仮想環境
|||
|:-:|:--|
|ソフト|VMware Workstation 15|
|実装RAM|2 GB|
|OS|Ubuntu 64 ビット|
|isoファイル|ubuntu-mate-20.04.1-desktop-amd64.iso|

#####コンピュータ
|||
|:-:|:--|
|デバイス|MSI|
|プロセッサ|Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz 2.50GHz|
|実装RAM|8.00 GB (7.89 GB 使用可能)|
|OS|Windows (Windows 10 Home, バージョン：1909)|

#####ROS
|||
|:-:|:--|
|Distribution|noetic|
|プログラミング言語|Python 3.8.5|

##配信者と購読者の混合とは？
文字通り，１つのノードに配信者と購読者の機能を持たせることである．１つのファイル内で，配信者と購読者のコードを記述できる．このようにROSでは複数の配信と購読を１つのノードで行うことができる．

##どんなときに１つのノードに配信者と購読者の機能を持たせるのか？
データに何らかの処理を加えて変換するときなど．
例えば，カメラの画像を含むトピックを購読して，その画像から顔を検出し，顔の位置をほかのトピックとして配信するかもしれない．このような場合，「購読」してさらに「配信」することとなる．

##実装
ここでは，何かしら数値を得た時に，それを2倍にした値を配信する例を扱う．以下にソースコードを示す．

#####ソースコード
```python:doubler.py
#! /usr/bin/env python3

import rospy

from std_msgs.msg import Int32

rospy.init_node('doubler')	#doublerという名前でノード作成

def callback(msg):
	""" データ変換のように，新たなデータを受け取ったときのみに変換するために，この関数内で配信する """
	doubled = Int32()			#データにアクセスするためにインスタンス作成
	doubled.data = msg.data * 2	#受け取ったデータを2倍にする
	pub.publish(doubled)		#callback関数実行するときのみ配信

sub = rospy.Subscriber('number', Int32, callback)			#numberというトピックを購読
pub = rospy.Publisher('doubled', Int32, queue_size = 10)	#配信準備

rospy.spin()
```

以下にプログラムを実行後，今扱われているトピックを``rostopic list``により表示させたターミナル(端末）を示す．
![キャプチャ4_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/b2afa90f-f5ff-90d1-0be3-de693e1030b6.png)
確かに``/doubled``，``/number``の２つが扱われている．ここでは，前者が配信で，後者が購読対象である．では，ここで購読対象に``rostopic pub``を使って，値を入力し，そのときの出力を見てみる．以下に３つのターミナル（端末）を示す．上から順に，「プログラム実行」，「購読対象に値を入力」，「配信情報の観察」である．
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/ab360614-4f1e-f18a-e378-15f21a22e5b2.png)
2, 3が入力されると，結果として4，6が配信されていることが分かる．ただし，入力されないと配信はされない．なぜなら，上のソースコードにおいて，``publish()``が``callback()``内にあり，``Subscriber()``が動くたびのみに，配信するためである．これは，このノードの目的がデータ変換する（ここでは，購読しているトピックからやってきた数を２倍にする）ことなので，**新しいデータが入ってきたときにだけデータを配信したい**という考えが背景にある．

##感想
今回で，トピックの学習は終わりである．最後に混合によるデータ変換を学んだが，まさにラジコンなどでPS4のコントローラを使うときに``joy``から得られるデータを``cmd_vel``に変換したいときが出てくると思うが，そのときの変換はこれを使えばよいのかなとヒントが得られた気がする．実際にやってみるが，その結果はまた別にまとめることとする．

##参考文献
プログラミングROS Pythonによるロボットアプリケーション開発
　　　　　　　　Morgan Quigley, Brian Gerkey, William D.Smart 著
　　　　　　　　　　　　　　　　　　　　　　　河田　卓志　監訳
　　　　　　　　　　  　松田　晃一，福地　正樹，由谷　哲夫　訳
　　　　　　　　　　　　　　　　　　オイラリー・ジャパン　発行
DCM画像をjpgに変換する

import pydicom
import matplotlib.pyplot as plt

d = pydicom.read_file('test.dcm')
plt.imshow(d.pixel_array)

img.shape

cv2.imwrite('dcm_test.jpg',  img[0])
![dcm_test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069967/e6cdc013-25a1-a387-db86-17a63c5b7929.jpeg)
[Rails]ActionMailerのRSpecテスト

#はじめに
RailsでActionMailerを使い、メールのテストをRSpecで書いたので残しておきます。
この記事に書くのはテストの部分だけです。


#さっそく

ActionMailer::Base.deliveriesにメールの情報があります。

```
ActionMailer::Base.deliveries
```

sizeメソッドでメールが何件送信されたのか確認できます。

```
ActionMailer::Base.deliveries.size
```

ActionMailer::Base.deliveriesは配列になっており、送信したメールの内1件目は[0]で指定します。

```
ActionMailer::Base.deliveries[0] #1件目
ActionMailer::Base.deliveries[1] #2件目
```

宛先確認

```
ActionMailer::Base.deliveries[0].to[0]
```

メール本文確認
メールをhtmlとtextの両方を用意している場合、指定しないといけません。
[参考] https://jpcloud.net/q/zdvigken

```
ActionMailer::Base.deliveries[0].html_part.body
ActionMailer::Base.deliveries[0].text_part.body
```

#終わりに
メール本文確認でhtmlかtextを指定していなかったのでハマってしまいました。。。
[Unity,Photon2]Photon2でルームを作成したい

#Photon2で名前を設定してルームを作成する

Photon2を使ってルームを作成したいと思います。
Photonについての使い方などは特に詳しい説明はしないのでそのあたりは自分で調べてください。

作成したルームをオブジェクトとして表示するルームの可視化はこちら
次回：[[Unity,Photon]Photon2で自動更新されるルームのリストを作る](https://qiita.com/yukienko/items/a9a08ee3f457be386771)

## ルームの名前を入力させる
今回はルームの作成ということでまずルームの名前を入力させ、ルーム作成という形にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/364e4bef-461f-7fc8-eccc-966dda556951.png)
上画像の"CreateRoomNameInputField"にルーム名を入力、
"CreateRoomButton"を押したらその名前でルーム作成。という形にしたい。
このボタンのOnClickについているGameObjectがこれ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/4e557da7-600b-5674-31f0-1f85f234f466.png)

##ルーム作成のコード
"MoveScene.cs"はシーン遷移用なのでルーム作成には関係ないです。
ルームの作成に関しては"MatchMenuManager.cs"で行っていきます。

```C#:MatchMenuManager.cs
public InputField playerNameInputField;

public void CreateRoom()
    {
        createRoomName = playerNameInputField.text;

        //ルーム名が入力されてないなら自動生成
        if(createRoomName == "")
        {
            createRoomName  = "room" + Random.Range(1000, 9999);
        }
        //ルームのオプションの設定
        RoomOptions roomOptions = new RoomOptions();
        roomOptions.IsVisible = true;
        roomOptions.IsOpen = true;
        roomOptions.MaxPlayers = 2;
        // ==指定したルーム名と同じルーム名が存在している場合、PhotonNetworkの方で作成できないようになっている==
        PhotonNetwork.CreateRoom(createRoomName, roomOptions , null);
    }
```

"CreateRoomButton"を押したときに"CreateRoom()"を実行させるととりあえずルームが作成できます。
細かい設定などはPhotonNetwork.CreateRoom(createRoomName, __roomOptions , null__);
この太文字のあたりをいじれば設定できるそうですが、今回は特に設定する意味がなかったのでしてません。
##ルーム作成後
ルームが正しく作成された時は以下の"OnCreatedRoom()"でコールバックを受けることができます。

```C#
public override void OnCreatedRoom()
    {
        Debug.Log("[Success]RoomCreate:" + createRoomName);
    }
```

"testRoom"という名前のルームを作成できました。
ログだけだとわかりにくいので可視化させています。
上の"MatchMenuManager.cs"でルームを作成すれば中身はこんな感じになります。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/9cb9db3c-523a-1351-d90e-eb8e33cae4b6.png)


##作成したルームの一覧をオブジェクトとして表示
上画像のように作成したルームをリスト化して可視化する方法はこちら
次回：[[Unity,Photon]Photon2で自動更新されるルームのリストを作る](https://qiita.com/yukienko/items/a9a08ee3f457be386771)

##おわり
ルームの作成は**PhotonNetwork.CreateRoom(createRoomName, roomOptions , null);**
ルーム作成後のコールバックは**public override void OnCreatedRoom()**
Djangoを利用する際のシステムアーキテクチャの整理

#はじめに
本ページは、Djangoを使用した際のシステムアーキテクチャを整理したもの。
システムアーキテクチャとは、サーバ、ミドルウェア構成、どこに何を配置するのか、なぜそれを配置するのか、といった内容。
[Udemyの【3日でできる】Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/course/django-beginner/)を受講した際に講座内で触れられていなかった、システム構成の背景を整理した。

#Djangoを使用したWebアプリケーションの構成
###1. 構成とその理由
中規模～大規模なシステムをWebサーバはNGinxを、APサーバはGunicornで、開発フレームワークをFlaskではなくDjangoで構築する。
OSはLinuxを使用。

- 何故Gunicornを使用するのか？<br>
PythonのWebアプリケーションは[WSGI](https://wsgi.readthedocs.io/en/latest/what.html)という仕様に則って開発されており、WSGIに則って作られたWebアプリケーションは、WSGIの仕様に則ったサーバ上で動作が出来る。WSGIに該当するのがGunicornであり、他にもuWSGIがある。
上記をふまえ、Gunicornを使用する理由は、処理が安定して早いからと言われているため。

- 何故Gunicornだけでなく、NGinxを使用するのか？<br>
[Gunicorn公式](https://docs.gunicorn.org/en/latest/deploy.html)より、以下記載があり、公式推奨のため。
>We strongly recommend using Gunicorn behind a proxy server.

- FlaskとDjangoの違いは？<br>
Flsakはシンプルなフレームワーク、Djangoはリッチなフレームワーク。
API系はFlaskでやっている人を見かけることあり。

###2. 今後の学習計画

- 以下の本を読み実践して、基礎固め<br>
    - 動かして学ぶ！Python Django開発入門<br>数多ある本の中でこの本を選んだ背景は、一般的なWebアプリケーションの説明とDjangoの特徴（View等の使用方法）の説明がしっかり記載されていたため
　
- ポートフォリオを作成する(一旦以下２種のポートフォリオがあればよいと考える。)<br>
    - Djangoを使用した自分の紹介サイト<br>
　Flaskより需要があるため（少なくとも日本国内では、現時点でpythonのフレームワークに限ればDjangoのほうが需要が高い。）
    - Djangoを使用したAPI<br>
　Djangoおよび全体アーキテクチャの理解が可能なため
jlinkしたアプリでSSLを使う

#はじめに
gradle run では動くのに jlink してから実行すると SSL Handshake で失敗することがあったので、原因を調べてみた。

#暗号方式
-Djavax.net.debug=all して調べてみたところ、使える暗号が無くて失敗していることがわかった。

#モジュールを調べる
暗号化モジュールが組み込まれていないんじゃないかと思って、モジュールを調べることにした。
java --list-modules するとずらずらと表示されるので、この中からそれっぽいものを探す。

すると、
jdk.crypto.cryptoki
jdk.crypto.ec
jdk.crypto.mscapi
というものが見つかった。

#モジュール組み込み
module-info.javaにとりあえず必要そうな jdk.crypto.ecを追加したら gradle run の時と同様に動いた
Laravelのバリデーションにフォームリクエストバリデーションを使ってみた

##はじめに
自分の記録としてなのでわかりにくい箇所があったら申し訳ありません。
不明点があれば、ページの最後に参考にさせて頂いたリンクを張っているのでそちらを見てみてください

##フォームリクエストバリデーションとは
* ファイル置き場所はapp/Http/Requests/
* バリデーションエラー時には、入力値とエラー情報を付与して前のページにリダイレクトしてくれる
* artisanコマンドで生成できる

##手順
さっそくフォームリクエストを使用していきましょう
コマンドは
```php artisan make:request StoreBuy
```
実行すると app/Http/Requests/StoreBuy.phpができます。

```php:StoreBuy.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreBuy extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true; //falseからtrueに変更
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'=>'required|max:20',
            'postalcode'=>'required',
            'region'=>'required',
            'addressline1'=>'required',
            'phonenumber'=>'required'
        ];
    }
}
```

今回自分はこのように記述しました。
public function rules()から自分がバリデーションをかけたいフィールドにルールを記述。
ルールは目的にそったものでカスタマイズしましょう。
それと、return trueの箇所ですが、初期状態はfalseになっているので、trueに変更してください。
falseのままだとうまく動きません。
使用できるバリデーションルールはこちらのページを参照してみてください
https://readouble.com/laravel/6.x/ja/validation.html

##コントローラーを編集
```php:BuyController.php
use App\Http\Requests\StoreBuy; //コントローラーに追記
   public function store(StoreBuy $request) //引数を修正
    {
        if($request->has('post')){
            Mail::to(Auth::user()->email)->send(new Buy());
            CartItem::where('user_id',Auth::id())->delete();
            return view('buy/complete');
        }
        $request->flash();
        return $this->index();
    }
```
コントローラーの引数をフォームリクエストバリデーションに変更



##viewにエラーメッセージを表示
```php
@if($errors->any())
<div class="alert alert-danger">
    <ul>
        @foreach ($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
    </ul>
</div>
@endif
```
ここはviewに表示するだけなのですが参考までに
if文で何がエラーが入っていたら表示という形になります
※classはBootstrapの書き方です。

##今回参考したページ
最後になりましたが、今回参考にさせて頂いたページです
Laravel学習帳
https://laraweb.net/knowledge/2156/

Qiita
https://qiita.com/sakuraya/items/abca057a424fa9b5a187
Rspecの導入

#はじめに
忘れないためにアウトプットさせてもらいます
テストコードのためfactory_botとfakerも導入します

#テストで使うGemを導入
Gemfileの中のgroup :development, :test do ~ endとある「do ~ endの間」に記述する

```:Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
end
```
１つ目　rspec導入
２つ目　factory_bot導入(毎回インスタンスを生成するのをなくすため)
３つ目　faker導入(ダミーデータを生成するため)

#必要なGemが記述できたら、ターミナルへ

```:ターミナル
% bundle install
```
#Gemを新しくインストールしたのでローカルサーバーを再起動
```:ターミナル
% rails s
```
#導入したRSpecを使用できるようする
```:ターミナル
% rails g rspec:install
```
#テスト結果のログを見やすくしテストコードの結果をターミナル上で可視化する
```:.rspec
--require spec_helper
--format documentation
```
#最後に
簡単なアウトプットでした