OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on Rails の link_toで使うnew_user_path の謎を解決します。

まずは答えから

```
rails routes
```
をした時に表示されるルーティングのPrifixに「_path」を付けたものです。「rails routes」コマンドで確認することができます。


```
[--- 例 ---]
Prefix                 Verb       URI Pattern                   Controller#Action
new_user_session       GET        /users/sign_in(.:format)      devise/sessions#new
```
この場合は「new_user_session_path」と指定した時のリンク先は「http\://xxxxx.com/users/sign_in」になります。


#もう少し詳しく解説
Ruby on Railsのビューでよく使われるlink_toメソッドのリンク先の指定でよく使われる「new_user_path」ですが、初めて見た時はこれが何を意味しているのか全く分かりませんでした。

```ruby
link_to  "ログイン",  new_user_session_path
```

例えばこんな感じで使います。
こうすることでログインという文字に対してリンクが付きます。クリック時の移動先はnew_user_session_pathなになりますが、このnew_user_session_pathがどこを表しているのか不明です。

link_to自体は、名前を見るとリンクを付けるメソッドということは分かるのですが、なぜnew_user_session_pathを指定すると違うページへリンクされるのかが分かりません。

##rails routes で答えが分かる

最大の疑問はnew_user_session_pathがどこから出てきたのかとうことですが、これは

```
rails routes
```

このコマンドを実行すると分かります。
実行するとルーティング一覧が表示されます。

```
Prefix                 Verb       URI Pattern                   Controller#Action
new_user_session       GET        /users/sign_in(.:format)      devise/sessions#new
user_session           POST       /users/sign_in(.:format)      devise/sessions#create
```

最初の行は列の説明です。２行目の
Prefixを見てください。このPrifixに「_path」を付けたものが「new_user_session_path」の正体です。

```
new_user_session       GET        /users/sign_in(.:format)      devise/sessions#new
```

この行の場合、「new_user_session_path」と指定するとURI_Patternで指定された「users/sign_in」というURLに飛びます。
「http\://localhost:3000」がルートURLの場合、リンク先は「http\://localhost:3000/users/sign_in」になるということです。
(.:format)は拡張子を表すシンボルです。ここでは説明は省略しますが無視しておいて大丈夫です。

##どんなアクションが実行されるのかも分かる。
このprefixを見ると、どんなアクションが実行されるのかも分かります。
「new_user_session_path」を指定した場合、「devise/sessions#new」をいうアクションが実行されます。
そのため、対応するコントローラーのnewアクションを編集すればよいということになります。

#最初は分かりにくいけど、分かるとかなり便利
この「xxxx_path」という書き方は分かるとかなり便利です。最初は戸惑うこともありますけど、たくさん使って慣れてしまいましょう！
この書き方に慣れてくると

```
rails routes
```

がかなり大事だと分かります…
WebAPIとはこういうものだよ、をざっくり意識合わせするための材料

「WebAPI」といった時に各自の経験や知識、慣れ、不慣れによって認識にブレが出るなあと思い、ざっくりこの辺を皆で見てイメージ統一すると良いのではないかなと思った材料。
このページに「WebAPIとは」は表現されていませんが、**ここに貼ったリンクや記事を一緒に見て、「こういうことだね」というのがすり合わせできると良い** とおもうものたち。

超基本: https://e-words.jp/w/Web_API.html

## 各種API一覧

https://github.com/public-apis/public-apis

https://api.app-rox.com/

## 手習い

http://httpbin.org/
[curlコマンドでちょこっとHTTPリクエストを試すだけの記事 - Qiita](https://qiita.com/akane_kato/items/34b408336f4ec372b139)


## 触りやすい具体例

### Pixela

https://qiita.com/e99h2121/items/59a80db4b107c76a3ff1

### 猫API

https://qiita.com/e99h2121/items/6d5cc72679f43aa37be2

https://qiita.com/e99h2121/items/56b9d7a9db88e0b4744a

### エンジニア・プログラマにしか使えないSNS

https://qiita.com/HawkClaws/items/599d7666f55e79ef7f56

https://versatileapi.herokuapp.com/api/user/88463ee435f58d07ad42471b86f74cb1e4710024

https://github.com/nyanpyou106/versatileapisns_client

https://github.com/javaboy-github/only-programer-sns-client/blob/main/user/user.go

### Google API
https://console.cloud.google.com/apis/dashboard?pli=1

https://qiita.com/e99h2121/items/e5fa65e886706fa680d2

https://qiita.com/e99h2121/items/c7fc8648a07e6b1b3e9e

### Microsoft 

https://github.com/microsoft/api-guidelines

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-implementation

### Spotify 

https://developer.spotify.com/documentation/web-api/

https://zenn.dev/yuriponx/articles/ccb87e276dc361


## フレームワーク

https://qiita.com/gcyata/items/342073fa7607fd4082bd


## クライアント

### curl
https://qiita.com/sensuikan1973/items/b2085a9cdc6d1e97e8f8

### VSCode (REST Client)
https://qiita.com/toshi0607/items/c4440d3fbfa72eac840c

### Postman
https://qiita.com/zaburo/items/16ac4189d0d1c35e26d1


## APIファースト

https://cloud.google.com/blog/ja/products/api-management/api-first-digital-transformation

https://developer.ntt.com/ja/blog/58aa2ca4-ef7c-4f50-86b6-b5758df58de6

https://japan.zdnet.com/article/35100284/3/


## アーキテクチャ論

https://www.ibm.com/jp-ja/cloud/learn/microservices

https://www.ibm.com/blogs/solutions/jp-ja/cloudvision3-itmanager/

https://www.ibm.com/jp-ja/cloud/learn/three-tier-architecture

## マイクロサービス

[マイクロサービスとは - 日本 | IBM](https://www.ibm.com/jp-ja/cloud/learn/microservices)

その価値は、次に挙げる比較的単純なビジネスや組織のメリットから、より一般的に理解されています。

- コードの更新が簡単。アプリケーション全体に触れることなく、新機能を追加できる。
- チームは、さまざまなコンポーネントに異なるスタックやプログラミング言語を使用できる。
- 各コンポーネントは互いに独立してスケーリングできる。単一のフィーチャーが過負荷に直面しているという理由でアプリケーション全体を拡大する必要があった際の無駄とコストが削減される。

同じページのマイクロサービスとモノリシック・アーキテクチャーの違いの動画を参照のこと

マイクロサービス入門[Introduction to microservices – IBM Developer](https://developer.ibm.com/tutorials/cl-ibm-cloud-microservices-in-action-part-1-trs/)



## WebAPI REST/RESTfulAPI参考

https://www.ibm.com/cloud/learn/api

[Web APIとは何なのか - Qiita](https://qiita.com/NagaokaKenichi/items/df4c8455ab527aeacf02)

https://qiita.com/e99h2121/items/4409af3879e8638b8200

https://www.knowledgewing.com/kw/blog/2017/02/201702230900.html


以上このあたりをざっくり見て話してみるのが良いのかなと思う物たちでした。参考になればさいわいです。
Railsで架空のCafeのHPを作ってみよう!【16日目】『colorboxのスクロール固定』編

#概要
基本Railsの記法に則り書いていきます！
１から全ての説明ではなく
その中であれ？どうやるの？と
疑問に思った点や実装に困った箇所を
ピックアップして紹介していきます♩

#設定と準備
・Rails
・HTML
・CSS
・Javascript(jQuery)

↑上記の言語とフレームワークを使い
架空(自分で考えたテキトーなもの)のCafeの
HPを作っていこうと思います！

#16日目の作業内容:round_pushpin:
・colorboxを導入しモーダルを作成

#16日目の気になった箇所:zap:
モーダルを作成できたのは良いが
スクロールすると一緒にスクロールされて
モーダルが見えなくなってしまうの固定したい！

#仮説:pushpin:
position: fixed;
などを使えば上手くいくのかな。

#結論:star:
調べてみたが理解するのが今の自分には非常に難しかったので
今回はどうすれば上手くいくのかだけの紹介になります。

どのような方法でも良いので
JSのファイルがモーダルを使っているHTMLで読み込めるようにしてください。
方法をしましてはcolorboxの導入に成功していることが前提なので、お分かりかと思いますが
拡張子の.jsをつけたファイルを作成しscriptタグで読み込むなどの方法になります。

今回、私はrailsでアプリを作成しているため、

app/javascript配下にmodal.jsという
ファイル(モーダルに関してなのでmodalとしましたが.js付ければ名前はなんでも可)
を作成し、

```app/javascript/packs/application.js
require('jquery')
require("../jquery.colorbox-min.js")
require("../jquery.colorbox-ja.js")
require("../modal.js")
```

このように読み込ませています。

読み込みが成功したら、
作成したファイルに

```modal.js
$(document).ready(function(){
  $(".iframe").colorbox({iframe:true, width:"90%", height:"90%",
  fixed: true,
    onOpen: function() {
      var ycoord = $(window).scrollTop();
      $('#colorbox').data('ycoord',ycoord);
      ycoord = ycoord * -1;
      $('body').css('position','fixed').css('left','0px').css('right','0px').css('top',ycoord + 'px');
    },
    onClosed: function() {
      $('body').css('position','').css('left','auto').css('right','auto').css('top','auto');
      $(window).scrollTop($('#colorbox').data('ycoord'));
    }
  });  $("#click").click(function(){
  $('#click').css({"background-color":"#f00", "color":"#fff", "cursor":"inherit"}).text("Open this window again and this message will still be here.");
  return false;
  });
  });
```

このような記述をしてください。
正直、どこが何を示しているのかほとんどわからないので
コピペで出来なかったらお手上げです...。
iframeはクラス名を自由に変更が可能なので
クラス名を変えている方は
2行目の

```
$(".iframe")
```

この箇所を自分のクラス名に変える必要があるかもしれません。
少しでもお力になれたら幸いです。
2021/08/02開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[AWSの基礎を学ぼう 第五十二回](https://awsbasics.connpass.com/event/217742/)|[AWS エバンジェリストシリーズ　AWSの基礎を学ぼう](https://awsbasics.connpass.com/)|392||
|:two:|[みんなのディープラニング講座 Section1【 Live!人工知能 #59】](https://liveai.connpass.com/event/220236/)|[Live!人工知能](https://liveai.connpass.com/)|143||
|:three:|[Monthly Serverless Update 2021/07](https://serverless-newworld.connpass.com/event/218162/)|[新時代のサーバーレス](https://serverless-newworld.connpass.com/)|99||
|:four:|[ふりかえりから始める組織カイゼン](https://retrospective.connpass.com/event/217857/)|[ふりかえり実践会](https://retrospective.connpass.com/)|80|97|
|:five:|[JAWS-UG CLI専門支部 #198R IAM基礎(インスタンスプロファイル)](https://jawsug-cli.connpass.com/event/217735/)|[JAWS-UG CLI専門支部](https://jawsug-cli.connpass.com/)|62|80|
【xammp】mysqlが起動しない時の対処

# 概要
XAMPPのコントロールパネルからMySqlをStartをしようとすると以下のようなエラーが出ました。
これはApacheやMySQLが起動に失敗した場合に表示される`テンプレのエラーメッセージ`でここだけではエラーの原因は特定できません。
詳しくはエラーのログから確認するのですがエラーの数が多すぎたので割愛します。
当記事では復旧までの手順のみとします。

```:
12:36:20 [mysql] Error: MySQL shutdown unexpectedly.
12:36:20 [mysql] This may be due to a blocked port, missing dependencies,
12:36:20 [mysql] improper privileges, a crash, or a shutdown by another method.
12:36:20 [mysql] Press the Logs button to view error logs and check
12:36:20 [mysql] the Windows Event Viewer for more clues
12:36:20 [mysql] If you need more help, copy and post this
12:36:20 [mysql] entire log window on the forums
```

# 復旧までの手順
## １．MySqlフォルダのバックアップ：重要
`C:\xampp\mysql`をコピペでバックアップします。
デスクトップでも`C:\xampp`でもどこでもいいので`エラーの状態のフォルダ`をバックアップします。
これを忘れると復旧できない可能性があるので<b>とても重要</b>です。

## ２．他で起動しているMySQLのタスクをキルする
管理者権限で実行している場合はstartできないのでQuitで終了すれば起動できる可能性があります。

## ３．port番号を変える
ポートが重複していると起動できないので確認します。
コマンドプロントでもxammpコンパネでも好きな方法で確認します。
個人的にはcammpコンパネのNetstartボタンからが見やすくて好きです。
重複があれば`C:\xampp\mysql\data\my.ini`でポートを編集すれば起動できる可能性があります。

## ４．破損ファイルの退避
`C:\xampp\mysql\data`内にある以下のファイルを削除します。
・ibdata1
・ib_logfileで始まる全ファイル

MySQLが強制終了した場合などにこれらのファイルが破損ファイルとして残る場合があり、退避することでMySQLが正常に起動するケースがあります。

## ５．バックアップからの復旧
`C:\xampp\mysql\backup`からの復旧で、今回の事案を解消した方法です。
少し長くなるので次章で記述します。

# バックアップからの復旧
前章の１と２を試して駄目だったのでバックアップファイルから復旧しました。
主な原因は`正しくxammpを終了していない`ことです。
xammpコンパネでMySQLのstopせずにPCをシャットダウンすると起きることがあるみたいです。

## 復旧手順１．dataフォルダ内の初期テーブルを削除
`C:\xampp\mysql\data`から以下のフォルダを削除します。

・mysql
・performance_schema
・phpmyadmin
・test

## 復旧手順２．バックアップフォルダ内のファルダをコピペ
にある以下のフォルダを`C:\xampp\mysql\data`にコピペします。
手順１と削除したものと同じフォルダです。、
`C:\xampp\mysql\backup`はxammp様が定期的に作成してくれています。

・mysql
・performance_schema
・phpmyadmin
・test

## 復旧手順３．MySqlのstart
これでstartできればほぼ完了です。
ただし、前章の手順４を実行している場合はMySqlを起動できてもテーブルにアクセスできないはずです。
原因はデータベースの情報を保存している`ibdata1`を一度削除しているからです。

### 補足．前章の手順４を実行している場合
前章の手順１でバックアップしたフォルダ内の`ibdata1`を`C:\xampp\mysql\data`内にコピペします。

# まとめ
人間なのでミスは前提で、エラーやバグは仕方ないことと考えています。
大事なの前の状態に復旧することで、エラーやバグが発生した状態を保存することの重要さを改めて感じました。

# 参考
・[xamppのMySQLがshutdownエラーで起動できない、タスクキルでもport変えても直らないのをようやく解決できた話。](https://y-a-d.hatenablog.jp/entry/2020/01/28/183000)
・[XAMPPでMySQLがStart出来ない場合の対処方法](https://blog.senseshare.jp/debugging01.html)
JUCEのSpectrum Analyser Tutorialをビルドして動かす

https://docs.juce.com/master/tutorial_spectrum_analyser.html

ここで紹介されてるdemo projectが動かなくてハマったのでメモを残しておきます。
同じ問題に当たった人の参考になれば幸いです。  

プロジェクトファイルは、リンク先のページ内のPIP | ZIPのリンクからチュートリアルのプロジェクトファイルはダウンロードできる。
チュートリアルダウンロード直リンクはこちら。
[ZIP](https://docs.juce.com/tutorials/ZIPs/SpectrumAnalyserTutorial.zip)

# includeファイルを変更する
これが一番のハマりポイント。
Main.cppの頭に書いてある、ヘッダファイルのinclude部分を変更します。

```
//#include "SpectrumAnalyserTutorial_01.h"
#include "SpectrumAnalyserTutorial_02.h"
```

# Project Settingsでマイクを使用できるようにする

[![Image from Gyazo](https://i.gyazo.com/a367a523eab417304a10b529dd92e1b2.png)](https://gyazo.com/a367a523eab417304a10b529dd92e1b2)
Microphone AccessをEnableにします。

あとは、macならばXCodeでビルド。

[![Image from Gyazo](https://i.gyazo.com/9efe4b38808ee31634eb525ddde63904.gif)](https://gyazo.com/9efe4b38808ee31634eb525ddde63904)

このように、マイクの入力がスペクトルアナライザーで表示されるはず。

# その他

ここに作成したプロジェクトを置いておきます。
https://github.com/uchidama/SpectrumAnalyserTutorial
PyCharmでRedoアクションをCtrl + zに設定を変える方法

# 問題
デフォルト設定ではRedo（直後の操作をやり直す）アクションがCtrl + Shift + Zに割り当てられている。
昔の設定？のためか、Ctrl + yで慣れてしまっているので不便。

# 解決方法
Settingを Ctrl + Alt + s で開く
サイドバーから「keymap」を選択
Main Menu -> Edit => Redoをダブルクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/a4bb2b8a-ec0b-8062-800f-e2ae26f209de.png)

Ctrl + y を入力（使いたいコマンドを入力）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/208e6f24-ef16-b478-db5a-0e616a8d9174.png)

「このショートカットは既にほかのアクションに割り当てられていますよ」と警告が出るが、問題なければRemoveを選択

最後に不要なショートカットを削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/b0525e64-b00d-530c-ff1e-fd3b14b4fba6.png)
DjangoとReactへ進むための現状の問題点

## はじめに

AWS試験のSAA試験も終わって、いい加減プログラミング言語の方に戻らないといけないので改めて方向性を確認するためにまとめる。
とりあえずJS、TypeScript、React、Python、Djangoに絞りたい……。

## 現状の問題点

- Django(というよりサーバーファーストでアーキテクチャを構成する場合)とフロントファーストのアーキテクチャの統合は難しい

## サーバーファーストでの問題点

- TemplateにまたがってJavascriptがインラインで分散(Templateに直接書き込む形)してしまうので該当のコードがどこにあるのか検索しにくい
- ベースとなるTemplateにJSファイルを大量にロードするので、ページサイズが大きくなりページレベルの依存関係の理解が困難になる
- ライブラリを管理するためにWebpackやnode_moduleを使わないので、JSにおいて適切な依存関係の構成や管理ができていない

## クライアントファーストでの問題点

クライアントファーストはJSフレームワーク(わかりやすい例でReact)を使い、サーバーエンド側はあくまでAPIとして管理する手法。
React、Vue　＋ Django Rest Frameworkのような構成。
JSフレームワークを使いつつ、Djangoも使いたい！ という場面で一見有効に見えるが問題も結構ある。

- CORSを設定が難解

クライアントファーストで完全にフロントとサーバーを分離する場合、オリジンの問題がある。
例えば開発環境においても大体、フロントがlocal3000でサーバーがlocal8000と分かれてしまうので、こうなると当然Frontで出したサーバーAPIへのリクエストはXSS、CSRF対策でエラーになってしまうという問題がある。
なのでCORSを設定しないといけないのだが、それをフロント側でやるのかサーバー側でやるのか難しいところがある。

- サーバーサイドのフレームワークを利用する意味がそもそもなくなる

UI全体をJSフレームワークに担わせることで、Templateを一切しなくなる。
そうなるとせっかくサーバーサイドであったテンプレートやフォーム(例えばDjangoでCSRF対策する際は、Templateに1行書き足すだけで済む)のサポートの恩恵を受けることはできない。
その他でもView、Form、組み込みの認証機能等も使えないのでそれなら別にサーバーサイドはいらないのでは？ となる。
こういうところの一つのアンサーとしてFlutterなどが存在するのも頷ける。

- 認証問題

クライアントファーストにしたいということの動機としては基本的にSPAを構成したいというのがあると思う。
ただし、SPAの場合認証にはTokenを利用したものが殆どになる。
このToken認証が曲者で適切にCSRF、XSS対策をしないといけないのはもちろんのこと、SPAは基本的にセッションを使わないステートレスな構成になってくるはずなので認証状態の管理にこのTokenをいつでも利用できるような状態にしておかないといけないのでこのTokenを保管しておかないといけない。
しかし、このTokenはlocalstorageに保存すれば簡単に抜き取られ、Cookieに保存しようとすればHttpOnlyにしようとすると今度はフロント側からアクセスできなくなって利用に困るという難点があり、Cookieをサーバーに渡すのにも苦労する。
ついでにいうとそもそもToken認証はTokenを外部DBにでも保存しない限り、セキュアではないのでは？ という議論もあったりする。
そして何より大変なのがこのような問題に対する対策を自分で実装しないといけないことだ。
サーバーファーストであれば認証なんてフレームワークがさくっと解決してくれる分、これは結構しんどい。

- APIを作る手間が発生する

例えばDjango Rest FrameworkならView.pyの他にSerializerとAPIエンドポイントを作らないといけない。
で、このSerializerをViewに読み込ませる……と結構手間だったりする。
しかも、これをModelごとに作らないといけないのでリレーションを行っていたりModel数が多かったりすると作業量はえらいことになる。
開発・ビルド・デプロイのセットアップも難しい。

- 特にDjangoにおいてはまだクライアントファーストは未開拓な部分が多い

もともとPythonなので、Pythonを扱える人がわざわざこれでWebアプリを作ろうという人たちが中々出てこないという身も蓋もない事実。
なのでフロントファーストでDjangoを利用するためのアレコレ、特にライブラリやプラグイン周りがRailsやPHPに比べて圧倒的に少なかったり、あっても更新が途中で止まっていたりと結構辛い。

## ハイブリッドアーキテクチャという考え方

というわけで、現状DjangoでJSフレームワークを使うには結構ハードルが高いというか課題が多すぎる。
なので、その課題を解決するための視点がハイブリッドアーキテクチャになる。
具体的にはプロジェクトレベルではなく、ページレベルでクライアントファーストなのかサーバーファーストなのかを選択するということをする。
例としては認証やフォームはDjangoのTemplateを使い、JSフレームワークを利用するような複雑であったり、動的なページを作りたい場合はJSフレームワークでページを作るなど。
。

つまり

- JavaScriptをほとんど使わないサーバーファーストのDjangoページ(ログインフォーム)
- TemplateにクライアントファーストのJavaScriptをBuildしてきたページ(動的なページやSPAなページ)
- その中間のもの

という3つの考え方でページを作っていく考え方がハイブリッドアーキテクチャになる。

## これから

とりあえずプログラミング言語の方はハイブリッドアーキテクチャを理解するためにもJSとPythonをちゃんと身につけようと思ってます。
というのも結局TypeScriptがわからなければReact……というよりJSフレームワークをキャッチアップし続けるのは難しいであろうということと、Webpackについても理解を深めないとハイブリッドアーキテクチャへ進むこともできないので。
Pythonは性にあっているのとある程度使えると応用も効きそうなので。
特にPythonについておすすめの教材と情報源とかあったら教えて下さい。
まずはJSかな……
G検定に合格した時の勉強方法

#はじめに
G検定　2021 \#1 に合格した時の勉強方法をまとめます
結論を言うと、当日のggり力が最重要です

#G検定について
AIの知識を問う検定
自宅で受験ができ、googleで検索するなどのカンニングが認められている
以下の内容を非常に幅広く問われる
- 人工知能とは？
- 人工知能分野の問題(トイプロブレム、フレーム問題、強いAI、弱いAIなど、AI全般の哲学的なもの)
- 機械学習の手法
- ディープラーニングの概要
- ディープラーニングの手法
- ディープラーニングの研究分野
- ディープラーニングの応用に向けて(産業への応用、倫理など)
試験では下に行くほど出題される問題数が多くなり、下に行くほど難しいことを聞かれます

カンニングが認められているが、120分で約220問（私が受けた時は190問程度だった）を解く必要がある。つまり、1問あたり30秒で解く必要がある。
いかに簡単な問題を瞬殺して難しい問題でggる時間を稼ぐかが重要となる

#勉強方法
私が行った勉強方法としては
- 本を読む
- study AIの問題を解く
- G検定の用語がまとめてある記事を購読
です。それぞれについてまとめていきます

##本を読む
私が買って読んだ本はこの3つ
1. https://www.amazon.co.jp/gp/product/4798157554/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1
2. https://www.amazon.co.jp/gp/product/4295005665/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1
3. https://www.amazon.co.jp/gp/product/429711609X/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1

まずは1つ目を読んで内容を完璧に理解しましょう
1つ目の本に出てくる問題はすべて瞬殺できるようにしておきましょう

2つ目の本については買う必要はありません、3つ目の下位互換でしかありません

3つ目の本は1つ目の本を読んだ上で読むと知識が非常に深まります。解説をしっかりと読んだ上で問題は8割は瞬殺できるようにしておきましょう

この本での勉強により、試験当日の問題は2〜3割が瞬殺できるようになります
5割くらいはカンニングしないと手も足も出ない状況です

## study AIの問題集
atudy AI：https://study-ai.com/gkentei/
私が受けた時は模擬問題しかなかったのに今見たらかなりいろんなことができるようになってる
ここの模擬問題はディープラーニングに特化していて、難易度はそんなに高くない
9割は解けるようになっておきたいところ
模擬問題以外はやっていないので自身で試してみて欲しい

これで当日の問題の3~4割は解けるようになったと思う

## 記事の購読
この記事を購読する
https://note.com/g_kentei_gokaku/n/nd935727ed18a
瞬殺できるものから瞬殺できないものまですごくまとめられている
試験当日は、このページを開いておいてcommand(windowsならctrl)+Fでページ内検索めっちゃした
これで試験の6割は解ける

# 試験当日
最新の法律や倫理などはどうしても本や記事の内容では不十分（そもそも試験範囲が広すぎるし抽象的だし網羅しようがない）
当日のにいかに効率よくggれるか、いかにggる時間を残せるかが重要
GASを使ってgooglespreadsheetに自動的に目次を生成する

google documentがあまりにショボいもので、仕方なくgoogle spreadsheetで仕様書を書かざるを得ないってのは、よくある苦痛だと思う。
そしてspreadはシートが増えるとやってられないので、GASで簡単にURL付きの目次を作れるようにしてみた。

- sheetに"contents"と名前のついたsheetを作ると、"B3"から1行おきにURLを生成してくれる。
- myfunctionに入れておいて、sheetが追加されたり更新されたりのトリガで起動すると、自動的に目次が更新される。

sortするとか、もうちょっと目次らしくするとかもできるが、基本関数としてはこれでいいかなと。

```javascript:myfunction()
  const ss = SpreadsheetApp.getActiveSpreadsheet(); // ともかくspreadsheetを取得する。
  const ssId = ss.getId();
  const contSheet = ss.getSheetByName("contents");
  const sheets = ss.getSheets();

  let sRow=3;
  let sCol=2;
  sheets.forEach(item=>{
    let sheetId = item.getSheetId();
    let sheetName = item.getSheetName();

    let url = "https://docs.google.com/spreadsheets/d/" + ssId + "/edit#gid=" + sheetId;
    let link = [ '=HYPERLINK("' + url + '","' + sheetName + '")' ];

    contSheet.getRange(sRow,sCol,1,1).setValue( link );
    sRow=sRow+2;
  });
```
Azure ADを使って既存のサービスを簡単に多要素認証対応にする

# はじめに
「境界型防御はもはや時代遅れ、これからはゼロトラストだから既存のサービスにも多要素認証導入して！あと多要素認証導入されていないサービスは社外からはVPN経由でないと利用できないようにしといて」という無茶ぶりがあったとする。
VPNならいいのかよ？というツッコミは置いといて、なんとか対策を考える。

# Azure AD
Azure AD Premium P1だと「条件付きアクセス」、P2なら「リスクベースの条件付きアクセス」が使えるので、希望する条件で多要素認証を利用するように設定できる。
多要素認証を求められた場合にも、Microsoft Authenticatorアプリで承認するだけなので、利用者の負担も軽いのが良い。
せっかくなので新規に多要素認証対応のIdPを構築したりせず、この仕組みを利用することにする。

# 設定
今回リバースプロキシサーバを用意し、アクセス時にはAzure ADで認証OKならサービスを利用できるようにする。リバースプロキシサーバのFQDNは proxy.example.com、サービス提供サーバを service.example.com とする。

本設定にはAzure Portalでのアプリ登録が必須のため、管理者の協力が必要となる。

## Azureへのアプリ登録
Azure ADを使って認証したいウェブサイトについて、Azure Portalでアプリとして登録する。

## OnenID Connectモジュールの設定
リバースプロキシサーバでApache httpdにOpenID Connectモジュールを設定する。
RHEL 7の場合はyumコマンドでモジュールを追加できる。

```
# yum install mod_auth_openidc
```

OpenID Connect用の設定を、アプリとして登録した内容に合わせて変更する。**OIDCRedirectURI**の値は https://proxy.example.com/oidc/auth のようなURLにしておく。

```conf:/etc/httpd/conf.d/auth_openidc.conf
OIDCRedirectURI <Azure Portalで登録したアプリ用リダイレクトURL>
OIDCClientID <Azure Portalで確認したアプリ用ClientID>
OIDCClientSecret <Azure Portalで生成したアプリ用Secret>
OIDCProviderMetadataURL https://login.microsoftonline.com/<テナントID>/.well-known/openid-configuration
OIDCCryptoPassphrase <適当に決定>
OIDCScope openid
OIDCAuthRequestParams prompt=select_account
OIDCAuthRequestParams domain_hint=<your-azure-ad.domain>
OIDCResponseType code
OIDCRemoteUserClaim upn
```

サービス提供サーバのリバースプロキシとして動作するよう設定する。

```conf:/etc/httpd/conf.d/oidc.conf
ProxyRequests Off
ProxyPass / https://service.example.com/
ProxyPassReverse / https://service.example.com/
SSLProxyEngine on

<Location />
  AuthType openid-connect
  Require valid-user
</Location>
```

以上の設定をした後で https://proxy.example.com/ にアクセスすると、Azure ADを利用した認証画面が表示される。条件付きアクセスの設定によっては、多要素認証を求められる。
``OIDCAuthRequestParams domain_hint=<your-azure-ad.domain>`` で制限しているため、当該ドメイン以外の個人用MSアカウントなどは、ログイン済みでも表示されなくなっている。

## 参考にしたサイト
https://heartbeats.jp/hbblog/2017/08/mod-auth-openidc.html
https://heartbeats.jp/hbblog/2017/08/mod-auth-openidc-azure-ad.html
git push heroku masterで躓いた話

Rails を使ってサンプルアプリを作っていたときの話
ある程度の機能を付けたからherokuにデプロイしようとしたら....

```
remote:  !
remote:  !     Precompiling assets failed. <-　エラー
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !	Push rejected to <アプリ名>.
remote: 
To https://git.heroku.com/<アプリ名>
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/<アプリ名>
```

今出ているエラーを見てみると
`Precompiling assets failed`
プリコンパイルができなかったみたいなエラー
`error: failed to push some refs to ~~~`
合ってるかわかりませんが、いくつかpushできないファイルがあったよというエラー

ここだけ見ても解決しそうにないので、こんな時は__ターミナル__のログを見たら原因が見つかるかもしれません！

ちょっとログを遡ってみると、、、、

```
remote:        Running: rake assets:precompile
remote:        rake aborted!
remote:        NoMethodError: undefined method `new' for :Uglifier:Symbol
```

それっぽいのがありました！
何となく書いてあることを理解しようとしてみました。

まず1行目はプリコンパイルを行なっているような感じ
2行目はabortedを直訳してみると、__打ち切られた__つまり何か不具合があるから中止したってことだと思います。
3行目はそのままでメソッドが定義されていないかスペルミス等で合致するメソッドがない状態


ひとまずプリコンパイルの動作を記載してあるproduction.rbを見てみました。

```ruby:&#x20;production.rb
config.assets.js_compressor = ：Uglifier.new(harmony: true)
```

調べてみたところ、Uglifierの前に":"は要らないのでこれを消した後に再度 herokuにデプロイしてみます。

```ruby:&#x20;production.rb
config.assets.js_compressor = Uglifier.new(harmony: true)
```




調べた感じこれで解決しそうですが、、

結果は

```
remote:        Running: rake assets:precompile
remote:        rake aborted!
remote:        SyntaxError: /tmp/build_debf70f6/config/environments/production.rb:26: syntax error, unexpected tIDENTIFIER, expecting end
remote:        ...lifier.new(harmony: true)　　
remote:        ...                         ^~~~~~
```

はい、またエラーが出ました笑

でもさっきとエラー文が変わっています。
`SyntaxError: ~~`
構文エラーで間違った書き方をしている時に出ます。
さきほど構文の誤りを修正したので、どこが間違っているかなとコードをじっくりみた結果

`(harmony; true)`の後に`^~~~~`と書いてあることに気づきました
何かな？と実際に書いてある`(harmony: true)`にカーソルを持っていくと原因がわかりました。
``全角スペースが入っていたのです``
実際書いている時は、スペースを加えた覚えがないのですがいつの間にか入っていました笑

正直このエラーで2時間くらい原因を調べてたので、アホやなと思いましたがもしまたスペースが入ってしまっていた時にすぐに対処できるでしょうかそのための2時間だったと思って前向きにいきます笑

記録用として書きました。
間違い等ありましたらご指摘ください！
<h1>解決の際に参考にさせていただいた記事</h1>
https://qiita.com/koda_7932/items/63061c197aabf1dafb0e
【初見】ActiveRecord::InvalidForeignKey を初学者なりに噛み砕いて備忘録を記述してみる。

# タイトルにもあるとおり始めてのエラーです（多分）
Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails　とありまして、何が原因になっていたかを備忘録として書き残そうと思います。

#解決策から紹介します。
このエラーの解決は、モデルに追記した後に、データベースをリセットすることで、解決しました。
コードだけだと意味がわからない記述になっているの以下の説明も一緒に読んでください。

```Ruby
# model/study_time.rb
belongs_to :skill, optional: true #optional: true　を追記

# mdoel/skill.rb

has_many :study_time, foreign_key: :skill_id, dependent: :destroy #foreign_key: :skill_id, dependent: :destroy を追記

```

# どういう仕組みで起こったのか。
作成しているアプリケーションを例に出しますと・・・・。
・ユーザーがスキルテーブルにAを作成します。
・アプリケーションには学習時間を追加する機能（スタディータイムテーブル）があり、ユーザーはスキルAに学習時間を追加していきます。（学習時間を追加するために、スキルをforeign_keyで制約を結んでいます。）
そこでスキルAを削除しようとすると、スタディーテーブルに、スキルAの学習時間が残ってしまっている状態になり、タイトルのエラーを吐きだすと、いうことになります。
softbank airユーザーだけど外部からjupyter notebookにアクセスした話

この記事は、以前はてなブログにて公開していたものです
qiitaにも公開したくなったのでこちらでも公開
はてなブログのほうは非公開にしました

# はじめに
私はsoftbank airユーザー

最近自宅のPCでjupyterサーバーを立ち上げたjupyter notebookをリモートで使いたくなったのですが、softbank airのせいで外部から接続できない

https://www.softbank.jp/support/faq/view/19046

一時期は解約とか格安simとか考えてた

でもふと閃いた

awsでVPNサーバー立ち上げればいいんじゃねと(月額500円くらいかかるけどね)

# AWSへの登録とサーバーの立ち上げ

まずは以下のawsのサイトにアクセス

https://aws.amazon.com/jp/

そしたら右上のコンソールにサインインを押す

![20201208230410.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855735/b5826f38-ae8b-9a7e-3bdd-8ed425f9156f.png)

![20201208230544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855735/02aec490-1e11-7a74-2dd5-0b4f6827bce7.png)

まだawsのアカウントを持ってない人は左下のボタンから作成

持ってる人は普通にサインイン

サインインしたら下の画像のような画面になる

![20201208231012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855735/25fd9f7f-8084-4a26-337e-329db808b489.png)


サービスの検索枠にlightsailといれてlightsailを立ち上げる

インスタンスの作成というボタンが右のほうにあるからそれを押す

# VPNサーバを立ち上げる

以下の記事の通りに設定する

実際5分くらいで設定できた

https://qiita.com/alfa/items/6ae09a48769c5f6bf5e9

私はユーザーを3つ作った

* 自宅サーバー用

* ノートPC用

* ipad用

PC用のクライアントの使い方は以下が参考になる

https://qiita.com/otappi/items/7a4758f3723790491ad3

 (管理画面の操作についても書いてあるけどそこは気にしなくていい)

ios用は以下のサイトが参考になる


https://www.startup-plus.com/techblog/pritunl-vpnサーバへ接続する方法

androidはわかんないけどiosと似たようなものなんじゃないかな

# まとめ

awsでVPNサーバーを作った

それによってsoftbank airでも外部から自宅サーバーに接続できるようになった

しかもとっても簡単
MQTTってなんだ？

#はじめに
3分で読める記事です。

IoTデバイスのセキュリティの勉強してます。
その一環でIoTネットワークに使われているプロトコルの勉強してみました。

#４行で説明
###・アプリケーション層プロトコル
###・省電力/軽量(IoTデバイスに向いてる)
###・Publish/Subscribe型
###・ちゃんとパスワード設定しよう！！！


#もうちょっと詳しく
IoTデバイスによく使われるデータ伝送プロトコルの代表です。
昔はHTTPが主流だったのですが、IoTデバイスの小型化・増加に伴いこっちが使われるようになりました。
(他にも、MQTTを高機能化したAMQPや産業向けのCoAPとかもあります。)

##HTTPとMQTTの比較
HTTPとMQTTの比較をおおまかに表にしてみます。

![HTTPとMQTT.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686089/56941b89-83ad-13a4-8f2b-3345603b7c67.png)

短いヘッダ長によって、HTTP通信の10分の1程度の消費電力を実現しています。\[1] 
(状況によって大幅に変わります)
そのヘッダ長は驚きの2バイトです。（後で詳しくみます）
また、Publish/Subscribe型というネットワーク構成によって一対多・双方向・非同期通信を実現してます（これも後で詳しくみます）

##Publish/Subscribe型って？
Publisher(データを送るデバイス)、Broker(データを中継するサーバ)、Subscriber(データを受け取るデバイス)の3つから構成されるネットワークです。
Brokerさんがデータを中継してくれるお陰で、Subscriberはすぐにデータを受け取らなくていいし(非同期通信)、色んなデバイスが同じ情報を受け取ることができます(1対多の通信)。また、PublisherとSubscriberの関係は入れ替わることもできます(双方向通信)。
<details><summary><font color="red">もう少し正確に</font></summary><div>
0.SubscriberはBrokerと接続を確立し、受け取るtopicを指定する
1.Publisherが配信したいデータをtopic名をつけてBrokerに送信する
2.Brokerは受け取ったデータのtopicを確認して、そのtopicを指定しているSubscriberに送信する
－－－－－－－－－－－－－－－－－－－－－－－－－－－－
</div></details>

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130303838312f66323936346532632d373735612d626634652d333565382d3533663561666436633830622e6a706567.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686089/f8bfd632-613d-02d8-e086-31f898a4893c.jpeg)

##ヘッダの中身

![MQTTヘッダ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686089/9daad48c-dd5a-b1e1-936b-e79c49a9a0d3.png)
(参考[2])

2バイトって逆に何が入ってるねんって感じなんですけど、基本的に上の3つです。
###メッセージタイプ
Connect、Subscribeなどメッセージの形式の指定
###固有フラグ
メッセージタイプがPublishの時以外あまり関係ないです。
Publishのときは、以下のようにフラグが設定されます。

|bit3|bit2|bit1|bit0|
|---|---|---|---|
|DUP|QoS|QoS|RETAIN|

DUP：パケットが重複しているか否かのフラグ。何らかの要因でパケットを再配信するときはDUPフラグが1になる
QoS：送信の品質を3段階で指定します。[3]
　QoS0：パケットを一度だけ送信する(到達保障なし)
　QoS1：パケットが到達したことを確認する(重複して到達する可能性あり)
　QoS2：パケットを正確に1度だけ送信する(到達の確認の確認を行う)
RETAIN：フラグが1になっているものでtopicごとに最新のものだけ、Brokerで保持されます。新たなSubscriberが登録されたとき、要求されたtopicごとに最新のものが自動的に送信されます。
###残りの長さ
読んで字のごとく、固定ヘッダを除いたパケットの長さです。

#MQTTの課題（セキュリティ面）
MQTTはTLSで暗号化することができるので、通信面で脆弱性は持っていません。(その分伝送効率悪くなるけど…)
ただし、Brokerサーバがパスワードがかけられずに放置されている例が非常に多いです。(『Shodan』というサイトで確認可能)
Brokerサーバは中継地点であるため、行き来するすべての情報が読めてしまいます。
###パスワード設定しよう！！！


#最近の研究
セキュリティに関する研究はあんまなかったです。。
ほとんどHTTPやWebsocketとの性能比較の研究ばっかりのイメージ
[軽量暗号に関する研究](https://dl.acm.org/doi/10.1145/3309074.3309081)くらい？
あれば教えてくださいm(_ _)m


#おわりに
読んでいただきありがとうございました。
おおまかにしか書きませんでしたので、間違っていましたら指摘いただけると嬉しいです。
正確な情報が知りたい方は参考文献[2]をご参照ください。

#参考文献
[1]かもめエンジニアリング『[MQTTとは](https://kfep.jp/solution/iot-mqtt/mqtt)』
[2][MQTT Version 3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html)
[3]さきブログ『[QoSとは？MQTTにおける通信の種類！](https://sakiot.com/what-is-qos-of-mqtt/)』
強化学習　文献まとめ2

# 強化学習　文献まとめ2
リレー解説 強化学習の最近の発展 第2回
「探索と利用のトレードオフとベイズ環境モデル」
計測と制御 第52巻 第2号 2013年2月号 P154~161
牧野 貴樹
https://www.jstage.jst.go.jp/article/sicejl/52/2/52_154/_article/-char/ja/
をまとめた個人用めも

※この記事をまとめたのは2021年5月あたりで、強化学習について勉強し始めのときにまとめたもので、間違った内容が含まれている可能性があります

前回：https://qiita.com/he-mo/items/ec86c0b18dd193ef3aaa
次回：https://qiita.com/he-mo/items/65e0505243934423a966

## 多腕バンディット問題
バンディッド問題の定義とリグレットの説明
- バンディッド問題・・・腕が何個もあるルーレットマシーン、腕ごとにルーレットが当たる確率が割り当てられてる
- リグレット・・・はじめから一番いいものを選択していればいくら得したか

探索をしすぎたらリグレットが大きくなるし、探索しなさすぎたら最適な腕が見つからない
### ランダム探索
要するにイプシロングリーディー
### 不確かなときは楽観的に: UCB アルゴリズム
その腕の良さだけでなく、どれだけ知っているかを考慮する
選んだ回数が少ない・・・分散が大きい
分散も含め一番いいものを選択（報酬の期待値＋分散の半分）

### Thompson サンプリング
「ある腕の報酬の期待値が他のどの腕の報酬の期待値よりも高い」確率に従って，その腕を選択
https://cafeunder.github.io/rosenblock-chainers-blog/2018/03/08/thompson-sampling-gaussian-sicq-prior.html
### その他のバンディット問題
バンディット問題にもいろいろある
- 敵対的 (adversarial) バンディッ ト (相手が自由に設定を変えられる場合に相当し，確率的仮 定が通用しない)
- 文脈つきバンディット
- 連続バンディット (腕が離散ではなく d 次元実数空間上の点で表わされる場合)
## 強化学習における探索コスト最小化
探索と利用のトレードオフについて
探索すべき未知の状態につながる行動も探す必要がある
### 楽観的初期価値法
Q学習でいう、最初に与えるQ値を大きくしておく
効率的とは言えない
### サンプル複雑性: モデルベース手法
定義
- サンプル複雑性・・・行動履歴全体の中で最適なものではなかったものの数
- PAC-MDP・・・サンプル複雑性が小さく抑えられている

#### PAC-MDPであると認められたアルゴリズム　E3、Rmax
一定回数(m回)探索してない選択肢は探索してない物と扱い、高い価値を与える
mが非常に大きくなければならないため実用的ではない

#### 効率的に探索するアルゴリズム　モデルベース区間推定 (MBIE, Model-based interval estimation)
各状態–行動ペアに対する報酬と遷移確率に関する信頼区間（分散）を求め，その信頼区間のなかで最大 の価値となるような行動を，モデル上の計算で解く


### サンプル複雑性: モデルフリー手法
q学習のようなサンプル複雑性を抑えるアルゴリズム　
Delayed Q- learning
一定回数探索してない選択肢に関しては、その時点ではQ値を更新しない
一定回数後に一気に更新する

## ベイズ主義的アプローチ
事前知識を活用できたら探索回数が少なく済む
ベイジアン強化学習と呼ぶ

部分観測マルコフ決定過程

    マルコフ決定過程を拡張したもので、環境を全て観測できない
    環境を[θ,s]で表し、θは観測できない

ベイジアン強化学習においては、θが事前知識に対応する

手法として、以下の3つがある

### 共役分布表現を直接利用する方法
事前知識を直接利用、操作
BEETLE、BVRがある

### 環境モデルのサンプリングに基づく手法
事前知識をサンプリング
Bayesian DP、MBBE、BOSS、MC-BRLがある

### モンテカルロ木探索法
θを探索木の探索であると解釈し、モンテカルロ法を用いる
 UCT、FSSS、BFS3がある
強化学習　文献まとめ1

# 強化学習　文献まとめ1
リレー解説 強化学習の最近の発展 第1回
「強化学習の基礎」
計測と制御 第52巻 第1号 2013年1月号 P72~77
木村　元
https://doi.org/10.11499/sicejl.52.72
をまとめた個人用めも

※この記事をまとめたのは2021年5月あたりで、強化学習について勉強し始めのときにまとめたもので、間違った内容が含まれている可能性があります

次回：https://qiita.com/he-mo/items/b1689b6df605936e82d3

## はじめに
強化学習は教師あり学習と違い、教師データがない代わりに一連の行動に対して報酬を与える。これを手掛かりに学習を行う。ただし、報酬や状態遷移は不確実性（非決定的環境）や時間的遅れがあるため、実行した直後の報酬を見るだけではエージェントはその行動が正しいか判断できない。
エージェントと環境は、以下のやりとりをする
1. 時刻t、環境の状態観測s<sub>t</sub>に応じて行動a<sub>t</sub>を実行
2. 環境はs<sub>t+1</sub>に遷移、報酬r<sub>t</sub>をエージェントに与える
3. 時刻tをインクリメント

<!--
エージェントは利得の最大化を目的として方策を獲得する
行動の利得＝報酬＋割引率<sup>1</sup>＊次の報酬＋割引率<sup>2</sup>＊次の報酬＋・・・
-->


## 政策反復法と価値反復法
## actor-critic
政策反復法の1つ
actorとcriticの2つの要素で構成される
- actor・・・確率的政策(π)にしたがって行動を選択する
- critic・・・状態価値を推定し、政策を改善

πに正規分布を適用することで、連続値にも拡張できる
πにしたがって行動が選択され、改善されていくものをon-policyという

アルゴリズム
1. 状態s<sub>t</sub>を観測し、πに従って行動aを選択
2. 報酬rを受け取り、状態s<sub>t+1</sub>を観測
3. 直前の状態価値よりよい状態か悪い状態かを求め、πを更新
## Q学習
価値反復法の1つ
最適な行動価値を求めるアルゴリズム
πとは関係なしに最適なπや最適な行動価値を求められる(off-policyという)

アルゴリズム
1. 状態を観測し、行動価値に従って行動aを選択
2. 報酬を受け取り、状態を観測
3. 行動価値の更新式に基づき、行動価値を更新

行動選択(探査戦略)
Q学習は全ての行動を十分な回数選択すれば、最適な行動価値に収束するが、学習過程においても多くの報酬をえるような行動選択が求められる。
行動選択として下記の3つなどが提案されている。
- イプシロングリーディー
    - 一定確率で探索
- ボルツマン選択
    - 最初はQ値が均等になる
    - 時間が経つにつれてQ値が均等ではなくなる
- 楽観的初期値
    - Q値の初期値を高めに設定しておく
Bashで終了ステータスごとに異なる処理を行いたい場合にハマった

### 複数パターンの終了ステータスを返す「とあるスクリプト」を作成

終了ステータスが成功パターン(`exit 0`)、失敗パターンA(`exit 1`)、失敗パターンB(`exit 2`)のように3パターンにわかれる「とあるスクリプト」を作成しました。（元々のスクリプトはもっと複雑なんですが、ここでは簡略化して書いてます）

```:とあるスクリプト.sh
処理A || {
    # 失敗パターンA
    exit 1
}

処理B || {
    # 失敗パターンB
    exit 2
}

# 成功パターン
exit 0
```

### 「とあるスクリプト」の終了ステータスを判定して、それぞれ異なる処理を行うスクリプトを作成

「とあるスクリプト」を「呼び出す側のスクリプト」で、終了ステータスごとに異なる処理を行おうと思い、以下のような条件分岐を書きました。
元々は成功パターンと失敗パターンAの2パターンだけだったんですが、失敗パターンBが登場して3パターンとなり、以下のような分岐にしてみたという経緯があります。

```:呼び出す側のスクリプト.sh
bash とあるスクリプト.sh
if [ $? -eq 0 ] ; then
    echo '成功パターンの場合の処理'
elif [ $? -eq 1 ] ; then
    echo '失敗パターンAの場合の処理'
elif [ $? -eq 2 ] ; then
    echo '失敗パターンBの場合の処理'
fi
```

### 想定外の結果に
すると、 `exit 1` と `exit 2` のどちらの場合も「`失敗パターンAの場合の処理`」と出力されてしまいました。
パッと見は間違ってなさそうに見えるんですが、どうにもうまくいきません。なぜでしょう？

### 問題の原因
「とあるスクリプト」の実行後に `if [ $? -eq 0 ] ; then` の部分で　 `[ $? -eq 0 ]` というコマンドが実行されます。
失敗パターンB(`exit 2`)の場合は `[ 2 -eq 0 ]` なので、判定は偽となり終了ステータスが `1` となります。
`$?` は「直前に実行した処理」の終了ステータスが格納される変数なので、 `bash とあるスクリプト.sh` を実行した際は `$?` に `2` がセットされていますが、 `[ $? -eq 0 ]` が実行されることにより `$?` が `1` に変わるわけです。
これにより、失敗パターンBの場合、 `elif [ $? -eq 1 ] ; then` の部分で `[ $? -eq 1 ]` というコマンドは `[ 1 -eq 1 ]` になってしまうので、判定は真となり「`失敗パターンAの場合の処理`」と出力されていたワケです。

### 解決方法
この問題を解決するにはどうしたらよいのでしょう？
`$?` が上書きされてしまうことが問題なので `bash とあるスクリプト.sh` を実行した直後に終了ステータスを変数にセットすることで解決します。

```:呼び出す側のスクリプト.sh
bash とあるスクリプト.sh
result=$?
if [ $result -eq 0 ] ; then
    echo '成功パターンの場合の処理'
elif [ $result -eq 1 ] ; then
    echo '失敗パターンAの場合の処理'
elif [ $result -eq 2 ] ; then
    echo '失敗パターンBの場合の処理'
fi
```

終了ステータスが2パターンから3パターンに増えて、これからも増えるかもしれないことを考慮すると、 `elif` をたくさん並べるよりも `case` に書き換えるというのもアリかもしれませんね。

```:呼び出す側のスクリプト.sh
bash とあるスクリプト.sh
result=$?
case $result in
    0 )
      echo '成功パターンの処理' ;;
    1 ) 
      echo '失敗パターンAの処理' ;;
    2 )
      echo '失敗パターンBの処理' ;;
esac
```

### おまけ

ちょっと前に、「[シェルスクリプトの「if」は条件式の「コマンド」の実行結果を判定している](https://qiita.com/akase244/items/41f31ec80a2561227887)」という記事を書いてまして、 `if` の仕組みは理解していたつもりだったのにハマってしまいました。。。

### 参考URL
- [Man page of TEST](https://linuxjm.osdn.jp/html/GNU_sh-utils/man1/test.1.html)
- [if 文と test コマンド](https://shellscript.sunone.me/if_and_test.html)
- [Bashで終了ステータスよる条件分岐](https://blog.codebase.co.jp/conditional-branch-by-exit-status-on-bash)
文字列を指定した部分だけ表示する

#今回の内容

* 文字列を指定した部分だけ表示する

##.prefix（ ）

* 文字列を、左から指定した文字数分だけ表示。

* 今回は、左から5文字分だけprintしています。

```Swift:
        let testString = "Swift大好き"
        print(testString.prefix(5))          
```

```:デバッグエリア
        Swift   
```

##.suffix（ ）

* 文字列を、右から指定した文字数分だけ表示。

* 今回は、右から8文字分だけprintしています。

```Swift:
        let testStringTwo = "IOSアプリ開発大好き"
        print(testStringTwo.suffix(8)) 
```

```:デバッグエリア
        アプリ開発大好き
```

# 終わり
今、作成してるアプリで使いそうなので、先に調べてみました。
簡単な内容ですけど、どんな感じで使うか考えるのが楽しい!!! 

ご指摘、ご質問などありましたら、コメントまでお願い致します。
【Laravel】mysqlに接続できず、migrateできなかった

Laravelをインストールして、migrateしようとしたら、

```
[ec2-user@ip-172-31-39-229 mosaku]$ php artisan migrate

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from information_schema.tables where table_schema = mosaku and table_name = migrations and table_type = 'BASE TABLE')

  at /var/www/html/mosaku/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673|

  Exception trace:

  1   Doctrine\DBAL\Driver\PDO\Exception::("SQLSTATE[HY000] [2002] No such file or directory")
      /var/www/html/mosaku/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18

  2   Doctrine\DBAL\Driver\PDO\Exception::new()
      /var/www/html/mosaku/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43

  Please use the argument -v to see more details.
```

これに数時間取られてしまったので、備忘録として記載。

###.envにDB_SOCKETを追記
結局これだけでmigrateできるようになったのですが、mysql.sockの場所をずっと勘違いしてました。
私の環境は、ec2のAWS Linux2なのですが、正解はここ。

```
/var/lib/mysql/mysql.sock
```

/var/run/mysqld/mysqlx.sock がありましたが、違いました。
これを.envのDB_SOCKETに追記してあげれば動きました。

```:.env
...
DB_SOCKET=/var/run/mysqld/mysqlx.sock
...
```
LINEBotを使用してマニュアルの検索ツールをつくってみた（未完成）

こんばんは。

仕事で新入社員、パートさんの教育を実施しています。

LINEBotを使用して業務で使用するマニュアル・用語を検索し、
そのページに移行してくれるツールや、用語の意味を返信してくれるツールを作ってみました。

これをすることによって、以下の業務改善ができます。
①グループ会社で働く方が統一された用語を使用し、用語の意味を素早く理解できる。
②作業方法を探す手間を省き、仕事を効率良く進めることができる。


#できたこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811930/48cc5f76-31ab-a078-e9c1-cd8bf74ff449.png)


```javascript

if (msg.payload.events[0].message.text == '前進立体陳列') {
    // 「前進立体陳列」を受信したら「人の目に対し、商品が盛りあがった感じに見せる陳列の型のことです。１個目の商品を陳列棚の一番手前に置き、２個目からその上に積み上げていき、積み上げられきれなくなるとはじめて、１個目の後へ並べ、さらにその上へ積み上げていく陳列の型。手前から並べていくので、前進といい、2個目を1個目の上におくので、立体といいます。迫力が出れば、店舗イメージも向上し豊富感も強調され、買物の楽しさが増えるだけでなく、ついで買いなどを誘発できる効果があります。」と返事する
    msg.payload.events[0].message.text = '人の目に対し、商品が盛りあがった感じに見せる陳列の型のことです。１個目の商品を陳列棚の一番手前に置き、２個目からその上に積み上げていき、積み上げられきれなくなるとはじめて、１個目の後へ並べ、さらにその上へ積み上げていく陳列の型。手前から並べていくので、前進といい、2個目を1個目の上におくので、立体といいます。迫力が出れば、店舗イメージも向上し豊富感も強調され、買物の楽しさが増えるだけでなく、ついで買いなどを誘発できる効果があります';
} else if (msg.payload.events[0].message.text == '原価') {
    // それ以外を受信したら「原価とは商品の仕入れ価格のことをいいます。」と返事する
    msg.payload.events[0].message.text = '原価とは商品の仕入れ価格のことをいいます。';
} else if (msg.payload.events[0].message.text == '棚替え') {
    // それ以外を受信したら「棚替えの方法　https://teachme.jp/65261/manuals/10780836/」と返事する
    msg.payload.events[0].message.text = '棚替えの方法\nhttps://teachme.jp/65261/manuals/10780836/';

} else {
    msg.payload.events[0].message.text = 'わかりません';
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811930/ea3d9b8d-0059-40ea-a8ba-f4530558fe62.png)



自分が作ったマニュアルが言葉１つで呼び出すことができるようになりました。



#したかったこと
会社でTeachmeBizのアプリを使用してマニュアル作成をしています。
TeachmeBizのAPIがなかったので、URLを張り付けて対応したのですが、
大量にあるマニュアルを紐づけるのは大変だと思います。
それが紐づけられるようにしたいと思っています。

最後まで読んでいただきありがとうございました。
【Swift】throws 関数の中で throws 関数を呼び出したときの挙動【エラー処理】

# 概要

タイトルのとおりです。

サンプルを見ればわかると思います。

いろいろ探したのですが、このケースについて解説している記事がなかったので、Playground で実際にコーディングして挙動をまとめてみました。

環境は Xcode 12.5.1 になります。

## 基本編

### サンプル

```swift
import Foundation

enum TestError: Error {
    case largeError
    case smallError
    case sixError
}

func methodA(num: Int) throws -> Int {
    if num > 8 {
        throw TestError.largeError
    }
    return num
}

func methodB(num: Int) throws -> Int {
    if num < 4 {
        throw TestError.smallError
    }
    return num
}


func methodC(num: Int) throws -> Int {
    let _ = try methodA(num: num) // throws 関数のなかで throws 関数を呼び出す ← こいつ
    let _ = try methodB(num: num) // throws 関数のなかで throws 関数を呼び出す ← こいつ
    if num == 6 {
        throw TestError.sixError
    }
    return num
}

func methodD(num: Int) {
    do {
        let c = try methodC(num: num) // 通常の関数のなかで throws 関数を呼び出す ← いつもの
        print(c)
    } catch {
        print(error)
    }
}
```

### このときの挙動

```swift
methodD(num: 9) // largeError
methodD(num: 3) // smallError
methodD(num: 6) // sixError
methodD(num: 7) // 7
```

### ポイント

- methodC で methodA や methodB のエラーを methodC 内で `throw` しなくても methodD 側までエラーを飛ばしてくれる
- methodC で methodA や methodB の `do-catch` は記述しなくてもコンパイルエラーにならない
- ただし、methodA や　methodB の前に `try` はつけないとコンパイルエラーとなる
- methodC ならではのエラーを飛ばす場合は、普通に `throw` すればよい（`throw TestError.sixError` のところ）
- `rethrows` はクロージャーで発生したエラーに関するハンドリングをいい感じにするやつなので、これとはあんまり関係ない（[rethrows のわかりやすい記事](https://swift.codelly.dev/guide/%E3%82%A8%E3%83%A9%E3%83%BC%E5%87%A6%E7%90%86/#rethrows)）


## 応用編

methodA や methodB も methodC 内で `do-catch` で囲むことで、別のエラーとして `throw` することが可能です。

### サンプル

```swift
import Foundation

enum TestError: Error {
    case largeError
    case smallError
    case sixError
    case wrapError // ← 追加
}

func methodA(num: Int) throws -> Int {
    if num > 8 {
        throw TestError.largeError
    }
    return num
}

func methodB(num: Int) throws -> Int {
    if num < 4 {
        throw TestError.smallError
    }
    return num
}

func methodC(num: Int) throws -> Int {
    let _ = try methodA(num: num)
    do {
        let _ = try methodB(num: num) // methodB を do-catch で囲む
    } catch {
        throw TestError.wrapError // methodB のエラーを wrapError に変換
    }
    if num == 6 {
        throw TestError.sixError
    }
    return num
}

func methodD(num: Int) {
    do {
        let c = try methodC(num: num)
        print(c)
    } catch {
        print(error)
    }
}
```

### このときの挙動

```swift
methodD(num: 9) // largeError
methodD(num: 3) // wrapError ← smallError から変更されている
methodD(num: 6) // sixError
methodD(num: 7) // 7
```

### ポイント

- methodA や methodB も methodC 内で `do-catch` で囲むことで、別のエラーとして `throw` することが可能（＝ エラーの置き換えが可能）

# まとめ

記事を探すよりも Playground でコーディングしたほうが早いこともある
「Error: Could not start Firestore Emulator, port taken.」のエラー対処法

Firebase emulatorを起動しようとしたら「Error: Could not start Firestore Emulator, port taken.」というエラーがでた。

起動できない原因は前回Firebase emulatorの終了に失敗したため。
以下のxxxx番のportが開いていないので、エミュレーターを起動することができなかった

```
firestore: Port xxxx is not open, could not start Firestore Emulator.
Error: Could not start Firestore Emulator, port taken.
```

以下コマンドで任意のプロセスを終了することで、次回からemulatorが起動できる

```
lsof -ti:xxxx | xargs kill
```

覚えるのがめんどくさいのでpackage.jsonに登録しておくのもいい

```js
"script": {
  "stop": "lsof -ti:xxxx | xargs kill"
  // 複数のポートを対象にしたい場合
  "stop2": "lsof -ti:xxxx -i :xxxx | xargs kill"
}
```
Javaにおけるアノテーションの復習メモ

## アノテーションとは
- ソースコードの注釈
- コンパイラやJVMに付加情報を伝える
- 目印のようなもの

## 主なアノテーション
- @Override→スーパークラスのメソッドをオーバーライド

- @FunctionalInterface→関数型インターフェイス

→単一の抽象メソッドを持つインターフェイス(1つだけ持てる)
→staticメソッド、デフォルトメソッドは複数可
→Objectクラスのpublicメソッドである抽象メソッドは含まない(複数定義可)

```java
package cp2.no3;

@FunctionalInterface
public interface FunctionalInter<T> {

	// 単一の抽象メソッド(抽象メソッドは1つしか定義できない。2個以上は不可)
	void foo(T t);

	// Objectクラスのpublicメソッド
	String toString();

	// Objectクラスのpublicメソッド
	boolean equals(Object object);

	// staticメソッド
	static void X() {};

	// defaultメソッド
	default void Y() {};
}

```

- @Deprecated→非奨励の要素

→プログラマが使用することを推奨されていないプログラム要素
→(例)コンストラクターDate(String)は非奨励
→DateFormatクラスのparse()メソッドの使用が推奨
→since, forRemovalという要素がある
→since…非奨励になったバージョンを示す
→forRemoval→将来のバージョンで注釈付きプログラム要素を削除する意志を示す

```java
package cp2.no6;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {

	@Deprecated public static void main(String[] args) throws ParseException {

		// 非奨励コード
		Date date = new Date("2021/8/3");
		System.out.println(date);

		// 奨励コード
		DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
		Date date2 = df.parse("2021/8/3");
		System.out.println(date2);
	}
}

```

- @SuppressWarnings→コンパイラの警告を無効化

→引数に抑制したい警告を指定することで、コンパイル時に表示される警告を抑制できる。
→rawtypes…List<String>ではなくListの使用など、型の使用に関連する警告を抑制
(古いJava環境下でメンテナンスする際に、警告を抑制するなど)
→deprecation…@Deprecatedアノテーションがつけられたものに関する警告を抑制

```java
package cp2.no7;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Main {

	public static void main(String[] args) {

		// @Deprecatedによる警告
		@SuppressWarnings("deprecation")
		Date date = new Date("2021/8/3");

		// 型指定をしていない
		@SuppressWarnings("rawtypes")
		List list = new ArrayList();
	}
}

```

- @SafeVarargs→安全でない可変長引数に対する警告を無効化

→実行時にClassCastExceptionが発生する可能性があるコードなど
→final, static, privateのいずれかのメソッドに限定

```java
package cp2.no8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

	public static void main(String[] args) {
		m(new ArrayList<String>());
	}

	@SafeVarargs
	static void m(List<String>...stringLists) {

		Object[] array = stringLists;
		List<Integer> tempList = Arrays.asList(1);
		array[0] = tempList;

		// [[1]]の要素であるint型の1をStringの文字列に格納しようとするので
		// 実行するとClassCastExceptionが発生
		String s = stringLists[0].get(0);
	}
}

```

## 今後の課題
- カスタムアノテーションについても学習していく必要があると感じる。
Rを使って愛知県の地図を書いてみた

## はじめに
今年の5月に関東から愛知県に引っ越してきました。まだまだ愛知県がどういうところなのか、どういう地域があるのか分からないので、Rと統計情報を使って色々と可視化してみようと思います。

今回は`{jpndistrict}`というパッケージを使って、愛知県の地図を表示してみます。

## {jpndistrict}のインストール
`{jpndistrict}`パッケージは、現在CRANからダウンロードできないため、`{remotes}`パッケージを使ってインストールします。

```r
install.packages("remotes")
remotes::install_github("uribo/jpndistrict")
```


## 地図の描画
以下のソースを実行することで、愛知県の地図を描画することができます。

```r
library(tidyverse) 
library(jpndistrict)

aichi <- jpn_pref(23)

g <- ggplot(aichi) + 
     geom_sf() +
     theme_void()

g
```

結果は以下のような感じです。

![スクリーンショット 2021-08-03 22.38.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/4b882f23-918c-216f-1a8b-6d529e32ff7e.png)

### 詳しく見る
地図を描画には`{ggplot2}`パッケージを使って描画します。今回はそれが含まれる`{tidyverse}`パッケージを使ってます。

```r
library(tidyverse) # 地図描画に使う
library(jpndistrict) # 地図のデータを取得する
```

愛知県のデータは以下のように取得します。引数は都道府県コードを使って指定できます。

```r
aichi <- jpn_pref(23)

# 中身の確認
# head(aichi)
#
## A tibble: 69 × 5
#   pref_code prefecture city_code city                                  geometry
# * <chr>     <chr>      <chr>     <chr>                       <MULTIPOLYGON [°]>
# 1 23        愛知県     23101     名古屋市 千種区 (((136.9321 35.15738, 136.933…
# 2 23        愛知県     23102     名古屋市 東区   (((136.9092 35.1829, 136.9095…
# 3 23        愛知県     23103     名古屋市 北区   (((136.8994 35.18655, 136.916…
# 4 23        愛知県     23104     名古屋市 西区   (((136.8684 35.21179, 136.878…
# 5 23        愛知県     23105     名古屋市 中村区 (((136.8383 35.14849, 136.839…
# 6 23        愛知県     23106     名古屋市 中区   (((136.9122 35.14321, 136.910…
# 7 23        愛知県     23107     名古屋市 昭和区 (((136.9369 35.14045, 136.937…
# 8 23        愛知県     23108     名古屋市 瑞穂区 (((136.9211 35.11126, 136.922…
# 9 23        愛知県     23109     名古屋市 熱田区 (((136.8862 35.14058, 136.882…
#10 23        愛知県     23110     名古屋市 中川区 (((136.7975 35.12183, 136.805…
## … with 59 more rows
```

### 市区町村名の追加
地図に市区町村名も追加できたら見やすいなと思い、追加してみました。
以下、参考記事。
[Rを使ってシェープファイルから白地図を描く](https://qiita.com/nozma/items/8e890595c07d3be86bc9)

以下のソースを実行すると、市区町村名付きの地図が描画できます。

```r
library(tidyverse)
library(jpndistrict)

# 重心を求めるパッケージ
library(sf)

aichi <- jpn_pref(23) %>%
         mutate( # ポリゴンのデータを使って、重心を計算し、tibbleを追加
            centroid = st_centroid(geometry),
            x = st_coordinates(centroid)[, 1],
            y = st_coordinates(centroid)[, 2]
         )

g <- ggplot(aichi) + 
     geom_sf() +
     theme_void() +
     geom_text(
       aes(x = x, y = y, label = city), # 位置と市区町村名を指定
       family = "Osaka", # フォントを指定
       size = 2
     )

g
```

名古屋市がごちゃごちゃになってしまいました

![スクリーンショット 2021-08-03 23.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/005bcd70-adff-a736-cef5-b573b464fde5.png)

## 最後に
今回は愛知県の地図を描画して、最後には地図に市区町村名を追加してみました。
これからは統計情報を追加して、色々と愛知県を知っていこうと思います。
create-react-appしたらあるはずのsrcフォルダーがなかったときの対処法

## 記事の前提

create-react-appしたらあるはずのsrcフォルダーがなかったときの対処法について話します。

当方の環境ではcreate-react-app後、yarn startをしたが、エラーを起こしていました。
そしてpackage.jsonやnode_modulesなどのファイルしかありませんでした。

```
＜当初の状態＞
package.json
package-lock.json
node_modules
```

そして対処策として、yarnのアンイストールをしたほうがいいと分かりましたが、そこに苦戦しました。


そこで本記事では、下記の状態時のyarnのアンイストールについての対処法を記事にしました。

- create-react-app後、yarn startでつまづく
- package.jsonやnode_modulesしかインストールされていない（create-react-appしたらあるはずのsrcフォルダーがない）


create-react-appしたけれど、node_modules、package-lock.json、package.jsonしかインストールできず、srcやpublicフォルダーがない状態で、yarn startやnpm startでエラーを起こしている方、あるいは下記の状況で書いているようなエラー文に遭遇した方にとって何かヒントになるかもしれません。



## 状況

表示されたエラーメッセージ。

> A template was not provided. This is likely because you're using an outdated version of create-react-app.

> Please note that global installs of create-react-app are no longer supported.

> You can fix this by running npm uninstall -g create-react-app or yarn global remove create-react-app before using create-react-app again.



そこで下記を試し、

```
$ yarn global remove create-react-app
→yarn global v1.22.10
````

その後createしても変わらず。

さらにnpm アンイストールを進めるが、`npm uninstall -g create-react-app` しても下記のエラーが発生。


```
...省略）
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
```


## 対処法



そこで下記の記事を参考に下記を実行。
https://qiita.com/10mi8o/items/ec12ccf25270626a948b

```
$ which create-react-app
→/usr/local/bin/create-react-app
```
```
$ cd /usr/local/bin/
```
```
$ rm create-react-app
```
↓
$ npx create-react-app


## 余談
npmをアンイストールをしたことで転機を迎えた感があったので、
npmがなにか悪さをしていたのか？
CodeCommitレポジトリを共有してレビュー「だけ」して貰うための権限設定

開発チーム外のメンバーに、CodeCommitレポジトリ上のコードを見て貰いたいことがある。
pushやプルリクの必要はなく、調査協力やアドバイスのためにレビューだけをお願いしたいという時に、設定すべき権限一式と手順についてメモ。

### 前提
- AWS SSOを使う。
    - SSOドメインは東京リージョンに作成。
    - アクセス権限セット名はCodeReviewerとする。
- git-remote-codecommit（GRC）を使ってクローンする。

### 権限セットの準備

アクセス権限セットを作成し、CodeCommitレポジトリのあるAWSアカウントとレビュー用SSOユーザー（またはグループ）に紐付ける。

```json:CodeReviewer
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CodeCommitRepositorySpecificAction",
            "Effect": "Allow",
            "Action": [
                "codecommit:EvaluatePullRequestApprovalRules",
                "codecommit:BatchGet*",
                "codecommit:GitPull",
                "codecommit:Describe*",
                "codecommit:BatchDescribe*",
                "codecommit:Get*",
                "codecommit:List*"
            ],
            "Resource": [
                "arn:aws:codecommit:ap-northeast-1:123456789012:<レポジトリ名>"
            ]
        },
        {
            "Sid": "CodeCommitGlobalAction",
            "Effect": "Allow",
            "Action": [
                "codecommit:ListRepositoriesForApprovalRuleTemplate",
                "codecommit:GetApprovalRuleTemplate",
                "codecommit:ListApprovalRuleTemplates",
                "codecommit:ListRepositories"
            ],
            "Resource": "*"
        }
    ]
}
```

### レビュワーに手順を伝達

アクセス権限セットを作り、紐付けを行ったら、レビュワーに以下の手順を伝えてログインして貰う。

#### 1. プロファイル作成手順

ログイン用のAWSプロファイルはホームディレクトリの.aws/configを編集して作る。
`aws configure sso --profile reviewer-profile`として、インタラクティブに作成することもできる。

```bash:reviewer-profile
[profile reviewer-profile]
sso_start_url=https://<SSO URL>.awsapps.com/start
sso_region=ap-northeast-1
sso_account_id=123456789012
sso_role_name=CodeReviewer
region=ap-northeast-1
output=json
```

#### 2. ログイン＆クローン手順

上記のプロファイルを使ってログイン後、git cloneして完了。
あとはIDEなりエディタなりでレビューして貰う。

```bash:ログイン手順
% pip install git-remote-codecommit
% aws sso login --profile <プロファイル名>
% export AWS_PROFILE="<プロファイル名>"
% git clone codecommit::ap-northeast-1://<レポジトリ名>
```