OmniAICreator/Qiita-1.07M huggingface dataset:
RSpecでよく使うマッチャ

　この投稿では、私がRSpecでよく使うmatcher(マッチャ)についてまとめています。

「[RSpecのgitURL](https://github.com/rspec/rspec-rails "Qiita")」
「[Relish](https://relishapp.com/rspec/rspec-expectations/v/3-4/docs "Qiita")」



##1. include
includeは、``expectの引数``に``includeの引数``が含まれていることを確認するマッチャです。

```ruby
describe "スポーツ" do
  it "スポーツに野球が含まれている" do
     expect(["野球", "サッカー", "ラグビー", "テニス"]).to include("野球")
  end
end
```
このテストコードを実行した場合、想定通り配列のなかに``野球``は含まれているため、``テストは成功``します。
##2. eq
eqは、``expectの引数``と``eqの引数``が等しいことを確認するマッチャです。

```ruby
describe "足し算" do
  it "1 + 1の計算結果は2と等しい" do
     expect(1 + 1).to eq(2)      # 1 + 1 = 2 =>正しい
  end
end
```
このテストコードを実行した場合、想定通り``1 + 1``は``2``と等しいため、``テストは成功``します。

##3. be_valid
be_validは、``バリデーション実行時の返り値``が``true``であることを確かめるマッチャです。

```ruby
# バリデーションでuserのnicknameは最大５文字まで
it "nicknameは5文字以下であれば登録できる" do
  user.nickname = "あいうえお"      # nicknameを上書きする 
  expect(user).to be_valid       # be_validでuserが登録できるか判定
end
```
このテストコードを実行した場合、想定通り``nickname``は``5文字以下``のため、``テストは成功``します。

##4. have_content
``expect(page).to have_content('X')``
 訪れた``page``の中に、``X``という文字列があるかどうかを判断するマッチャです。
``page``は訪れた先の``ページの見える分だけの情報``が格納されています。例えば、ページに「ログイン」と書かれたボタンがある場合、「ログイン」という文字列情報が``page``に格納されています。
ただし、カーソルを合わせてはじめて見ることができる文字列は``page``の中に含まれません。

```ruby
# ログインページに「ログインボタン」があることを確認する
expect(page).to have_content('ログイン')
```
また、have_contentの逆で、文字列が存在しないことを確かめる``have_no_content``マッチャがあります。

##5. have_link
``expect("要素").to have_link 'ボタンの文字列', href: "リンク先のパス"``
``要素の中``に当てはまる``リンク``があることを確認するマッチャです。また、have_linkは``a要素``に対して用います。 

```ruby
# ログインページにログイン処理を行うパスが存在する
expect(page).to have_link 'ログイン', href: new_user_session_path  # このコードでは要素でなくpageを用いています。
```
また、``have_link``の逆で、``当てはまるリンクがない``ことを確認する``have_no_linkマッチャ``があります。
``expect("要素").to have_no_link 'ボタンの文字列', href: "リンク先のパス"``とすることで、要素の中に当てはまるリンクがないことを確認できます。





##6. change
``expect{ "何らかの動作" }.to change { "数が変化するもの" }.by(X)``
``数``がいくつ(X)変化するのかを確認するマッチャです。

```ruby
# pageにある「投稿する」ボタンをclick_onメソッドでクリック
expect{ click_on "投稿する" }.to change { Tweet.count }.by(1)   # Tweetモデルのレコードのカウントが１つ上がる
```
```ruby
# 変数aに対して、いくつ変化するか確認
expect { a += 1 }.to change { a }.by(1)            # 値の増減を、相対値で検証     
# => a = 2     
expect { a += 3 }.to change { a }.from(2).to(5)    # 状態が何から何に変わったのかを検証
# => a = 5 (aが2から5に変化)
```

##まとめ
　今回紹介したRSpecのマッチャはは、ごく一部で勉強する中でまだまだ多くのマッチャが存在することを知りました。
　今後も、新しい気付きや学んだことを投稿していきたいと思います。何か誤り等あれば、コメントにて教えてください。
[Rails] CSS適用方法

#結論
CSSファイルをapp/assets/stylesheets/ディレクトリに配置すればOK
自動的に読み込まれ、適用される。

※ロジックは下記知識を得れば理解できます。
※「自動的に読み込まれ、適用される」が当てはまらない場合がありますが、
　おおよその場合当てはまります。

#レイアウトテンプレート
アプリケーションのビューファイルの共通部分をまとめたもの。
headの情報や、ヘッダー・フッターなどのすべてのビューで共通となる部分を記述しておく。
各テンプレートファイルは個別の見た目を記述するだけでよくなる。


#application.html.erbファイル
Railsのレイアウトテンプレートファイル。
レイアウトファイルとも呼ばれる。
デフォルトでapp/views/layoutsディレクトリに配置されている。

[![Image from Gyazo](https://i.gyazo.com/7a86c8fb2961fbe5257ce2b9c6384021.png)](https://gyazo.com/7a86c8fb2961fbe5257ce2b9c6384021)

#yieldメソッド
レイアウトテンプレートに、各テンプレートファイルを展開するためのメソッド。
yieldを記述することで、indexアクションの場合はテンプレートファイルのindex.html.erbが、
newアクションの場合はnew.html.erbが、yield記述部分へ展開される。

上記application.html.erbでは、body要素内に<%= yield %>の記述があり、これによって
「body要素内に各ビューファイルの記述が集約される」という仕組みができている。

*=のような特殊な記法に続けて他のCSSファイルを指定すれば、複数のCSSファイルをまとめて読み込むことが可能。

#stylesheet_link_tagメソッド
読み込むCSSファイルを指定できるヘルパーメソッド。
application.html.erbのstylesheet_link_tagの引数には、'application'と書いてあるため、app/assets/stylesheets/ディレクトリ内のapplication.cssというCSSファイルを読み込むことを示している。


#application.cssファイル
Railsにデフォルトで用意されている、CSSファイルをまとめるためのファイル。
アプリケーション全体に適用するCSSを指定する。
マニフェストファイルとも呼ばれる。
[![Image from Gyazo](https://i.gyazo.com/94375a23863d1acbe1d55ba124c1f152.png)](https://gyazo.com/94375a23863d1acbe1d55ba124c1f152)

#require_tree
引数として与えられたディレクトリ以下のCSSファイルをアルファベット順に
すべて読み込むメソッド。

デフォルトでapplication.cssにrequire_tree .と記述してある。
引数に与えられた.(ドット)は、カレントディレクトリを指す。

つまり、このrequire_tree .の記述によって、app/assets/stylesheets/というディレクトリにあるCSSファイルは、すべてapplication.cssに読み込まれる。
【Laravel】php artisan コマンド

Laravelで使う php artisanコマンド
artisan　アルチザンと読むらしい。

アルチザンとは、 職人。技工。とかの意味らしい。

## 対話モード
```
$ php artisan tinker
```
これで対話モードができる。
データベースの中身などを調べるときに使える。

例えば,,,

```
User::all()
```
このように行えば、Userテーブルのデータを確認することができる。

## マイグレーション
```
$ php artisan migrate
```
これで、マイグレーションの実行ができる.

## マイグレーションのやり直し
```
$ php artisan migrate:fresh
```
これで、一旦全てのテーブルを削除しマイグレーションをやりなおすことができる。

## seedデータの投入
```
$ php artisan db:seed
```
seedファイルで作成したデータをDBに保存する
AVCaptureVideoDataOutputのCMSampleBufferからCVPixelBufferにアクセスするときのお作法


CVPixelBufferを取得する場合は`CVPixelBufferLockBaseAddress`でロックを確保してpixelBufferにアクセス、終わったら`CVPixelBufferUnlockBaseAddress`でアンロックする

[Detecting Human Body Poses in an Image](https://developer.apple.com/documentation/coreml/detecting_human_body_poses_in_an_image) より

```swift
// Attempt to lock the image buffer to gain access to its memory.
guard CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly) == kCVReturnSuccess
    else {
        return
}

// Create Core Graphics image placeholder.
var image: CGImage?

// Create a Core Graphics bitmap image from the pixel buffer.
VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &image)

// Release the image buffer.
CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)

DispatchQueue.main.sync {
    delegate.videoCapture(self, didCaptureFrame: image)
}
```

[captureOutput(_:didOutput:from:) | Apple Developer Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutputsamplebufferdelegate/1385775-captureoutput)
Rails アプリの作成初めかた

・画面に表示する

１．Railsでアプリの土台を作る

$ rails _5.2.1_ new アプリ名 -d mysql
　必要なファイルが一気にできる

2．ルーティングを作成
　config/routes.rb にdef index end
　
3.コントローラー作成
　$ rails g controller ファイル名
 contlloers/applocation_controller.rb
 HTTPメソッド　'ファイル名'　=> 'ファイル名＃index'

４．ビューファイル
  app/views にindex.html.erbファイルを作成し、<p>Hello World!</p>　




・データベースに保存する

５. データベースの作成
　rails db:create

６.モデル作成
　rails g model ファイル名
　マイグレーションファイルができる

7．カラムの作成
　db/migrate/ファイル名.rb　にカラム記入
　　カラムデータ型指定  :カラム名

8.マイグレート
　rails db:migrate

　



☆ＷＥｌｌ　ＤＯＮＥ(^^♪☆
laravel をブラウザで表示しようとしてcould not be opened in append mode: failed to open stream: Permission deniedとなった時の解決法

larval をローカル環境であれこれ編集しようとして、
途中経過をブラウザで表示しようとしていたのですが、

could not be opened in append mode: failed to open stream: Permission denied 

とエラーが起きていつまでも解決しませんでした。
上記のエラーメッセージの手前に該当箇所のファイルの階層が示されており
そこの編集権限がない？といったメッセージ内容。


解決できそうな参考記事をあれこれあたってみても、

sudo chmod 777 storage -R 　

と書かれていて、バカ正直にそのまま打ち込むと、
-R  なんてファイルは存在しません。(No such file or directory) と出てくる。。。
そりゃそうか。


誰かこの先詰まった時の参考になれば良いと思い書き残しておきます。

・エラーの意味

Permission denied : 権限が拒否されました。
つまり何かしら権限を書き換える必要がありそう。


・どこの権限がない？
laravel プロジェクトが入っているXAMMP内の、
 
~/laravelプロジェクト名/strage/logs/laravel.log で編集権限がないと言われました。
larval 開発の最初って多分このエラーにぶち当たることが多いのか。。？


・やったこと
logsディレクトリ以下の権限を書き換えられるように以下のコードを
自分のディレクトリ名に合わせて実行(エラーで表示されたディレクトリ名を最後のファイル名除いてコピペ)

$ sudo chmod 777 /Applications/XAMPP/xamppfiles/htdocs/laravelプロジェクト名/strage/logs
→ 実行

これで権限の書き換えができるのでエラーが起きているファイルをリロード。
表示されました！



参考にさせていただいた記事：
http://www.thirtyfive.info/entry/2018/06/07/laravel%E3%81%AE%E8%B5%B7%E5%8B%95%E8%A8%AD%E5%AE%9A%E3%81%A8%E3%82%A8%E3%83%A9%E3%83%BC#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%AD%E3%82%B0%E3%81%A7failed-to-open-stream-Permission-denied-in-


めちゃくちゃスッキリした。。
functions.phpからスタイルシートやjsを読み込む

#functions.phpからスタイルシートやjsを読み込む

WordPressのwp_head( )とwp_footer( )という関数を読み込んでいく。

そのためには以下をする必要がある。

wp_enqueue_style( )はwp_head()で読み込むcssを追加するための関数で、
wp_enqueue_script( )はwp_footer( )で読み込むjsを追加するための関数です。

下記の内容をfunction.phpに記述。

```
/**
* CSSとJavaScriptの読み込み
*
* @codex https://wpdocs.osdn.jp/%E3%83%8A%E3%83%93%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC
*/
function my_script_init()
{
wp_enqueue_style('fontawesome', 'https://use.fontawesome.com/releases/v5.8.2/css/all.css', array(), '5.8.2', 'all');
wp_enqueue_style('my', get_template_directory_uri() . '/css/style.css', array(), '1.0.0', 'all');
wp_enqueue_script('my', get_template_directory_uri() . '/js/script.js', array( 'jquery' ), '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'my_script_init');
```

これでstyle.cssとscript.jsがそれぞれ読み込まれるようになりました！


そして、それぞれheader.phpとfooter.phpに以下のように書いていきます。


header.php

```
<meta property="og:description" content="">
<meta name="twitter:card" content="summary_large_image">

<!--
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css?ver=5.8.2">
<link rel="stylesheet" href="./css/style.css">
ここを置き換える
-->

<?php wp_head(); ?>
<link rel="icon" href="./img/icon-home.png">
```


footer.php

```
<div class="floating">
  <a href="#"><i class="fas fa-chevron-up"></i></a>
</div>

<!--
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="js/script.js"></script>
ここを置き換える。jqueryはWPデフォで読み込まれるので消してOK。
-->

<?php wp_footer(); ?>
</body>
</html>
```


これで読み込み完了です。
以上、ありがとうございました。
C/C++ の演算子による演算の結果の型一覧

# これは何？

C/C++ で組み込み型を演算した結果の型がどうなるのかの表って見たことないなと思ったので作った。

試した環境は macOS(amd64) + clang++ なので、LP64。つまり、int は 32bit。long と long long は 64bit。
単なる `char` には符号がある。

32bit 環境とかだと違った結果になると思う(自信はない)。
Windows の amd64 も LLP64 だからちがうかな。

型名は、1〜3 文字に省略したけどわかるよね。

## ( left + right )

まずは加算。

|left＼right|c|uc|sc|s|us|i|ui|l|ul|ll|ull|f|d|ld|
|:--|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|c|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|uc|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|sc|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|s|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|us|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|i|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|ui|ui|ui|ui|ui|ui|ui|ui|l|ul|ll|ull|f|d|ld|
|l|l|l|l|l|l|l|l|l|ul|ll|ull|f|d|ld|
|ul|ul|ul|ul|ul|ul|ul|ul|ul|ul|ull|ull|f|d|ld|
|ll|ll|ll|ll|ll|ll|ll|ll|ll|ull|ll|ull|f|d|ld|
|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|f|d|ld|
|f|f|f|f|f|f|f|f|f|f|f|f|f|d|ld|
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|ld|
|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|

四則演算は全部これ。
シフト以外のビット演算も同じだと思う。

見どころは `ul()+ll()` が `ull` になるところ。

## ( left << right )

続いてシフト。

|left＼right|c|uc|sc|s|us|i|ui|l|ul|ll|ull|
|:--|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|c|i|i|i|i|i|i|ui|l|ul|ll|ull|
|uc|i|i|i|i|i|i|ui|l|ul|ll|ull|
|sc|i|i|i|i|i|i|ui|l|ul|ll|ull|
|s|i|i|i|i|i|i|ui|l|ul|ll|ull|
|us|i|i|i|i|i|i|ui|l|ul|ll|ull|
|i|i|i|i|i|i|i|ui|l|ul|ll|ull|
|ui|i|i|i|i|i|i|ui|l|ul|ll|ull|
|l|i|i|i|i|i|i|ui|l|ul|ll|ull|
|ul|i|i|i|i|i|i|ui|l|ul|ll|ull|
|ll|i|i|i|i|i|i|ui|l|ul|ll|ull|
|ull|i|i|i|i|i|i|ui|l|ul|ll|ull|

シフトの場合は、右辺は結果の型に影響を与えない。

## ( cond ? left : right )

続いて条件演算。

|left＼right|c|uc|sc|s|us|i|ui|l|ul|ll|ull|f|d|ld|
|:--|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|c|c|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|uc|i|uc|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|sc|i|i|sc|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|s|i|i|i|s|i|i|ui|l|ul|ll|ull|f|d|ld|
|us|i|i|i|i|us|i|ui|l|ul|ll|ull|f|d|ld|
|i|i|i|i|i|i|i|ui|l|ul|ll|ull|f|d|ld|
|ui|ui|ui|ui|ui|ui|ui|ui|l|ul|ll|ull|f|d|ld|
|l|l|l|l|l|l|l|l|l|ul|ll|ull|f|d|ld|
|ul|ul|ul|ul|ul|ul|ul|ul|ul|ul|ull|ull|f|d|ld|
|ll|ll|ll|ll|ll|ll|ll|ll|ll|ull|ll|ull|f|d|ld|
|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|ull|f|d|ld|
|f|f|f|f|f|f|f|f|f|f|f|f|f|d|ld|
|d|d|d|d|d|d|d|d|d|d|d|d|d|d|ld|
|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|ld|

第二項と第三項が同じ型だとその型になる。

見どころは、`cond ? c() : sc()` が `i` になるところ。

かな。
heroku rake db:migrateでエラーが出た時の対処


プログラミング初心者で勉強中の身ですが、ググってもなかなか情報が出なかったので報告します。

## 環境
Mac OS X
Ruby:　2.7.1
Rails:　6.0.3.4
heroku stack: heroku-20(エラーが出た時)
DB: MYSQL
## 起こったこと
https://qiita.com/murakami-mm/items/9587e21fc0ed57c803d0
こちらの記事を参考にherokuへのデプロイを試みたところ、



``` console:console
$ heroku rake db:migrate
```

を実行した時に

```console:console
Mysql2::Error::ConnectionError: SSL connection error: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
```
とエラーが出た。

## 原因・対処

###原因
自身の環境でこのエラーが起きた原因は二つ

➀heroku stackが heroku-20であった
➁config/database.ymlに必要な記述が無かった

###対処

➀heroku stackが heroku-20であった
→heroku-18を利用できるようにする

```console:console
heroku stack:set heroku-18 -a <app name>
```

➁config/database.ymlに必要な記述が無かった
productionに以下のコードを追加

```config/database.yml
production:
  url: <%= ENV['DATABASE_URL'] %>
```

##理由
きちんとした理由は随時募集しています。。誰か教えてください。。

➀heroku stackが heroku-20であった
　heroku-20に変わることで出てきた、書くべき必要な処理が書けていなかった？
　→これまでのheroku-18にすることでとりあえず解決

➁config/database.ymlに必要な記述が無かった

config/database.ymlにはこんな記述があるらしいです(自分は何故か消えていた)

```config/database.yml

# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
```

特に今回は後半の記述が大切で

```config/database.yml
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
```
雑に和訳すると

「Herokuや他のプラットフォーム上で、あなたは環境変数の形で様々なURLをもらえるでしょう。こんなかんじで：
DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
あなたはこのデータ構成をこのように使えます
production:
     url: <%= ENV['DATABASE_URL'] %>」

要はこの記述が無かったことで、どこのデータベースを使えばいいか分からずにエラーが出ていた。

##まとめ
何かおかしいことが起こり、ググっても分からないときは使っているもののバージョンを確認してみよう！

読んでいただきありがとうございました。
spring boot ポート重複問題

spling bootのポート重複エラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935036/5e70133d-a2b6-8634-555d-195b84f49042.png)

これの解決方法

１コマンドプロンプトで以下の画像のように"netstat -nao | find "8080"と検索する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935036/82738a27-77c0-b9d4-df9c-51949cee7d86.png)

2 コマンドプロンプトの検索結果で出てきた　listening の右の番号（下の画像では　19356）を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935036/454a1e44-0d5c-3791-8798-a3f8cc2067e7.png)

を　PIDにもつ"java.exe"をタスクマネージャーで調べて、タスクを切る。

これで解決しました
[Python] 動的計画法 ナップザック問題

#[AOJ Knapsack Problem](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_1_C&lang=jp)

#個数制限なしのナップサック問題
価値が $v_i$ 重さが $w_i$ であるような $N$ 種類の品物と、容量が $W$ のナップザックがあります。

次の条件を満たすように、品物を選んでナップザックに入れます：

最適化問題に適用する場合、一般的に、以下の2つが適用する問題に成立していないといけない:

* 選んだ品物の価値の合計をできるだけ高くする。
* 選んだ品物の重さの総和は $W$ を超えない。
* 同じ種類の品物はいくつでも選ぶことができる。

価値の合計の最大値を求めてください。

#問題の解法


動的計画法による外部設計は次のようになります。

$dp[i+1][j]$の定義：
$i$ 問目までの品物から重さの総和が$j$以下となるように選んだときの、価値の総和の最大値とする。

dp初期条件：

```math
dp[0][j]=1
```

dp漸化式の定義：

```math
dp[i+1][j]=max\{dp[i][j-k×w[i]]+k×v[i] \}
```

これだと三重ループになってしまうため、計算量は $O(nW^2)$ となり、タイムオーバーです。漸化式の式変形を行うことで $k$ のループをなくすことができ、計算量を $O(nW)$ とすることができます。この変形は情報処理における重複計算を省く目的です。理解の仕方としては、$dp[i+1][j]$ を求めるには一段手前の $dp[i][*]$ からではなく、$dp[i][j]$ と $dp[i+1][j-w[i]]+v[i]$ を見れば十分ということであり、逆にループを回すということでもあります。蟻本の解説が分かり易いです。

dp漸化式の変形：

```math
dp[i+1][j]=max(dp[i][j], dp[i+1][j-w[i]]+v[i])
```

求める解：$dp[n][W]$


```python:サンプルコード
n = int(input())
w = []
v = []
for i in range(n):
    w_, v_ = map(int, input().split())
    w.append(w_)
    v.append(v_)
W = int(input())

dp = [[0] * (W + 1) for i in range(n + 1)]

for i in range(n):
    for j in range(W + 1):
        if j < w[i]:
            dp[i + 1][j] = dp[i][j]
        else:
            dp[i + 1][j] = max(dp[i][j], dp[i + 1][j - w[i]] + v[i])

print(dp[n][W])
```
Qiitaアドカレ　DataRobot賞 結果発表

![DataRobot_LinkedIn_Personal-account_Social-media-banner_2019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837643/c12e4c4a-c9e4-94e3-42cd-41de7da7e271.png)

Qiitaアドベントカレンダー

[機械学習の自動化プラットフォームDataRobotを使って楽しむ冬のイベント予測チャレンジ 【PR】 DataRobot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/datarobot)

に参加させていただいた　機械学習の自動化プラットフォーム　DataRobotのコミュニティマネージャの @mana_robot です

本日(1/15)に結果を発表させいただきました！

* DataRobotデータサイエンス賞
* DataRobot優秀賞
* DataRobot最優秀賞

## テーマ：冬ならではのテーマで機械学習モデルを試そう

■プレゼント

* iPad Air 256 GB WiFiモデル（1名様）
* NVIDIA Jetson Xavier NX 開発Kit （1名様）
* 機械学習書詰め合わせ（1名様）


## DataRobotデータサイエンス賞

DataRobot データサイエンティスト・Kaggle  Grand Masterによる推薦機械学習書詰め合わせ（1名様）

* 統計的学習の基礎―データマイニング・推論・予測― (日本語) 単行本–」
* オライリーの機械学習関連書書籍

[【DataRobot】顕微鏡画像から粒子数を推定するAIを教師データから作ってみた](https://qiita.com/kon2/items/fcbc43d0d95f39097ce5) @kon2

DataRobotで画像が扱える　Visual AIの機能を応用し、顕微鏡画像の中にある、粒子数を機械学習を使ってカウントする記事です。
実務でも応用ができるとのことで、弊社のデータサイエンティストから評判の良かった記事でした。

##DataRobot優秀賞

NVIDIA Jetson Xavier NX 開発Kit （1名様）

[【DataRobot】しゃぶしゃぶ用のお肉の部位を分類](https://qiita.com/zakuzakuzaki/items/c5f577fd6559ac6427ef) @zakuzakuzaki 

DataRobotのVisualAIを使って、しゃぶしゃぶのロースとバラ肉を判定する記事です。
身近なテーマですが、うまくVisual AIの機能を使っていただき、記事を書くためにしゃぶしゃぶを食べに行っていただいたりありがとうございました！

##DataRobot最優秀賞

iPad Air 256 GB WiFiモデル（1名様）

[AutoMLでおせちの価格予測&GANで非実在おせちを作る](https://qiita.com/resnant/items/75543fb5047e90dd8202) @resnant

おせちと元旦(GAN)をかけて、DataRobotだけでなく、GANを使って画像生成も含めて本格的な記事をかいていただきありがとうございました！

GAN ... Generative Adversarial Network

###たくさんの投稿ありがとうございました！

![スクリーンショット 2021-01-15 20.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837643/a7cc320e-328a-7b49-9eaf-ff1fd8f6349f.png)


機械学習のテーマの決定、データ収集、モデル構築と、かなりの手間のかかるテーマでしたが、たくさんの方に[DataRobotフリートライアル版](https://www.datarobot.com/jp/trial/)を利用して、記事を書いていただきありがとうございました！

テーマが冬の風物詩でしたので、１２月の投稿期間を経て、イベントやテレビ番組の放送後に答え合わせもできる、二度楽しい企画でした。

受賞記事以外にも参考になる記事がたくさんございます！ぜひご覧ください。

[機械学習の自動化プラットフォームDataRobotを使って楽しむ冬のイベント予測チャレンジ 【PR】 DataRobot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/datarobot)
シンボルファイル(.pdb)をデバッグ前にダウンロードする

Visual Studioでデバッグする際、シンボルファイルのダウンロードで待たされる時があります。(特にWindows Update後)

事前にシンボルファイルをダウンロードしておけば、待ち時間を減らすことができます。

[SymChkコマンド](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symchk-command-line-options)を使えばコマンドラインからシンボルファイルをダウンロードすることができます。

SymChkコマンドはWindows Software Development Kitに含まれてるので、デバッグするPCにはインストールされているかと思います。

ダウンロード対象は、基本的に下記のオプションを指定することになります。

- 実行中のプロセス名指定(例:`/ie notepad.exe` または `/ip 1000`)
- ファイルまたはディレクトリパス指定(例:`/ie C:\Windows\system32\*.dll`)
- テキストファイル(例:`/it TextFileList.txt `)

事前にダウンロードするので、なるべく多くのシンボルファイルをダウンロードしておきたいですが、ワイルドカードですべて取得しようとすると使用する可能性が低いファイルも含まれ、大量にダウンロードすることになるため、サーバー負荷やディスク容量的に嬉しくありません。

そこで、実行中の`explorer.exe`を指定することで、常用するDLLは大体カバーできます。  
(ただし、WOW64のDLLは読み込まれないので、この記事の方法ではダウンロードされません。)

## 設定

タスクスケジューラーにタスクを追加します。
`c:\symbols`は環境に合わせて変更する必要があります。

- 全般
    - タスクの実行時に使うユーザーアカウント: ユーザーがログオンしているときのみ実行する
- トリガー
    - タスクの開始: ログオン時
    - (必要に応じて)遅延時間を指定する: 15分間
- 操作
    - プログラム/スクリプト: `"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symchk.exe"`
    - 引数の追加: `/ie explorer.exe  /s srv*c:\symbols*https://msdl.microsoft.com/download/symbols`

タスク内でUIセッションにアクセスすることになるため、ログオンしている時だけ実行するようにします。
fasttext の get_sentence_vector の結果を get_word_vector を使って表す

## get_sentence_vector と get_word_vector の関係

fasttext の `get_sentence_vector` を使って得られた値は、出現する単語についての `get_word_vector` の平均とは異なります。具体的には、単語のベクトルに対し、L2ノルムで正規化し、その平均をとったものに、改行文字（終端文字）のベクトルを加算したものが`get_sentense_vector` の出力になります。

このあたりのissueやコードに記載されている内容です。
https://github.com/facebookresearch/fastText/issues/323
https://github.com/facebookresearch/fastText/blob/26bcbfc6b288396bd189691768b8c29086c0dab7/src/fasttext.cc#L474


## コードで確認する

実際にコードで確認します。まずは学習済みモデルをDLします。

```python
import fasttext.util
fasttext.util.download_model("ja", if_exists='ignore')
```

モデルを読み込み、適当な文章のベクトルを取得してみます。

```python
import fasttext
import numpy as np

ft = fasttext.load_model('cc.ja.300.bin')
sentence = ["月", "きれい", "です"]

sentence_vector = ft.get_sentence_vector(" ".join(sentence))
print(sentence_vector[:10])
```

出力結果はこうなります。

```
[ 0.00897631  0.00557499  0.1755976   0.06277581  0.04944817  0.00894921
 -0.00580985 -0.03669543 -0.02011267 -0.03041974]
```

続いて、`get_word_vector` を使って同じベクトルを構築してみます。少々ややこしいですがこんな感じ。

```python
v = np.sum([i / np.linalg.norm(i) for i in map(ft.get_word_vector, sentence)], axis=0) / len(sentence) + ft.get_word_vector("/n")
print(v[:10])
```

少し計算誤差が生じていますが、ほぼ同値です。

```
[ 0.0089763   0.00557499  0.17559756  0.06277581  0.04944817  0.00894922
 -0.00580985 -0.03669542 -0.02011267 -0.03041972]
```

念の為、値が一致しているかを確認しておきます。

```python
print(all(np.isclose(sentence_vector, v, rtol=1e-06, atol=1e-08)))
```

```
True
```
Alpine Linux 3.13 インストール、日本語入力

* https://note.com/usuha/n/n208a51e4c4cd

で良いと思います。

![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/ac5d8e4a-faf3-d7ae-3ee3-0033908f10ae.png)


## isoダウンロード

https://alpinelinux.org/downloads/

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/e28171a9-8dd9-22f8-f684-386facf7b858.png)


## isoから起動

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/d18d745e-0382-f632-0dfe-711a2b3a844e.png)

* ログイン
    * root
* `setup-alpine`
    * jp
    * (enter連打)
    * Asia/Tokyo
    * openssh
    * (diskの選択) `sda` `sys` `y`
    * reboot

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/fb39e776-7743-23c9-8e61-d53eeaf2651e.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/0165bc88-1a67-b006-981f-120fadc240a0.png)

## DISKから起動

* root でログイン

* vi /etc/apk/repositories

```sh
sed -i -e 's/^#http/http/g' /etc/apk/repositories
```

```sh
apk update
```

```sh
apk add \
 ibus-anthy \
 dbus-x11 \
 zenity
```

### ibusの設定

```sh:~/.ashrc
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
```

### xorg

```sh
setup-xorg-base
```

```sh
apk add slim 

rc-update add slim
rc-update add dbus
rc-update add udev
```

```sh
reboot
```

![slim.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/f822e779-dc00-9ad0-4d56-53b162b2bba6.png)


```sh
apk add xfce4 xfce4-terminal
apk add faenza-icon-theme
```

### virtualbox-guest-additions

```sh
apk add xf86-video-vboxvideo
apk add xf86-video-vesa
apk add xf86-input-synaptics

apk add virtualbox-guest-additions
rc-update add virtualbox-guest-additions default

echo vboxpci >> /etc/modules
echo vboxdrv >> /etc/modules
echo vboxnetflt >> /etc/modules
```

自分のvirtualboxだと `xf86-video-intel`を入れるとslimが起動しなかった。

### 日本語入力

```sh
apk add font-noto-cjk
apk add font-noto-cjk-extra

apk add setxkbmap
setxkbmap jp
```

`contrl-J`で日本語入力開始

### ibus-daemon の自動起動

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/280245cf-0b76-9188-8d23-8af2200de91e.png)

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/5f24e5a4-1760-3ec0-0220-ffdeb61cb688.png)
NotesデータベースをMicroSoft Accessで作ってみる（年齢計算）

（[前回の内容](https://qiita.com/NomuSunder/items/ec2d02f3a4377fe8b51d)）自分の端末にMicroSoft Accessがインストールされていることを知り、Access VBAに挑戦を決意。自分の分野であるHCL Notesの開発言語もBASIC言語であることから、Notesでモックアップを作成してNotesとAccess VBAを対比させて演習を進めることに。作成するのは社員情報データベース。今回から、Access側の開発に入ります。

#今回、挑戦すること
1. 生年月日フィールドに日付を入力すると、年齢を自動計算させる。（フィールドのイベントトリガーの確認）
2. 生年月日フィールドに入力がない状態で保存するとき、メッセージを表示させる。（フォームのイベントトリガーの確認）
3. 自動的に、今日の日付と生年月日を突き合せて年齢の更新を行う。（スケジュールエージェントの確認）

###参考文献
[MicroSoftのヘルプ情報](https://docs.microsoft.com/ja-jp/office/client-developer/access/access-home?redirectedfrom=MSDN)

##生年月日フィールドに日付を入力した後、年齢を自動計算させる。

フィールドのイベントトリガーは、NotesもAccessも大差はない。
![Hikaku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983034/f49c67cc-4fc5-ed3a-8a8e-d1603112b9fe.png)

###Lotus Scriptの場合
```VB
Sub Exiting(Source As Field)
	
'現在の画面を取得
	Dim workspace As New NotesUIWorkspace
	Dim uidoc As NotesUIDocument
	Set uidoc = workspace.CurrentDocument
	
'誕生日と今日の日付を取得
	Dim birthday As New NotesDateTime(uidoc.FieldGetText("BirthDay"))
	Dim nowday As New NotesDateTime( "Today" )	
	
'今日と誕生日の差分を計算
	Dim y ,m As Integer	
	Dim age As Integer
	y = Year(nowday.LSLocalTime) - Year(birthday.LSLocalTime)
	m = Month(nowday.LSLocalTime) - Month(birthday.LSLocalTime)
	
	If m < 0 Or (m = 0 And Day(nowday.LSLocalTime) < Day(birthday.LSLocalTime)) Then
		age = y - 1
	Else
		age = y
	End If	
'年齢に計算結果をセット
	Call uidoc.FieldSetText ( "age", Cstr( age ) )	
End Sub
```

###Access VBAの場合
```VB
Private Sub BirthDay_LostFocus()
    Dim y, m As Integer
    Dim age As Integer

    y = Year(Now) - Year(Me.BirthDay)
    m = Month(Now) - Month(Me.BirthDay)
    
    If m < 0 Or (m = 0 And Day(Me.BirthDay) < Day(Me.BirthDay)) Then
        age = y - 1
    Else
        age = y
    End If    
    Me.age = CStr(age)
End Sub
```

Lotus ScriptとAccess VBAを比較すると、自分自身を取得する方法が異なることが分かりました。それから、Lotus Scriptでは日付型にパラメータが必要ですが、Access VBAにはパラメータがありませんでした。
コードの構成はそのまま書けたので、お作法さえ押さえれば苦労はしないかも？

##生年月日フィールドに入力がない状態で保存するとき、メッセージを表示させる。
フォームのイベントトリガーも、NotesもAccessも大差はありませんでした。
（フォームのイベントは、NotesもAccessも数が多すぎて１画面に収まらないため、画像は省略）

###Lotus Scriptの場合
```VB
Sub Querysave(Source As Notesuidocument, Continue As Variant)
	If Source.FieldGetText("BirthDay") = "" Then
		Msgbox "生年月日の入力がありません", 16, "入力チェック"
		Continue =False
	End If
End Sub
```
###Access VBAの場合
```VB
Private Sub Form_BeforeUpdate(Cancel As Integer)
    If (IsNull(Me.BirthDay)) Or (Me.BirthDay.Value = "") Then
        MsgBox "生年月日の入力がありません", 16, "入力チェック"
        Cancel = True
    End If
End Sub
```

Acess VBAは、Microsoftの[BeforeUpdate イベント](https://docs.microsoft.com/ja-jp/office/vba/api/access.form.beforeupdate-event)の解説を参考にしました。

ここでも、Meキーワードが使用されています。フロントエンドの処理はLotus Scriptよりも簡潔にコードが書けそうです。また、Me.BirthDay.Value の .value は省略しても問題なく動作しました。Lotus Scriptよりも細かい作法に気を使わなくても動作はするという印象を受けました。（もっとも、その分だけバグを見逃しがちになりそうですが…。）


※「自動的に、今日の日付と生年月日を突き合せて年齢の更新を行う。」は次の記事にまわします。
複数ファイルを1回でrsyncする

## --files-fromオプション
- rsyncしたいファイル名を改行区切りでテキストファイルに記載
- そのテキストファイルを指定して、1回のrsyncコマンドで送信する
- **rsyncしたいファイルは同一のディレクトリに格納されている必要がある。**

## 準備
/path/to/images.txtにファイル名を入力(改行で区切る)

```:images.txt
file1.png
file2.png
file3.png
```
## 実装 
※送信元のディレクトリにimages.txtに記入したファイルがあることを確認

```php
$images = '/path/to/images.txt'
$src_path = '/path/to/src/';
$tar_path = '/path/to/tar/';
$rsync_host = 'ユーザ名@送信先IPアドレス';

$command = "rsync -av --files-from=".$images." ".$src_path." ".$rsync_host.":".$tar_path;
exec ( $command, $output, $ret );
if($ret == 0) {
   return true;
} else {
   return false;
}
```
apacheのMaxRequestWorkers を設定して同時接続対策をする

## 概要
同時アクセス対策として、apacheの`MaxRequestWorkers`を増やす対策が可能です。
apacheのバージョン2.4系の場合は`MaxClients`ではなく`MaxRequestWorkers`という表現が使われています。

### エラーログの確認
まず、apache同時接続によるボトルネックがあるか確認します。

```sh
cat /var/log/htttpd/error_log |grep MaxRequestWorkers
[Fri Jan 15 01:35:27.458186 2021] [mpm_event:error] [pid 38749:tid 140604360575296] AH00484: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
```

### 原因
MaxRequestWorkersの制限によって、requestに対応するworkerが割り当てられず、requestの処理が遅くなっている状態です。

### MPM の確認
ApacheのMPM(Multi Processing Module)には、`prefork`,`worker`,`event`の3種類があり下記のコマンドで確認できます。

```shell
httpd -V |grep MPM
Server MPM:     event
```


### MPM Eventの場合
デフォルトの`ServerLimit`は、16です。
`ServerLimit x 25 = MaxRequestWorkers`となるように、`/etc/httpd/conf/httpd.conf`に`mpm_event_module`の`IfModule`を追記して`MaxRequestWorkers`および、`ServerLimit`を設定します。

例：
20(`ServerLimit`) x 25 = 500(`MaxRequestWorkers`)


```apache
<IfModule mpm_event_module>
    ThreadsPerChild 25
    ServerLimit 20
    MaxRequestWorkers 500
</IfModule>
```
### MPM Preforkの場合
同様に、`ServerLimit`を上げる必要があります。

## 参考
https://support.plesk.com/hc/en-us/articles/214529205-Apache-keeps-going-down-on-a-Plesk-server-server-reached-MaxRequestWorkers-setting

## メモ
同時リクエスト数をカウントするコマンド

```
netstat -an |grep -e :80 -e :443 |wc -l
```
pythonのargsortを理解するまでに時間がかかった話(備忘録)

#np.argsortをnp.sortと同じ勢いで使ったら全く違うよね

下の画像がすごく参考になった

![argsort.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667059/b4a83903-eaaf-84ba-ed40-0eb4b85e9fe0.png)

てっきりarrayの順番が返ってくると思ってた(上の写真なら[1,2,0])から、かなり混乱したけど勘違いだった。

参考
https://www.headboost.jp/numpy-argsort/
CodePipelineのbuildのレビューを一気に承認したい

# 起きた状況
stg環境での作業が終わり、いよいよ本番の準備をしようとなり、本番のcodepipelineを見ると、ビルドのレビューを一つも承認してなくて、一つ一つ承認していかないといけない、、
先輩に聞くと解決方法を教えていただいたので、メモがわりに記載
# 解決方法
流れ
編集→そのまま保存→変更をリリースする→レビューを承認

パイプライン内の
![スクリーンショット 2021-01-15 16.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624073/6a9d0053-6dbc-9523-dd8c-e22683ee4707.png)
編集で
![スクリーンショット 2021-01-15 16.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624073/b702de54-975e-c974-5699-117dde7adec8.png)
何も変えずに保存
![スクリーンショット 2021-01-15 16.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624073/3ca6d497-9b96-3f8c-9b9a-23343256991d.png)
変更をリリース
![スクリーンショット 2021-01-15 16.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624073/1af826a6-6f83-57f1-aa09-187fbaee817f.png)
最後にレビューを承認
AS400メモ：CRTMNU で作ったと思われるメニューの設定が知りたい

あんまりQiitaの使い方に慣れていないので
[ CRTMNU で作ったと思われるメニューの設定が知りたい - Qiita ](https://qiita.com/moitaro/questions/3769eee89808ffc53c68)
に書いてしまったのですが
やっぱり記事の方が自分が落ち着くし後で見やすいと思ったので記事に書きます。

Q&Aだとたまにアクセス失敗しますし……なので↓に上記質問を貼り付け失礼します。

EDTMNUみたいな命令は無いのかな……



### 解決したいこと
現在社内AS400上でシステムが動作しています。

ログインするとすぐメニュー画面に行くのですが
その際どういう設定でメニューに行っているか知りたい。

テストのため自分でPUB400.com上で
CRTMNUとしたがまずTYPEが分かりません……
*PGMだと

```as400
                              Create Menu (CRTMNU)

 Type choices, press Enter.

 Menu . . . . . . . . . . . . . . MENU         > MOITEST
   Library  . . . . . . . . . . .                  *CURLIB
 Menu type  . . . . . . . . . . . TYPE         > *PGM
 Program  . . . . . . . . . . . . PGM            *MENU
   Library  . . . . . . . . . . .                  *LIBL
 Current library  . . . . . . . . CURLIB         *NOCHG
 Product library  . . . . . . . . PRDLIB         *NOCHG
 Replace menu . . . . . . . . . . REPLACE        *YES
 Text 'description' . . . . . . . TEXT           *SRCMBRTXT                     

```
と表示され
*DSPFだと


```
                              Create Menu (CRTMNU)

 Type choices, press Enter.

 Menu . . . . . . . . . . . . . . MENU         > MOITEST
   Library  . . . . . . . . . . .                  *CURLIB
 Menu type  . . . . . . . . . . . TYPE         > *DSPF
 Display file . . . . . . . . . . DSPF           *MENU
   Library  . . . . . . . . . . .                  *LIBL
 Message file . . . . . . . . . . MSGF           *MENU
   Library  . . . . . . . . . . .                  *LIBL
 Command line . . . . . . . . . . CMDLIN         *LONG
 Display function keys  . . . . . DSPKEY         *NO
 Current library  . . . . . . . . CURLIB         *NOCHG
 Product library  . . . . . . . . PRDLIB         *NOCHG
 Replace menu . . . . . . . . . . REPLACE        *YES
 Text 'description' . . . . . . . TEXT           *SRCMBRTXT                     
```

と表示されます。

現在業務で使用しているシステムが
*PGMか*DSPFだと思うのですがどちらを利用しているのか分かりかねるので
設定を知りたいと思っております。

そのようなコマンドは無いのでしょうか？？？


### 自分で試したこと
コマンド入力の所で　F4を押下しメジャー・コマンド・グループ　で
EDTMNU　みたいなの無いかな？と探したり
グーグルさんで調べたりしたのですが見つけられませんでした。
Nuxt.js（Vue）でイベントの構造化データ マークアップの書き方と例

Nuxt.js（vue）でイベントの構造化データ マークアップの書き方と例になります。
JSON-JDやmicrodataと言った書き方がありますが、本記事ではJSON-JDの例になります。

## Nuxt.js（Vue）でイベントの構造化データ マークアップの書き方

```vue
<script>
export default {
  head() {
    return {
      __dangerouslyDisableSanitizers: ['script'],
      script: [
        {
          innerHTML: `{
            "@context": "http://schema.org",
            "@type": "Event",
          }`,
          type: 'application/ld+json'
        }
      ]
    }
  }
}
</script>

```

headの中に記載していきます。

## Nuxt.js（vue）でイベントの構造化データ マークアップの例
```vue
<script>
export default {
  data() {
    return {
      name: 'demo',
      description: 'demo',
      img: 'https://demo.jp/demo.jpg'
    }
  },
  head() {
    return {
      __dangerouslyDisableSanitizers: ['script'],
      script: [
        {
          innerHTML: `{
            "@context": "http://schema.org",
            "@type": "Event",
            "name": "${this.name}",
            "description": "${this.description}",
            "startDate": "2021-01-28T15:00+09:00",
            "endDate": "2021-01-28T18:00+09:00",
            "eventAttendanceMode":
              "https://schema.org/OfflineEventAttendanceMode",
            "eventStatus": "https://schema.org/EventScheduled",
            "location": {
              "@type": "VirtualLocation",
              "url": "https://demo.jp"
            },
            "offers": {
              "@type": "Offer",
              "price": "0",
              "priceCurrency": "JPY",
              "url": "https://demo.jp",
              "availability": "http://schema.org/InStock",
              "validFrom": "2021-01-24T10:00+09:00"
            },
            "performer": {
              "@type": "PerformingGroup",
              "name": "${this.name}"
            },
            "organizer": {
              "@type": "Organization",
              "name": "demo",
              "url": "https://demo.jp"
            },
            "image": "${this.image}"
          }`,
          type: 'application/ld+json'
        }
      ]
    }
  }
}
</script>
```

上記がNuxt.js(Vue)イベントの構造化データ マークアップの例になります。
構造化データについては、下記が参考になります。
[https://developers.google.com/search/docs/data-types/event?hl=ja](https://developers.google.com/search/docs/data-types/event?hl=ja)
Jenkins+CapistranoでUser credentialをデプロイ先へ渡す

# Capistranoで実行元の環境変数をデプロイ先へ送るにはどうすれば良いか?

`direnv`で`Access token`をセットして使うなどは`AWS CLI`の常套手段だったりします。
また環境変数にUser credentialを保持させるのはわりとある手段です。

Credentialには `username`, `password`, `access token`, ... と沢山あります。
これをデプロイ先でも使いたい場合のお話です。

## Jenkins User Handbookを読む

[Jenkins User Handbook](https://www.jenkins.io/doc/book/ ) にドンピシャに書いてあったりします。

- [Handling Credentials - Using a Jenkinsfile](https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#handling-credentials )

これで`pipeline`-`stage`-`steps`の中で参照できます。

このセクションにはもうひとつのやり方が記述されています。
JenkinsにCredential情報を持たせることができますよね。(GUIで操作するヤツです)
アレを参照できるんです。

[Usernames and passwords - Using a Jenkinsfile](https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#usernames-and-passwords )


ただちょっとトリッキーなので解説。

1. `hoge_credential`として登録します
2. `Jenkinsfile`に使うように指示を追加します。
3. 参照する時
 - user: `USER_CREDENTIAL_USR`
 - password: `USER_CREDENTIAL_PSW`

`Jenkinsfile`のサンプル

```groovy:Jenkinsfile
pipeline {
    environment {
        USER_CREDENTIAL = credentials('$hoge_credential')
    }
}
```

こうなります。

## Capistranoから環境変数をリモートへ送る


`Jenkinsfile`の中で参照できましたので`Capistrano`からも`ENV`として参照できます。


先程の`USER_CREDENTIAL`で書くと、

```ruby:deploy.rb
namespace :deploy do
  tasks :sample-task do
    on roles(:app) do
      with hoge_user: ENV['USER_CREDENTIAL_USR'] do
        with hoge_passwd: ENV['USER_CREDENTIAL_PSW'] do
          capture(:echo, '--user=$HOGE_USER', '--password=$HOGE_PASSWD')
        end
      end
    end
  end
end
```

となります。
【vscodeで xdebug 3.0 × PHP × Docker】

### 【ディレクトリ構造】

```
.docker-practice
├── html
│   └─ arraypractice.php // デバックするファイル
├── php
│   ├── Dockerfile
│   └── php.ini
└── docker-compose.yml
```

### 【最終的なコードと設定】
#####docker-compose.yml
追記 versionを2.0 -> 3.8 にした。（特に書き方は変わらず、いくつかoptionがなくなっただけ）

```yml:docker-compose.yml
version: '3.8'
services:
	php:
    　build: ./php
    　ports:
        - '80:80'
    　volumes:
        - ./html:/var/www/html
        - ./php/php.ini:/usr/local/etc/php/php.ini
```
* * *
#####phpディレクトリ内のDockerfile
( ```build: ./php``` にあたるファイル)

```dockerfile:Dockerfile
FROM php:7.4-apache
# php.iniをdockerコンテナ内にコピって設置している
COPY php.ini /usr/local/etc/php/
# xdebugのinstallと設定に必要なzend_extensionを生成している
RUN pecl install xdebug \
  && docker-php-ext-enable xdebug
  # /usr/local/etc/php/conf.d/docker-php-ext-xdebug.iniに
  # zend_extension = ~ 出力される
```

* * *
#####php.iniにxdebug3.0の設定を追加

```ini:php.ini
[xdebug]
xdebug.mode=debug
xdebug.start_with_request = yes
; host.docker.internalはdockerのhostマシンのIPを解決してくれる。
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
```
* * *
#####vscodeのlaunch.json

`port`はphp.iniの`xdebug.client_port`に合わせる
`pathMappings `は、`'dockerコンテナ側ルートディレクトリ' : 'vscode側ルートディレクトリ'`の構成

```json:launch.json
{
 "version": "0.2.0",
 "configurations": [
     {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9003, 
      "pathMappings": {
         "/var/www/html": "${workspaceRoot}/html"
      }
     }
 ]
}
```
* * *
#####実行
./html直下のデバッグしたいファイルにブレークポイントをつけて、
緑の三角ボタンで実行するとvscodeの下の部分がオレンジになる。
その状態で、ブラウザでreloadすればbreakpointで止まってくれて、変数なんかもVARIABLESに表示される。
（21行目ではちゃんとksort後の$arrayが表示されている。）
![800A6CDE-D918-45F0-A97C-D189623072C2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530710/362c8c58-8ad7-2806-cd8d-eafdafb99bcf.jpeg)


## 【こういったコードになった経緯】

１，最初はdockerコンテナに入って、`pecl install xdebug` でxdebugをinstallしようとしたらphpのvarsionが7.2以上にするようにエラーが出たのでDockerfileのイメージを7.0→7.4にした。

２，とりあえずphpinfo()にxdebugの項目がでるようにしたかったが、
`docker-php-ext-enable xdebug` で `zend_extensin = ~` を作らないと表示されなかったので追加した。
また、buildしなおすたびにxdebugをinstallし直すのは面倒なのでDockerfileのRUNコマンドで実行できるようにした。

３，php.iniについては、 `xdebug.start_with_request = yes` がないとbreakpointで止まってくれなかった。

４，vscodeのlaunch.jsonは、pathMappingsは最初意味がわからず、
"./html" : "{workspaceRoot}" みたいにしてたが、dockerコンテナ側のルートディレクトリ : vscode側のワークスペースだとわかって変更。
jQuery MigrateでjQueryのバージョンアップとエラーチェック

#概要
**jQueryv3.2.1→v3.5.1**にバージョンアップ（アップグレード）したときのメモです。
jQuery Migrateを使ってエラーや非推奨APIのチェックをします。

#jQuery Migrateとは
バージョンアップに伴って削除・変更された関数などの動かなくなった部分の補完をし、コンソールに表示して教えてくれるプラグインです。どこを修正すればよいのかが分かります。

- [Github - jquery/jquery-migrate](https://github.com/jquery/jquery-migrate/)

また、jQuery3.0にバージョンアップするには1.12.xまたは2.2.xが必要です。
（参考：[jQuery Migrate が便利](https://ararabo.com/2019-07-13/?p=9681)）

今回は上記以上のバージョンでの3.xでの方法を記載します。

##使い方
まずはバージョンアップ後のjQueryを読み込みます。
その後に[jQuery Migrate](https://code.jquery.com/jquery-migrate-3.3.2.js)を読み込みます。

コンソールに警告を表示したいので、開発版（Development）を利用します。

```index.html
<script src="/scripts/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/jquery-migrate-3.3.2.js"></script>
```
　
この状態でページをブラウザで確認すると、コンソールに警告が表示されます。
`JQMIGRATE: ~~~`で表示されているのがエラーや非推奨の警告です。
![9b7567d2ca96d8ee74f4cb4038d8bb1c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655954/9bb0b922-1ce7-4cb2-4bbf-554e8cdab5fa.png)

エラーを解消したり、非推奨部分を書き換えるなどして警告が無くなればOKです。
`.hover`や`.click`などは`.on`を使った記述に書き換えました。

これで、バージョンアップは完了です。

基本的には警告を無視せずなるべく解消しておくことが大事です。
（非推奨もいつかは使えなくなるので）

一応、致命的なエラーなどで解決できない場合は製品版（Production）を使えば、**廃止された機能を復元し、呼び出してもエラーにならず正常に処理する**ことが可能です。（コンソールに表示されない）

必要に応じて使用・対応してください。

#参考
- [jQuery Migrate が便利](https://ararabo.com/2019-07-13/?p=9681)
- [jQuery Migrate 3.0.1 の使い方と警告文の自分なりのまとめ](http://myjquery.blog.fc2.com/blog-entry-36.html#message-29)
- [jQuery 便利なonを使おう（on click)](https://qiita.com/shizuma/items/d561f37f864c3ebb5096)
RSpec コントローラーテストの書き方

##前提##
・deviseが導入されています
・今回書くテストの内容について
　　・ユーザーがログインしていれば、正しく表示されること

```ruby:app/controllers/posts_controller.rb
  class PostsController < ApplicationController
    before_action: authenticate_user!

    def index
      @posts = Post.all
    end
  end
```

##ファイルの作成・役割について##
①spec配下にrequests,　factoriesフォルダを作成

・spec/requests/posts_request.rbを作成
　　→テストの内容を記述するファイル

・spec/factories/user.rb
・spec/factories/post.rbを作成
　　→userとpostに関するダミーデータを作成するファイル

②FactoryBotを使えるようにするためにspec配下にsupportフォルダとfactory_bot.rbファイルを作成

```ruby:spec/support/factroy_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Method #FactoryBotのため
  config.include Devise::Test::IntegrationHelper, type: :request #deviseのsign_inメソッドが使えるようになる
end
```

次にrails_helper.rbの編集

```spec/rails_helper.rb
require 'spec_helper'
...
require 'rspec/rails'
require 'support/factroy_bot'  #←この記述によってFactroyBotを使用できる
```
##ダミーデータの作成##

```ruby:spec/factories/user.rb
FactoryBot.define do
  factory :user do 
    email { Faker::Internet.email }
    name { "testuser1" }
    password { "password" }
    password_confirmation { "password" }
  end 
end
```

```ruby:spec/factories/post.rb
FactroyBot.defind do
  factory :post do
    body { Faker::Lorem.charactors(number: 15) } #15文字のダミー文を作成
  end
end
```

##テストコードの作成##

```ruby:spec/requests/post_spec.rb
require 'rails_helper'

RSpec.describe 'post_controllerのテスト', type: :request do
  let(:user) { create(:user) }
  let(:post) { create(:post) }
  describe 'ログイン済みの場合' do
    before do
      sign_in user
      get posts_path
    end

    it '投稿一覧ページへのリクエストは200 okとなること' do
      expect(response.status).to eq 200
    end

    it 'ページタイトルが正しく表示されていること' do
      expect(response.body).to include('投稿一覧')
    end
  end

  describe "ログインしていない場合" do
    before do 
      get posts_path
    end
    
   it 'リクエストが401となること' do
     expect(response.status).to eq 401
   end
  
   it 'タイトルが表示されない' do
     expect(response.body).to_not include("投稿一覧")
   end
  end
end
```

あとはRSpecを動かしてみるのみ！

```terminal
$ rspec spec/requests
```

###最後に###
初心者中の初心者の記事なので、十中八九ミスがあると思います。
気づかれた方がおられたら、教えていただけるととてもありがたいです！
！
ユーザーのトークンによるAPI実行

## 目次
- Keycloakでユーザー追加とユーザー属性を追加する
- 【Postmanで実行する場合】API実行
- 【エンドポイントで実行する場合】API実行

## 参考サイト
- [KeycloakとSpringBoot/SecurityでOpenID Connect(リソースサーバー編)](https://qiita.com/kasa_le/items/259792d3ae4df7f1d2b2)

## Keycloakでユーザー追加とユーザー属性を追加する
[Keycloakの操作について](https://qiita.com/nayylin/items/e9dd41d0cdf923c6d0c9) を参考し、ユーザー作成とユーザー属性の設定を行う。

## 【Postmanで実行する場合】API実行

### ①ユーザーのアクセストークンを発行する
パラメータにて、[user, password, scope]を設定し実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/b5dea9bb-5f73-e9f9-1bc6-e2973a005bdb.png)

レスポンス

```
{
    "access_token": "xxxx",
    "expires_in": 300,
    "refresh_expires_in": 0,
    "token_type": "Bearer",
    "id_token": "xxxx",
    "not-before-policy": 0,
    "scope": "openid profile email special"
}
```

### ②APIを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/ac8c3472-4e3a-18e3-cb30-e6f034f80575.png)

## 【エンドポイントで実行する場合】API実行

### ①ユーザーのアクセストークンを発行する


```
curl -X POST "http://localhost:8088/auth/realms/[作成したrealm名]/protocol/openid-connect/token" --data "grant_type=password&username={作成したユーザー名}&password={作成したユーザーのパスワード}&client_secret={clientのsecret}&client_id=boot-sample&scope=openid [スコープ名]"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/970b3278-23a2-9496-680a-acccf18ec3c2.png)

### ②APIを実行する。

```
curl -v -X GET -H "Authorization: Bearer 取得したアクセストークン" http://localhost:8080/API名
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602725/3c631f49-c979-fa78-153a-cea08e6b5ead.png)
【ミライトデザイン社内勉強会#12】「IDDD本から理解するドメイン駆動設計」輪読会~第3章「コンテキストマップ」~

### 前回の記事
[【ミライトデザイン社内勉強会#11】「IDDD本から理解するドメイン駆動設計」輪読会~第2章「ドメイン」「サブドメイン」「境界づけられたコンテキスト」を読み解く~ - Qiita](https://qiita.com/tkek321/items/71096b6404ab2091f9b1)

## [実践DDD本 第3章「コンテキストマップ」～「境界づけられたコンテキスト」の関係を俯瞰する地図～ (1/3)：CodeZine（コードジン）](https://codezine.jp/article/detail/9837)

### コンテキストマップとは
- 複数の「境界づけられたコンテキスト」間の関係を俯瞰する図で、システムの全体像や相互関係を把握する
- システム間の関係を把握できる

### 巨大な泥団子
- [大きな泥だんご - Wikipedia](https://ja.wikipedia.org/wiki/%E5%A4%A7%E3%81%8D%E3%81%AA%E6%B3%A5%E3%81%A0%E3%82%93%E3%81%94)
- レガシーなシステムにありがち
- 巨大な泥団子の中にあるクラスなどに依存してしまうと新規のシステムも泥団子の一部になってしまう
    - 泥団子の一部にならないように新規のシステムはコンテキストを泥団子から分け、泥団子とはPublished Languageのみでやりとりをして、腐敗防止層を作成するなどする

### 公表された言語（Published Language）
- 例えば、APIを叩いた時にJSONで連携するみたいな
- コンテキスト間のやりとりはPublished Languageのみで行う

### 腐敗防止層
- Adapterパターンとかを使って依存しないようにするとか？
    - というよりかはほとんどがマッピング作業になると思う
- 外からきたデータをそのまま使う前提だと、例えばJSONでnullがこない前提のデータにnullが入っていたらエラーになってしまう。
    - 不正なデータがあればエラーを出して弾くとか
    - nullを適切な値（空文字とか）に変換するしてシステムが落ちないようにするとか
- 単純に言えばマッピング作業
    - 顧客のデータがJSONで連携されたら、システムの内部で使用するモデルに変換するみたいな

### 1アプリケーションないに複数コンテキストがあってもいいが、別コンテキストの情報は使えない
- 1アプリケーション内に1コンテキストが理想ではあるけど
- 1アプリケーション内に複数コンテキストがある場合でも、コンテキスト間のやりとりはPublished Languageでのみやりとりをする
    - 別のコンテキスト内のクラスを使うことはない
        - 同じクラスを使っていると依存関係が発生してしまうので
- コンテキストはクラスのカプセル化みたいなも
    - 使う側は内部の実装をしる必要はない
    - Published Language（公表された言語）のみを知っていればいい


### コンテキストマップを書くときに、U（Upstream）とD（Downstream）以外書くことって実際あるの？例えばACLとか

> <img width="500" alt="image.png (32.9 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2021/01/07/67007/288a378e-078b-4178-bdfd-5eaa0712dc20.png">

- 認識さえ共有できていれば、書いても書かなくてもいいと思う
- 情報は多い方がいいけど、必要に応じて




### 境界づけられたコンテキスト間の連携方法を示す「統合パターン」に「共有カーネル」があるが、コンテキスト間でクラスを共有することもあるの？
- https://codezine.jp/article/detail/9837?p=2
- 基本はやらない方がいい、
- 完全に全く同じコードとかであれば、共有することもあるかも
    - でも、依存関係になってしまうので、やめた方がいい
    - 別のコンテキストで使われている可能性もあるので気軽にさわれない
    - せっかくコンテキストを分けたのに、同じ言語で書かないといけないなどの縛りも出てくる

## 次回
[【ミライトデザイン社内勉強会#13】「IDDD本から理解するドメイン駆動設計」輪読会~第4章「アーキテクチャ」~ - Qiita](https://qiita.com/tkek321/items/00686c0dd823d690e2ad)
【インフラ】whileコマンドまとめ

## 1. 基本的なwhile文

```:コマンド
while true
> do
> echo "hello world"
> sleep 1
> done
```
```:出力結果
// 実施結果
hello world  // 際限なく繰り返す
hello world
```

## ファイル検索 + 中身の文字列検索
```:コマンド
$ find ./ -type f -name "sample.txt" | while read line;
> do
> $line
> grep sample $line
> done
```

```:出力結果
./tmp/sample.txt
sample
```

## ファイル検索 + 文字列検索（検索対象一部除外）

```:コマンド
$ find ./ -type f \! \( -name "exclusion" -o "test" \) | while read line;
> do
> echo $line
> grep sample $line
> done
```

```:出力結果
./tmp/sample.txt
sample
```

## ディレクトリ情報検索
```:コマンド
$ find / -type d | xargs ls -ld | awk '{print $3,$4,$6,$9}' | sort
```
```:出力結果
root root 1月 14日 /tmp/test
```


## Vim頻出操作

```
１行目先頭：1G or gg
最終行先頭：G

カーソル行先頭：^
カーソル行末尾：$

１語次へ：w
１語前へ：b
単語末尾：e

取り消し：u

１行コピペ：yyp
複数行コピペ：10yyp

１行削除：dd
複数行削除：10dd

置換：%s/before/after/g
```
AWS IoT Coreの検証とraspberryPiとを使った空席情報表示アプリの作成


## 概要
業務内でテレビ会議用のスペースの空席情報が知りたいといった需要あったので、一つのユースケースとしてAWS IoT Coreについて検証を行いながら、RaspberryPiと組み合わせて座席の空席情報の表示ができるアプリを実際に構築してみました。アプリを構築した際の手順等のメモを各機能ごとに記載しています。

## ユースケース詳細
着座センサの付いた raspberry Pi を使って座席の空席状況を監視するアプリケーション。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/515f6767-37f9-0cf5-ba7b-bc183e6657a7.png)

デバイスから送られてきたデータに対して以下の流れで処理を行っています。
① RaspberryPiからAWS IoT Coreへのセンサーデータ送信。
② AWSの証明書を利用したデバイスの認証認可。
③ デバイスの稼働状況などの管理情報を記録。
④ IoT topicでデバイスから送られてきたデータを受信。
⑤ IoT topicで受け取ったデータにIoT ruleでデバイス管理情報等をDynamoDBから抽出して追加。
⑥ 加工したデータをIoT actionから他サービスに送信。
⑦ デバイス状態の更新。
⑧ 空席情報を判別してモニタリング用Webアプリへのデータ連携。

座席のセンサーを検知してこんな感じで画面が遷移します（画像）
![client.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/6a0f2aad-af3c-59ec-2c52-0195a8255e04.gif)



## 検証内容のメモ（リンクのURL調整中）
このアプリを作成した際の検証内容をAWS IoT Coreの各機能ごとに以下の内容で記載していきます。

- [AWS IoT Core検証メモ①:AWS IoT Core事始め](https://qiita.com/tomzono/items/9419c1197b6bff413312)
 - AWS IoT Coreの設定とデバイスの登録、デバイス側の設定とIoTCoreへのメッセージ送信について
- [AWS IoT Core検証メモ②：IoT rule について](https://qiita.com/tomzono/items/12f6253c864f8f8c4070)
 - AWS IoT Coreにデバイスからメッセージが送られてきた際のアクションの追加方法について
- [AWS IoT Core検証メモ③：IoT action について](https://qiita.com/tomzono/private/e5eb603d7f84348cc95c)
 - AWS IoT CoreからIoTactionを利用して他サービスへのデータ連携を行う際の設定方法について
- [AWS IoT Core検証メモ④：IoT shadow について](https://qiita.com/tomzono/items/d9fdf05b3acff1d04e80) 
 - AWS IoT Coreに接続しているデバイスの状態監視、デバイスへの指示をクラウドから行う方法について
- [AWS IoT Core検証メモ⑤：FleetProvisioningについて]() 
 - AWS IoT Coreへのデバイス登録を自動化する仕組みについて
- [AWS IoT検証メモ⑥ : AWSIoTを使ってみて便利だって点と気を付けるべきこと](https://qiita.com/tomzono/items/0e4c16dd7eae0cba4ccd)
 - 自分がAWS IoT Coreを使ってみて活用した方がいいと思った機能や運用上の注意点などについて
GASでスプレッドシートを操作するときに日付が合わない→タイムゾーンだ！

GASでスプレッドシートにある「日付」を扱ってる人はいっぱいいると思います。ここ、大きな罠があって、

* スプレッドシートのタイムゾーン
* スクリプトエディタのタイムゾーン

を合わせておかないと時間がズレます。1月15日を扱ってるはずなのに1月14日の数字が出てる、みたいなことが起こります。

私の手元ではスクリプトエディタのタイムゾーンが

```
"timeZone": "America/New_York",
```

になってました。


# スプレッドシートのタイムゾーン

スプレッドシートの「ファイル→Googleスプレッドシートの詳細」から設定可能

![g1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/6e27da2b-cf39-0eae-9619-ba0c6bbf9579.png)

# スクリプトエディタのタイムゾーン

2020年末にエディタが新しくなりました。旧エディタは画面から設定ができたのですが新エディタになって設定できるメニューがなくなりました。そのため 自分で「appsscript.json」を編集する必要があります。(他の方法があった教えてほしい！

スクリプトファイルの左メニュー

![menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/603f90b4-9be2-cf23-f159-ec71064c8a42.png)

「appsscript.json」マニフェストファイルをエディタで表示する をチェックします。

エディタに戻ると、`appsscript.json` が表示されるようになります。

![editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/03c5a271-d8bf-5d15-1f00-b75c97c3551e.png)


そこの `timezone` を `"Asia/Tokyo"` に変更することで日本標準時のタイムゾーンが設定されます。
AWS CLIでAmplifyのフロント環境を構築/デプロイする

# スクリプト
```bash
# フロントの成果物を"./build.zip"に固めておく

APP_ID=<Amplify APP ID>
BRANCH_NAME=<Git Branch>

# Amplifyのフロント環境を作成
aws amplify create-branch --app-id "$APP_ID" --branch-name "$BRANCH_NAME" --stage "EXPERIMENTAL"

# 手動デプロイを作成
DEPLOY_RES=$(aws amplify create-deployment --app-id "$APP_ID" --branch-name "$BRANCH_NAME")
DEPLOY_JOB_ID=$(echo $DEPLOY_RES | jq -r ".jobId")
UPLOAD_URL=$(echo $DEPLOY_RES | jq -r ".zipUploadUrl")

# 成果物をアップロード
curl -D - -X PUT --header "Content-Type:application/octet-stream" --upload-file $(pwd)/build.zip "$UPLOAD_URL"

# デプロイ開始
aws amplify start-deployment --app-id "$APP_ID" --branch-name "$BRANCH_NAME" --job-id "$DEPLOY_JOB_ID"

DEPLOY_URL=$(echo $BRANCH_NAME | sed -e s:[_/]:-:g)
# このURLで公開されてます
echo "https://$DEPLOY_URL.$APP_ID.amplifyapp.com"
```

# なんでこんなことを？
レビュー時にローカルにチェックアウトして動作確認するのが手間なので
プッシュされたらAmplifyのフロント環境をCI/CDで構築したかった

AmplifyにGithubと連携してプルリク用のプレビュー環境を作ってくれる機能があります
使える方はそちらのほうが楽です。

Enterprise版のGithubを使ってたりGitlabを使ってたりで使えない方はこんな感じでCI/CDに組み込めます。
**※このままだとプルリククローズ後も環境が残り続けるので、実際の運用はゴミ掃除も必要です**