OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】WhereHasの使い方・デメリット

## どういうときに使う？
主に「リレーション先のテーブルの条件で検索したいとき」に使います。

例えば、ユーザー情報が入った"usersテーブル"と記事の情報が入った"articlesテーブル"があるとして、「2022年6月5日以降に記事を投稿したユーザーだけを取得したい」という場合、「created_atが2022年6月5日以降の記事」を投稿した 「ユーザー」 を取得する必要が有ります。

つまり、「usersテーブル」にとってリレーション先のテーブルである「articlesテーブル」の条件（ここではcreated_atの日付）を使用してユーザーを検索する、ということになります。

こういったケースで役に立つのがWhereHasです。

## 基本の使い方
上に書いたケースでは下記のようになります。
（すでにUserモデルにリレーションメソッドが定義されている前提）
```php
$users = User::whereHas('articles', function ($q) {
     $q->where('created_at', '>=', '2022-06-05');
})->get();
```
※whereHasの第一引数にはリレーションメソッド名が入ります。

## 変数を使いたい場合
これはwhereHasに限ったことでは有りませんが、useメソッドを使用するとクロージャの中で変数が使えます。
```php
$date = '2022-06-05';
$users = User::whereHas('articles', function ($q) use ($date) {
     $q->where('created_at', '>=', $date);
})->get();
```

## 中間テーブルの条件で検索したい
上に書いたusersテーブルとarticlesテーブルの例は1対多でしたが
多対多の場合でも同じ書き方で問題ありません。
しかし、「多対多で、なおかつ中間テーブルの条件で検索したい場合」は注意が必要です。

具体的な例としては、usersテーブルとarticlesテーブル、そして、どのユーザーがどの記事にいいねを押したかを管理するための中間テーブル「likesテーブル」があるとして、「2022年6月5日以降にいいねが押された記事のみを取得したい」といったケースです。

この場合、以下のようにクロージャの中のcreated_atにテーブル名をつけてlikes.created_adとする必要があります。
（すでにArticleモデルにリレーションメソッドが定義されている前提）
```php
$articles = Article::whereHas('likes', function ($q) {
    $q->where('likes.created_at', '>=', '2022-06-05');
})->get();
```
## WhereHasのデメリット
WhereHasは動作が重いようです。
小規模サイト等では特に問題にならないかもしれませんが
大量の処理が必要になるようなケースでは避けた方がいいかもしれません。
参考になる記事様↓

https://qiita.com/hisash/items/40532808e61ed3210a6a


## 代替
下記の記事様を見て知ったのですが
一対多の場合であればWhereInで割と簡単に置き換えられますね。

https://qiita.com/semi-san/items/39c826c4a7e09b2624f0

ライブラリを作成してくださった方もいらっしゃるようです。

https://qiita.com/mpyw/items/0761a5e44836c9bebcd5
Cloudflare Load Balancing オリジンサーバーの場所（緯度経度）をもとにクライアントを誘導する機能のテスト

# Proximity Steering
## Proximity Steering とは
オリジンサーバのPoolにその緯度・経度の情報をメタデータとして追加することで、送信元IPの緯度・経度と比較し、近いところに誘導するというものです。
https://developers.cloudflare.com/load-balancing/understand-basics/traffic-steering/steering-policies/proximity-steering/
## テスト結果
Load Balancing は DNS onlyで実験
https://developers.cloudflare.com/load-balancing/understand-basics/proxy-modes/#gray-clouded-dns-only-load-balancing
### セットアップ
GCPのリージョンにオリジンを設置
![Screen Shot 2022-06-01 at 1.21.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/a376d025-7c59-36bb-8d0f-9916b25b0b4e.png)
オリジンプールを設定
![Screen Shot 2022-06-01 at 1.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/10705b70-65a7-8924-2570-56a4a86d1a51.png)

トラフィックのステアリング方式にProximity Steeringを選択し、オリジンの緯度経度を入力
![Screen Shot 2022-06-01 at 1.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/dcf1c1a4-a578-2ae6-de5b-a2715c3e7e6f.png)
Load balancing 対象のホストにDNSリクエストを発行、どのオリジンのIPが帰ってくるかを調査（Maxmindを利用し、各国のIPをランダムに選択、そのIPをEDNS0 Client Subnetに入れて、DNSリクエストを発行）
![Screen Shot 2022-06-01 at 1.22.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/91a8fe24-edb6-8898-8a67-169c49e05a8f.png)
### 結果
Maxmindの国IPの精度もあるかと思いますが、おおよそ近いオリジンに誘導されています
オリジン：東京・ロンドン・サンパウロ
https://leafletjs.com/ でプロット
![Screen Shot 2022-06-01 at 1.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/a5622ebe-4d75-4f84-bf72-93e5e2be5201.png)
Load Balancing Analytics 画面でも分布を把握することが可能です。
https://developers.cloudflare.com/load-balancing/reference/load-balancing-analytics/
![Screen Shot 2022-06-01 at 1.45.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218045/3489c8f9-a017-128c-852b-6cba1dfb5550.png)

## 補足
Pool選択メソッドとしては
Off：フェイルオーバーのプライオリティ順（例 Active-Standby）
Dynamic： ヘルスチェックでモニタしたレイテンシ
Geo： リクエストを受信したCloudfalreのデータセンター（地域・国）
Proximity： オリジンPoolの緯度経度
Random： ランダム（例 Active-Active）
があります。
https://developers.cloudflare.com/load-balancing/understand-basics/traffic-steering/steering-policies/

Pool内でのオリジン選択はこちら（Random、Hash）
https://developers.cloudflare.com/load-balancing/understand-basics/traffic-steering/origin-level-steering/

Workersでやる一例
https://blog.cloudflare.com/update-response-headers-on-cloudflare-workers/
翻訳レビュー体験記: カンバンガイド

# Summary
[カンバンガイド](https://kanbanguides.org/)の英語版から日本語版への翻訳レビューに初めて参加した際の経験を簡単にまとめました。
誰かの挑戦を後押しすることに繋がると嬉しいです。

# Who
[わたし](https://inside.dmm.com/entry/2020/08/06/yondemasu07)は、[合同会社DMM.com](https://dmm-corp.com/company/)で同人事業のエンジニアリングマネジメントに携わっています。
英語が特別に得意な訳では無く、翻訳の仕事や翻訳のレビューに携わった経験はこれまでありませんでした。

# What
無償のボランティアとして、以下3つのドキュメントの英語版から日本語版への翻訳レビューに参加させて頂きました。

* [カンバンガイド(12ページ)](https://kanbanguides.org/wp-content/uploads/2022/05/The-Kanban-Guide-Japanese.pdf)
* [カンバンガイドの定義集(11ページ)](https://kanbanguides.org/wp-content/uploads/2022/05/Definitions-for-Kanban-Guide-Japanese-1.pdf)
* [カンバンガイド 付録 実現手段と詳細説明(28ページ)](https://kanbanguides.org/wp-content/uploads/2022/06/Addendum-to-Kanban-Guide-implementation-options-details-Japanese-1.pdf)

# Why
Twitterのタイムラインに以下のツイートが流れてきました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「カンバン（Kanban）」についてのドキュメント（合計40ページくらい）について翻訳レビューをしてくださる方を募集しまーす。<br>カンバンについて詳しい人と、詳しくない人で、読みやすさとわかりやすさを中心に、できたら誤訳も見つけてくれると嬉しいです。<br>こちらから: <a href="https://t.co/Glz6dw9QQh">https://t.co/Glz6dw9QQh</a></p>&mdash; 長沢 智治【本人】 (@tnagasawa) <a href="https://twitter.com/tnagasawa/status/1516316017303367680?ref_src=twsrc%5Etfw">April 19, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実は、長沢さんのことを従来からフォローや存じていた訳では無かったのですが、他にフォローしていた方のいいねによりタイムラインで偶然発見し「こんなにカジュアルに募集されていることもあるんだ」と興味を持ち、すぐに対象のGoogleフォームから応募しました。

丁度ゴールデンウィーク前で、GW中の予定が詰まってもいなかったのでタイミングが良かったのと、カンバンに対する色々な習熟度の方を対象としている点が翻訳レビュー未経験の自分でも何か1つでも貢献できる余地がありそうと感じた事、ある程度のボリューム感が明示されていたので必要なおおよその時間が見積もれたことが応募のキッカケです。

この他、スクラムガイドは以前から馴染みがあり何回も読んだことがあったけれど、カンバンガイドは存在すら知らなかった事、普段の業務においてJiraやZenhubなどでカンバン方式を採用しているのでカンバンガイドが参考になりそうで翻訳レビューするとなると必然的に精読することになるため一石二鳥だと感じたのもモチベーションになりました。

# How
## 応募
対象のGoogleフォームに必要事項を記入し応募しました。
面識が無いため、カンバンに対する知識が垣間見える文章と英語の理解度がある程度分かるアピール文言（過去のTOEIC点数やDuolingo学習中など）を付記しました。
仮に応募者が多数だと先着順もあり得ると考え、ツイートを目にしてからすぐに応募しました（確かツイートされてから3時間以内くらい）。

## 翻訳レビュー
翻訳者の長沢さんから期待されていたことは「誤字脱字、読みやすさ、わかりやすさを中心に、できれば誤訳やもっとよい訳をコメントいただきたい」という観点でした。

最終的にはGoogleドキュメントに提案モードでコメントしていく形ですが、文章のチェック方法は自由なため、以下の形で工夫しました。

* 集中力を切らさないため、ある程度のブロック（3行程度の文）単位で進める
* [DeepL](https://www.deepl.com/translator)で原文を翻訳する
* チェック範囲の原文を全て音読する
* DeepLの翻訳結果(日本語)と、レビュー対象の文章を、全て音読する
* (意訳の場合) 表現の違いが意図的な意訳なのかどうかGoogle検索する
* 馴染みの薄い日本語だった場合に[別の辞書](https://ejje.weblio.jp/)で翻訳の候補を探す
* 前後の文と比較して抜け落ちているニュアンスが無いか考える

また、指摘コメントを書く際には以下の点に気をつけました。

* 敬意と礼儀を重んじる（断定しすぎたり強い主張は控える）
* 自らが誤って解釈したり読み違えていないか改めて確認する（実際にコメントを書いた直後に誤りに気付いて削除したものが1つあった）

# Fun
すでに翻訳が完了したドキュメントや書籍を見るだけでは分からない、翻訳者の苦労（どの部分で翻訳を悩んだか、候補はあったが不採用にしたなど）が分かった事、他のレビューアの観点/指摘コメントをリアルタイムで拝見できたことが楽しかったです。

# Done
3つのドキュメントに対して、合計レビュー時間が約15時間、合計14件ほどコメントさせて頂きました。

# Learn
* 読点での読みやすさ向上は、主観によるところが大きいため挙げない方が良さそう
* ドキュメントの要旨(本題)を超える補足は、やりすぎない方が良い
DXについて、調査してみてのおぼえがき

<h3>DXとは</h3>

経済産業省レポートによるDXの定義
企業がビジネス環境の激しい変化に対応し、データとデジタル技術を活用して、顧客や社会のニーズをもとに、製品やサービス、ビジネスモデルを変革すると共に、業務そのものや、組織、プロセス、企業文化・風土を変革し、競争上の優位性を確立すること

<h3>DXを実現するためのテクノロジー・技術</h3>

代表的なもの
・IoT（Internet of Things/モノのインターネット）
スマートスピーカーやスマートホーム、自動運転者など、近年急速に実用化が進んでいる先端テクノロジー
・AI（Artificial Intelligence /人工知能）
収集した大量データ（ビッグデータ）から判断の仕方を学習し、単純作業などを行う先端テクノロジー
・5G（第五世代移動通信システム）
既存ネットワークより、「高速性」「低遅延」「他端末接続」などが可能
・クラウド
インターネット上にあるサーバーが提供する機能をネットワーク経由で利用者が手元のパソコンやスマートフォンで利用する形態。ソフトウェア、サーバー、ストレージなどのインフラを持っていなくても、インターネット経由でそれらの機能を利用できる仕組み

<h3>DXを実現するための人材</h3>

・プロデューサー
DXやデジタルビジネスの実現を主導するリーダー格の人材
・ビジネスデザイナー
DXやデジタルビジネスの企画・立案・推進等を担う人材
・アーキテクト
DXやデジタルビジネスに関するシステムを設計できる人材
・データサイエンティスト・AIエンジニア
DXに関するデジタル技術（AI・IoTなど）やデータ解析に精通した人材
・UXデザイナー
DXやデジタルビジネスに関するシステムのユーザー向けデザインを担当する人材
・エンジニア・プログラマ
上記以外にデジタルシステムの実装やインフラ構築などを担う人材

<h3>DXのメリット</h3>

・生産性の向上・利益拡大
・変化する消費行動・ニーズへの対応
・新たな利益や価値を生み出すビジネスモデルへの移行
・社内のDXから、社を超えたDXへ〜デジタル化されたさまざまなサービス同士が相互作用するデジタル社会の実現
・デジタル社会において競争力を獲得し、ビジネスで生き残れる確率を高める
・BCP（自然災害やコロナなどのパンデミックの緊急事態時に損害を最小限に抑え、事業の継続や復旧を図るための計画）の実現

<h3>DX認定制度</h3>

感想：DXに認定制度があるのは初耳

DX認定制度とは、２０２０年５月15日に施行された「情報処理の促進に関する法律」に基づく認定制度
対象は、全ての事業者（法人と個人事業者。法人は会社だけではなく、公益法人なども含む）が対象となる
以下のような、メリットがあるため各企業が重視している
・DX認定制度を受ける過程でDXを推進する際の論点が整理される
・国がDX認定企業として情報を公開するための信用力、ブランド向上につながる
・経済産業省と東京証券取引所が共同で実施する「DX銘柄２０２１」の応募の資格が得られる

<h3>デジタイゼーション・デジタライゼーションとの関係</h3>

簡単に考えると、段階の違い
・デジタイゼーション
アナログからデジタルへ変換すること
　　　　　　　　　　　　　　　　　　　　　↓
・デジタライゼーション
組織やプロセスをデジタル化すること
　　　　　　　　　　　　　　　　　　　　　↓
・デジタルトランスフォーメーション
デジタル技術による革新的なイノベーション（革新的技術：新たなものを創造し、変革を起こすことで経済や社会に価値を生み出す様）を起こすこと

<h3>IT化とDXの違いと関係性</h3>

IT化とは
明確な定義があるわけではないが、一般的にIT化、IT導入というと既存の業務プロセスは維持したまま、その効率化・強化のためにデジタル技術やデータを活用するというイメージがある

例えば、電話や手紙であった連絡手段が、Eメールやチャットツールなどに置き換える
連絡の是非自体は問われることなく、ツールを導入することで効率化が図れた事になる
近年ではRPAやAI、ビッグデータなど大きな可能性を秘めた技術が次々と登場しているが、既存プロセスの効率化＝IT活用にとどまるケースが少なくはない

IT化とDXの関係は「手段と目的」

DXはデジタル技術の活用によって製品・サービスやビジネスモデルに変革を起こすもの
従って、IT化はDXの手段であり、DXはIT化の先にある目的であると考えられる

IT化による変化とDXによる変化の違い

IT化による変化は「量的変化」、DXによる変化は「質的変化」

IT化は、既存プロセスの生産性を向上させるもの。
何がどのように変化するか、社内でもわかりやすいのが特徴。
DXは、プロセス自体を変化させる。単に「作業時間が減る」「〇〇の作成プロセスを自動化する」などのわかりやすい変化ではなく、「顧客との接客方法がデジタルを通じて根本的に運用が変わる」「物流の配送計画をデジタルを用いて確認プロセスが抜本的に変わる」など、会社全体に関わるようなドラスティックな変化であるのが特徴

・IT化
既存の業務プロセスの効率化を目指す（手段）→量的変化
・DX
デジタル技術の活用によって製品・サービスやビジネスモデルに変革を目指す（目的）→質的変化
【JavaScript】セレクトボックスの要素を移動させる

今回はセレクトボックスの要素の移動について記述します。
この実装はJQueryでよく見かけるのですがJavaScriptで実装しているものがなかった為
メモを残したいと思います。

<h1>【view】</h1>

![【view】.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/d31481b3-c84d-0c32-81c8-a4860c92bfcd.png)


![【view】ver2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/64e3b6b8-b334-b70c-ab79-3eafe6a40ae5.png)

左のセレクトボックスの要素を選択して右のセレクトボックスに移動させます。
※逆も可能。

<【JavaScript】>

![【JS】コード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/73149410-bfad-0b93-4cba-27be626dc76a.png)

![【JS】コード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/c8827528-4b27-efc0-3fe1-817f3df2d686.png)

基本的に左の要素について記述しています。

移動ボタンをクリックした際にイベントが発生するように作っています。
17行目でobejctListに要素を格納していますがここは変数でも問題ないと思います。
※検証はしていません。

左から右へ移動する際は選択した要素を左のセレクトボックス(optionタグ)から
消えるようになっています。
※18行目のleftList.remove(i)が該当部分になります。

※コードにコメントを付けている為、そちらも参照ください。

<h1>【html】</h1>

![【html】コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/6f5c827d-69a8-7674-72bf-3df553c46296.png)

<h1>【Controller】</h1>

![【Java_Controller】コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665680/fee25d3f-8fd4-f460-8078-46335b2bc0fc.png)

画面を表示する為だけに作成しました。
NVIDIA CUDA Compiler Driver NVCCの導入

# 環境
- OS
Windows 11 Home
バージョン	21H2
OS ビルド	22000.675
# 目標
nvccコマンドを利用し、実行プログラムを生成すること。
# 手順
基本的に[NVIDIA公式ドキュメント](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html)に乗っ取って進めていく。
1. システム要求を満たしているか確認
    - CUDAと互換性があるGPU 
    [ここ](https://developer.nvidia.com/cuda-gpus)で確認。
    - サポートされたバージョンのWindows
    Windows 10または11の64bitなら多分問題ない。
    - サポートされたバージョンのVisual Studio
    Visual Studio 2015はCUDA Toolkit 11.1 では非推奨と書かれている。
    今回はVisual Studio Community 2022を使用する。
    インストール時にC++によるデスクトップ開発のワークロードを選択しておく。
    また、言語の欄で英語にもチェックを入れておく。

2. NVIDIA CUDA Toolkitのインストール
[ここ](https://developer.nvidia.com/cuda-downloads)からダウンロードできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2409331/ebc3fe28-7934-3bcb-fae6-88255cf63340.png)
自分の環境にあったものを選択する。
Installer Typeに関して理解が正しいかは怪しいが、localが全部入りであるのに対し、
networkはインストーラクライアントのみがダウンロードされ、必要な機能はその都度ダウンロードする必要がある。
慣れない間はlocalを選択するのが無難だと思う。
ちなみに、ダウンロードサイズはlocalだと2.5GB、networkだと34.7MBであった。
　
あとはダウンロードしたインストーラを起動してインストールを進める。
オプションは特に気にせずに推奨されているものを選択した。

3. サンプルプログラムの実行
[公式サンプル](https://github.com/nvidia/cuda-samples)をクローンするかzipをダウンロードするかでローカルに持ってくる。
Visual Stuidioの各バージョンの`.sln`があるので自分の環境に適したもので起動。
　
ここでビルドしようとするとエラー発生。
CUDA 11.6.propsが見つからないとのこと。
調べていると、インストールした現在(2022/6/5)最新のCUDA Toolkitのバージョンが11.7であるのに対し、サンプルプログラムのバージョンが11.6であることが原因であることが分かった。（[参考](https://forums.developer.nvidia.com/t/cannot-run-samples-on-ms-visual-studi-2019/72472))
CUDA Toolkitのバージョン11.6をダウンロード・インストールし、再度ビルドすると成功した。

4. nvccによるコンパイル
簡単なサンプルプログラムを作成([参考](https://qiita.com/JmpM/items/ada670ec80be9566269e))
コンパイルして実行する。
```
>nvcc sample.cu -o sample
sample.cu
   ライブラリ sample.lib とオブジェクト sample.exp を作成中

>sample
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
Hello CUDA World !!
```

# まとめ
バージョン違いに気を付けていれば難しいことはない。

# 参考
プログラムを引用させていただきました。
[並列"Hello World"から始めるCUDA入門](https://qiita.com/JmpM/items/ada670ec80be9566269e)
Classic Platform Release Overview AUTOSAR 22-11(ID:0) 書き換え選手権(1)。

買ってよかった技術書を紹介しよう！
https://qiita.com/official-events/8746fa99d4e403fad3d1

参加記事です。

あなたがAUTOSARのEditorだったら、どの文書をどう書き換えたいか選手権。
https://qiita.com/kaizen_nagoya/items/0055bb88f43f98a61739

に参加する記事でもあります。

AUTOSAR 21-11, 317文書読んだ。2022年6月3日にFO, AP, CP全部到達。
https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4

に掲載している技術文書を、「買ってよかった」と思える資料に変換できないかという試みでもあります。

Classic Platform Release Overview AUTOSAR 22-11(ID.0)
https://qiita.com/kaizen_nagoya/items/3b2bcfea95cbda5f8fcb

ID: Document Identification No

# 書き換え点１
文書番号０であれば、Classic Platform Release Overviewではなく、
AUTOSAR 2022-11 Release Overviewであるとよい。

全体の設計を示さずに、部分を示すのはやめよう。

![firstpage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/2c6a6187-24b7-9cad-afec-e65cb956639b.png)

第一章は、全体の説明になっている。
第二章がClassic Platform だけに言及しているところを、Foudation, Adaptive Platformを付け加えればよい。

表題以外は修正というよりは、追加で大丈夫。

# 誰が何のために読むとよいか。
今年の資料から

### 目的と成果(Purpose and Outcome)

|item|description|
|:--|:--|
|who|CP user|
|what|known technical deficiencies|
|importance| very high|
|others| scheme version|
|comment| This should be foundation|

という項目を足した。
誰が、何のために読むとよいかを示すため。

## 関連資料
【毎日自動更新】買ってよかった技術書を紹介しよう！ LGTMランキング！
https://qiita.com/torifukukaiou/items/24f5d98638b4aae9f56e#_reference-043bbd5c570bebcd9934

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Spring Boot 2.7.0 & Spring Security5.7.1 sample

# 内容
SpringBoot2.7.0かつSpring Security5.7.1でカスタマイズポイントを作るだけの例。

# env
|name|version|
|:---|:------|
|OS|Ubuntu 20.04|
|IDE|IntelliJ IDEA 2022.1.1 (Ultimate Edition)|
|SpringBoot|2.7.0|
|SpringSecurity|5.7.1|

# document
## release note
https://spring.io/blog/2022/05/19/spring-boot-2-7-0-available-now

## spring security document
https://docs.spring.io/spring-security/reference/getting-spring-security.html

# setting
## build.gradle
```gradle
plugins {
    // Apply the java plugin to add support for Java
    id 'java'

    // Apply the application plugin to add support for building a CLI application.
    id 'application'

    id 'org.liquibase.gradle' version '2.0.3'
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'idea'
    id 'io.freefair.lombok' version '5.0.0-rc4'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.session:spring-session-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-security'
}
```

# Java
## WebSecurityConfigure
意味もなく、全パス許容で空のセッションを発行するようにする。
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class WebSecurityConfigure {

    @Bean
    SecurityFilterChain httpSecurityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
                .and()
                .authorizeRequests().mvcMatchers("*").permitAll()
                .and()
                .build();
    }
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/6f44ec0c-018e-7071-b82a-cdfd7f65316d.png)

なぜかBeanが見つからないエラーがIntellij上、出るが動く。

:::note alert
SpringBootなので、`@EnableWebSecurity`は不要。
:::

----
ここから、Controllerなどで肉付けしていけば動く。
AtCoder Beginner Contest 254

## [A - Last Two Digits](https://atcoder.jp/contests/abc254/tasks/abc254_a)

O(1)
１文字目と２文字目を表示します。

```C++:C++
#include <bits/stdc++.h>

int main() {
    string N;
    cin >> N;
    cout << N.substr(1,2) << endl;
    return 0;
} 
```

## [B - Practical Computing](https://atcoder.jp/contests/abc254/tasks/abc254_b)

O(N*N/2)
問題文の制約通りにコーディングできるかを問われています。

```C++:C++
#include <bits/stdc++.h>

int main() {
    int N;
    cin >> N;
    vector<vector<int>> A(N);

    for(int i=0; i<N; i++){
        for(int j=0; j<i+1; j++){
            if(j==0 || j==i) A[i].push_back(1);
            else A[i].push_back(A[i-1][j-1]+A[i-1][j]);
        }
    }

    for(int i=0; i<N; i++){
        for(int j=0; j<i+1; j++){
            cout << A[i][j];
            if(j<i) cout << ' ';
        }
        cout << endl;
    }

    return 0;
} 
```

## [C - K Swap](https://atcoder.jp/contests/abc254/tasks/abc254_c)

O(N)
i番目と、i+K番目を入れ替えることができます。
入れ替え可能な回数は0回以上です。
まずテストデータを作成します。

```txt
10 3
6 1 1 3 1 1 2 1 1 1
```

のテストデータの時、i=0からi=N-1まで、各要素を１回だけ昇順に入れ替えをします。

```txt
10 3
3 1 1 2 1 1 1 1 1 6
```

この結果から、i番目と、i+K番目を入れ替えを行う際、
昇順になるまで無制限にソートを行う必要があると分かります。
また、i番目からi+K*j番目の要素のみ入れ替えています。

つまり、i番目からi+K*j番目の要素のみの集合を作成し、
昇順にソートを行なったものを、
Aの要素に順番通りに代入すると解答になります。

```C++:C++
#include <bits/stdc++.h>

int main() {
    int N, K;
    cin >> N >> K;
    vector<int> A(N);
    vector<int> f(N, 0);
    for(auto &a:A) cin >> a;

    for(int i=0; i<N-K; i++){
        if(f[i] == 1) continue;

        multiset<int> st;
        for(int j=i; j<N; j+=K){
            st.insert(A[j]);
            f[j] = 1;
        }

        auto itr = st.begin();
        for(int j=i; j<N; j+=K){
            A[j] = *itr;
            itr++;
        }
    }

    int ok=1;
    for(int i=0; i<N-1; i++){
        if(A[i]>A[i+1]) ok = 0;
    }
    if(ok) cout << "Yes" << endl;
    else cout << "No" << endl;

    return 0;
} 
```

## [D - Together Square](https://atcoder.jp/contests/abc254/tasks/abc254_d)

O(N√N)
AtCoder math Contestです。
N以下のi,jを使用して、i*jの平方数がいくつあるか組み合わせの数を求める問題です。

O(N＾２)では、TLEになります。
O(NlogN)、O(N√N)、O(N)にする方法を考えます。

iを固定した時、jがとる値を計算しましょう。
iから、約数の組み合わせて２乗になっている物を取り除きます。

```txt
2*2*2*2*3*5
```

3*5=15として、15に平方数をかけてN以下の数字が、
jのとる値になります。

```C++:C++
#include <bits/stdc++.h>

int main() {
    ll N;
    cin >> N;
    vector<int> A;
    //  N以下の平方数を全て計算する
    for(int i=1; i*i<=N; i++){
        A.push_back(i*i);
    }

    ll ans = 0;
    // iを固定した時、jがとる値を計算する
    for(int i=1; i<=N; i++){
        ll t = i;
        // N以下の平方数でiを割る。
        // 大きい平方数から割らないと余りが出る。
        for(auto itr = A.rbegin(); (*itr) != 1; itr++){
            while(t%(*itr)==0) t /= *itr;
        }
        // 残った約数と、N以下の平方数をかけて、
        // N以下なら組み合わせの一つであると判定できる。
        for(auto itr = A.begin(); t * (*itr)<=N && itr != A.end(); itr++){
            ans++;
        }
    }
    cout << ans << endl;

    return 0;
} 
```
【Python】型ヒント入門編

# この記事で書くこと
この記事ではpythonの型ヒントについて簡単に説明していきます。

# 型ヒントとは?
型ヒントとは、関数の引数と返り値の型を書いておくものです。
型ヒントは、あくまで注釈であり、あってもなくても、Pythonの実行時にはなにか特別効果があるわけではありません。(別に最悪なくても良い☺︎)
ただ、注釈を書いておいて置くことにより、コードの改修時や、チーム開発で他のメンバーがコードを見た時にわかりやすいようにすることができます。
なるべく記載した方が良いでしょう☺︎




# 型の種類
基礎的な方になりますのでなるべく全部暗記できるようにしましょう。
私はbytesを使ったことがなかったのでこの記事書いてて初めて知りました...

| 名称     |       型 |  
|:-----------------|:------------------|
| 整数             |              int |   
| 浮動小数点数           |            float |  
| 文字列            |              str |  
| バイト          |           bytes |     |
| 真理値             |                bool 
| None             |             None |  




下記型はそのまま使用してしまうとエラーとなってしまうので、importしてあげましょう
```
from typing import List, Tuple, Dict, Set
```
| 名称     |       型 |  簡単な使用例
|:-----------------|:------------------|:------------------|
| リスト             |             List |  List[int]  
| 辞書             |             Dict |  Dict[str, int]|  
| タプル            |             Tuple |  Tuple[int, int] |  
| セット            |             Set |  Set[int]|  








# 型ヒント定義例

### 変数定義
```
変数名: 型　= 初期値
age: int = 0
``` 

### 関数の引数定義
```
def 関数名(引数名: 型 = 初期値):
    pass

def get_age(age: int = 0):
    pass
``` 

### 関数の戻り値定義
```
def 関数名(引数名: 型 = 初期値):
    pass

def get_age(age: int = 0):
    pass
``` 
### 関数の返り値定義
```
def 関数名(引数) -> 返り値型:
    return 返り値

def 　get_age(age) -> int:　           ←返り値が10でintなのでintとする　
    return 10
```



### 全部使ってみる
```
def 関数名(引数: 型 = 初期値) -> 返り値型:
　　　　　　　　　配列変数: 型　= 初期値
　　　　　　　　　配列に引数を追加
    return 返り値

def 　get_user(user: str = "田中") -> List[str]:　           ←返り値がListで中身がstrなので
    user_list: List[str] = []
    user_list.append(user)
    return user_list
```

# まとめ
pythonの型ヒントは他にもあるのでこちら更新しましたら、こちらの記事にリンクを貼りまする☺︎
間違っている点やこの書き方の方がわかりやすいなどありましたらコメントしていただけると幸いです。
勉強メモ52_可変幅フォントの件

# 1 以下の記事を見とく
https://wa3.i-3-i.info/word13834.html

# 2 同じバイト数でも全角あと半角aで幅が変わる、画面の最大桁のデータ表示の幅とかを確認をする際は、下記aが連続した半角20文字をテストデータとして使ったりする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730323/bc40a587-2751-12e4-cde6-aba18bfaf7b1.png)

# 3　テスト工程で入力ボックスの桁数テストをするときは、全角だったら、記号の「＿」（アンダーバー）を使い、半角だったら、大文字の「Ｗ」を使ってテストするとよいかも
下記画像のように同じ桁数でも文字の幅によっては溢れるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730323/54041b1e-cf88-55b2-3530-3eceacba80fe.png)
Django+Reactで学ぶプログラミング基礎(4): 開発環境構築(Redux)

##### [前回] [Django+Reactで学ぶプログラミング基礎(3): 開発環境構築(React)](https://qiita.com/mingchun_zhao/items/505a4fe76dfb8aa73023)

## はじめに

前回に続き、開発環境の作成です。
今回は、Redux開発環境です。

## 開発環境情報(Windows)
- 前回までインストール済み
    - Python 3.10
    - VS Code(Visual Studio Code) 1.67
    - Django 4.0
    - React関連
- 今回は、Redux開発に必要なもの

## Reduxとは

- アプリの状態を予測可能なコンテナ
    - シンプルで限定的なAPIを備えた小さなライブラリ
- Reduxはなぜ必要か
    - SPA(シングルページアプリケーション)が複雑になり、state(状態)管理が煩雑に
        - バグが目立つように
    - Reactは、この問題を解決するため、Viewレイヤーから非同期と直接なDOM操作を取り除いた
        - その結果、state(状態)管理は開発者に委ねられた
        - 解決策としてReduxが採用されるように
- Reduxのデータフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/7cad10d3-2482-df21-33a0-4571a30f4002.png)
※ 引用元: https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow
    - State: アプリの状態を保持する唯一の手段
        - 特定時点でのアプリの状態を表す
    - View: 現在の状態に基づく、UIの宣言型説明
        - UIは状態に基づいてレンダリングされる
    - Actions: ユーザー入力による、アプリ発生イベントおよび状態更新トリガー
        - ユーザーがボタンをクリックすると
            - 発生内容に基づき状態が更新される
            - UIは新しい状態に基づいて再レンダリングされる

## Redux開発環境の構築

### Redux Toolkit(RTK)をインストール
- Reduxロジックを作成するため、公式に推奨されるアプローチ
- Reduxコアをラッピングし、Reduxアプリ構築に必要なパッケージと関数が含まれる
- 推奨されるベストプラクティスが組み込まれている
    - Reduxタスクを簡素化
    - イージーミスを防ぐ
    - Reduxアプリケーションの作成を容易に
- Redux Toolkitを、npmパッケージとしてインストール
```
>npm install @reduxjs/toolkit
```

### Reduxコアをインストール
- Reduxコアライブラリを、npmパッケージとしてインストール
```
>npm install redux
```

### React Redux アプリを作成
- 公式`Redux+JS`テンプレートを使用
    - メリット
        - Reactコンポーネントで、`Redux Toolkit`と`React Redux`を統合可能
```
C:\kanban>npx create-react-app my-react-redux-app --template redux
```
- 起動すると、ブラウザにサンプルアプリが表示されます
```
C:\kanban>cd my-react-redux-app
C:\kanban\my-react-redux-app>npm start
You can now view my-react-redux-app in the browser.
  Local:            http://localhost:3000
  On Your Network:  http://172.28.128.1:3000       
... ...
webpack compiled successfully
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/1ee7c003-7406-defc-4326-6232789de910.png)

## おわりに

Windows環境にRedux関連をインストールし、
`React Redux`アプリのサンプルを見てみました。
次回も続きます。お楽しみに。

##### [次回] [Django+Reactで学ぶプログラミング基礎(5): Djangoチュートリアル(投票アプリその1)](https://qiita.com/mingchun_zhao/items/477ea8780a88b97f309a)
RPAの選定

SEとして、活動していると、RPAの選定に係ることがたまにあります。
その際に選定の判定として利用した内容について

選定方法により、選定するRPAも変更されると思いますが、
一端の意見としてあるなと思って頂ければ幸いです。

#### 選定する条件　シェア率
まずはシェア率で比較。※RPAの特定製品を広めようとする記事が多数あるので注意。
出来れば総研等の正確な数字を知りたいところだが、最新データを取るのには有償となるため
この辺りは感覚で。

#### 実現できる機能について調査
実現できる機能について、本当にできるかを調査。
試用期間などあれば、この期間に調査ができると良いですね。

#### 技術者が醸成される環境があるか
RPAというものは、結局スクリプト言語に近いものだと思って導入・提案を行った方がよいです。
少なくともVBAくらいできると良いですね。ですので技術者は必要です。

#### 価格
同じような費用ですが、突然大きな変更あるものと思った方が良いです。

#### 何に利用したいのか
人の代わりなのか
バッチの代わりなのか
ファイルシステムの代わりなのか
RPAそのものになっていないか

等、実施の効果を含めて導入の検討をしたほうが良いのかと思います。
Go で文字列を for-range で回したら rune 型が出た件

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やっぱりGoでも文字列は配列みたいなノリで扱えるのか〜という所感</p>&mdash; BitterBamboo (@bitter_bamboo) <a href="https://twitter.com/bitter_bamboo/status/1533080875533238273?ref_src=twsrc%5Etfw">June 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

このように、文字列を直感的に配列の如く扱っていいだろうと高を括っていたら、
`for-range` でまさかの `rune` 型が飛び出してきて、見事にぶちのめされました。

## 問題のコード

文字列から "ぴえん（🥺）" を全て除去するプログラムです。
今回は標準パッケージの `strings.ReplaceAll` は使わずに、
文字列中の1文字1文字を `for-range` で回そうとしてみます。

### エラー吐いた

``` go
package main

import (
	"fmt"
)

func removeAllPiens(word string) (noPienWord string) {
	for _, char := range word {
		if char == "🥺" { // Error!!
			continue
		}
		noPienWord += char // Error!!
	}
	return
}

func main() {
	result := removeAllPiens("🥺fizz🥺buzz🥺")
	fmt.Println(result)
}
```

これを実行すると、以下のようなエラーを吐かれます。

```
./prog.go:9:14: invalid operation: char == "🥺" (mismatched types rune and untyped string)
./prog.go:12:3: invalid operation: noPienWord += char (mismatched types string and rune)
```

どうやら文字列中の1文字1文字に該当する `char` が `rune` 型なせいでエラーとなっているみたいですね。
`string` 型ちゃうんか工藤。。。

### これなら動く

`char` を `string`型 にキャストします。

``` go
package main

import (
	"fmt"
)

func removeAllPiens(word string) (noPienWord string) {
	for _, char := range word {
		if string(char) == "🥺" {
			continue
		}
		noPienWord += string(char)
	}
	return
}

func main() {
	result := removeAllPiens("🥺fizz🥺buzz🥺")
	fmt.Println(result)
}
```

直感からは少々外れることになりましたが、
なんとか当初の目論見通りにプログラムが動作しました。

## 文字列を `for-range` で回すと1文字1文字は `rune` 型として現れる

試しに文字列を `for-range` で回した際の要素の中身を出力してみます。

``` go
package main

import (
	"fmt"
)

func main() {
	word := "🥺fizz🥺buzz🥺"
	for index, char := range word {
		fmt.Println(index, string(char), char)
	}
}
```

結果:

```
0 🥺 129402
4 f 102
5 i 105
6 z 122
7 z 122
8 🥺 129402
12 b 98
13 u 117
14 z 122
15 z 122
16 🥺 129402
```

あっ... これ **Unicode コードポイントの10進数表記** だ...（察し）

ここで [A Tour of Go の Basic Types](https://go-tour-jp.appspot.com/basics/11) における説明を思い出します。

> rune // int32 の別名
> 　  　// Unicode のコードポイントを表す

基本的に動的型付け脳なので、華麗に素通りしてしまっていましたが、、今なら納得です。。

> (訳注：runeとは古代文字を表す言葉(runes)ですが、Goでは文字そのものを表すためにruneという言葉を使います。)


また、文字列中の `index` は 1 byte ごとに振られているようです。

🥺 は UTF-8(可変長) で 4 byte の文字なので、
🥺 に後続する文字の `index` は 4つ跳んでます。

## `for-range` の言語仕様

気になったのでググってみました。
`string` 型に対して `for-range` を適用すると、
繰り返しの各要素が `rune` 型となることがはっきりと記述されています。

> For a string value, the "range" clause iterates over the Unicode code points in the string starting at byte index 0. On successive iterations, the index value will be the index of the first byte of successive UTF-8-encoded code points in the string, and the second value, of type rune, will be the value of the corresponding code point. If the iteration encounters an invalid UTF-8 sequence, the second value will be 0xFFFD, the Unicode replacement character, and the next iteration will advance a single byte in the string.

https://go.dev/ref/spec#For_statements

# 次回

`rune` 型の基本的な挙動をおさらいしていきます。

https://qiita.com/BitterBamboo/items/401020a8fb500e518d07
ソフトウェアにおけるテストケース方法まとめ

テストケースをまんべんなく作ることというのは、難しくはないが面倒な作業です。

テスト方法はかなりありますので、ざっくり纏めました。

・ペアワイズ法（オールペア法）
・同値分割法
・境界値分析
・デシジョンテーブルテスト
・原因結果グラフ法
・状態遷移テスト
・直交表
・nワイズテスト
・ドメイン分析
・クラシフィケーションツリー法
・ユースケーステスト
・制御フローテスト
・データフローテスト
・エラー推測
・チェックリストベースドテスト
・探索的テスト

◆ペアワイズ法（オールペア法）
2つのパラメータ間の組み合わせを
総当たりのパターンを出す方法「ペアワイズ法（オールペア法）」
例えば1つの条件に　真(true)と偽(false)の条件があり、
これが何パターンかある状態というのがプログラム中の条件となります。

そのパターンは真(true)と偽(false)のパターンの場合
発生するパターンは2となります。

これが2つの条件が重なると、
2×2の4パターンになります。

以下のパターンが出来上がります
a:true b:true
a:true b:false
a:false b:true
a:false b:false

これらをパターン化し、テストケースとして作成していきます。
すべてデータ化し、単体テストを自動化している場合もありますよね。

プログラム中の判断としては単体テストで実施することが多く
この中である程度のパターンによる障害を削除しておくことが必要になります。

よくある手戻りで機能要件として一部変更となると、
このケースのテストケースを作成しなおす状態になります。
そりゃぁ…プログラム上は数文字変更するだけだけど…と愚痴がでるのはこれです。

◆同値分割法
同値分割では、入力条件を類似と見なすことができるグループまたはセットに分割します。
システム上は同等に処理されると想定したデータを「同値パーティション」または「同値クラス」と
呼ばれるグループに振り分け、テストを実行します。

メリット：最小限のテストにてテストが実施可能。
デメリット：すべて適用できるわけではなく、例外値、境界値などが存在する場合は
　　　　　　別途実施しないとテスト抜けが発生しやすい

例：１～１０が正常の場合
ー５　、　５　、　１１　　AA　等の代表的な値をチェックする

◆境界値分析
有効になる範囲がある場合、境界値についてテストを行い、特に境界値を重点的にチェックする方法です。

例：１～１０が正常の場合
０、１、１０、１１　　等の値の切り替わりをチェックします。

同値分割法と合わせて実施する場合があります。
メリット　　境界値にて判断が及ぶテストが可能
注意点　　　通常の値にて見逃すことがある。
　　　　　　正常値の範囲がIF文に記載されていることだけではないことを気を付けてほしい。

◆デシジョンテーブルテスト

条件と結果を設定し、設定の条件に合った結果が出ているかを
ブラックボックス化し、Aの場合はBになるといったものをチェックを
すべてのパターンについて行っていくテストになります。
https://www.itmedia.co.jp/im/articles/1111/07/news138.html

◆原因結果グラフ法
原因と結果のフロー図を作り、そこから結果表を作っていく方法です。
イメージを作ってから行いますので、何をやりたいかというのが判明していく方法となります。
デバッグにて実施すると原因が判明する場合がございます。

◆状態遷移テスト
Aが終わったらBになるという状態を順に状態を追うことを想定するテストとなります。
運用テストやシステムテスト等の値の状態をチェックする際に使用されます

http://www.jasst.jp/symposium/jasst19tohoku/pdf/S5-2.pdf

◆直交表
2つの入力に対して、すべての値が同一の数だけ
当てはまることをチェックする方法。

これを行うパターンは、
すべてのパターンを実施しましたが、全く発生しませんでしたのように証明する際に必要になるかもしれません。

◆nワイズテスト
任意のN個のパラメータのパターンをすべて網羅するテストを作成することです。
オールペア法とほぼ同じですね。N個のパターンとなります。

◆ドメイン分析
関係性のある複数の変数を使うときこの分析方法をつかうようです。
境界値と関連性のある別のデータをひとつの結果として取り扱うときなどです。
共通関数などでの塊での判定などを取り扱うときなどに見るといいかもしれません。
http://www.jasst.jp/archives/jasst11t/pdf/s2-1.pdf

◆クラシフィケーションツリー法
テスト対象が持つ要素を木構造でモデリングするテスト設計技法です

◆ユースケーステスト
代表的なステークスホルダーが行う標準の要求動作のテストを行っていくテストです。
システムテストやユーザーテスト等にて行う技法となります。

https://www.qbook.jp/column/20190605_722.html

◆制御フローテスト
ホワイトボックステストと呼ばれるテストです。
システムの内部構造を元にテストを行っていきます。
https://note.com/akiyama924/n/n57a4b4caa188

◆データフローテスト
ソースコードのデータ（変数、データオブジェクト）に対して
の状態変化に対して問題が無いかをチェックします。
宣言、消滅などの無駄な状態が無いかなどのチェックを行います。

◆エラー推測
ソフトウェアの処理について、エラーが発生することを想定してテストする技法
これは経験則が元となるチェックとなります

◆チェックリストベースドテスト
有識者がいることが前提のテストとなります。
有識者が経験したチェック内容を元に該当するかをチェックする技法となります。

◆探索的テスト
ソフトウェアのふるまいを見ながらチェックリストを作る技法です。
これも経験則的なテスト方法です

参考：
https://www.iestudy.work/entry/2019/12/05/001815
amplify override category , override.ts「 Skipping override due to VMError: Cannot find module 'fs'」

## 事象
- Amplify の `amplify override auth` で作成された `override.ts`で、getProjectInfo は　まだ使えない

### 利用しているバージョン
- amplify cli 8.3.1 で発生（GitHubのissuesを見ると8.0.2でも発生している模様）

### 記載したコード
```ts
import { AmplifyAuthCognitoStackTemplate, getProjectInfo } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyAuthCognitoStackTemplate) {
  const { projectName, envName } = getProjectInfo();
}
```
## エラー内容

- 以下のようになって処理がスキップされてしまう
```sh
$ amplify push
⠇ Fetching updates to backend environment: feass from the cloud.
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠋ Fetching updates to backend environment: feass from the cloud.✅ GraphQL schema compiled successfully.

Edit your schema at /workspaces/amplify/amplify-appname/amplify/backend/api/appname/schema.graphql or place .graphql files in a directory at /workspaces/amplify/amplify-appname/amplify/backend/api/appname/schema
⠙ Building resource auth/appnameXXXX73b🛑 Error: Skipping override due to VMError: Cannot find module 'fs'

✔ Successfully pulled backend environment feass from the cloud.
⠙ Building resource auth/appnameXXXX73b🛑 Error: Skipping override due to VMError: Cannot find module 'fs'

```


## 既知の問題
- https://github.com/aws-amplify/amplify-cli/issues/9063
- https://github.com/aws-amplify/amplify-cli/issues/9885
- https://github.com/aws-amplify/amplify-category-api/issues/109


## ワークアラウンド
- https://github.com/aws-amplify/amplify-cli/issues/9063#issuecomment-996200713
- https://github.com/aws-amplify/amplify-cli/issues/9063#issuecomment-1034851846
- https://github.com/aws-amplify/amplify-cli/issues/9063#issuecomment-1037656768
- https://github.com/aws-amplify/amplify-cli/issues/9725#issuecomment-1035465649
- amplify-meta.json を使う
```
    const amplifyMetaJson = require('../../../amplify-meta.json');
    console.log(amplifyMetaJson.providers.awscloudformation.StackName.split("-").slice(-2, -1).pop());
```
【Node】NVMによるバージョンアップ

# 指令：Nodeのバージョンをupgradeしろ！

```sh
You are using Node v10.19.0, but this version of @vue/cli requires Node ^12.0.0 || >= 14.0.0.
Please upgrade your Node version.
```
りょうかいです！

## 現在インストールできるNode.jsのバージョン一覧を確認

```sh
$ nvm ls-remote
　　　　～省略～
       v16.12.0
       v16.13.0   (LTS: Gallium)
       v16.13.1   (LTS: Gallium)
       v16.13.2   (LTS: Gallium)
       v16.14.0   (LTS: Gallium)
       v16.14.1   (LTS: Gallium)
       v16.14.2   (LTS: Gallium)
       v16.15.0   (LTS: Gallium)
       v16.15.1   (Latest LTS: Gallium)
        v17.0.0
        v17.0.1
        v17.1.0
        v17.2.0
        v17.3.0
        v17.3.1
        v17.4.0
        v17.5.0
        v17.6.0
        v17.7.0
        v17.7.1
        v17.7.2
        v17.8.0
        v17.9.0
        v17.9.1
        v18.0.0
        v18.1.0
        v18.2.0
        v18.3.0
```

めっちゃでてくるじゃん…

## バージョンを選ぶ

どれを選べば…？
(LTS: Gallium)ってなんだ…？

- LTS
    - Long Term Support(長期間サポート)
    - バグのでにくい安定版
- Gallium
    - コードネーム
    - Node.jsは偶数バージョンがLTSに移行し、コードネームがつけられる
    - コードネームは元素になっていて、v4からArgon, Boron, Carbon... と続いている
    - ちなみに、ガリウムという元素は手指の摩擦熱によって容易に融点まで温度を上げられることから、いわゆる“スプーン曲げ”や“スプーン切断”用のスプーンの製造材料に用いられることがある、らしい。へえ～

**結論：LTSって書いてあるやつ（安定版）を選ぶのが良さそう！**

## バージョンアップ！
現在のバージョンを確認する
```sh
$ node -v
v10.19.0
```
すきなバージョンをインストール（今回はv16.15.1）
```sh
$ nvm install v16.15.1
```
Node.js 環境を追加インストールすると、自動的にそのバージョンがアクティブになるそう:thumbsup:
本当に変更されているか確認する
```sh
$ node -v
v16.15.1
```
できた～！

## おまけ
インストールされている Node.js 一覧表示
（行頭に -> が表示されてるやつ：現在アクティブになっているバージョン）
```sh
$ nvm ls
->     v16.15.1
         system
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.15.1) (default)
stable -> 16.15 (-> v16.15.1) (default)
lts/* -> lts/gallium (-> v16.15.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.19.3 (-> N/A)
lts/gallium -> v16.15.1
```

使用する Node.js のバージョンを切り替え
```sh
$ nvm use v16.15.1      # nvm でインストールしたバージョン v16.15.1 の Node.js を使う
$ nvm use 16      # nvm でインストールしたバージョン 16 の Node.js を使う
$ nvm use system  # システムインストールされた Node.js を使う
```


## 参考

- [LTSとは。そしてLTSバージョンと最新バージョンのどちらを選ぶべきか](https://yongjinkim.com/lts%E3%81%A8%E3%81%AF%E3%80%82%E3%81%9D%E3%81%97%E3%81%A6lts%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%A8%E6%9C%80%E6%96%B0%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AE%E3%81%A9/)
- [【Node.js入門】バージョンアップ手順と管理ツールまとめ！](https://www.sejuku.net/blog/82819)
- [Node.js16(Gallium)リリース記念 Node.js再入門](https://scrapbox.io/teamlab-frontend/Node.js16(Gallium)%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E8%A8%98%E5%BF%B5_Node.js%E5%86%8D%E5%85%A5%E9%96%80)
- [Wiki ガリウム](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%AA%E3%82%A6%E3%83%A0)
- [nvm で複数の Node.js バージョンを切り替えて使用する ](https://maku77.github.io/nodejs/env/nvm.html)
iPhoneショートカットで小さな努力をやめる

iPhoneのショートカット機能を使って
iPhoneに関連する小さな努力を止めています。

こんなショートカットを使ってます。

ショートカット
・端子に水滴が入っている場合の排水
・一定の幾つかのアーティストから、選んだ人からランダムに選曲
・壁紙をアルバムからランダムに変更

オートメーション
・背面クリックによる起動
・充電されたら実行
・充電が５０％を切ったら自動実行
・定時になったらアラームをONにする
・定時になったら音量を少なくする
・定時になったら、省電力にする


作ったものもあるので、こちらにリンクを張っておきます。ご参考まで。
・壁紙をアルバムからランダムに変更
https://www.icloud.com/shortcuts/72c38059ae154f178b4821bd1424f935
・目的地までの経路
https://www.icloud.com/shortcuts/cb992ed7e33c44349e5dbdabc0680b30
コード値からEnum型へ変換するユーティリティクラス

JavaのEnum型はフィールドを定義することができて、コード値に変換したりするのに便利ですが、コード値からEnum型への変換は標準では用意されていないため、各Enum型に取得用のstaticメソッドが乱立しがちです。
```java
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum Pokemon {
    PIKACHU("025", "ピカチュウ"),
    RAICHU("026", "ライチュウ"),
    PICHU("172", "ピチュー"),
    ;

    private final String no;
    private final String jName;

    public static Pokemon getByNo(String no) {
        Optional<Pokemon> result = Stream.of(values())
            .filter(p -> p.no.equals(no))
            .findFirst();
        return result.orElse(null);
    }
}
```

Apache Commons辺りに良い感じのメソッドが無いかと調べたところ、`EnumUtils#getEnum()`というそれっぽいメソッドが、見つかりました。
```java
// 使い方
Pokemon p = EnumUtils.getEnum(Pokemon.class, "PIKACHU");
```

・・・違う、そうじゃない。。。

という訳で、コード値からEnum型へ変換するユーティリティクラスを自作しました。
可変長引数をごにょごにょして`dummy`から`Class<E>`を取得しているのがポイントです。
（あと、警告がたくさん出ます。。。）

```java
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

public class MyEnumUtils {
	
	public static <E extends Enum<E>, T> E getEnum(T value, Function<E, T> getter, E... dummy) {
		Class<E> clazz = (Class<E>) dummy.getClass().getComponentType();
		Optional<E> result = Stream.of(clazz.getEnumConstants())
				.filter(e -> Objects.equals(getter.apply(e), value))
				.findFirst();
		return result.orElse(null);
	}
}
```

以下のように使用します。
第3引数の`dummy`は名前の通りダミーなので何も渡しません。

```java
// 使い方
Pokemon pika = MyEnumUtils.getEnum("025", Pokemon::getNo);
Pokemon pich = MyEnumUtils.getEnum("ピチュー", Pokemon::getJName);
```

なお、このコードはJava8以降でしか動作しません。

第3引数の`dummy`が、格好悪いなぁと思って、
privateメソッドに隠してしまいたかったですが、がうまく動きませんでした。

```java
public class MyEnumUtils {
	
    // このメソッドは正常に機能しません。
	public static <E extends Enum<E>, T> E getEnum(T value, Function<E, T> getter) {
		return getEnumInternal(value, getter);
	}

	private static <E extends Enum<E>, T> E getEnumInternal(T value, Function<E, T> getter, E... dummy) {
		Class<E> clazz = (Class<E>) dummy.getClass().getComponentType();
		Optional<E> result = Stream.of(clazz.getEnumConstants())
				.filter(e -> Objects.equals(getter.apply(e), value))
				.findFirst();
		return result.orElse(null);
    }
}
```

なんでやろなぁ。。。

参考にしたサイト
---
https://language-and-engineering.hatenablog.jp/entry/20120502/p1
Julia言語のインストールとjuliaupのメモ

Juliaがどのようなプログラミング言語かは割愛
`juliaup`というコマンドでrustupやnpmのようにJuliaのバージョン管理やアップデートが行えるようなのでメモ

# Juliaの基本的なインストール
:::note warn
`juliaup`のインストール時に自動的にJuliaもインストールされるので
あらかじめJuliaをインストールしておく必要がある訳ではありません

`juliaup`を利用しない場合の基本的なインストール方法です。
:::

[Juliaの公式ページのDownload](https://julialang.org/downloads/)からバイナリをダウンロードしてインストールする。
この場合、`juliaup`は使えない（はず）。

新しいバージョンが出た場合にはまたダウンロードページからバイナリをダウンロードしてインストールする必要がある。

メリットとしてはインストールする場所などを任意に指定できることくらい？
環境変数で`Path`を通す場合などは都度変更する必要がある。

# `juliaup`を使えるようにする

https://github.com/JuliaLang/juliaup

Julia言語公式のリポジトリで`juliaup`が開発されている。

このリポジトリに従うと、
`juliaup`コマンドを使えるようにするには

まず、環境変数を設定している場合は`JULIA_BINDIR`や`Path`に通すための設定は削除しておく。

次に
* Windowsでは[Microsoft StoreからJuliaをインストール](https://apps.microsoft.com/store/detail/julia/9NJNWW8PVKMN)する必要がある。<br>（またはPowerShellから`winget install julia -s msstore`）
* LinuxやMacでは `curl -fsSL https://install.julialang.org | sh`
* Homebrewを使用している場合は `brew install juliaup`

インストールを実行すると`juliaup`がインストールされ、releaseの最新のJuliaがインストールされる。

(MS storeからインストールした場合juliaupがどこにあるかわからないが)
`juliaup`という名前のディレクトリが作成されて、その中に`juliaup`によってインストールされた各バージョンのJuliaが入るようになる。（具体的なディレクトリが知りたければJuliaを起動してエラーを起こせばいい、`rand(-1)`とか）

環境変数：`JULIA_DEPOT_PATH`を設定している場合は、
Windowsでは`%JULIA_DEPOT_PATH%\\juliaup`が
他のOSでは`$JULIA_DEPOT_PATH/juliaup`が作成されてその中へ各バージョンのJuliaがインストールされる。
何らか事情でOSとは違うドライブへインストールさせたい場合などに使える。

Windows Terminalをインストールしている場合はJuliaのプロファイルが追加される。

`juliaup`コマンドの使い方は`-h`オプションか[リポジトリを参照](https://github.com/JuliaLang/juliaup)
Hasura APIでサクッとCRUD機能を実装 + Axiosでリクエストを送信する

## 対象読者
- 個人開発でちょっとHasuraを使ってみたいけど、使い方がいまいちよくわからん！な方
- クライアント側（JavaScript）から作ったAPIにリクエストを送りたい方

## Hasuraプロジェクトを立ち上げる

https://cloud.hasura.io/

まずHasuraでアカウントを作成、ログインします。

ログイン後、新規プロジェクトを作成し、データベースを接続します。

![スクリーンショット 2022-06-05 14.31.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/7bee7451-7754-3a7f-1446-52ee49803239.png)

今回はPostgreSQLのサーバーとしてHerokuを使用します。
"Create Database"をクリックすれば、サクッとDBサーバーが作られ、自動的にHasuraとの接続が完了します！



## テーブルを用意する

プロジェクトの作成・DBサーバーとの接続が完了したら早速テーブルを作成してみます。

Dataメニューから、"Create Table"を選択し、テーブルを作成します。

![スクリーンショット 2022-06-05 14.38.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/6d26af35-0555-7bf3-1743-3714894bc986.png)

今回はPostというテーブルを例として使用します。

![スクリーンショット 2022-06-05 15.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/4a924796-01d3-c93a-aca4-0733b7285d10.png)



## CRUDを実装 + Axiosでリクエスト送信

コンソールのRESTメニューから、RESTエンドポイントを作成します

### Create
```graphql
mutation MyMutation($data: Posts_insert_input!,) {
  insert_Posts_one(object: $data) {
    content
  }
}

```

graphQL入力画面からRESTタブをクリックすると、エンドポイントが作れます

![スクリーンショット 2022-06-05 14.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/a787ccd1-4d98-8cec-d3bd-60733555e96d.png)


```javascript

var headers = {
  "x-hasura-admin-secret": {Hasuraのシークレットキー}
};

// Mutationの引数に渡すデータを定義する
const data = 
{
  data: {
    content: "hoge"
  }
}

axios.post(
  {作成したエンドポイント},
  data,
  {headers: headers}
)
.then(res => {
  console.log(res.data)
})

```




### Read

```graphql
query MyQuery {
  Posts {
    id
    content
  }
}

```

Axiosでのリクエスト
```javascript
axios({
  url: {エンドポイントURL},
  method: 'GET',
  headers: headers,
})
```



### Update

```graphql
# $id: 編集対象のレコードid
# $data: 編集内容
mutation MyMutation($id: Int, $data: Posts_set_input){
  update_Posts(
    where: {id: {_eq: $id}},
    _set: $data
  ) {
    returning { # リクエスト時のレスポンスとして返すデータ
      id
      content
    }
  }
}


```

Axiosでリクエスト

```javascript

const data = 
{
  data: {
    content: "hoge"
  }
}

axios.post(
  {作成したエンドポイント},
  data,
  {headers: headers}
)
.then(res => {
  console.log(res.data)
})

```


### Delete

```graphql
# $id: 削除対象のレコードid
mutation MyMutation($id: Int!) {
  delete_Posts_by_pk(id: $id) {
    id
  }
}
```

Axiosでリクエスト

```javascript

const data = 
{
   id: this.props.id,
}

axios.post(
  {作成したエンドポイント},
  data,
  {headers: headers}
)
.then(res => {
  console.log(res.data)
})

```

ちなみにエンドポイントにパラメータを持たせることも可能

`posts/delete/:id`
このようにパラメータを指定


```javascript
var id = 1;

// postではなくdeleteを使う
axios.delete(
  {作成したエンドポイント} + id,
  {headers: headers}
)
.then(res => {
  console.log(res.data)
})

```

こうした方が楽かも？
localstackをローカル環境に立ち上げてみる

# 前提
AWSのCLIコマンドを学習する目的でlocalstackを立ち上げます。
プログラムの動作確認用にも使えます。

# 環境
- macOS 11.6.4
- docker-compose: 2.0.0
- localstack: 0.14.3（執筆時点で最新）

# 手順
#### docker-compose.xmlを任意のディレクトリに作成
以下にdocker-compose.ymlがあるのでこちらを参考に作成。
https://github.com/localstack/localstack/blob/master/docker-compose.yml

```docker-compose.yml
version: "3.8"

services:
  localstack:
    container_name: "localstack"
    image: localstack/localstack:0.14.3
    ports:
      - 4566:4566
    environment:
      - SERVICES=s3, sqs
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
```

environmentに定義できる設定は以下に載っています。
https://docs.localstack.cloud/localstack/configuration/
- `SERVICES`: カンマ区切りで使用したいサービスを記載
- `DEBUG`: ログをより詳細に出力したい場合にフラグを立てる
- `DATA_DIR`: 永続データを保存するためのローカルディレクトリ

#### コンテナを立ち上げる
```
docker-compose up -d
```

#### 立ち上がっているか確認
```
XXX % docker ps           
CONTAINER ID   IMAGE                          COMMAND                  CREATED          STATUS          PORTS                                             NAMES
205ec2df7163   localstack/localstack:0.14.3   "docker-entrypoint.sh"   20 minutes ago   Up 20 minutes   4510-4559/tcp, 5678/tcp, 0.0.0.0:4566->4566/tcp   localstack
```

#### AWSの設定ファイルと認証情報ファイルを設定
AWS CLIコマンドを使用するときに必要になります。
設定ファイル(config)と認証情報(credentials)を直接編集で以下の通り記載してください。
コマンドでも設定できます。[こちら](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)を参考にしてください。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html

`~/.aws/config`
```config:config
[profile localstack]
region = ap-northeast-1
output = json
```

`~/.aws/credentials`
```config:credentials
[localstack]
aws_access_key_id = dummy
aws_secret_access_key = dummy
```
[備忘録]MacにDockerとHomebrewをインストールする方法

一旦自分の備忘録用です。
気が向いたら清書します。

<h1>手順</h1>

1.Homebrewをターミナルからインストール
2.treeをインストール

3.Docker for Desktopをダウンロード
4.Docker for Desktopをインストール
5.Docker Hubにアカウント登録
6.DockerFileのBuild

7.Docker->mysql->Dockerfileの編集


docker-compose ps 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700084/2ab900fc-730a-d591-da6d-e4dfbd2fa027.png)
Nameがコンテナ名
docker-django_app_1　→　Pythonが入っているコンテナ
docker-django_db_1　→　MySQLが入っているコンテナ
docker-django_web_1　→　Nginxが入っているコンテナ
Stateという列がUpになっていたらそのコンテナが起動しているということになります。

<h1>[参考文献]</h1>

Docker:
https://trend-tracer.com/docker-django/
https://niwakatech.info/django-docker-compose/#toc4

homebrew:
https://qiita.com/kanuma1984/items/c158162adfeb6b217973
Web ページをベクタ形式で綺麗に保存する方法 (CSS の @media をいじってブラウザで印刷)

# 前提

画像ファイルにはラスタ形式とベクタ形式があります．
ラスタ形式はピクセル単位で画像データを管理しているため，拡大するとギザギザしてきます．PNG や JPEG などはラスタ形式です．
ベクタ形式は「座標 (10, 20) から座標 (60, 20) に直線を引く」みたいな感じで文字や図形を表現しているため，拡大しても綺麗なままです．SVG や EPS などはベクタ形式です．
PDF は基本的にベクタ形式ですが，ラスタ形式の画像を埋め込むことも可能です．

(と思っているのですが，画像形式の仕様について特別詳しいわけでないので，間違っていたら教えてください．)

# やりたいこと

Web ページをベクタ形式で保存したいです．普通の方法でスクリーンショットを撮るとラスタ形式になってしまいます．ラスタ形式は特に印刷すると汚くなってしまいます．

上述の通り，PDF はベクタ形式です．よって，ブラウザの印刷機能を使用して，プリンタの代わりに「PDF に保存」を選んであげれば Web ページをベクタ形式で保存できます．

# 困ったこと

一部のサイトは印刷を試みるとデザインが乱れてしまいます．これは

1. 画面表示用のデザインが適用されなくなり，
1. 印刷用のデザインが適用されるようになる

からです．

# 対処方法
まず，Web ページを保存します．今回は Save Page WE という Google Chrome の拡張機能をお借りしました．画像をデータ URI スキームに変換したり CSS を埋め込んだりして，Web ページを単一の HTML ファイルにして保存してくれます．かなり精度が良かったです．

https://chrome.google.com/webstore/detail/save-page-we/dhhpefjklgkmgeafimnjhojgjamoafof?hl=ja

これで所望の Web ページの単一 HTML ファイルを手に入れたら，次のようにファイルの中身の置換を行います．

1. `@media screen` → `@media all`
1. `@media print` → `@media tv`

Web ページのデザインを表現する CSS において，`@media screen` は画面用のデザインを指定することを，`@media print` は印刷用のデザインを指定することを，それぞれ意味します．そこで，画面用のデザインがすべての環境で適用されるように，そして印刷用のデザインをテレビ画面 (あるいはプロジェクタ用の `projection` とか，なんでも OK) でしか適用されないように修正します．

これで，画面上の見た目を保ったまま，Web ページを印刷してベクタ形式で保存できます．

なお，あるページでは `@media only screen` とかいうのもありました．上記の置換処理では漏れているメディアタイプ指定もいろいろあると思いますので，うまくいかなかったら `@media` で検索するなどして原因を探してみてください．
TwitterAPI v2でuser_fieldsの項目が取得できていないように見えても、実は取得できているから大丈夫

# 結論
user_fieldsのようなオプショナルな項目は、単にオブジェクト全体をprintしただけでは文字列として表現されないようになっているらしい。
ちゃんと明示的にアクセスすれば取り出せる。

```python
params = {
    'id' : 1526881736214597632,
    'user_fields' : 'public_metrics'
}
res = client.get_user(**params)
# ID: 1526881736214597632の総ツイート数を知りたかったので、public_metricsを要求

print(res.data)
# => <User id=1526881736214597632 name=壱百満天原サロメ💯🦂 username=1000000lome>
# user_fieldsやpublic_metricsが出てこないので、一見すると含まれていないように見える

print(res.data.public_metrics)
# => {'followers_count': 564575,
#     'following_count': 1,
#     'listed_count': 4033,
#     'tweet_count': 182}
# ちゃんと個別の項目を指定するとアクセスできる

```

# 環境
- Python 3.9
- tweepy

# 経緯
レスポンスデータを単純にprintして
`user_fieldsを指定したのに入ってないじゃないか😡`
と怒っていたところ、以下のStackOverflowの記事に救われた。

[Unable to retrieve public metrics using tweepy.Client](https://stackoverflow.com/questions/71390621/unable-to-retrieve-public-metrics-using-tweepy-client)

曰く、[TwitterAPI　v2のFAQ](https://docs.tweepy.org/en/v4.6.0/faq.html#why-am-i-not-getting-expansions-or-fields-data-with-api-v2-using-client)に書いてあるよとのこと。

>Why am I not getting expansions or fields data with API v2 using Client?
>
>If you are simply printing the objects and looking at that output, the string representations of API v2 models/objects only include the default attributes that are guaranteed to exist.
>
>The objects themselves still include the relevant data, which you can access as attributes or by key, like a dictionary.
>
>[Google翻訳]
>クライアントを使用してAPIv2で拡張またはフィールドデータを取得できないのはなぜですか？
>
>**オブジェクトを印刷してその出力を確認するだけの場合、API v2モデル/オブジェクトの文字列表現には、存在が保証されているデフォルトの属性のみが含まれます。**
>
>オブジェクト自体には、属性として、または辞書のようにキーでアクセスできる関連データが含まれています。
ActionDispatch::Http::Parameters::ParseError: 859の対処方法メモ

## 環境
macOS Monterey 12.3.1
ruby 3.1.2
rails 6.1.6

## エラー内容

[Talend API Tester](https://chrome.google.com/webstore/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm?hl=ja)でRails APIのテストを実施していたところ、以下のエラーが発生した。

```json:Talend API Tester
{
  "status": 400,
  "error": "Bad Request",
  "exception": "#<ActionDispatch::Http::Parameters::ParseError: 859: unexpected token at '{\n  
  \"name\": \"team1\",\n}\n'>",
  ...
}
```

## 発生時の状況

POST "http://localhost:3000/api/v1/teams" で以下の情報を送信していた。

```json
{
  "name": "team1",
}
```

コントローラは以下の様に設定していた。

```ruby:teams_controller.rb
class Api::V1::TeamsController < ApplicationController

  def create
    team = Team.new(team_params)
    if team.save
      render json: { team: }, status: :created
    else
      render json: {}, status: :internal_server_error
    end
  end
end
```

## 対処方法
[こちらの記事](https://qiita.com/murata0705/items/c6245d5b7f7ab3372497)を参考に、[JSONLint](https://jsonlint.com/) に送信したjsonをコピペしてチェックしました。
末尾に不要なコンマが入っていたため、エラーが発生していました。
修正後、無事リクエストが通るようになりました。