OmniAICreator/Qiita-1.07M huggingface dataset:
RailsチュートリアルのサンプルアプリにCSV出力機能を拡張

[Railsチュートリアル](https://railstutorial.jp/)で作成したサンプルアプリに、特定のユーザーのマイクロポストをCSV出力する機能を拡張します。

# 環境
・Rails 5.1.6
・Railsチュートリアル第4版(Rails5.1) 14章まで実装済み

# 仕様
・ユーザーのプロフィールページのExport CSVボタンを押すと、そのユーザーのマイクロポストがCSV出力される。

完成版のイメージは以下の通りです。

・Export CSVボタンを追加
<img width="1168" alt="スクリーンショット 2019-04-06 9.25.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/362742/0457f413-7882-645d-69aa-249a7ac93e7b.png">

・出力されたCSV
<img width="1234" alt="CSV.png" src="https://qiita-image-store.s3.amazonaws.com/0/362742/efe70cc1-d027-e42b-e8a9-30bff18544af.png">

# 実装
以下の手順で実装していきます。

**Export CSVボタンを表示する**
・プロフィールページにExport CSVボタンを表示
・ボタンを押したときにCSV形式でレスポンスを返すようにリクエストを投げる

**CSVをレスポンスする**
・リクエストを受け取り、CSVを返す

**CSVを生成する**
・返すCSVを生成する

## Export CSVボタンを表示する
showビューにExport CSVボタンを追加します。
リクエスト先を`user_path(@user,format: :csv)`とすることで、このボタンを押したときに、csv形式でレスポンスを返すように指定したリクエストが`user_path`に送信されます。

```erb:/sample_app/app/views/users/show.html.erb
:
:
  <% if @user.microposts.any? %>
    <% micropost_count = @microposts.count %>
    <h3 id="micropost-count">Microposts (<%= micropost_count %>)</h3>
    <%= link_to "Export CSV", user_path(@user,format: :csv),
      class: "btn btn-primary btn-csv",
      data: { confirm: "You are about to export #{@user.name}'s #{micropost_count} microposts.\nAre you sure you want to continue?" } %>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>
```
マイクロポスト数とExport CSVボタンを横並びで表示します。

```css:/sample_app/app/assets/stylesheets/custom.scss
:
:
#micropost-count{
  display: inline;
}
.btn-csv{
  margin-left: 30px;
  margin-bottom: 5px;
}
:
:
```

## CSVをレスポンスする
ユーザーコントローラーのshowアクションに、Export CSVボタンが押されたときの処理を記述します。
`respond_to do |format|`によって、リクエスト内で指定されたフォーマットごとに場合分けをします。リクエスト内で指定されたフォーマットがCSVだった場合(=Export CSVボタンが押された場合)は、CSVファイルを生成してレスポンスします。

```ruby:/sample_app/app/controllers/users_controller.rb
:
:
def show
  @user = User.find(params[:id])
  redirect_to root_url and return unless @user.activated?
  @microposts = @user.microposts.paginate(page: params[:page])
  respond_to do |format| #リクエスト内容によって処理を振り分ける
    format.html
    format.csv do
      send_data render_to_string, filename: "#{@user.name}'sMicroposts.csv", type: :csv
    end
  end
end
:
:
```

## CSVを生成する
`show.csv.ruby`ファイルを作成し、CSVファイルを生成する処理を記述します。
`column_names`配列にマイクロポストレコードのカラム名を代入し、これを利用して、マイクロポスト一つ一つについて、カラム名に対応する値をcsvに追記します。

```ruby:/sample_app/app/views/users/show.csv.ruby
require 'csv'

CSV.generate do |csv|
  column_names = Micropost.column_names
  csv << column_names
  @microposts.each do |micropost|
    csv << column_names.map{ |column_name| micropost[column_name] }
  end
end
```
以上で、特定のユーザーのマイクロポストをCSV出力する機能が完成しました。

# 参考
> [【簡単3ステップ】RailsでCSV出力する方法](https://qiita.com/ngron/items/60915083cb2bc3622c79)
> [RailsでMVCを意識してシンプルにCSV出力](https://qiita.com/necojackarc/items/39e0f0c438363f7084db)
AmazonLinuxについて

自分の覚書のために投稿します。

[Amazon Linux サーバ基本設定メモ](https://qiita.com/Ping/items/09deb80a0be86d5e3145#daemon%E3%81%AE%E4%B8%80%E6%8B%AC%E8%A8%AD%E5%AE%9A)

デーモン　　Daemonの一括設定
*sudo ntsysv*　を使ってグラフィカルの一括管理最低限残す
Demon

```
atd                 # キュージョブ at コマンド用
auditd              # （※任意）後述「セキュリティ要件」参照
cloud-config        # cloud-init用 (AWSのEC2設定ユーティリティ)
cloud-final         # cloud-init用 (AWSのEC2設定ユーティリティ) 
cloud-init          # cloud-init用 (AWSのEC2設定ユーティリティ)
cloud-init-local    # cloud-init用 (AWSのEC2設定ユーティリティ)
crond               # cron
irqbalance          # IRQ割込み処理のCPU間での負荷分散. コアが1つなら要らない.
netfs               # （※任意）NFSを使うならば必要
network             # ネットワーク利用で必要
ntpd                # 時刻合わせで必要
ntpdate             # OS起動時の時刻合わせ
psacct              # （※任意）後述「セキュリティ要件」参照
rngd                # （※任意）乱数ジェネレータ。サービスとしてユーザー認証が頻繁にあるシステムとかなら導入。
rsyslog             # syslogクライアントまたはsyslogサーバとして必要
sshd                # sshd接続に必要
```

#ログ管理
*Syslogホスト*（いわゆるログサーバ）用にRsyslogを使用している。ホスト側ではログを受け付ける設定
*Syslogクライアント*クライアントはホストへログを飛ばす設定　　
基本的に下記のログホストにログを飛ばす

#ディレクトリ構造
[Linuxの基本の基本。Linuxの基本的なディレクトリ構成](https://oxynotes.com/?p=5987)
ディレクトリの一覧と詳細を一行で表示
`ls -a1l /`

- /bin
システムを管理するための基本コマンドが入っている
- /boot
ブートに必要なファイル。ブートログやカーネルイメージが保存されている
- /dev
デバイスファイルが配置されている
- /etc
ほとんどの設定ファイルが帆保存される
- /home
一般ユーザのホームディレクトリ
- /lib
/bin(コマンド)や/sbinの実行ファイルが配置されている
- lost+found
システムのバックアップや復元用のファイルが格納される。意図しない再起動やシャットダウン時に使われる
- media
リムーバブルメディアのマウントポイント
- /mnt
一時的なマウントポイント
- opt 
パッケージ管理システムのインストール先
- /prot
プロセスのIDの付いたディレクトリが配置され、プロセス独自の情報を格納するプロセス
- /root
rootユーザのホームディレクトリ
- tmp
テンポラリデータの保存場所。メモリ上の一時ファイルの保存場所(再起動時に削除される)
- usr
各ユーザが共通して利用するプログラム・ライブラリのデータ
- /usr/bin
usrのコマンドが保存されている
- usr/etc
/usrのコマンドの設定ファイル
- /usr/libexec
コマンドから内部的い呼ばれる補助コマンド
- /usr/local
システム管理者のローカルファイル
- usr/sbin
usr版管理者コマンド
- /usr/src
ソースコードの保存場所
- /usr/tmp
usr版テンポラリファイルの保存場所
- /var
ログやキャッシュなど可変的システムデータ(再起動しても消えません)
- /var/log
ログファイルの保存場所。システム、メール、インターネットアクセスログなど

#ファイル属性
| ls -lでの表示　|    意味                                  |
|:--------------|:----------------------------------------:|
| -             |  普通のファイル（Regular File）            |
| d             |  普通のファイル（Regular File）            |
| l             |  シンボリックリンク                      　|
| c             |  キャラクタ型デバイスファイル（特殊ファイル）|
| b             |  ブロック型デバイスファイル（特殊ファイル）  |
|表1　「ls -l」で表示されるファイルの種類                     |
（レポート）Management 3.0 同窓会（19/04/04）

# はじめに

この記事は2019/04/04に行われたManagement 3.0の同窓会に参加したときに、話題に上がった話のピックアップです。
この会は組織やチームをよくするために頑張っている人たちによる相談会のような場です。
私は毎回リモートで参加しています。
Management3.0の話をしたり、ふりかえりの話をしたり、色々しています。

「チームや組織になにかアプローチしたいなー」という人にゆるっと読んでいただければと思います。

# 内容

## Celebration Gridをどう使う？

色々使い道はありそうです。
単純にアイデア出しとして使うのもいいですね。
または、Celebration Gridで分類して、穴のある部分を埋めるために、今後どう動きたいか？と話をする、という風に、Fun/Done/Learnのような使い方もできそう。
「実験」が出ないのであれば、実験を今後増やすためにどうしたいか、を考えたり。

※Celebration Grid についてはこちらをご参照ください

- [学びを祝うふりかえり「Celebration Grid」](https://qiita.com/viva_tweet_x/items/439574320cc2ad61f757)

※[Fun/Done/Learn についてはこちらをご参照ください]

- [ファン・ダン・ラーン(FDL)ふりかえりボード](https://qiita.com/yattom/items/90ac533d993d3a2d2d0f)
- [Fun/Done/Learnによるふりかえりレポート / 学び・楽しさにフォーカスするアクティビティ紹介](https://qiita.com/viva_tweet_x/items/7e279f41f4388d9162ef)

## ふりかえりの時間はどれくらい取る？

1週間のふりかえりであれば、90分をおすすめしています。
KPTだけ、YWTであれば40分あれば十分なのですが、アクションを具体化したり、ふりかえりをふりかえったり、とやっていくと90分あったほうが無難です。
2週間のふりかえりであれば、思い出しに時間がかかるので、120分でやることが多いです。

1週間のふりかえりのタイムスケジュール例

- 場作り 5～10分
- データの収集（Timelineなど） 20分
- アイデア出し（KPTや(Y)WTなど） 30分
- アクション決め 20分
- ふりかえりのふりかえり 5～10分

## カイゼンが部分最適になりがち

ふりかえりだけの話ではなく、マネジメント層も部分最適を選びがち、という話もでていました。

## QAは悪いGoodPracticeが続けられてしまう

チェックリストが増えていくイメージ。変えていきたいものの、変えたときの影響が怖くて変えられない。

## 斜に構える

[斜にかまえる・かまえないを1分ごとに切り替えるとどうなるか](https://dailyportalz.jp/kiji/sya_ni_kamaeru-kamaenai)がTwitterで話題になっていたよね、という話。
及部さんの[斜に構える・構えないを切り替えるロールプレイングふりかえり](https://takaking22.com/2019/role-playing-retrospective/?fbclid=IwAR0WKrwJIypLime_W7vq0NC8ICg0ADpHZSZ-IhkuVTaxS79gEdMjzXFwrKE)
も楽しそうだね、という話もしました。
視座を高めるのにも有効そう。

## ふりかえりの手法「闇鍋」

[新しいふりかえりのやり方『闇鍋』](https://www.ryuzee.com/contents/blog/7138?fbclid=IwAR2rpOM5uMYvGm167Bbsq9jMcHfV0psCqS1Lirg-2Mkuxq_UMMf4obn_qkE)もはすに構えるのと一緒で、思考を切り替えるのにはいいですね。

## ヤバイところにはチョコ

とりあえず甘いものを導入すれば、会議の危うい空気を変えられるはず。

## KPTをGoogleスプレッドシートでやってみた

リモートでふりかえりやってみたよ、というお話。
「みんながどこを書き込んでいるのかが見れるからいいよね。」
[RealtimeBoard](https://realtimeboard.com/)はリモートふりかえりや、リモートワークショップのときに私も愛用しています。
セルから画像がはみ出る場合の設定方法

下記のイメージで作ったのですが、イメージがセルからはみだすと言う事象が起こりました。
Storyboardでははみ出していないのになぜかと思いましたが、意外と簡単な設定ミスでした

<img width="281" alt="スクリーンショット 2019-04-06 9.37.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/239560/c895fd0d-8c69-6150-48f2-10e834c778cb.png">

しかも、下記エラー(ワーニング)が発生していたので、調べて直そうと思いました。
「Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.」

原因は単純なんですが、TableViewの高さの設定がうまくできていませんでした。
<img width="196" alt="スクリーンショット 2019-04-06 9.42.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/239560/52bdac42-5ce6-f722-0724-f08801a49a31.png">

TableViewの高さが自動設定になっていて、値が何も入力されていない状態でした。
デフォルト値が入っていて、想定より小さい高さが設定されていたので、イメージがはみ出していました。

<img width="250" alt="スクリーンショット 2019-04-06 9.45.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/239560/6f38aa9d-0a74-d312-e2f5-1d8bc9412c7d.png">

解決方法は2つあるかなと思っています。

**①TableViewの高さを設定する**
Row HeightのAutomaticにチェックが入っていたので、チェックを外し、値を設定します。
EstimateはXcode9で自動設定するようになっているため、入力しなくても問題はないはずです。

<img width="244" alt="スクリーンショット 2019-04-05 1.51.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/239560/0c6f673f-0694-b80b-42e4-53e94ed6ecd6.png">

**②セルの高さを実装で固定させる**

セルの高さを実装で下記のように、設定することもできます。

```
tableView.rowHeight = 80
```

今回はviewDidLoad()に処理を追加することで高さが修正されました。


いずれにせよ、Storyboardは目安ぐらいに考えて、実機やエミュレータでちゃんと動作、画面確認はしましょう。
Django2.2LTSがリリースされチェック制約とユニーク制約機能が実装された

# はじめに
2019年4月1日に、世界中が待望していたDjango2.2がリリースされました。
Django2.2は2系では初のLTSとして設計されており、リリースから少なくとも3年間に渡ってセキュリティや致命的なバグ、機能追加などが保証されています。
1系のLTSは2020年4月で終了するため、これを機に2系への移行も検討しては良いのでしょうか。

# Pythonとの互換性
Django2.2ではPython3.5以降をサポートしています。

# データベースの制約

チェック制約とユニーク制約が設定可能になりました。
この2つの制約は、データに整合性を適用するために使用します。

## チェック制約

データの追加、更新時に値が指定している条件を満たしているかをチェックすることができます。
checkにはQオブジェクトを利用して制約をかけ、nameには制約名を設定します。

```django:example
CheckConstraint(check=Q(age__gte=18), name='age_gte_18')
```

## ユニーク制約

こちらの制約は、チェック制約に他のデータとの重複禁止の制約をかけたものです。
fieldsに制約をかけたいフィールド名を設定し、nameには制約名を設定します。

```django:example
UniqueConstraint(fields=['room', 'date'], name='unique_booking')
```

さらに、conditionsを指定しておくことで、データ追加更新時に値への条件を指定することができます。

```django:example
UniqueConstraint(fields=['user'], condition=Q(status='DRAFT')
```

# 参考
[Django 2.2 released](https://www.djangoproject.com/weblog/2019/apr/01/django-22-released/)
4/6 jsコードレシピ集 outerHTML getAttribute classList

# 要素.innerHTML 要素内のみ取得

```js:js
const weatherInfo = document.querySelector('.weather');
alert(weatherInfo.innerHTML);
// 出力結果　晴れ <span class="temperature" > 16℃</span >
```

# 要素.outerHTML 要素全体を取得
```js:js
const weatherInfo = document.querySelector('.weather');
alert(weatherInfo.outerHTML);
// 出力結果　<p class="weather">晴れ<span class="temperature">16℃</span></p>
```

# 要素の属性を取得する 要素.getAttribute(取得したい属性)

```js:js
const anchorElement = document.getElementById('anchor');
const hrefElement = anchorElement.getAttribute('href');
alert(hrefElement);
```

# 要素に属性を設定する 要素.setAttribute(設定したい属性, 値)

```js:js
const imageElement = document.getElementById('image');
const srcElement = imageElement.getAttribute('src');
alert(srcElement);
```

# 要素に特定の属性があるかどうか 戻り値は真偽値 要素.hasAttribute(属性)

```js:js
alert(anchorElement.hasAttibute('href'));
```

# クラスの追加classList.add
# クラスの削除classList.remove
# クラスが含まれるか確認classList.contains(クラス)

```js:js
const box1 = document.getElementById('box1');
const box2 = document.getElementById('box2');

// box1にredクラスとyellowクラスを追加
box1.classList.add('red', 'yellow');

// box2にwhiteクラスを追加
box2.classList.add('white');

// box1にredクラスとyellowクラスが含まれてるかどうか 複数の場合は&&でチェック可
alert(box1.classList.contains('red' && 'yellow')); // true
alert(box2.classList.contains('green')); // false

// box1からredクラスを取り除く
box1.classList.remove('red');

// box1にredクラスがあるかどうかチェック
alert(box1.classList.contains('red')); // false
```
memo:thymeleaf+bootstrap

```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<meta charset="UTF-8">
<link th:href="@{/webjars/bootstrap/3.3.5/css/bootstrap.min.css}" rel="stylesheet" />
<script th:src="@{/webjars/jquery/3.3.1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/3.3.5/js/bootstrap.min.js}"></script>
    <title>Home</title>
</head>
```

```xml
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>jquery</artifactId>
			<version>3.3.1</version>
		</dependency>
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<version>3.3.5</version>
		</dependency>
```

* versionを合わせる
* こうするとintteliJで補完してくれる

cf.

* https://getbootstrap.com/docs/4.1/getting-started/introduction/
Minikubeをwindowsにセットアップ

# 前提条件
- 以下のものが利用できる
    - Virtual Box
    - kubectl

# 実行環境
- Windows10 64bit
- Virtual Box 6.0.4
- git version 2.20.1.windows.1
    - Linuxコマンドを実行するために使用

# 参考
- https://kubernetes.io/docs/setup/minikube/
- インストール
    - https://kubernetes.io/docs/tasks/tools/install-minikube/

# インストール
- 上記のサイトからminikube-windows-amd64.exeをインストールし、minikube.exeにリネームした後に/usr/binに移動

# Quickstart

## 起動
- 以下のコマンドで開始する
- --vm-driver=xxx でVM driverを指定できるが、何も指定しない場合はVirtual Boxが使用される

```
$ minikube start
```

- しばらく待つとセットアップが完了する

```
$ minikube start
o   minikube v0.35.0 on windows (amd64)
>   Creating virtualbox VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
@   Downloading Minikube ISO ...
 184.42 MB / 184.42 MB  100.00% 0ss
-   "minikube" IP address is 192.168.99.100
-   Configuring Docker as the container runtime ...
-   Preparing Kubernetes environment ...
@   Downloading kubeadm v1.13.4
@   Downloading kubelet v1.13.4
-   Pulling images required by Kubernetes v1.13.4 ...
-   Launching Kubernetes v1.13.4 using kubeadm ...
:   Waiting for pods: apiserver proxy etcd scheduler controller addon-manager dns
-   Configuring cluster permissions ...
-   Verifying component health .....
+   kubectl is now configured to use "minikube"
=   Done! Thank you for using minikube!
```

- 上記のコマンドにある通り、kube-configにminikubeの情報が追記され、current-contextがminikubeに設定される
- 下記のコマンドでクラスタの情報を取得

```
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```

- ノードの情報を取得

```
$ kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
minikube   Ready    master   9m12s   v1.13.4
```
- マスタが一台動いており、シングルノードであることが確認できる
Glueの使い方的な㊳(WorkerTypeとは)

# Glue JobでWorkerTypeが選べるようになりました

公式ドキュメントはこちら

https://aws.amazon.com/jp/about-aws/whats-new/2019/04/aws-glue-now-supports-additional-configuration-options-for-memory-intensive-jobs/

https://docs.aws.amazon.com/en_us/glue/latest/dg/add-job.html

# 設定箇所

"ジョブの追加"をクリック

![スクリーンショット 0031-04-06 8.59.29.png](https://qiita-image-store.s3.amazonaws.com/0/27932/da7680fd-69cf-bb12-9ddd-e2c58f1983e5.png)

ジョブプロパティで"セキュリティ設定...."をクリック

![スクリーンショット 0031-04-06 8.59.52.png](https://qiita-image-store.s3.amazonaws.com/0/27932/31c732a8-993b-fd55-64a9-6c94a8239fcb.png)

#### "Standard"、"G.1X"、"G2.X" から選ぶことができます。

* Standard:4vCPU, 16GBメモリ, 2Executor(ようは今までの)
* G.1X:4vCPU, 16GBメモリ, 1Executor, 64GBディスク(ようはExecutor1にしたよ)
* G.2X:8vCPU, 32GBメモリ, 1Executor, 128GBディスク(ようは2DPU)

<img width="644" alt="スクリーンショット 0031-04-06 7.35.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/7ff90742-0b4a-df0c-3457-dc6600ff0a44.png">

#### 上限(多分ソフトリミット)

* Standard DPU：100
* G.1X Worker数:299(Maximum capacity=300)
* G.2X Worker数:149(Maximum capacity=299)

# Standardで実行したログ

core=4　なのでvCPU4
spark.executor.memory=5g　なので1Executorあたり5GB
spark.dynamicAllocation.enabled=true　なので(最大メモリが以下のように12GBで、1Exeあたり5.5GB(以下のmemory overhead足して))最大2Executor起動する(5.5GB*2 = 11GB <12GB でこれ以上はExecutor起動できない)

maximum memory capability (12288MB)　なので最大12GB
512MB overhead　なのでメモリ512MB上乗せ

![スクリーンショット 0031-04-06 9.17.13.png](https://qiita-image-store.s3.amazonaws.com/0/27932/85e1ffc9-fa5c-2b84-7aba-f506ce175439.png)

# G.1Xで実行したログ

core=8　なのでvCPU8?
spark.executor.memory=10g　なので1Executorあたり10GB
spark.dynamicAllocation.enabled=true　なので(最大メモリが以下のように12GBで、1Exeあたり11GB(以下のmemory overhead足して))最大1Executor起動する(11GB*1 < 12GB でこれ以上はExecutor起動できない)
spark.yarn.executor.memoryOverhead=2g　なのでメモリ2GB上乗せ

maximum memory capability (12288MB)　なので最大12GB
1024MB overhead　なのでメモリ1024MB上乗せ(多分こっちで上書かれる)

![スクリーンショット 0031-04-06 9.42.58.png](https://qiita-image-store.s3.amazonaws.com/0/27932/6063ea31-03cf-0da3-4049-beea038102ce.png)

# G.2Xで実行したログ

core=16　なのでvCPU16?
spark.executor.memory=20g　なので1Executorあたり20GB
spark.dynamicAllocation.enabled=true　なので(最大メモリが以下のように24GBで、1Exeあたり2GB(以下のmemory overhead足して))最大1Executor起動する(22GB*1 < 24GB でこれ以上はExecutor起動できない)
spark.yarn.executor.memoryOverhead=4g　なのでメモリ4GB上乗せ

maximum memory capability (24576MB)　なので最大24GB
2048MB overhead　なのでメモリ2048MB上乗せ(多分こっちで上書かれる)

![スクリーンショット 0031-04-06 9.51.21.png](https://qiita-image-store.s3.amazonaws.com/0/27932/ba47b10f-904d-95e4-b07b-3e833d0a1874.png)

## こちらも是非

Glueの使い方まとめ
https://qiita.com/pioho07/items/32f76a16cbf49f9f712f
標準出力を受け取りコマンドを実行する　Go

#[|]で値を流してreadで変数に格納し、変数の値のファイルを3つ作成する
Linuxコマンド

```
./request | ./scan | sh mkfile.sh
```
![キャプチャ7.PNG](https://qiita-image-store.s3.amazonaws.com/0/347413/de368dd3-1826-949f-6176-da206a499ca1.png)
request.go　　ランダムにUUIDを生成して標準出力する
scan.go　   　UUIDから数値のみを抽出して標準出力
mkfile.sh　　 標準出力から受け取った数値のfileを3つ作成する

今回初めてスクリプトで標準出力を受け取りLinuxコマンドを実行したので覚書です。

*request.go*

```
package main

import(
        "fmt"
        "time"
        crand "crypto/rand"
        "math"
        "math/rand"
        "math/big"
)
func main() {
        for {
            seed, _ := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
            rand.Seed(seed.Int64())
            s :=rand.Int63()
            fmt.Printf("UUID=%v\n",s)
            time.Sleep(1 * time.Second)
        }
}
```
*scan.go*

```
package main

import (
    "fmt"
    "strings"
)
func main() {
    var a string
    dst := ""
    for {
    fmt.Scan(&a)
    if strings.Contains(a,"UUID"){
        dst = strings.Replace(a, "UUID=", "", 1)
        fmt.Println(dst)
    } else {
        fmt.Printf("none\n")
    }
    }
}
```
*mkfile.sh*

```
#!/bin/bash

echo "Enter files name"
read file_name1
echo "get file_name1"
read file_name2
echo "get file_name2"
read file_name3
echo "get file_name3"


touch $file_name1
touch $file_name2
touch $file_name3
```
凄く基本的な部分ですが、なんとなくスクリプトのイメージができるようになりました。
個人目標管理が機能する条件。仮説（14）

人事に６年いた経験を基に、その後管理系の国際規格のeditor, 国際規格の日本の代表, 研究会のプログラム委員長などの経験を基に記述

個人目標管理が機能する条件は、次の仕組みのうちどれかが機能している場合

# 組織内のその分野の最高の専門家が、自分の専門分野のすべての人間の能力を把握している

例えば、プログラマであれば、その組織内の最高のプログラマが、すべてのプログラマの能力を知っている。

プログラマの人数が100人くらいまでなら、特別な仕組みがなくても、すべてのプログラマのreviewに最高のプログラマが参加すればよい。

また、個々のプログラマの、過去の作品と、特許・論文などを把握していて、個人目標管理も評価、助言している。

# 組織内のその分野の最高の専門家が、外部の尊敬する専門家に、個人目標管理を依頼している

組織で、人事、経理などの事務を外部委託している場合。

いくつかの組織を横断的に、いろいろな規模の組織を担当していると、
どのくらいの規模の組織には、どんな管理方法がいいかが見えてくるかもしれない。

30人の組織なら、社長が全員を見ても良い。
300人くらいの組織なら、誰か人事担当がいてもよい。
3000人くらいの組織なら、人事は組織があってもよい。
30000人くらいの組織では、専門分野ごとに管理できる人がいるとよい。

例えば、製造業であっても、30,000人を超える組織では、
ITの人事を専門で見渡せる人がいるとよい。

# 参考資料
今年度(2019)の目標的な何か:docker(106) 統計と確率(22)
https://qiita.com/kaizen_nagoya/items/8224430eccbb5592d752

2019年のQiita記事の目標。　Qiita(17)
https://qiita.com/kaizen_nagoya/items/33988e811b174e443bfa

アニメねたをつぶやき、その背景にある技術(IT)について整理する。(目標100)
https://qiita.com/kaizen_nagoya/items/06fdcfbd1666d53d516c

viewsが1,000,000, goodsが10,000が第五目標を達成した人、達成していない人。
https://qiita.com/kaizen_nagoya/items/fd5161da67fd3e663aaa

連休中の記事数は目標達成した。質向上のために集計。平均が無意味なことを再確認。転職(14)
https://qiita.com/kaizen_nagoya/items/138c543c5e74e380d31d

64歳の目標半分達成。量子計算機を期間中に新規着手。未達成項目は65歳の年度末に延長。転職(7)
https://qiita.com/kaizen_nagoya/items/d7f8a58dfd20024d4d7e

なぜdockerでpython/Rを使って機械学習するか 書籍・ソース一覧作成中 (目標100) docker(18)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2
# 文書履歴(document history)
ver. 0.01 初稿 20190406
ver. 0.02 追記 20190419
ver. 0.03 参考資料追記　20229313

@## 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Railsチュートリアル第５章②

#Railsチュートリアル　第５章より〜

自身のポートフォリオにも今後使いそうだなと思い、
振り返り用でメモします。


#・リンクのテスト
→いくつかリンクを埋めることができたら、
リンクが正しく動いているかどうかチェックするテストを書く。
「統合テスト (Integration Test)」を使って一連の作業を自動化していく。
統合テストを使うと、アプリケーションの動作を端から端まで (end-to-end) シミュレートして
テストすることができる。

まずは、```site_layout```というテストのテンプレートを生成する。

```$ rails generate integration_test site_layout```
QEMU/KVM の環境をCentOSからDebianに移設するときのポイント

CentOS6.9の環境を捨て、Debian9に移行しました。
そのとき、仮想環境の持ち出し、移植をしたので、そのときのメモです。

# 移設のポイント
3つだけ。ディレクトリ構成を変えなければ、2つだけ。さらに、そのうち1つは、kvmのバージョンの影響。
- emulatorの変更 (centosとdebianの違いから、ほぼほぼmust)
- machineの変更 (選択したマシーンによるけど、無意識に使っていたなら、ほぼmust)
- source fileの変更 (引っ越し後のディレクトリ構成を変更したなら、must)

なお、/etc/libvirt/qemuというフォルダ構成は、centos/debianともに同じです。

# emulatorの変更

Before

```Before
    <emulator>/usr/libexec/qemu-kvm</emulator>
```

After

```After
    <emulator>/usr/bin/kvm</emulator>
```

変更するコマンドはこちら。xmlファイルへのパスは、適当に設定してください。root権限がいります。

```
# sed -i".bk" -e "s/libexec\/qemu-kvm/bin\/kvm/" *.xml
```

# machineの変更

Before

```Before
    <type arch='x86_64' machine='rhel6.6.0'>hvm</type>
```

After

```After
    <type arch='x86_64' machine='pc-i440fx-2.8'>hvm</type>
```

変更するコマンドはこちら。

```
# sed -i".bk" -e "s/rhel6\.6\.0/pc-i440fx-2\.8/g" *.xml
```

# source fileの変更

変更対象は、ここです。

```
    <source file='/dir/to/my/myvirt.raw'/>
```

移設先のフォルダ構成が同じなら、変更の必要はないです。
今回は、同じ構成なのでしたので、設定例は割愛。

# おまじない#1 - virtに登録
変更したxmlの情報を、登録し、実行可能状態にします。
ここでは、myvirt.xmlとします。

```
# virsh define myvirt.xml
```


# おまじない#2 - virt-managerを再起動
GUIとして、virt-managerを使っている場合は、デーモンの再起動をしたほうがよい。
しなくても、いける

```
# systemctl restart libvirtd
```

これで、移植作業は終わり
テキスト操作ばかりなので、バッチ化すれば、多くの仮想マシンの移設も簡単

# おまじない#3 TAPの準備

VMのwindows remote desktopを使う場合は、TAPｇないと、つながらない。
よって、tapの準備もしておく

```
auto br0
iface br0 inet static
      address 192.168.0.2
      netmask 255.255.255.0
      network 192.168.0.0
      broadcast 192.168.0.255
      gateway 192.168.0.1
      dns-nameservers 192.168.0.1
      bridge_ports eth0 tap0
      bridge_stp off
      bridge_maxwait 0
      bridge_fd 0
      pre-up ip tuntap add dev tap0 mode tap user root
      pre-up ip link set tap0 up
      post-down ip link set tap0 down
      post-down ip tuntap del dev tap0 mode tap
```

[EOF]
【Laravel】Laradockを利用したLaravel環境構築

忘れっぽいので自分用かも...

Laradockという、オープンソースを使って環境を構築する
また、GitとDockerはインストール済みとして進めて行く

## Laradockのダウンロード

まずは、gitからclone

```php5:
$ git clone https://github.com/Laradock/laradock.git
```

## .env作成

cloneしてきたlaradockディレクトリに移動し、env-exampleファイルをコピーして、
.envファイルを作成

```php5:
$ cd laradock
$ cp env-example .env
```

## コンテナ起動

次に以下コマンドで、コンテナを初期化
初期化には少し時間がかかる

```php5:
$ docker-compose up -d nginx mysql workspace phpmyadmin
```

## Laravelのプロジェクト作成

プロジェクトはworkspaceコンテナ上に作成する

まずは、workspaceコンテナへログイン

```php5:
$ docker-compose exec --user=laradock workspace bash
```

新規プロジェクト作成
プロジェクト名はsample

```php5:
$ composer create-project laravel/laravel sample --prefer-dist "5.5.*"
```

すると、sampleプロジェクトが作成される
一度、コンテナからログアウト

```php5:
$ exit
```

## 共有ディレクトリの設定

最後に.envファイルを開き、編集する

```php5:.env
###########################################################
###################### General Setup ######################
###########################################################

### Paths #################################################

# Point to the path of your applications code on your host
# APP_CODE_PATH_HOST=../          // コメント化
APP_CODE_PATH_HOST=../sample      // 追加
...
```

編集が完了したら、保存
設定変更を反映させるためにコンテナを停止させ、再起動

```php5:
// 停止
$ docker-compose stop
// 再起動
$ docker-compose up -d nginx mysql
```

これで環境構築完了です

## Migration時のエラー

下記のエラーでMigrationが実行できなくて詰まったので追記
権限の問題らしい

```php5:
In Connection.php line 664:
                                                                                                                                                           
  SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from information_schema.tables where table_schem  
  a = default and table_name = migrations)                                                                                                                 
                                                                                                                                                           

In Connector.php line 67:
                                                                                           
  SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client  
                                                                                           

In Connector.php line 67:
                                                                                                                
  PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password]             
```

まず、mysqlコンテナに入り、mysqlコマンドを叩く

```php5:
$ docker-compose exec mysql bash
$ mysql -u root -p
```

権限を変更するコマンドを叩く

```php5:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
ALTER USER 'default'@'%' IDENTIFIED WITH mysql_native_password BY 'secret';
```

実行できたらexitで終了
これでmigrationできた
Linux システム管理コマンドリファレンス


## w

wコマンドはログインしているユーザとそのプロセス情報を表示します。また、システムの稼働時間や負荷平均も表示します。

## ディスクI/Oの状態を表示するコマンド

- iostat
- vmstat
- sar -b

## CPUの負荷平均を表示するコマンド
- top
- uptime
- w

## 物理メモリとスワップ領域の使用状況を表示するコマンド
- free
- vmstat
- top

## システム全体としてのCPU使用率およびCPU毎の使用率を表示するコマンド
- sar
- mpstat

...続く
シェルスクリプト基本まとめ

# はじめに
演算子の種類や基本構文等、シェルスクリプトの基本的な書き方についてまとめます。

# シバンの定義
シェルスクリプトの1行目にはシェルスクリプトを実行するシェル（インタプリタ）を定義します。

```
#!/bin/sh
```

### その他の主なシバン

| シバン| インタプリタ |
|:--|:--|:--|
| #!/bin/bash/ | bash |
| #!/usr/bin/python | python |

# シェルスクリプトの実行方法
シェルスクリプトは実行方法により必要になるパーミッションが異なります。
シバンで指定したシェルを起動してスクリプトを実行する場合は、そのスクリプトファイルに実行権が必要です。（下記の表を参照） 


| 例 | 備考 |
|:--|:--|
| ./script.sh | ・シバンで定義されたシェル（子プロセス）を起動する <br>・ファイルに実行権が**必要** |
| bash script.sh | ・別途bash（子プロセス）を起動する（シバンを読み込まない） <br>・ファイルに実行権不要 |
| . script.sh | ・"source script.sh" と同様の処理 <br>・現在のシェル（プロセス）がスクリプトを実行（シバンを読み込まない） <br>ファイルに実行権不要|

# パーミッションの追加（実行権の付与）

パーミッションの確認方法

```
$ ls -l script.sh
-rw-rw-r--. 1 user user 20  7月 10 15:27 script.sh
```

全てのユーザに実行権を付与する場合

```
$ chmod a+x script.sh
$ ls -l script.sh
-rwxrwxr-x. 1 user user 20  7月 10 15:27 script.sh
```

# 特殊引数

| 特殊引数 | 説明 |
|:--|:--|:--|
| $0 | スクリプト自身のファイル名が格納される |
| $1-9 | 実行時に指定した引数が順番に格納される　<br>10以上の引数を指定する場合は数字を{}で括る <br>例：${10} |
| $# | 引数の数が格納される |
| $* | $0以外の引数が1つの文字列として格納される |
| $$ | スクリプト実行時のプロセスIDが格納される |
| $? | スクリプトの終了ステータスが格納される（正常終了：0　異常終了：1） |


```
#!/bin/bash

echo $#
echo $0
echo $1
echo $2
echo $10 #$1までが解釈される
echo ${10}
echo $$
echo $?
echo $#
echo $*

# 実行結果
. script.sh a b c d e f g h i j k l m
13
-bash #スクリプトをパスで指定すればファイル名になる
a
b
a0
j
5601
0
13
a b c d e f g h i j k l m
```

# 配列

複数のデータを扱う

```
#!/bin/bash

list=("string" 10) #配列の定義

#配列の要素の取得
echo ${list[0]} #1番目の要素の表示
echo ${list[1]} #2番目の要素の表示
echo ${list[0]:1} #1番目の要素を2文字目から表示
echo ${#list[0]} #1番目の要素の文字数を表示
echo ${#list[@]} #要素数
echo ${#list[*]} #要素数

# 実行結果
$ ./script.sh
string
10
tring
6
2
2
```
Google Chromeの閲覧履歴をエクスポートする(Windows, Mac対応)


## はじめに

インターネットブラウザの閲覧履歴を見返していると自分の人生を振り返ってるみたいで楽しいですよね。
私の場合はChromeの履歴が2013年からのものが残っていましたが、
それ以前はIEやFireFoxなどを使っていたので残念ながら残っていませんでした。


他のブラウザについては以下の記事でまとめています。
- Microsoft Edge

https://qiita.com/MURAMASA2470/items/35cf540cf44a3c1617ab

- Apple Safari

https://qiita.com/MURAMASA2470/items/c29a9209c0d80956d913

## OS毎の履歴データの保存場所

履歴データは以下のディレクトリにあります

```
// Windowsの場合
~\AppData\Local\Google\Chrome\User Data\Default\

// Macの場合
~/Library/Application\ Support/Google/Chrome/Default/
```

この中に`History`というファイルがあるので、それがChromeの履歴データになります

## sqlite3のインストール

履歴データの閲覧には、`sqlite3`が必要です。
まだインストールされていない方は、以下を参考にインストールしてください。

### Windowsの場合

```
choco install sqlite
// or 
winget install --id SQLite.SQLite
```
コマンド以外のインストール方法としては、[SQLite公式サイト](https://www.sqlite.org/download.html)からダウンロードする方法もあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243130/8457c1f2-13d9-4a9f-8476-794f6bf81d38.png)


### Macの場合
※最近のバージョンでは初めからインストールされている。
```
brew install sqlite
```

## 履歴データの中身を確認

それでは以下のように進めていきます

```
// Windowsの場合
> cd '~\AppData\Local\Google\Chrome\User Data\Default\'

// Macの場合
> cd ~/Library/Application\ Support/Google/Chrome/Default/

// sqliteの中に入る
> sqlite3 History

// テーブル一覧の表示
sqlite> .tables
```

`History`の中には以下のようなテーブルがあります

| テーブル名 |
|:--|
| downloads |
| download_url_chains |
| meta |
| urls |
| keyword_search_terms |
| segments |
| segment_usage |
| visits |
| visit_source |

今回は訪問時間も欲しいので`urls`と`visits`を結合して使います
`urls`と`visits`の構造は以下のようになっています

| urls | visits |
|:----|:----|
| id | id |
| url | url |
| title | visit_time |
| visit_count | from_visit |
| typed_count | transition |
| last_visit_time | segment_id |
| hidden | visit_duration |
| favicon_id | |

## 履歴データを抽出してみる

今回は`csv`形式で出力しますが、他にも以下のようなものもあるそうです

|mode  |説明   |
|:-----|:-----|
|csv      |カンマ区切りで出力|
|column   |カラム毎に左揃えで出力|
|html     |HTMLのTABLE形式で出力|
|insert   |INSERT文として出力|
|line     |各カラム毎に行を分けて出力|
|list     |区切り文字でカラムを区切り1行で出力(デフォルト)|
|tabs     |タブ区切りで出力|
|tcl      |TCLのlist形式で出力|

それでは実際に出力していきます
※`visit_time`がUNIXタイムもどき(1601/01/01 0:00 からのマイクロ秒)になっているので一般的な形式に変換しています

```
// .mode [モード名] でモード指定
sqlite> .mode csv

// .output [ファイル名].csv でファイル名指定
// 今回はユーザーのホームディレクトリに保存
sqlite> .output ~/result.csv

// ヘッダーをつける
sqlite> .headers on

// 抽出
sqlite> select urls.id, datetime(visits.visit_time/1000000-11644473600,'unixepoch','localtime') as visit_time, urls.title, urls.url from visits left join urls on visits.url = urls.id order by visits.id desc;
```
抽出で使用したSQLの内容は以下のようになっています

```sql
select 
 urls.id,
 datetime(visits.visit_time/1000000-11644473600,'unixepoch','localtime') as visit_time, 
 urls.title, 
 urls.url 
from visits 
left join urls 
 on visits.url = urls.id 
order by visits.id desc;
```

sqliteを抜けるとホームディレクトリに`result.csv`というファイルができています。

もし`Error: database is locked`と出たら一度Google Chromeを終了してから、もう一度試す、
もしくは、Historyファイルを別名でコピーしたものに対して実施してみてください。

以上です。
cronについて

# はじめに

cronはしばらく書かないとすぐ忘れるのでまとめてます。

## 環境
さくらのVPS　CentOS7


## cronの書き方
/etc/crontabを開いたらこんな風に書いてあるのでそのまんまです。
実際設定する時はここに直接書き込んではいけません。

```
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
```

```
例）*/5 * * * * command_name（絶対パス指定）

これで5分おきにコマンドが実行される
```

## cron書く時のcommand
```
$ crontab -e
```

## cronの一覧表示

```
$ crontab -l
```

## cronのスケジュールを全部消す

```
$ crontab -r
```
## cron ログの確認方法

```
$ sudo tail -f /var/log/cron
```
php.iniの場所を調べる

# php -i で大体の情報は見れる

```
# php -i | grep php.ini

Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini

# ls /etc/ | grep php
php.d
php.ini ←みっけ
```

前アカウントの投稿時 @mpyw さんが教えてくれた。

```
mpyw@localhost:~$ php --ini
Configuration File (php.ini) Path: /Users/mpyw/.phpbrew/php/php-7.1.0/etc
Loaded Configuration File:         /Users/mpyw/.phpbrew/php/php-7.1.0/etc/php.ini
Scan for additional .ini files in: /Users/mpyw/.phpbrew/php/php-7.1.0/var/db
Additional .ini files parsed:      /Users/mpyw/.phpbrew/php/php-7.1.0/var/db/callee.ini

mpyw@localhost:~$ 
```

まぁふつうにfindで探してもいいやね。

```
find / -name php.ini
```
ルーティングに関して自分が困ったこと

# 例えば、
**<font color="#005CAF">詳細画面のルーティングを設定しよう</font>**
**<font color="#005CAF">削除画面のルーティングを設定しよう</font>**
**から始まる一連の実装の流れがあると思うが、**

    アクション定義時は、
    対応するコントローラに、def index〜と、アクションを定義すればいい

    ビュー作成時は、
    そのアクションに対応するビューを作成すればいい

**と、上記二つに関しては、**
**機能の連携を、頭の中で追いかけながら実装することができる**

**が、**


#ルーティングの作成時
**時々考えてしまう瞬間があって、**
**例えば、以下のような
コントローラーのアクションを動かすルーティング
を設定したいとして、**

```ruby:app/controllers/tweets_controller.rb
 #Tweetsコントローラーのindexアクションを動かしたい
 class TweetsController < ApplicationController
  def index
    @tweets = Tweet.includes(:user)
  end
 (中略)
```
**下のルーティングが<font color="#005CAF">条件反射的に</font>浮かんでしまう。**

```ruby
  get  'tweets'  =>  'tweets#index'
```



**この時、いつも自分は左側のパスの設定に悩まされていて**
**このパスは一体何に基づいて決定されているのか**
**URLに基づいて決定されているのか**
**パスの起点となるリンクの設定が、URLを決め、それに従って、パスもそのように設定するのか**
**それとも、<font color="#005CAF">tweetsコントローラーだから、tweetsにしなければならない</font>のか**
**コントローラとルーティングどちらを最初に考えるものなのか**<br>
**要は、<font color="red">ルーティングのパス部分は何に基づいて決まるものなのか</font>が分からなかった。**

## そこで、この本を参照に考えてみたい。
[<img width="150" alt="代替テキスト" src="https://images-na.ssl-images-amazon.com/images/I/71dEH9dqYDL.jpg">](https://www.amazon.co.jp/dp/4774188832/ref=cm_sw_em_r_mt_dp_U_OsjPCb5V8XXXY)


## P31〜32(要約)
**Helloコントローラーのindexアクションの<font color="#005CAF">ルーティングを設定</font>する流れ**

```ruby:app/hello_controller.rb

#Helloコントローラーのindexアクション
class HelloController < ApplicationController
  def index
     render plain: '一歩一歩'
  end
end





#自分が推測したルーティング(これしか推測できなかった)
get 'hello' => 'hello#index'

#紹介されていたルーティング
get 'hello/index', to: 'hello#index'


#この時点でも面食らい、宙に飛ばされた感じがあった...、
```

**引用**

>**これで、「http://localhost:3000/hello/index」 と言うURLが要求されたら、hello#indexアクションを呼び出しなさいと言う意味になります。ここでは、URLと、対応するアクションを同じ名前にしていますが、両者は一致していなくても構いません。例えば、以下の設定により、「http://localhost:3000/hoge/piyo」 で呼び出せるようになります。**

```ruby
#以下の設定
get 'hoge/piyo', to: 'hello#index'
```

>**そもそも両者はあえて異なる名前を付ける必要もないから、本書では、まずは「コントローラー名/アクション名」となるようにURLを決めていくものとします。**



# つまり、どういうことか、差異を比較

```ruby
get 'hello' => 'hello#index'
#「http://localhost:3000/hello」

get 'hello/index', to: 'hello#index'
#「http://localhost:3000/hello/index」

get 'hoge/piyo', to: 'hello#index'
#「http://localhost:3000/hoge/piyo」
```

# 踏まえて、疑問を考えてみると、

**今まで、
このパスが来たら、このコントローラの、このアクションが動く、**
**このアクションを動かしたいのなら、<font color="red">このようにルーティング(のパス部分)を構成しないといけない</font>と、
<font color="red">何かに基づいてパス部分が規定されている</font>ように考えていたのだが、**

**原理的にはそうではなく、**
**結局、何で混乱していたかと言うと、**

**自分で設定したルーティングこそが、**
**対応させたいコントローラーのアクションを動かすURLを規定していることを知らなかったからだ。**
素数ライブラリ(sieve)の使い方 （＋1億以下の素数の和計算パフォーマンス）

Python の素数用ライブラリ [(scipy.sieve)](https://docs.sympy.org/latest/modules/ntheory.html) 　の基本的な使い方：

##ライブラリ読込：
```python
from sympy import sieve
````
※Google colabratory 上では sympy はデフォルトで利用可能

##素数の判定：
内部的には[「エラトステネスの篩」](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9) のアルゴリズムが巧妙に用いられている。(裏で自動的に素数リストの作成、拡張等を行い、キャッシュされる）

```python 
6 in sieve
 #False

7 in sieve
 #True
```


##素数リスト（ジェネレータ）
```python
print([i for i in sieve.primerange(7, 18)])
#[7, 11, 13, 17]

```

###1億までの素数の和

[こちらのページ](https://qiita.com/BMJr/items/87d9d81884d52b6d13d4)
では、1569秒かかった1億までの素数の和の計算ですが
Google　Colaboratory　+　Pythonのライブラリでは53秒でした。

```python
%time sum(sieve.primerange(1,100000000))
```


```text 
#実行結果:
CPU times: user 53.7 s, sys: 1.33 s, total: 55 s
Wall time: 55.1 s
279209790387276


```
Raspberry Pi の Node.js をアップデートする

# 経緯

[Raspberry PiからGoogle Homeを喋らせる](https://qiita.com/ktetsuo/items/8c9cd5714e231aa6ae09) で、google-home-notifierをインストールするためにNode.jsのバージョンアップが必要で、手動でコマンドを打ってアップデートしていたが、以下の問題があった。

* コマンドの手打ちが面倒
* Node-REDがアンインストールされてしまう

# 解決方法

Node-RED ユーザーグループのページ
https://nodered.jp/docs/hardware/raspberrypi
に、簡単にアップデートできるスクリプトがあった。
これは Node-REDをアップデートするスクリプトだが、Node-REDは内部でNode.jsが動いており、Node-REDをアップデートすることによってNode.jsもアップデートされる。

そのスクリプトがこちら。

```bash:
bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
```

これを実行すると、20〜30分放っておくだけでNode.jsとNode-REDをアップデートすることができる。
もちろんNode-REDが消えることもない。

2019/04/06 現在、Node.js v10.15.3がインストールされた。
k3sとGCP無料枠でおうちハイブリッドK8sしてみる

#K3sとは
Rancherによる軽量Kubernetesディストリビューション
https://k3s.io/

5 less than k8sといっているがいくつか追加で組み込まれている機能もある。
通常のK8sの要件は
> 2 GB or more of RAM per machine

となっているため、そこそこのVMでないと立てられないが、k3sは

> 512 MB of ram per server
> 200 MB of disk space

とだいぶ軽くなっている。

#GCP無料枠
https://cloud.google.com/free/
無料枠で使えるGCEインスタンス(VM)は

> 1 f1-micro インスタンス（1 か月あたり、米国リージョン us-central1、us-east1、us-west1 のみ）
> 30 GB の HDD（期間合計）
> 5 GB のスナップショット（期間合計、一部のリージョン）
> 1 GB の北米から全リージョン宛ての下りネットワーク（1 か月あたり、中国とオーストラリアを除く）

f1-microはvCPU x 1、メモリ 0.6 GBなのでk3sならいけるはず！

#全体構成
![全体構成](https://qiita-image-store.s3.amazonaws.com/0/91672/a03ac067-642c-bd65-cd16-c145dab62c52.png)
GCE上にはK8sのコントロールプレーンをデプロイし、グローバルIPを持つ。おうちのサーバはワーカーノードとして動かす。おうちなのでNAT配下にありプライベートIPしか持たない。

#構築
## k3s server
まずコントロールプレーンを構築する。
今回は以下のスペックで作成した。

* f1-micro
* 10GB HDD
* us-west1
* Debian

外部からアクセスするためにはTCP6443ポートを開けておく必要があるので、ファイアーウォールを開けておく。

* Firewall Rule: 0.0.0.0/0 tcp:6443

### インストール

```bash
$ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable-agent" sh -
```
### SANの追加
k3sはデフォルトでは自分から見えているIFのIP（プライベートIP）しかTLSのSANに追加しないので、オプションでグローバルIPを追加しておく。

```diff:/etc/systemd/system/k3s.service
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
After=network.target
[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
- ExecStart=/usr/local/bin/k3s server --disable-agent
+ ExecStart=/usr/local/bin/k3s server --disable-agent --tls-san {GLOBAL_IP}
KillMode=process
Delegate=yes
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
[Install]
WantedBy=multi-user.target
```

```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart k3s
```

###トークンのチェック
agentを追加するときのトークンをチェックしておく。

```
$ cat /var/lib/rancher/k3s/server/node-token 
```

## k3s agent
おうちのインターネットにつながる好きなマシンで以下のようにしてagentをインストールする。

```bash
$ curl -sfL https://get.k3s.io | K3S_TOKEN={TOKEN} K3S_URL=https://{GLOBAL_IP}:6443 sh -
```

## 確認
うまく行っていればこれでちゃんと構築できているはず。

```
$ k3s kubectl get nodes
```

ちなみにk3sは立派なK8sなので、普通に他のPCからkubectlなどで操作できる。
コントロールプレーンにあるkubeconfigのserverのlocalhostをグローバルIPに変えて、普段使っているラップトップなどに入れてみよう。

```diff:/etc/rancher/k3s/k3s.yaml
 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data: xxxxxx
-    server: https://localhost:6443
+    server: https://{GLOBAL_IP}:6443
   name: default
 contexts:
 - context:
     cluster: default
     user: default
   name: default
 current-context: default
 kind: Config
 preferences: {}
 users:
 - name: default
   user:
     password: xxxxxxx
     username: admin
```

これでどこでもおうちにあるK8sをVPNなしにいつでも操作できる！

# 注意点
* デフォルトではユーザー認証がpasswordになっているので少し弱いかも
* 無料枠がUSにしかないのでRTT厳しい
* 何もしてなくてもコントロールプレーンの通信がインターネットまたぎでされるので通信料に注意
* Kubeletの通信はTunnel Proxyでされるものの、コンテナネットワークにはノード同士のリーチャビリティが必要なのでそこのハイブリッドはもう少し色々考えないと難しい
[Pytorch] QATM:Quality-Aware Template Matching For Deep Learningを実装し直してみた

# 論文の概要
QATMは、2019年3月18日発表の、新しいDeep learningを用いたtemplate matchingの手法です。
従来の方法では難しかった、サンプル画像N枚とテンプレート画像M枚でのマッチングを可能にし、さらに微分可能な操作のみで記述することで学習することも可能になっています。
もともとtensorflow+kerasのコードは実装されていたのですが、それが若干中途半端なこともあって、使い慣れたPytorchで実装し直してみました。
ただし、今回の実装では空間計算量の点からサンプル画像1枚とテンプレート画像M枚での実装のみにとどめています。

# 論文紹介
論文arxiv: https://arxiv.org/abs/1903.07254
元のコード (tensorflow+keras): https://github.com/cplusx/QATM
今回実装したコード(pytorch): https://github.com/kamata1729/QATM_pytorch

## 問題設定
ざっくりとした動作原理としては、まずサンプル画像のある領域$s$とテンプレート画像$t$の間に、「どれだけマッチしてるか」の指標$Quality(s,t)$が定義されているとして、

```math
\begin{equation}
  R^* = argmax_R \left\{ \sum_{r\in R}max\left\{Quality(r,t)\mid t \in \bf{T}\right\} \right\}
\end{equation}
```
となる$R^*$を求めていく。ここで$\bf{T}$は複数のテンプレート画像である。

## Quality関数の決定
$s$をサンプル画像中の、テンプレート$t$と同じ大きさのパッチとする。
$f_s$, $f_t$を、$s$, $t$を学習済みモデルに入れて取り出した特徴量マップとし、$\rho(\cdot)$をこの二つの間の距離を測る関数とする（ここではコサイン類似度を使う）
あるパッチ$s$に対して、テンプレート$t$がマッチする確率の尤度関数を以下のように定義する。

```math
\begin{equation}
  L(t\mid s) = \frac{\exp\{\alpha\cdot\rho(f_t, f_s)\}}{\sum_{t'\in \bf{T}} \exp\{\alpha\cdot\rho(f_{t'}, f_s)\}}
\end{equation}
```
$\alpha$は正の定数である。
これは$\alpha$を学習するパラメータとした、softmax層として考えることもできる。
これを用いて、

```math
\begin{equation}
  QATM(s,t) = L(t\mid s)\cdot L(s\mid t)
\end{equation}
```
として、この$QATM(s,t)$を$Quality(s,t)$として用いる。

# 実装
動作原理としては実際これくらいなので、あとは論文中で実装してあったコード（https://github.com/cplusx/QATM ）をみながら何をやっているか追っていけばよいです。
これをPytorchで実装し直す際に、もともとコード自体はサンプル画像１枚に対しテンプレート画像１枚の場合しか対応していなかったものを、サンプル画像１枚に対しテンプレート画像複数枚でのマッチングを可能にしました。
また、元々の実装では、テンプレート画像がサンプル画像内にない場合が考慮（できると論文に書いてあるのに）されていなかったため、これも考慮に入れて、確率値が低いものをはじくようにしました。

今回実装したコード(pytorch): https://github.com/kamata1729/QATM_pytorch

# 実行結果
用意しておいたデモ画像で実行してみます
`template1_1.png`から`template1_4.png`はサンプル画像に存在しているものの、`template1_dummy.png`は存在していません。
この状況でも、正しく検出できていることがわかります

```
python qatm.py -s sample/sample1.jpg -t template --cuda
```

|template1_1.png|template1_2.png|template1_3.png|template1_4.png|template1_dummy.png|
|---|---|---|---|---|
|![](https://i.imgur.com/lP0Wy4I.png)|![](https://i.imgur.com/xDJoQOz.png)|![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/472c81ae-9afb-db49-a64c-86604cbe0884.png)|![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/d402a9d2-bbd4-5353-16aa-567b79ca06b8.png)|![](https://i.imgur.com/p10g33j.png)|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/2e4c4b8b-2889-7962-4f35-c313048dc403.png)
[MD] GitHubで使える記法

# Githubで使える記法

他人が使っていて良いなと思った記法は、聞いたり、 `edit` で書き方を盗み見てぱくってます。
その中でもよく使うものをまとめました。
（随時追加していく）

## テーブル

### ■ 普通の使い方

#### 書き方

```
|No.|食べ物|値段（円）|
|---|---|---|
|1|りんご|100|
|2|れもん|200|
```

#### 表示のされ方

|No.|食べ物|値段（円）|
|---|---|---|
|1|りんご|100|
|2|れもん|200|

### ■ 画像を埋め込む使い方

仕事をしていると、スクリーンショットをissueやPRに貼る機会は多いと思いますが、そのまま貼っていくとissueやPRが汚染されます。また、たくさん画像を貼ったりしたら、レビューする人はスクロールしまくる羽目になります。
そこで、テーブルに画像を埋め込むと良い感じにきれいにまとまるので、これはよく使っています。

#### 書き方

```
|before|after|
|---|---|
|<画像のパス>|<画像のパス>|
```

#### 表示のされ方

|before|after|
|---|---|
|<img width="123" alt="before.png" src="https://qiita-image-store.s3.amazonaws.com/0/233666/c6048542-dce0-ff59-8e59-22c7d7d795e4.png">|<img width="135" alt="after.png" src="https://qiita-image-store.s3.amazonaws.com/0/233666/dcf92518-5ea1-332f-b64a-fcf8cef90f5f.png">|

## 折りたたむ

ログの情報や大量の画像をそのまま書くと、これまたissueやPRが汚染されます。
こういった情報は `details` タグの中に入れることで、見た目がスッキリします。
特に画像が大量にある場合に有効です。

#### 書き方

`<details>` タグで囲みます。
`<summary>` タグで表記を変えます。（デフォルトは「詳細」）

```
<details>
<summary>押してください</summary>
春はあけぼの。やうやう白くなりゆく山際、少し明かりて、紫だちたる雲の細くたなびきたる。 
夏は夜。月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。また、ただ一つ二つなど、ほのかにうち光て行くもをかし。雨など降るもをかし。 
秋は夕暮れ。夕日の差して山の端いと近うなりたるに、烏の寝所へ行くとて、三つ四つ、二つ三つなど飛び急ぐさへあはれなり。まいて雁などの連ねたるが、いと小さく見ゆるは、いとをかし。日入り果てて、風の音、虫の音など、はた言ふべきにあらず。 
冬はつとめて。雪の降りたるは言ふべきにもあらず、霜のいと白きも、またさらでもいと寒きに、火など急ぎおこして、炭持て渡るも、いとつきづきし。昼になりて、ぬるくゆるびもていけば、火桶の火も、白き灰がちになりてわろし。 
</details>
```

#### 表示のされ方

<details>
<summary>押してください</summary>
春はあけぼの。やうやう白くなりゆく山際、少し明かりて、紫だちたる雲の細くたなびきたる。 
夏は夜。月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。また、ただ一つ二つなど、ほのかにうち光て行くもをかし。雨など降るもをかし。 
秋は夕暮れ。夕日の差して山の端いと近うなりたるに、烏の寝所へ行くとて、三つ四つ、二つ三つなど飛び急ぐさへあはれなり。まいて雁などの連ねたるが、いと小さく見ゆるは、いとをかし。日入り果てて、風の音、虫の音など、はた言ふべきにあらず。 
冬はつとめて。雪の降りたるは言ふべきにもあらず、霜のいと白きも、またさらでもいと寒きに、火など急ぎおこして、炭持て渡るも、いとつきづきし。昼になりて、ぬるくゆるびもていけば、火桶の火も、白き灰がちになりてわろし。 
</details>

※書いてて気付いたが、`details` タグは入れ子にできる

## まとめ

今のところはこのくらいですが、便利そうな記法があったらどんどん追加していく予定です。
[感想文&質問です]強化学習の研究をし始めてみて思ったこと

## はじめに
こんにちは！今大学院で強化学習の研究をしているモノの徒然なるままの戯れ言です。

最近ふと思うことがありましたのでコチラに書かせていただきます。おいおい今更こんなこと言っているの？ちげーーよ。ってことが多くあるかと思いますのでぜひご指導ご鞭撻のほどコメントでいただけましたら幸いです、。。本当に他の人からのコメントとかアドバイスが身にしみる今日このごろです。

## 今やっていること
すいません、そこは詳しくかけないのですが、DQN(横文字かよ？ってかたは下記の素晴らしい3つのリンクをどうぞ)関連の、もちろんDQNのみに限定しませんが、学習の初期段階での探索の非効率性と危険性をどのように改善していこうかというようなお題をしています。
1. [Mnih et al (2015)](https://www.nature.com/articles/nature14236)
2. [ゼロからDeepまで学ぶ強化学習](https://qiita.com/icoxfog417/items/242439ecd1a477ece312)
3. [DQN（Deep Q Network）を理解したので、Gopherくんの図を使って説明](https://qiita.com/ishizakiiii/items/5eff79b59bce74fdca0d)

## ここからが本題です。
まず、最初に思ったことが、Deepmindの研究の量が多いなってことですね。自分たちで出した論文で収めた成功を更に自分たちで更新をしていく。とんでもないスパイラルです。。。もちろん海外の優秀な大学からそれを超えるような論文が出てきているのも事実ですが、やはりdeepmindの力はすごいと思います。ただ、ひとつ言わせてください。なんでソースコードを公開してくれないんですか？いまだしているのは確認できる限り[Luaで実装をされたこのレポ](https://github.com/deepmind/dqn)ぐらいです。。。まあこれに関してはどんな研究でも同じかもしれませんがあまり他人のために実験の再現性を高めたくないのかもしれませんね。論文読んで理解して自分で実装してね！って感じでしょうか。もちろんそれができなきゃ研究者としては大成できないかもしれませんので、この点においてはしょうがないです。

ただ、根本的に強化学習の論文は研究結果の再現にかかる時間が他のcomputer scienceの分野と比べて長い気がします。もう少し言葉を直すと、実装したアルゴリズムの結果がわかるまでにかなり時間がかかることです。いかんせん最近の研究はゲームでのエージェントのパフォーマンスでの評価方法が多いのでゲームをプレイさせ続けないと学習が進みません。しかも難しいのは、ゲームが一つではなく[Atari2600games(M.Bellemare et al., 2012)](https://arxiv.org/abs/1207.4708)などのベンチマークでは[OpenAI](https://gym.openai.com/)が公開してくれてますが、だいたい50ほどのゲームを一気に評価しないといけません。。。これってどうやるの。。って感じです。いや本当にこれってみなさんどうやって解決してますか？？よくネットである、このアルゴリズム試してみた！、とかって言ったレベルではなくて、きちんとアルゴリズムを評価する軸を決めて且つ50のゲームでトレーニングをして評価をする。GPUの積んだマシーンが複数台でとかいうレベルではなく、50台ものGPUマシーンとか用意できないですよね。。。いや僕のところが違うだけで、、普通の研究室にはそれがあるのでしょうか。。

ちなみに、簡単なゲームを使って一旦アルゴリズムの正当性を試したらいいじゃん、もしくはトレーニングを終えなくても初期段階でうまく行ってるかわかるよね。。というご意見に関しては理解をしておりますが、如何せん自分が実装したアルゴリズムが、決められたベンチマークで本当に動くのかを、長い時間祈って待つのが嫌だというのが全段落の簡略です。。わかりづらい文章ですいません。どうにか効率的にすることはできないのでしょうか。

## この学生の若輩者にぜひ教えてください。
QuoraとかRedditみたいな記事になってしまった気がします。。読んでいただいた方、全くの無情報な文章で申し訳ございませんでした。。。ぜひ実験の仕方についてのいい方法があれば教えてください。個人的にコチラで強化学習のアルゴリズムをまとめてます！星やIssueなど頂けたら大変ありがたいです。。

- 
https://github.com/Rowing0914/Reinforcement_Learning/blob/master/DRL_Taxonomy.md
- https://github.com/Rowing0914/TF_RL
nfcpyでgoogle payを扱うとidmが出ない件の対処法

# まとめ

明示的にSuicaを読み取るようにしよう。
おしまい

---
kagisysを改造した際に、google payだとidmが正常に取れない（`088ff` みたいになる）問題があったので対応した話です。
基本的に **apple payのエクスプレスカード** と一緒で、suicaのみ明示的に読んであげれば治ります。

これ↓を

``` old.py
def on_connect(tag):
    if isinstance(tag,nfc.tag.tt3.Type3Tag)
        idm = binascii.hexlify(tag.idm)
        print(idm)
with nfc.ContactlessFrontend('usb') as clf
    clf.connect(rdwr={'on-connect': on_connect})
```

こう↓

``` new.py
with nfc.ContactlessFrontend('usb') as clf:
    target_req = nfc.clf.RemoteTarget("212F")
    target_req.sensf_req = bytearray.fromhex("0000030000")
    while 1:
        target_res = clf.sense(target_req,iterations=10,interval=0.01)
        if target_res != None:
            #idmを取るだけならactivateしなくていい
            tag = nfc.tag.activate(clf,target_res)
            tag.sys = 3
            idm = binascii.hexlify(tag.idm)
            print(idm)
            break
```

これでみんなもlet's nfcpy!


## 参考
- nfcpyでapple payのエクスプレスカードを扱う
    - https://qiita.com/LinaNfinE/items/945a795e53427e768e47
topコマンド

#オートスケーリングの評価のために、EC2のメトリクスを変化させるためにプログラム作成

***サーバの負荷を監視する***
[サーバ負荷を確認する方法](https://qiita.com/hiro-d/items/c3f724cb3d377e21cd91
)

topコマンド
[topコマンドの使い方](https://qiita.com/k0kubun/items/7368c323d90f24a00c2f)


簡単にCPU使用率まで掛ける(100%まで)

| PR     | NI        | VIRT      | RES       | SHR       | S    | %CPU      | %MEM        | TIME+   |
|:------:|:---------:|:---------:|:---------:|:---------:|:----:|:---------:|:-----------:|:-------:|
| 優先度　| 相対優先度 | 仮想メモリ | 物理メモリ | 共有メモリ | 状態 | CPU使用率 | メモリ使用率 | 実行時間 |



NI: Nice value。相対優先度。0が基準で、負だと優先度が高く、正だと優先度が低い。
VIRT: Virtual Image。確保された仮想メモリ全て。スワップしたメモリ使用量を含む。
RES: Resident size。 スワップしていない、使用した物理メモリのサイズ。
SHR: Shared Mem size。 他のプロセスと共有される可能性のあるメモリのサイズ。
S: Process Status。 以下のいずれの状態であるかを示している。
D: 割り込み不能
R: 実行中
S: スリープ状態
T: 停止中
Z: ゾンビプロセス



```
yes > /dev/null
```
インスタンスのコアの数だけ連打しないと100%にならないかも！
AWS認定 ソリューションアーキテクト アソシエイト [新版] 勉強したこと

# 概要
2018年12月にAWS SAA を受験し、合格したのでその時学習した内容を簡単にまとめ

試験範囲はこちら
https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

試験時間：130分
問題数：65問


## 学習教材

###公式
AWS クラウドサービス活用資料集 
https://aws.amazon.com/jp/aws-jp-introduction/
ドキュメントを１から読むよりサービスの特徴を把握し易いです。
細かい仕様を確認したい場合はAWSドキュメントを参照。

###WEB
https://aws.koiwaclub.com/  
問題に慣れたいならこのWEB問題集がオススメです。解説付き。
(有料ですがスマフォでも見れるので、通勤時など限られた時間でもできます)

## 受験準備
- 模擬試験受験
    - 本試験とのレベルを比べると若干優しいですが、受けて損はないと思います。自分は学習前と受験前の２度受けましたが、内容に変わりはありませんでした。
- 学習
    - AWSは業務で利用していたので、基本的に通勤時間を利用してWEB問題を説いていました。
    - 業務で使っていないサービスや詳しくないサービスを活用集のスライドで読み込んでいました。

学習期間は半月(2,3週間)くらいでした。
     
##受験と感想
時間は130分もあるので、見直しも含めても十分時間があります。
最後の問題を終えて、受験終了すると直ぐに結果が画面に表示されて驚きますが、
AWSから正式に合格の通知がくるのが受験から２日後くらいで、それまで半信半疑状態でした。

####詳細な仕様まで知っておくべきサービス
- EC2(EBS含む)
- VPC
- IAM
- RDS
- AutoScaling
- ELB
- S3(Glacierとセットで)
- DynamoDB
- Route53
- CloudFront
- CloudWatch
可用性については特によく問われます。

####概要レベルで知っておくサービス
- SNS
- SQS
- KMS
- CloudFormation
- Elastic Beanstalk
- Lambda
- APIGateway
- Trusted Advisor
- CloudTrail

####出題されたとしても1,2問かなぁと思うサービス
- Ops Work
- StrageGateway
- AWS Import/Export
- AWS Directory Service

業務である程度使われている方は1,2週間の学習(問題慣れ)をすれば十分受かると思います。
AWSの知識棚卸しとして利用しても良いかもしれません。

## その他教材

###書籍
自分は受験したときは書籍が古いものしかありませんでしたが、2019年になってからは２冊ほど出ているようです。
[徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E2%80%93-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8/dp/4295005495/ref=pd_bxgy_14_img_2/356-1197156-5338065?_encoding=UTF8&pd_rd_i=4295005495&pd_rd_r=4146d103-44da-11e9-a66f-07cee5f5a5fe&pd_rd_w=0Xa3N&pd_rd_wg=mf31t&pf_rd_p=546a854e-3ca8-49c6-8e2f-dc88f5c2740e&pf_rd_r=MJ5YRVH3HAQSP5BJ6X8R&psc=1&refRID=MJ5YRVH3HAQSP5BJ6X8R)
[最短突破 AWS認定ソリューションアーキテクト アソシエイト 合格教本](https://www.amazon.co.jp/%E6%9C%80%E7%9F%AD%E7%AA%81%E7%A0%B4-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E5%90%88%E6%A0%BC%E6%95%99%E6%9C%AC-%E6%9D%91%E4%B8%BB/dp/4297103826/ref=pd_bxgy_14_img_2/356-1197156-5338065?_encoding=UTF8&pd_rd_i=4297103826&pd_rd_r=48f4c1e1-44da-11e9-8341-4353734d890c&pd_rd_w=pH9R6&pd_rd_wg=sfHxt&pf_rd_p=546a854e-3ca8-49c6-8e2f-dc88f5c2740e&pf_rd_r=WFA4MD8RNYZCJSSDD02Q&psc=1&refRID=WFA4MD8RNYZCJSSDD02Q)