OmniAICreator/Qiita-1.07M huggingface dataset:
[キーワード] 学習 記憶 予習 復習 着想 効率的 逆算 計画 集中 戦略 攻略 脳 容量 英語 基礎 応用 

[逆算]
最初から考えて自分の行動を最小限にするための行動をする
手間を惜しむための手間を惜しまない
最初からビジョンを考えて軌道修正を重ねながら目標を達成する
e.g. 
　　授業前に予習しておいて、教科書に載っていないところだけを聞くなど

[逆算思考]
①. 目標ゴールを決める (目的意識を持つ) 
②. ゴールから引き算する
③. できることを確りやっていく
完璧主義は捨てる、ただし優先順位を厳密に守ることが重要
①. 自分の得意不得意を見据える
②. バランスを考え、できたときのイメージを持つ
③. 今、自分がやるこべきことを逆算する
④. 努力の方向性を間違えずに優先順位をつける
１日のタスクを適切に割り振る (時間管理)
自分のレベルにあった難易度、覚え方で行う

[勉強スケジュール]
タスクベースで目標を設定する
１つのタスクを小さくする（タスクの細分化: １時間本気でやれば終わるぐらいの粒度）
e.g. <Bad>英単語300個覚える
     <Good>英単語100個覚える、英単語100個覚える、英単語100個覚える
優先順位をあらかじめ決めることで１つのタスクに集中して取り組める
i.e. 脳は複数のタスクを同時に考えていると生産性が著しく低下する　
タスクの達成を短い間隔で繰り返し行えば、
タスクに対する心理的障壁が下がりモチベーションをキープにつながる
最終的にタスクを継続して達成するには、必ず目標を達成できるんだという精神力が必要

[暗記の基本]
短期・長期記憶の使い分けは暗記の基本
長期的に記憶したいときは、いかに繰り返し触れるかが大事
覚えたとことを思い出せたときに短期記憶を長期記憶に移行できる唯一の方法
覚えるときに目で追ったり線を引っ張るより、「いかに脳に負荷を与えるか」
自分の脳からその情報（記憶）を引き出すことが、たくさん覚えることにつながる

[キャパシティ]
脳にはキャパシティがあるので、毎回、全く新しい概念として覚えることは不可能
既存の知識と記憶すべき事項の関連性を考えて、本当に覚えるべき事項だけを選別して、
覚える必要のないものは既存の記憶と関連付けて簡単に覚える
新しい概念を既存の記憶に関連付けて覚える (コスパの良い記憶法)
eg.
　　１１９２作ろう鎌倉幕府 など、
すでにあるものに紐付けることで簡単に覚えられる
outbreakはoutとbreakからなるので、それぞれの単語の意味を理解した上で覚えると覚えやすい

[選択と集中]
労力を割くところ、割かないところのメリハリをつけるくことが大事
複数の参考資料を通読して重要なキーワードを把握する
基本的にどんなものがあるかを一通りチェックして１～２冊に絞って繰り返し読む
わからない概念があっても繰り返し読んでいくうちに、
少し見ただけで意味のネットワークが広がるようになる

[苦手分野の攻略]
必ずしも「理解することが」が先行する必要ない
暗記することで理解できることもある
理解と暗記のバランスが大事

[理解に至る過程]
ノートや教科書を見て目で覚える
書かずに、繰り返し読む（書いてる間に５回音読して覚えたほうが効率が良い）
人間はたくさんインプットに触れることでなんとなく物事がつかめてくる
e.g.
　　お医者さんの診断のときのように、症状や経過は一人ひとり違うため最初のうちは適切な診断ができない
　　そのため場数を踏むことで集合知を生み出し、次第にうまく診断できるようになる

[基礎と応用]
基礎を固めすぎると固執しすぎて応用ができなく恐れもあるため、
概念を理解したら、それを踏まえた上で応用する
分厚い参考資料は不要

[愚直に]
自分の脳から記憶を取り出す作業を数こなす

[戦略]
覚えるのが苦手なことは問題ない、むしろ武器になる
しかし、最低限覚えなければならないことは、戦略を自分なりに立てる
e.g. 
　　散歩しながら思い出す... 誰かにはなしてみる...
試して自分に合ったスタイルを見つけたらどんどん最適化していく
覚える作業は勉強の基本だから、基本を疎かにせず、効率も追求していくことが大事

[アウトプット]
インプットの組み合わせでしかアウトプットは出ない　
ある程度のレベルまでは、インプットを増やしていくことが大事　

[化学反応]
頭に知識を入れると化学反応がおきて、新しい知恵やアイディアを思いつく

[3キーワード暗記法]
3つのキーワードを頼りにして何度も思い出す
e.g. 
　　関ケ原の戦いは、1600年美濃の関ヶ原で、徳川家康を大将とする「東軍」と、
　　石田三成を中心とする「西軍」との戦い
　　東軍は総勢７万、西軍は総勢１０万が関ヶ原に人を構えた
    <ノートの書き方> P35 関ヶ原　東軍・西軍　７万・１０万
    <ノートの使い方> ノートを問題集として使う、３キーワードで思い出す
　　<復習方法>       翌日、３日後、７日後に復習する

[暗記復習の原則]
濃度と頻度が大切、自分の言葉で覚える(る)、脳に重要だと思わせながら反復する
・毎回、復習のときは１００％もしくはそれに近づくまでやる
・細かくタイミングを見つけてルーティーン的に復習していく
・自分の頭で噛み砕いたオリジナル(既存の知識を組み合わせた)文章で覚える
・本気で覚えようとしながら反復する (中途半端にやると脳がその情報を後回しにしてしまう)
e.g. 寿司職人で例えると、暗記は仕込みの作業、問題演習は握りの作業
　　 仕込みだけできても仕込んだものをどう組み立てるかを練習しなきゃ意味がない
     暗記はゴールじゃなくてスタート

[モチベーション]
環境から変える、スモールターゲットで成功体験をする、こまめに勉強を切る
自分を取り巻く環境を変えて、モノから遠ざかる
逆算して1日の目標を設定して達成すると明日もできると自信になりこれを繰り返し継続していく
たくさん暗記する代わりに薄く広くやる
反復する回転率を高く維持する

[英単語]
すべて音読する　
瞬時に思い出せるようになるまで繰り返す、思い出せたものだけにチェック
暗記は夜やって寝て朝起きてすぐ復習するのがより長期記憶に定着しやすい
書いていると、書くことが目的となり、目的の覚えるということを忘れてしまう
発音記号をみて音で英単語を覚える、スペルは重要じゃない！
英単語はコアイメージで覚える、例文があるとイメージしやすくて良い
e.g run = 一方向にながれるように移動するとイメージ
Cloud Tasks API は context に設定したタイムアウトが 30 秒より大きいとエラーになる

[googleapis/google-cloud-go](https://github.com/googleapis/google-cloud-go) を使用して [Cloud Tasks API](https://cloud.google.com/tasks/docs/creating-appengine-tasks#go) の `CreateTask()` 実行したところ 30 秒より大きいタイムアウトは設定できないというエラーメッセージ (`The deadline cannot be more than 30s in the future.`) が返ってきたので調べてみました。

## 同じ問題に遭遇した例がないか探す

エラーメッセージで調べたところ次の Issue が見つかりました。
(クローズされていますが内容を見る限りでは未解決のままです)

https://github.com/googleapis/google-cloud-go/issues/1577

個々のリクエストでタイムアウトを指定したつもりはなかったのですが context に設定したタイムアウトが 30 秒より大きいと Cloud Tasks API のサーバーがエラーを返すようです。

## タイムアウトはどのようにしてサーバーに伝わるのか？

`googleapis/google-cloud-go` が使用している [grpc/grpc-go](https://github.com/grpc/grpc-go) 内で context に設定された deadline を `grpc-timeout` ヘッダに設定しています。

https://github.com/grpc/grpc-go/blob/v1.38.0/internal/transport/http2_client.go#L492-L497

実は gRPC においてタイムアウトはクライアントのみが参照する情報ではありません。
gRPC のドキュメントにもサーバーは RPC がタイムアウトしていないか、または残り時間を取得できるとあります。

https://www.grpc.io/docs/what-is-grpc/core-concepts/#deadlines

gRPC の Blog でも無制限のリソース消費を避けるためにはサービス (今回は Cloud Tasks API) で適切な最長タイムアウトを指定する必要があるとしています。

https://grpc.io/blog/deadlines/

つまり context に設定したタイムアウトがサーバーに伝わることも、サーバーがそのタイムアウトをチェックすることも正しい動作になります。

## ドキュメントの記載を確認する

`googleapis/google-cloud-go` のドキュメントにはタイムアウトを設定していない context で非ストリーミング系 API が呼ばれた場合はデフォルトタイムアウトを設定する旨が記載されています。

https://pkg.go.dev/cloud.google.com/go#hdr-Timeouts_and_Cancellation

例えば `CreateTask()` の場合は 10 秒のタイムアウトを設定しています。

https://github.com/googleapis/google-cloud-go/blob/v0.84.0/cloudtasks/apiv2/cloud_tasks_client.go#L834-L838

しかし、 Cloud Tasks API がサポートするタイムアウト上限について記載されたドキュメントは見つけられませんでした。

## まとめ

- gRPC クライアントが設定したタイムアウトは gRPC サーバーでも参照できる
  - 設定によってはパラメータ不正でエラーになる
- Cloud Tasks API は context に 30 秒より大きいタイムアウトを設定するとエラーを返す
  - 30 秒という閾値はドキュメント化されていない
ADX2のビート同期が変わったので

ビート同期の機能の使い方が
CRIWARE Unity Plugin Ver.2.36.3
で
CriAtomExBeatSync.OnCallback
を使うように変わったので、
変更方法の備忘録

``` 旧.cs
CriAtomExBeatSync.SetCallback (this.BeatOn);
```
``` 新.cs
CriAtomExBeatSync.OnCallback += this.BeatOn;
```

```.cs
void BeatOn (ref CriAtomExBeatSync.Info info)
{
   Debug.Log ("<b>[MyDSound]</b> Beat! BPM(" + info.bpm + ") Beat(" + info.beatCount + ") Bar(" + info.barCount + ")");
}
``` 
こんな感じで曲のビート情報がログに出力できます。

[ビート同期のマニュアル](https://game.criware.jp/manual/adx2_tool/latest/criatom_tools_atomcraft_beatsync.html)

#コールバックも変わっていたようなので

``` 旧.cs
CriAtomExSequencer.SetEventCallback (SequencerEventCallback
```
``` 新.cs
CriAtomExSequencer.OnCallback += SequencerEventCallback;
```

```.cs
void SequencerEventCallback(ref CriAtomExSequencer.CriAtomExSequenceEventInfo info)
{
	Debug.Log ($"<b>[MyDSound]</b> {info.tag}");
}
``` 
[シーケンスコールバックのマニュアル](https://game.criware.jp/manual/unity_plugin/latest/contents/classCriAtomExSequencer.html#a9aba0fb44ad887d8e70c7a7eb0a373e6)
Webサイトをクロールしてtitleやdescription、h1タグを収集してCSV(or Excel)で管理する方法

Webサイトをクロール（スクレイピング）してtitleやdescription、h1タグを収集してExcel(or CSV)にまとめる方法を調べたので記事として残します。

Webサービスのコンテンツやページが増えてくるとページ１つ１つのtitleタグやmetaタグのdescriptionをチェックするのが困難になります。
例えば、バグで、あるページのh1タグが出力されなくなっていても気付くことが難しくなります。
本記事の手順でCSVを出力しバージョン管理しておくことで、SEOテキストに関係する処理を修正した後に差分を確認し、デグレや意図しない変更が発生していないかをチェックできるようになります。

# Site Audit SEO を使用します

<a href="https://github.com/viasite/site-audit-seo">site-audit-seo</a>というNode製のツールでWebサービスをクロールして各種SEOテキストを収集する事ができます。

インストール方法は上記リポジトリの<a href="https://github.com/viasite/site-audit-seo#install-with-npm">README</a>をご参照ください。（npmが必要です）

# クロールを行います

以下のコマンドでクロールを行います。
ここでは、ipaのページを最大10ページまでクロールしています。

```bash
site-audit-seo -m 10 -p parse --xlsx --out-dir . --out-name seo-texts -u https://www.ipa.go.jp/ \
    -f 'robots=$("meta[name=robots]").attr("content")' \
    -f 'canonical=$("link[rel=canonical]").attr("href")' \
    -f 'twitter_title=$("meta[name=\"twitter:title\"]").attr("content")' \
    -f 'twitter_description=$("meta[name=\"twitter:description\"]").attr("content")' \
    -f 'twitter_image=$("meta[name=\"twitter:image\"]").attr("content")' \
    -f 'og_title=$("meta[property=\"og:title\"]").attr("content")' \
    -f 'og_description=$("meta[property=\"og:description\"]").attr("content")' \
    -f 'og_image=$("meta[property=\"og:image\"]").attr("content")'
```

## 各オプションについて



| オプション | 説明 |
| --- | --- |
| -m 10 | max-requestsの略で、ページをスキャンする回数を最大10回に制限しています |
| -p parse | presetの略で、収集するフィールドのセットを指定できます。parseの場合はurl, title, h1, description, keywordを収集します。 |
| --xlsx | 処理結果をxlsxで出力します |
| --out-dir . | 処理結果を出力するフォルダを指定します。今回はカレントディレクトリを指定しています |
| --out-name seo-texts | 出力結果のファイル名を指定します。今回はseo-texts.xlsxになります |
| -u \<URL> | クロールの始点となるURLを指定します |
| -f '列名=処理' | 追加で収集するフィールドを指定します。左辺に列名を指定し、右辺に値を収集する処理を指定します。処理はjQuery(?)が使えるようです |

その他のオプションについては`site-audit-seo --help`で確認してください。

# 処理結果を確認する

処理が終了するとコマンドを実行したディレクトリにseo-texts.xlsxというファイルが出力されています。
この中に、収集したテキストが記載されています。

![](https://i.gyazo.com/5bd6641a3e3400651d1f3ee3f61cdfc0.png)

## Web Viewで結果を確認する

本記事では使用しませんが、処理結果をブラウザで確認する仕組みも用意されています。

クロールが完了すると、以下のようにコマンドが終了せず、待機状態になると思います。
これは内部的にサーバーが立ち上がっている状態です。

![](https://i.gyazo.com/c51c4901f7afab77f7222d5d6e70322c.png)

Online viewerの右のURLをクリックするとViewerが立ち上がり、ローカルサーバからデータを読み込んで可視化してくれます。

![](https://i.gyazo.com/bb45ef02b9a440e5579b437ae2c58294.png)

ローカルサーバを停止するにはCtrl+Cを押下します。

# 差分を把握する

上記のxlsxファイルをURL列の昇順でソートし、CSVにエクスポートしてgitで管理しておけば差分が閲覧でき、便利かと思います。

本記事は以上です。

# 余談

SEO関連のツールについて調べようとすると、検索結果にSEO業者の有料サービスへ誘導する記事ばかり表示されるのが辛い所ですね
【Rails】kaminariを使ってページごとに降順にする方法

##経緯
ページネーションを実装の際に、投稿したデータをページネーションの記述と合わせて降順にしたい時の方法が中々見つからなかったので、備忘録として書いています。

##Kaminariをインストール
こちらをご覧下さい↓

[参考URL](https://qiita.com/rio_threehouse/items/313824b90a31268b0074)

##方法
コントローラに以下を記述
```ruby:posts_controller.rb
@posts = Post.all.order(created_at: :desc).page(params[:page]).per(PER_PAGE)
```
または、
```ruby:posts_controller.rb
@posts = Post.all.order("created_at desc").page(params[:page]).per(PER_PAGE)
```

昇順にしたい場合は、`desk`を`asc`にすればOK!
UnityでのSwitch Pro コントローラーのボタン番号チートシート

<!-- Markdownのテンプレート -->

Sadmachineです．

UnityでSwitchのProコントローラーが使いたくなり，[Controller Tester](https://assetstore.unity.com/packages/tools/input-management/controller-tester-43621)を使用してProコンのボタン番号を調べてみました．

![image](https://user-images.githubusercontent.com/65950135/123572826-c8ca3d80-d807-11eb-8031-bdc76a00b9a2.png)
画像出典:Nintendo公式HP

<!-- /code_chunk_output -->

# UnityでのSwitch Pro コントローラーのボタン番号
|ボタン|番号| |
|:----|:----|:----|
|A|0|Positive|
|B|1|Positive|
|Y|2|Positive|
|X|3|Positive|
|L|4|Positive|
|R|5|Positive|
|ZL|6|Positive|
|ZR|7|Positive|
|+|8|Positive|
|-|9|Positive|
|Lスティックボタン|10|Positive|
|Rスティックボタン|11|Positive|
|HOMEボタン|12|Positive|
|キャプチャーボタン|13|Positive|

|スティック|番号| |
|:----|:----|:----|
|Lスティック→|2|Positive|
|Lスティック←|2|Negative|
|Lスティック↓|4|Positive|
|Lスティック↑|4|Negative|
|Rスティック→|7|Positive|
|Rスティック←|7|Negative|
|Rスティック↓|8|Positive|
|Rスティック↑|8|Negative|
|十字キー→|9|Positive|
|十字キー←|9|Negative|
|十字キー↑|10|Positive|
|十字キー↓|10|Negative|

Positiveは+，Negativeは-で入出力されます．

参考になったらLGTMお願いします！
【jQuery】Ruby on Rails で jQueryを使えるようにする方法と手順

#対象者

Ruby on Railsに初めてjQueryを実装する方

#手順目次

####1.gemを追加する

####2.application.jsにファイルを追加する

####3.スクリプトタグを自動的に生成


#実際の手順と実例

###1.gemを追加する


```````

gem "jquery-rails"

```````

追記できたら、***bundle install***を実行してgemを読み込みをする。

###2.application.jsにファイルを追加する


```````````
:
:
<この下の行を追加する>
//= require jquery
<この上の行を追加する>

//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
````````


###3.スクリプトタグを自動的に生成


app/views/layouts/application.html.erbを
下記ファイルに追加する

``````````
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
````````````

これでjQueryを使う準備ができました。

実際の例を上げると下記の通り

``````````
app/assets/javascripts/application.js
:
:

$(document).ready(function () {
  $('.jquery').on('click', function(){
    $(this).css('color','red');
  });
});
``````````

Viewファイルにて

`````````
<main>
  <div class="container">
    <div class="row">
     <h1 class="px-3 mx-auto">Welcome to <i class="fas fa-book"></i><strong>Bookers</strong>!</h1>
    </div>

    <!--クラスにjqueryを追加-->
    <p class="jquery">クリックすると色が変わるよ！</p>

  </div>
</main>
`````````

クリック後に色が変化しました！
Swiftで直接OpenCVを操作しよう！

SwiftでOpenCVを扱うための環境構築をメモしときます！
（参考サイトでうまくできなかった部分をメモ変わりに書いています）

# 環境
```
% swift --version
Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57)
Target: x86_64-apple-darwin20.5.0
% cmake --version
cmake version 3.20.4

CMake suite maintained and supported by Kitware (kitware.com/cmake).
% python --version
Python 3.8.5
% xcode-select --version
xcode-select version 2384.
```

# 環境構築
## OpenCV
```
// OpenCVをクローン
% git clone https://github.com/opencv/opencv.git
// ios用のディレクトリに移動
% cd opencv/platforms/ios
// ビルド
% ./build_framework.py <outputdir>
```

## Xcode
![General.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595751/3bff9d16-375f-5c05-2287-84e16c55dac8.png)

### BuildSetting
#### Linking

![BuildSetting-Linking.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595751/f9baf008-a040-3432-533c-2775513fd635.png)
- Other Linker Flags: ```-all_load```
- Path to Link Map File	
  - Debug:```$(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt```
  - Release:```$(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt```

#### SearchPaths
![BuildSetting-SearchPaths.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595751/7525edf5-1c2c-092e-252e-6aa67c9353f7.png)
- Framework Search Paths: ```$(inherited) $(PROJECT_DIR)/../.. $(PROJECT_DIR)/DemoOpenCV```
- Header Search Paths: ```../../opencv2/**```

# 参考サイト
https://qiita.com/treastrain/items/0090d1103033b20de054
【Android】右寄せEditTextの先頭に文字をつける

# 概要
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/25682470-cc7e-67bb-519e-aa5368df1a7f.gif" width=30%>

右寄せしたEditTextの先頭に＄マークなどをつける方法。

# レイアウト

＄マークの右に位置調整のためのスペースを配置するのがポイント。

```activity=main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	tools:context=".MainActivity">

	<!--$マークテキスト表示-->
	<TextView
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_marginEnd="8dp"
		android:text="$"
		android:textColor="@color/black"
		android:textSize="20sp"
		app:layout_constraintBottom_toBottomOf="@id/space"
		app:layout_constraintEnd_toStartOf="@id/space"
		app:layout_constraintTop_toTopOf="@id/space"
		tools:ignore="SpUsage"/>

	<!--$マーク位置調整のためのスペース-->
	<View
		android:id="@+id/space"
		android:layout_width="0dp"
		android:layout_height="0dp"
		app:layout_constraintBottom_toBottomOf="@id/edit_text"
		app:layout_constraintEnd_toEndOf="@id/edit_text"
		app:layout_constraintTop_toTopOf="@id/edit_text"/>

	<!--テキスト入力-->
	<EditText
		android:id="@+id/edit_text"
		android:layout_width="0dp"
		android:layout_height="wrap_content"
		android:layout_marginHorizontal="20dp"
		android:gravity="end"
		android:importantForAutofill="no"
		android:inputType="number"
		android:textColor="@color/black"
		android:textSize="20sp"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"
		tools:ignore="LabelFor"/>
</androidx.constraintlayout.widget.ConstraintLayout>

```

# 処理

テキストを入力する度に、レイアウトで配置したスペースのwidthを変更して＄マークの位置を調整する。

```MainActivity.kt
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		val binding = ActivityMainBinding.inflate(layoutInflater)
		setContentView(binding.root)

		binding.editText.addTextChangedListener(object : TextWatcher {
			override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
				// $マーク位置をスペースで調整
				val layoutParams = binding.space.layoutParams
				layoutParams.width = Layout.getDesiredWidth(s, binding.editText.paint).toInt()
				binding.space.layoutParams = layoutParams
			}

			override fun afterTextChanged(p0: Editable?) {}
			override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
		})
	}

```
Amazon Linux 2 に docker-compose のインストール

# 背景
環境構築を楽にするために、docker の勉強をしております。
今回は docker-compose を Amazon Linux 2 にインストールする手順を残します。

# 環境
Amazon Linux release 2 (Karoo)
Docker version 20.10.4
docker-compose version 1.29.2


# 手順
## バイナリファイルをダウンロード
公式Github からバイナリファイルをダウンロードします。

https://github.com/docker/compose/releases

```
sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
```

## 実行権限付与
実行権限を付与します。

```
sudo chmod +x /usr/local/bin/docker-compose
```

実行できるか確認

```
docker-compose -version
docker-compose version 1.29.2, build 5becea4c
```

# 最後に
`docker-compose`が実行できない方は、`/usr/local/bin`に PATH が通っていないかもしれません。
PATH を通すか、PATH が通っている場所にシンボリックリンクを張るか、`/usr/local/bin/docker-compose` で直接起動してください。
Power Automate Desktop<PAD>でエクセルの複数行を一括削除する方法

今回使用するファイル。8行まではちゃんとしたデータが入っているが、999行までゴミデータが入っている（今回は黄色で表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624137/7273df66-f6b2-50e0-ac14-0823b5c2b8c0.png)
PADの"Excelワークシートから行を削除"とLoopを組み合わせてもいいのですが、これだと如何せん時間がかかりすぎます。（一行ずつ削除するのですごく遅い）
なので以下の方法で一括削除していきたいと思います。
<h1>今回のフローはシンプルです</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624137/22cc36cc-4a01-50a1-4da3-b105087feeef.png)
エクセル起動
↓
空の行列取得
↓
削除したい範囲を選択（今回は手動で設定しています。）
↓
<b>キーの送信{LControlKey}({OemMinus}){Return}</b>
<h1>アクションにない項目はデスクトップレコーダーで録画してキーの送信で使いまわそう！</h1>
キーの送信、<b>{LControlKey}({OemMinus}){Return}</b>では、
「コントロールkeyを押しながらマイナスキーを押す、そのあとにエンターkeyを押す」　という作業を行っています。
既に削除したいエクセル範囲は選択されているのでこれを行うと行の削除を行って上方向にシフトをしてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624137/e2217f2e-a6bf-4e17-bfa2-e29a0c8eef48.png)
これはPADのデスクトップレコーダーで作業方法を取得しました。エクセルのレポート作成に結構使うので便利です。

<h1>おまけ</h1>
例えば、データが歯抜けの状態のエクセルがあって、
「特定の列に空白がある行だけを削除する」　というものやれそうな気がするのですが今のとこ出来ていません。
PADで出来ない部分はVBAで補う、といった工夫が大切だと思います。

次回はこの技を組み合わせてピボットテーブルを自動で作成しようと思います。
「断面二次モーメントと断面係数」の図(SVG)と数式(MathJax)をCodePenで表示してみた

# はじめに
　Qiitaは、数式をMarkdownの文中に記載できるが、SVGは表現できない。なので、CodePenに落とし込んでみた。
　~~上手くいったが、CodePenが縦に狭いのが残念。~~
　CodePenを縦に伸ばすことが出来きた。

# 結果
<p class="codepen" data-height="1331" data-default-tab="result" data-slug-hash="mdmbYEV" data-user="kobe2018" style="height: 1331px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kobe2018/pen/mdmbYEV">
  </a> by F.M (<a href="https://codepen.io/kobe2018">@kobe2018</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# リンク
[はてなブログ「断面二次モーメントと断面係数。断面形状はSVG」](https://good-kobe.hatenablog.com/entry/2021/06/24/225254)
WSL2のUbuntu(20.04.2 LTS)でHeroku CLIをアンインストールする

# はじめに
こんにちは。缶詰のココナッツミルクをスーパーで探すクエストがあり、お助けキャラ(やさしいおばちゃん店員さん)を頼って見事完了しました。缶詰コーナーに無くて、エスニックコーナーにあって難易度高めでした :innocent: 

さて、今回は**Heroku CLI**のアンインストールをしたので記事にしようと思います。

公式に記載のインストール方法ができなくて、エイヤでインストーラーcurlして取ってきてshellで入れたのですが、そもそもなんで公式の方法でインストールできなかったのかを調査したいと思ったので、一旦アンインストールしようと思った次第です。

# WSL2のUbuntu(20.04.2 LTS)でHeroku CLIをアンインストールする
アンインストールの方法は以下公式ドキュメントにも記載があります。
こちらを参考に進めていこうと思います。

https://devcenter.heroku.com/articles/heroku-cli#standalone-installs

## 1. コマンドを削除
ドキュメントには`/usr/local/bin/heroku`のようでしたが、私は以下にインストールされてました。

```sh
$ which heroku

/usr/bin/heroku
```

そんなわけでこいつを削除します。
(-v オプションをつけるのはクセです:pray: 消したよって表示される安心感が素敵 :v:)

```sh
$ sudo rm -v /usr/bin/heroku
removed '/usr/bin/heroku'
```

## 2. ソースを削除
ドキュメント見ると、`/usr`下にフォルダがあるっぽいので探してみます。

```sh
$ cd /usr/ && find -type d -name 'heroku'

./lib/heroku
```

いました。私の場合、ドキュメントとは違う場所ですが、こいつを削除します。

```sh
$ sudo rm -rfv /usr/lib/heroku
```

## 3. キャッシュ削除
ホームディレクトリに入るっぽいので探してみます。

```sh
$ find  -type d -name 'heroku'

./.cache/heroku
./.local/share/heroku
```

これはドキュメントと一緒ですね！
削除しましょう！

```sh
rm -rfv ~/.local/share/heroku ~/.cache/heroku
```

完了です :ok_hand:

# おわりに
インストールの仕方によって削除対象の場所が変わると思うので1個ずつ探しながら削除してみました。
参考になれば幸いです :pray:
随分前からifconfig, route, netstat, arpが非推奨になっていたというお話

# はじめに
LPIC201を勉強していてrouteの問題が出たので
vagrant環境で用意したCentOS7でrouteを実行したら「Command not found」と出たので
不思議に思って調べたら
https://www.ubuntu-perl-web.com/blog/20200324174004.html
より、今は非推奨となったことを知りビックリしたのでメモ

## 現在のネットワーク管理ツールはiproute2
http://iwashi.co/2014/08/07/reason-why-we-should-use-iproute2
によると（2014年の記事だよ…驚きです）
「高機能で、速くて、便利だから、iproute2を使うべき」
と非常にわかりやすい説明をいただいた。

## どうしてもifconfigを使いたい人はnet-toolsをインストールしたらいいよ

```
yum install -y net-tools
```

で使えるようになるそうです。そうかぁ…知らなかったなぁ…。
Cypressを触ってみる

#Cypressとは？

https://www.cypress.io/

Webサービスのテスト用に構築されたJavaScriptライブラリです。

JavaScriptライブラリなので、JavaScriptでテストスクリプトを記述して使用する
オープンソースなので、無料で使える
GoogleChromeのみ対応している
動作が軽い
単体テストからE2Eテストまで広く使える
コマンドごとに画面のスナップショットを見返せる
各種CIとの連携が可能である


#環境構築

https://nodejs.org/ja/download/

JavaScriptなので、node.jsを事前にインストールしておきます

#Cypressのインストール

Cypressはプロジェクト毎にインストールする必要があるので、インストールしたいディレクトリに移動します。
npm installを実行します。

```
npm install cypress
```

#Cypressの起動

Cypressの本体はnode_modulesのbinファイルにいるので、それをopenします。

```
./node_modules/.bin/cypress open
```

するとCypressの管理画面が起動します。

![スクリーンショット 2021-06-28 11.10.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/791219/756e8386-6b05-ed78-30d7-fdaf043cbbed.png)

あらかじめいくつかテストスクリプトが用意されているので、
試しに"action.spec.js"を起動します。

別ウインドウでGoogle Chromeが起動し、テストスクリプトが実行されます。

#ファイル構成

![スクリーンショット 2021-06-28 11.13.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/791219/d6ae0250-aa83-9470-b4c0-7a350b06bcaa.png)

integrationテストのスクリプトはintegrationの中に入っているので、試しにテストスクリプトを書いた"HelloWorld.js"を"integration"内に配置します。

Seleniumとの違いは下記の記事が参考になりました。

https://qiita.com/kkakizaki/items/4b6625a56fd2fa4c741c
備忘録：LocalDateTime型を受け取れない

thymeleafからLocalDateTimeを受け取ろうとして、modelのメンバ変数でlocaldatetimeにしたところ型変換エラー。

thymeleafは基本的にStringでのやり取りということを忘れていた。
今のところString型での運用で問題ないのでStringに変えて放置。
LPICレベル1を勉強しているあなたへ - システムを再起動させる4つのコマンド -

telinit 6

shutdown -r now

systemctl reboot

systemctl start reboot.target

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1600293/5a38ce4b-8733-3f57-6fb5-32626516584d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1600293/52d98b30-cefb-c178-d8d1-47974f2f015e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1600293/931e8fcf-8b33-ac8f-ff0f-225a1d88f23f.png)

引用元
https://mondai.ping-t.com/question_subjects/31/question_sessions/4063231/progressing_questions/62396601?result=true
LPICレベル1を勉強しているあなたへ - systemctlコマンドのサブコマンド一覧 -

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1600293/e420cee0-95b1-b37c-5f1a-9498d828e522.png)

引用元
https://mondai.ping-t.com/question_subjects/31/question_sessions/4063231/progressing_questions/62396598?result=true
HTML Bad character % after <. Probable cause: Unescaped <. Try escaping it as &lt;. エラーについて

###エラーの経緯
rubyを埋め込んだerbファイルのHTMLを構文チェックしたところ、エラーになりました。

### エラー内容
```
Bad character % after <. Probable cause: Unescaped <. Try escaping it as &lt;.
```
特殊記号がエスケープできていないから &it を試してね。
ということでした。

###エラー部分の記述
```
          <tr>
            <td>会社名</td>
            <td>
              <% c_name = params['company'] %>　<!--　この部分が構文エラー -->
              <%= c_name %>   <!--　この部分が構文エラー -->
            </td>
          </tr>
```
今回はrubyを埋め込むerbファイルをそのまま構文チェックしていたので、「ページのソースを表示」からそのページのHTMLを取得する必要がありました。

###よく使う特殊記号のエスケープ
```
 &amp;(アンパサンド)                    
    <br />
    &lt;(小なり)
    <br />
    &gt;(大なり)
    <br />
    &quot;(ダブルクォーテーション)
    <br />
    &nbsp;（空白）
    <br />
    &copy;（コピーライト）
```
waitUntilCompleted iOSの非同期処理を同期にする

# 概要

最近仕事で非同期を同期にして処理するニーズがあったので、古いコードでライブラリも使えないので、GCD使って簡単に実装してみました。

```swift
let task = Task()

task.doSomeThingAsync()
task.waitUntilCompleted()

print("finished")
```

## 詳細

- DispatchSemaphore インスタンス生成
- semaphoreインスタンスqueue止めたいところwait呼ぶ
- 非同期処理終わったらsemaphoreインスタンス signal呼ぶ


# コード

```swift
class Task {
    var semaphore: DispatchSemaphore?
    
    func doSomeThingAsync() {
        semaphore = DispatchSemaphore(value: 0)
        DispatchQueue.global().async { [weak self] in
            print("doing task...")
            sleep(1)
            print("task done!")
            
            // 実行終了
            self?.semaphore?.signal()
            self?.semaphore = nil
        }
    }
    
    func waitUntilCompleted(_ timeout: TimeInterval = 0) {
        // 0の場合はtimeout設定しない
        if timeout == 0 {
            semaphore?.wait()
            return
        }
        semaphore?.wait(timeout: .now() + .milliseconds(Int(timeout * 1000)))
    }
}


```

# 注意:

waitだとsignal呼ばないとqueueをブロックしてしまうので、実行queueはmain queueではなく別のqueueにするか、`func wait(timeout: DispatchTime)` 使ったほうが無難.

#　参照

[DispatchSemaphore](https://developer.apple.com/documentation/dispatch/dispatchsemaphore "DispatchSemaphore")
sudo python my_script.py で sudo: python: command not found となる場合の対処方法

# 環境

* Ubuntu 20.04.2 LTS (Focal Fossa)
* Python 3.8.5
* venv 環境

# 理由

パスの設定が上書きされ、Pythonコマンドがみつからなくなるため。

> Your /etc/sudoers is explicitly configured to override your user's path with a known, secure one.
> *1 より

# 対処方法

## [方法1] .bachrc にパスを引き継いで実行するコマンドを新設する

```bash:.bachrc
psudo() { sudo env PATH="$PATH" "$@"; } 
```

```bash:command
psudo python my_script.py
```

## [方法2] パスを引き継ぐように実行時のコマンドを編集する

```bash:command
sudo env "PATH=$PATH" python my_script.py
```

# 参考資料
- *1 https://stackoverflow.com/questions/44726377/sudo-python-command-not-found
シンプル星評価機能 ~ Rails 

# 星評価機能

このページでは投稿の星評価機能をシンプルに実装します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614347/ef3dcce3-8372-f69b-d025-d9eac8922264.png)


１．integer型のstarカラム追加
２．for文で番号の数だけ☆を表示
３．CSSで簡単にデザインを実装

投稿用のテーブルはtweetsテーブルを例に挙げています。

### １．integer型のstarカラム追加

```sh:cmd
$ rails g migration AddStarToTweets star:integer
$ rails db:migrate
```

### ２．for文で番号の数だけ★を表示

※過去に投稿していたレコードのstarカラムはnilになっているので、for文で扱うときにエラーが起こります。これを回避するために一旦過去レコードを削除しましょう。

```sh:cmd
$ rails c
> Tweet.destroy_all
> exit
```

次に、新規投稿ページと一覧表示ページを以下のように記述します。

```erb:views/new.html.erb
<%= form_for(@tweet, :url => { controller:'tweets', action:'create'})do |f| %>

<!-- 中略 -->

<div class="star-field">
    <input id="star5" type="radio" name="tweet[star]" value="5" />
    <label for="star5">★</label>
    <input id="star4" type="radio" name="tweet[star]" value="4" />
    <label for="star4">★</label>
    <input id="star3" type="radio" name="tweet[star]" value="3" />
    <label for="star3">★</label>
    <input id="star2" type="radio" name="tweet[star]" value="2" />
    <label for="star2">★</label>
    <input id="star1" type="radio" name="tweet[star]" value="1" />
    <label for="star1">★</label>
</div>

<!-- 中略 -->

<% end %>

```

ラジオボタンを利用しています。どれか一つが選択されたら、該当の数字が送られます。

```erb:views/tweets/index.html.erb
  <% @tweets.each do |t| %>
      
    <!-- 中略 -->

    <div class="star">
      <% if t.star? %>
        <% for i in 1..t.star do %>
          ★
        <% end %>
      <% end %>
    </div>

  <!-- 中略 -->

  <% end %>
</div>
```

もし`t.star`が存在していたら、t.starの数だけfor文を回して★を表示しています。

### ３．CSSで簡単にデザインを実装
一例として以下のように実装できます。
自分に好みにしていきましょう。

```tweets.scss
// 新規投稿ページ
// https://www.will3in.co.jp/frontend-blog/article/5star-rating-on-contact-form7
.star-field{
    display: flex;
    flex-direction: row-reverse;
    justify-content: right;
}
.star-field input[type='radio']{
    display: none;
}
.star-field label{
    font-size: 50px;
    padding-right: 10px;
    color: #ccc;
    font-size: 30px;
    cursor: pointer;
} 
.star-field label:hover,
.star-field label:hover ~ label,
.star-field input[type='radio']:checked ~ label{
    color: rgb(255, 145, 0);
}

// 一覧表示ページ
.star{
  font-size: 50px;
  color: rgb(255, 145, 0);
}
```
基本情報技術者試験（FE）を受けたので振り返りとその感想


# 基本情報技術者試験とは
ITエンジニアの登竜門と言われる試験。
経済産業大臣が行う国家試験「情報処理技術者試験」の区分の一つ。
年間10万人以上が受験するみたいです。（知らなかった...！）

試験は午前試験・午後試験に分かれています。
両試験ともに60点以上で合格です。

||午前|午後|
-+-+-
|試験時間|150分|150分|
|出題形式|多肢選択式（四肢択一）|多肢選択式
|出題数|出題数：80問|出題数：11問
|解答数|解答数：80問|解答数：5問|

# 受けようと思ったきっかけ
自分はネットワークやセキュリティ、アルゴリズムの知識が弱くて
体系的に勉強したいな〜と思っていたところ
基本情報の内容がぴったりだと感じ、勉強することにしました！

基本情報技術者試験が一時的にCBT方式になったことで
スケジュール内であれば受験日を自分で選べることを知り
「今から計画的に勉強すれば間に合うかも！」ということで受験することにしました。

# 試験勉強期間・学習計画
4月〜6月までの約3ヶ月。

4月は基本情報の参考書みっちり。

自分は午前試験と午後試験の間隔を１ヶ月空けたので、

5月~6月の間で、午前試験が終わるまでは午前の過去問対策、
午前試験が終わってから午後の過去問対策を始めました。

# 試験勉強で使った参考書・サイト
## キタミ式イラストIT塾 基本情報技術者
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564392/18a662ba-1087-a500-69f6-7c6fdd201e80.jpeg" width="200">

解説が詳しくて分かりやすいため、情報系の大学を出ていない自分でも
サクサク読み進めることができました！
（途中で過去問演習に切り替えたので全部は読めていませんが...！）

いきなり過去問を解き始めるよりも、ざっくりでもいいので参考書1冊読んでからの方が
過去問を解く土台が出来上がるので効率良いかと思います！


## 過去問道場
![スクリーンショット 2021-06-24 19.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564392/1a5cb4e5-7132-8dcc-5521-9c9efdf492f8.png)
解説付きで過去問が載っているので、ありがたく使わさせていただきました！
サイトにも記載がありましたが、過去問は最低でも4回分、余裕があれば8〜12回分を解くと良いそうです。

1年分の過去問でも意外と結構な分量だったので
自分は午前は3回分を2周して、
午後に関しては1年分解いて点数が低かったところを重点的に勉強しました。

# モチベーションの上げ方
試験勉強は長期戦になるので、何回か挫けそうになりました。
（特に午後試験のアルゴリズム...！）

心が折れそうになった時はTwitterで「基本情報 午後」とかで検索して
同じく基本情報技術者試験を受ける同志の方を見つけて
モチベーションを上げました。
「もう少し自分も頑張ろう！」って気持ちになれるのでおすすめです！

# 基本情報技術者試験の受けてみて
かなり広い範囲を問われるので、自分の知識が足りていない分野を知ることができて良かったです！
基本情報で問われる内容は即効性はないのかもしれませんが、他の知識を吸収するときの
土台にはなると思うので、自分は受けてみて良かったと思いました！

肝心の合否については来月発表なので、気長に待ちたいと思います！
（ps. 合格していました！）
SQL Sellについて

コマンドプロンプトの画面でパスワードが表示されないときは表示されていないだけで実際は打てていてパスワードを打ち間違えている可能性がある。


問：コマンドプロントにてＤＢへ接続するために「psql postgre」と入れたのですが

Password :

となるのですが、どのキーをたたいても入力することができません。エンターキーを押すと

psql: FATAL: password authentication failed for user "postgre"

と出るか

paql: fe_sendauth: no password supplied

と出てしまい何もできません。パスワードはコマンドプロントで入力できないのでしょうか？


答え：パスワードが表示されていないだけで、入力されているんですよ。

だから、
psql: FATAL: password authentication failed for user "postgre"
アクセス権が無い（パスワードが違ってる）
paql: fe_sendauth: no password supplied
パスワードが入力されていない（Enterを押しただけ）
というエラーが返ってきています。

表示されませんから、正確に入力してみましょう。
Google Colab で動画が出力できなかったとき

## はじめに

[Google Colab](https://colab.research.google.com/) は非常に便利なサービスです

GPU インスタンスを、限られた時間とはいえ、無償で利用できます

例えば、様々なAIモデルの比較検証を行なっているとき、すぐに GPU で高速に動かせるのは大変ありがたい（ローカルに GPU マシンを用意した方がいいのは間違いないが）

一枚の静止画で試すのであれば CPU でもどうにかなりますが、動画で試そうと思えば GPU がないのは辛いです

## なぜか動画が出力されない

多くの AI モデルのリポジトリーには、とりあえず動かしてみるためのコードが大体ついています

`demo.py` や `inference.py` などの名前で

また、 README.md にも大抵実行方法や実行例を親切に書いてくれています

しかも、多くの場合、動画でもちゃんとデモが動かせるのです

CenterNet2 のモデルをとりあえず動かしてみようとしたとき、静止画ではちゃんと動くのに、なぜか動画が出力できませんでした

https://github.com/xingyizhou/CenterNet2

なぜでしょうか

## 単純な答え

答えは単純で、実は[コードの中にコメントでも記載されていました](https://github.com/xingyizhou/CenterNet2/blob/master/demo/demo.py#L145)

要するに、動画コーデックが、 Google Colab 上で使えないものだったのです

OpenCV では、動画を出力するときに Writer を以下のようにインスタンス化します

```python
cv2.VideoWriter_fourcc(*"x264")
```

ここで指定している `*"x264"` の部分がコーデックです

Colab 環境では、 `*"x264"` が使えないのです

## コードの編集

左側メニューからフォルダアインコンをクリックすると、ファイルがツリー構造で表示されます

![スクリーンショット 2021-06-28 9.45.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/80889683-d29b-913f-5e05-7adc23e058d6.png)

編集したいファイルをダブルクリックすると、ウィンドウ内の右側にファイルが開きます

`*"x264"` を `*"mp4v"` に書き換えます

macOS の場合は ⌘＋S 、 Windows の場合は Ctrl+S で保存します（一定時間経過でも保存されます）

これで改めて実行すれば動画が出力されます

## まとめ

動画が出力されないときはコーデックを確認しましょう

Colab なら `*"mp4v"` で MP4形式の動画が出力できます

また、リポジトリーによっては Colab で動かすノートブックを置いてくれていたりもしますので、 README をよく読みましょう
Cluster API: v0.3.17, v0.3.18, v0.3.19 変更内容

## はじめに

ここでは Cluster API v0.3.17, v0.3.18, v0.3.19 の変更内容についてまとめています。

- https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.17
- https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.18
- https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.19

Cluster API は複数の Kubernetes クラスタのプロビジョニングやアップグレード、オペレーションをするための宣言的な API とツールを提供する SIG Cluster Lifecycle のサブプロジェクトです。

## Cluster API v0.3.17 (2021/5/28)

### ⚠️  Breaking Changes（破壊的変更）

- KCP: Kubernetes v1.22 で kubeadm の ClusterStatus の更新と使用を停止 ([#4485](https://github.com/kubernetes-sigs/cluster-api/pull/4485))
    - CAPI の上に構築されたすべてのツールは Kubernetes v1.22 に備えて同様にする必要があります

:memo: ClusterStatus は kubeadm v1beta と v1beta2 で `kubeadm-config` Configmap に記録される情報でクラスタで利用可能な API エンドポイントを記録するために使用されていましたが、kubeadm v1.18 で廃止予定となり、代わりに kube-apiserver Pods の annotation に記録するようになっていました。現在ではこれが最初に選択される方法ですが、2つめの廃止予定の機能としてまだメンテナンスされています。しかし kubeadm v1beta3 で ClusterStatus を完全に削除する予定で、ClusterStatus を使用している Cluster API に大きな影響がありました。

### 🐛 Bug Fixes（バグ修正）

- 修復される etcd メンバが見つからない場合に KCP remediation の許可 ([#4591](https://github.com/kubernetes-sigs/cluster-api/pull/4591))
- `cluster config cluster` で存在しない Kubernetes クラスタに対してコマンドが実行できないように修正 ([#4578](https://github.com/kubernetes-sigs/cluster-api/pull/4578))
- `cluster config cluster` で空のクラスタでコマンドを実行できないように修正 ([#4560](https://github.com/kubernetes-sigs/cluster-api/pull/4560))

### 🌱 Others（そのほか）

- kube-rbac-proxy を v0.8.0 にアップグレード ([#4639](https://github.com/kubernetes-sigs/cluster-api/pull/4639))
- &gt; 1 レプリカのサポートするために KCP remediation を更新 ([#4595](https://github.com/kubernetes-sigs/cluster-api/pull/4595))
    - :memo: これまで KCP remediation は3レプリカ未満の場合に実施されないようになっていましたが、[#4591](https://github.com/kubernetes-sigs/cluster-api/pull/4591) の修正により etcd メンバがいない KCP マシンに対しても remediation が問題なく実施できるようになったために remediation 可能なレプリカ数が緩和されました
- CAPI v0.3 リリースに metadata を含む ([#4589](https://github.com/kubernetes-sigs/cluster-api/pull/4589))
- クイックスタートの Azure プロバイダの前提条件のリンクを更新 ([#4539](https://github.com/kubernetes-sigs/cluster-api/pull/4539))

## Cluster API v0.3.18 (2021/6/9)

### 🐛 Bug Fixes（バグ修正）

- CAPD: conntrack sysctls を設定しない Linux セキュリティアップデートの修正 ([#4728](https://github.com/kubernetes-sigs/cluster-api/pull/4728))

### 🌱 Others（そのほか）

- Kubernetes v1.22 適合のための更新をバックポート ([#4766](https://github.com/kubernetes-sigs/cluster-api/pull/4766))
- github.com/coredns/corefile-migration を 1.0.11 から 1.0.12 に更新 ([#4743](https://github.com/kubernetes-sigs/cluster-api/pull/4743))

## Cluster API v0.3.19 (2021/6/10)

### 🐛 Bug Fixes（バグ修正）

- kubetest config をパースする際にデータをポインタに Unmarshal するように修正 ([#4776](https://github.com/kubernetes-sigs/cluster-api/pull/4776))
[React] フロントエンドのテストって何するの？

# テストってなんで書くの？
--- 

## こんな悩みはありませんか？

- 書いたコードに予期せぬバグがあるのではと心配になり、夜も眠れない
- 変更後に致命的なバグが突然発生する悪い夢にうなされる

--- 

## テストの目的
- 「想定通りに動くのか」を担保するため
- 開発者自身のため
- 変更に強い仕様書をつくる

---
# テストってどうやってを書くの？
---

## Testing Torophy

- JSテスト界の大御所Kent.Cが提唱するテストのコンセプト
- 体積が大きいところほど重要であるとしている(ここではIntegrationが最も大きい)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386799/16c8cc69-2e11-9fbf-5ac8-158943e082fd.png" width="550">

---
## トレードオフの発生
- テストの実行スピード
- 工数
- カバレッジ

<img src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F82363%2Fda49f860-4296-9ab4-cc08-186ecc8888ad.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=350ca04cddac9646515b2f4a526d9df0" width="700">

---
## Kent.Cの方針
<img src="https://kentcdodds.com/static/kent-985f8a0db8a37e47da2c07080cffa865.png" width="250">
Kent.Cがtesting-libraryのドキュメント内で言っていたこと。

- テストはアプリケーションの利用方法に似ているほど信頼性が得られるのさ
- 実装の詳細をテストしないことを勧めるよ（実施してもいいけどね)

---

# テストって何を書けばいいの？

---
## 実際に書いてみる
テスト対象: Incrementボタンを押すと、数字が1増えて表示される。(初期表示は0)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386799/de2c54e1-b76b-06b9-1d92-420e258ed729.png" width="200">

```react
export function Counter() {
  const [count, setCount] = useState(0);
  const increment() {
    setCount(count + 1);
  }
  return (
    <>
      <div>Number: {count}</div>
      <div>
        <button onClick={increment}>Increment</button>
      </div>
    </>
  )
}
```

---
## 実際に書いてみる
仕様ライブラリ: Jest, react-testing-library
テスト内容:
- 初期表示はNumber: 0
- Increamentボタンを押すと数字が1つ増える

```react
import { fireEvent, render, screen } from "@testing-library/react"
import { Counter } from "./"

describe("Counter", () => {
  test("render", () => {
    render(<Counter />)
    expect(screen.getByText('Number: 0')).toBeInTheDocument();
  })
  test("increment", () => {
    render(<Counter />)
    const button = screen.getByText("Increment")
    fireEvent.click(button)
    screen.getByText("Number: 1")
  })
})
```
なるほどこれは仕様書になる...!

---

## Reactで優先的に書くべきテスト

- ロジックがあるor少し複雑なUIコンポーネントのIntegration Test
- Custom Hooksなどの切り出されたロジックのUnit Test

ロジックが複雑でバグが出やすそう...
ここが壊れたらヤバい！不安で夜も眠れない...
そんな不安を解消してくれそうな部分からテストを書きましょう。

---

# はじめてテストをやってみて

---

## 感想・気づき

- サーバーサイドのテストとはまた違った難しさがある
- Integration Testをしっかり書けば仕様書になる
- E2EテストのCypressも触ってみたい

---

# ご清聴ありがとうございました

---

## 「複業クラウド」について
弊社Another worksでは複業マッチングプラットフォーム「複業クラウド」を開発しています！

▼複業でスキルを活かしてみませんか？複業クラウドの登録はこちら！
https://talent.aw-anotherworks.com/?login_type=none
【AtCoder】ABC207をPython3で解説

ABC207の解説。

https://atcoder.jp/contests/abc207

## A - Repression
### 解説
3枚のカードから2枚選び、その最大値を求めるという問題。

単純に、3通りの最大値を求める方法がある。
もっとスマートに書くなら、AとBとCの合計値から、A,B,Cいずれかの最小値`min()`を引くということもできる。 

### コード
```python
A, B, C = map(int, input().split())

print(A+B+C - min(A, B, C))
```

## B - Hydrate
### 解説

$A$個の水色ボールが入った容器に、水色ボール$B$個と赤色ボール$C$個を毎度足していく。
結果、容器の水色ボールの個数が赤色ボールの個数の$D$倍以下となれば良い。

水色ボール　<= 赤色ボール × D

つまり、$x$を回数とし、式にすると、

$A + Bx \leq D \times Cx$

これを満たす数があるか、または、あればこの最小値を求める。
これを式変形して、

$A + Bx \leq D \times Cx$

$A \leq CDx - Bx$

$A \leq (CD - B)x$

ここで、$CD - B$が0以下であれば、条件を満たさない。
そうでない場合は、$x$は$A / (CD - B)$で切り上げた値となる。

これをコードで実装してあげれば良い。

また、`while`を使ってコード2のように実装してあげることも可能である。

### コード1
```python
A, B, C, D = map(int, input().split())

e = C * D - B

if e <= 0:
    print(-1)
else:
    ans = (A+e-1)//e
    print(ans)
```

### コード2
```python
A, B, C, D = map(int, input().split())

blue = A
red = 0
cnt = 0

if B >= C*D:
    print(-1)
    exit()

while blue > D * red:
    blue += B
    red += C

    cnt += 1

print(cnt)
```

## C - Many Segments
### 解説

$1 \leq i < j \leq N$で、区間$i$と区間$j$の共通部分をもつ個数を数える問題。
1-4の各区間については、問題文のとおりである。

今回の問題で大切なことは、**$i$と$j$は、整数の組だということだ。**
開区間の"未満"をそのまま用いると実装が難しいので、すべて閉区間[ ]に直したい。
つまり、開区間の値を少しだけずらしてあげる必要がある。

どうやったらいいのかというと、$t, l, r$を入力するときに、$l, r$の値をそれぞれ2倍してやるといい。
こうすることで、整数ではない、0.5のような半分の値を扱うことができる。

開区間の設定は、`if`で$t$が3以上であれば、左側が開区間なので、その値自体を含まないように下限値に1を足してあげるとよい。同様に、$t$が2で割れる、つまり、右側が開区間の場合、上限値に1を足してあげると良い。

これについて、ループを回す。今回は、$1 \leq i < j \leq N$という制約があるので、$i$は$j$の値を超えてはならない。したがって、$j$についてのループは、$i+1$から始まるようにする。

中身の条件式は、条件をみたすように書く方法もある。しかし、少し条件式が長くなってしまい、スマートではない。したがって、今回は逆に条件を満たさないものを条件式として書き、それ以外のものを数え上げるというやりかたをしている。$j$の下限値が$i$の上限値よりも小さいのとき、また、$i$の下限値が$j$の上限値よりも小さい時は、お互いの区間が重なり合うことがないので、これ以外について数え上げると良い。


### コード
```python
N = int(input())

tlr = []
ans = 0

for i in range(N):
    t, l, r = map(int, input().split())

    l *= 2
    r *= 2

    if t >= 3:
        l += 1
    if t % 2 == 0:
        r -= 1

    tlr.append([t, l, r])

for i in range(N-1):
    for j in range(i+1, N):
        if tlr[i][2] < tlr[j][1] or tlr[j][2] < tlr[i][1]:
            pass
        else:
            ans += 1

print(ans)
```

## 編集後記

全部灰diffのコンテストとは一体誰に需要があるんだろう...。
#7 合格発表の日

この記事はシリーズものです。トップはこちらから。

 - [ネットワークスペシャリスト試験を受けることにしました【令和3年春季】](https://qiita.com/foxtail1979/items/5e333d28f2e93acb552b)


# 結果発表
残念ながら、不合格でした。
![15764F43-EA7C-4ADF-BF20-31B1BA158D3F.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581105/71dd7310-d5f2-14c9-42c0-4bb62ec7379d.jpeg)

午後Ⅱの得点が9点足らず…手応えとしては午後Ⅰまでは突破出来たんじゃないかと感じていたので、実感に近い結果となった印象です。
悔しいですが、また来年の春季試験でリベンジできるよう知識のアップデートを進めておきたいです。

# 不合格の要因
次回に向けて少し反省点を洗い出しておこうかと思います。

## 勉強時間不足

これは絶対的に不足していたと感じています。
午前Ⅰ 免除のため勉強せず
午前Ⅱ 10年分の過去問を一通り
午後Ⅰ 8年分の過去問を一通り
午後Ⅱ 7年分の過去問を一通り

午後問題は特に、過去問を繰り返すことで試験特有の考え方や問われ方を身につける必要があったと思います。今回の学習ではそれが足りなかった。それが午後Ⅱの9点だったと感じました。来年も受験するとしたら、午後Ⅱの演習に割く時間を増やす必要があるでしょう。

## 勉強方法と教材について

これについては、大きく間違っていなかったと思います。午前Ⅱはひたすら過去問を解く、午後Ⅰと午後Ⅱはそれぞれ分けて学習はせず、強いて言えば午後Ⅰは基礎知識を導入として回答を作成、午後Ⅱはさらに本文事例に特化した内容を踏まえて回答する、といった点が重視出来ていたと思います。
やっぱり方向は間違っていなかったけど、僕にとっては量が足りなかったという感触です。
ところでネットワークスペシャリスト試験、難しい割に考え方を解説してくれる書籍の質は結構充実しているのでは？とも思いました。

# 逆に出来たこともある

結果的に合格点には及んでいないですが、午後Ⅰまで突破出来ているということは、最低限の知識・考え方は身に付きつつあったのだと思います。とはいえ不合格は不合格。業務においては頑張ったんですけどダメでした、認めてくださいは通りませんしね。素直に反省です。

# 次の試験に向けて
秋季試験はSCかDBを受けようと考えています。NWと相性が良いのはSCだと思いますが、旧セキュリティスペシャリスト試験とは制度が異なるので、受けるだけになってしまいそうなのが懸念点ですね。DBはあまり業務に直結しないので、モチベーションが心配になります。

また秋季試験対策の時期になったら、書こうかなと思います。ありがとうございました。
[PHP] 16進数表現の罠

PHP5までは特に問題なかったところ、PHP7に移行して(今更)発覚した問題。

``` php:huh.php
<?php
var_dump(dechex(0xfedcba9876543210));
```
string(16) "fedcba9876543000"

…はぅ?

``` php:omg.php
<?php
var_dump(0xfedcba9876543210);
```
float(1.8364758544493E+19)

まさかのfloat。

``` php:max.php
<?php
var_dump(0x7fffffffffffffff);
```
int(9223372036854775807)

正数なら問題ないらしい不思議。

``` php:shift.php
<?php
var_dump(1<<63);
```
int(-9223372036854775808)

シフト演算で突き押し作戦。

``` php:ok.php
<?php
var_dump(dechex(0xf<<60|0xedcba9876543210));
```
string(16) "fedcba9876543210"

強引に解決。

## PHP8では…

``` php:huh.php
<?php
var_dump(dechex(0xfedcba9876543210));
```

Fatal error: Uncaught TypeError: dechex(): Argument #1 ($num) must be of type int, float given

叱られた…

``` php:ok.php
<?php
var_dump(dechex(0xf<<60|0xedcba9876543210));
```
string(16) "fedcba9876543210"

原因は同じなので、同じく強引に解決可。
AWS認定DevOpsエンジニアプロフェッショナル(DOP)を、再認定したふりかえりまとめ

# はじめに
認定をぐるっと回って、DOPの３年の有効期限が来てしまいました。
前回は旧バージョンの試験の時で、今は出題傾向も変わってきているのなと思い、少しだけ情報整理をして臨みました。
本格的な試験対策の記事は多くの方が投稿されているかと思いますので、記録として、事前準備と再認定を受けてみて感じたことについて簡単に記載してみたいと思います。

# 本記事の主な対象者
- AWS認定の他の試験区分は取得済みで、DevOpsエンジニアプロフェッショナルの受験を検討している方
- 取得に向けて有効な学習方法などの情報収集したい方

# 筆者のAWS認定履歴

|AWS認定  |取得日  |再認定日  |
|---|---|---|---|
|ソリューションアーキテクト - アソシエイト  |2018-05-13|（同SAP）|
|デベロッパー - アソシエイト  |2018-06-03|（同DOP）|
|SysOpsアドミニストレーター - アソシエイト | 2018-06-10|（同DOP）|
|ソリューションアーキテクト - プロフェッショナル  |2018-07-29|2021-06-05|
|DevOpsエンジニア - プロフェッショナル  |2018-08-26|2021-06-26|
|データアナリティクス専門知識<br>(ビッグデータ専門知識)  |2019-08-25|2020-11-21|
|セキュリティ専門知識  |2019-12-08|-|
|機械学習専門知識  |2020-02-23|-|
|高度なネットワーキング専門知識  |2020-06-20|-|
|データベース専門知識  |2020-07-04|-|
|Alexaスキルビルダー専門知識  |2020-07-24|-|
|クラウドプラクティショナー  |2020-07-27|-|

# 事前準備
下記の無料の公式のトレーニングコースを受講して、出題されるAWSサービスの確認を行いました。広さと深さに例えると、こちらのコースは広さの８割程度をカバーしていたような気がします。

 - [Exam Readiness: AWS Certified DevOps Engineer – Professional (Japanese)](https://www.aws.training/Details/eLearning?id=40664)

# 再認定を受けてみて感じたこと
 - CodePipline / CodeCommit / CodeBuild / CodeDeploy / CloudFormation の　CD/CIのユースケースを問う試験でした。設問文の条件にもっとも当てはまるものを選択すると良さそうです。
 - Beanstalk / OpsWorks も、CodePiplineとの比較的な感じで散見されました。実務であまり触っていない場合は、ドキュメントレベルで、できることできないことを整理しておく必要があります。
 - トラブルシューティング系は、ELBとASGとライフサイクルフックを絡めた復旧手段も把握しておく必要がありそうです。
 - CodeCommit に関連して、AWSが推奨する gitのブランチ戦略も問われていたような気がします（ブランチ切りましょう的な）
 - セキュリテイ関連は、AWSのセキュリティのベストプラクティスを問う素直な設問が多かった気がします（Inspector, Config, Trail, Trusted Advisor, etc...）
 - Systems Manager に関しては、深いところ（色々機能）まで問われていました。
 - 各専門知識の認定区分を一通り学習していると、類題シナジーがあったような気がします。
 - 落ち着いて設問を読みましょう。キーワードが隠れている（はず）
 - 余談的で、上記の公式トレーニングコースでは、正答率をあげるテクニックも紹介されていました。少し拡大解釈をすると 「手動でCLIコマンド」「cron定期実行」「サードパーティ使用」などの、AWSのベストプラクティスに乗ってこない選択肢は、実現可能そうな内容でも正当になり得る可能性は低そうです（こちらは自己判断で）


# おわりに
定期的な知識の棚卸しや、新サービスのキャッチアップという観点で、３年の有効期限は意外と有用かなと思いました。今回新しく得られた知識もそれなりにありました。
今後受験を検討される方の一助になれば幸いです。
IntelliJでgitを使いこなす！

# はじめに
gitのコマンド操作が怖い私がIntelliJでのgit操作について一通り駆使できるようになったため、IntelliJでのgit操作について紹介します:point_up_tone1:
※IntelliJはUltimate版を使用してますがgit操作はCommunity版とは変わらないと思われます。

# IntelliJでのgit操作の紹介
## git操作全て（多分）
Ctrl + Shift + A を押下すると以下の様にモーダルが表示されます。
ここに行いたい操作を入力するとほぼほぼできます。
commit,push,pull,fetch,stash,unstashをこの方法でよく行っています。
※以下commitの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/bed9e16c-772c-dc77-ec8b-dc618b4a4289.png)

以降はCtrl + Shift + A以外の方法でのgit操作を紹介していきます:information_desk_person_tone1::sparkles:

## add
ファイルを追加した際に以下のようにモーダルが表示されます。
「Add」ボタンを押下するとadd完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/4ba098b6-1fbe-821d-0be1-447863c1b379.png)

## pull
画面右上の水色の矢印をクリックするとpull完了です！
※同じブランチの内容がpullされます。
※３つ横の矢印をクリックすると前回のcommit以降に修正した差分を確認できます。（これはめちゃめちゃ使います:blush:）commit前に修正内容を確認する際など使い所満載です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/57e5a2ee-622e-8765-dad4-a52105f74122.png)

違うブランチをpullする場合はCtrl + Shift + Aから実行しています。
■手順
１、Ctrl + Shift + Aで表示されたモーダルにて「pull」と入力し、選択する。
２、表示されたモーダルのBranches to mergeにて取り込みたいブランチを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/e3051a49-d702-d270-5c0b-6167dcedcedf.png)
３、「Pull」ボタンを押下する。
※No fast forwardにチェックを入れるとコミット履歴が残るため、pullする際にはこちらにチェックを入れておくと良いと思います。操作を取り消したくなった場合に助かります:point_up_tone1:

## checkout、ブランチ名の変更、ブランチの作成
画面の右下にブランチ名が表示されているので、ブランチ名の部分をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/01caf848-e449-8f1b-e668-7d153965d579.png)
すると、以下のように画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/8127d77a-9469-496e-59aa-788ffbdf82ad.png)
今まで作成したブランチの一覧が作成されるのでcheckoutしたいブランチを押下するとchekout完了です！
ブランチ名を変更したい場合はブランチ名を右クリックすると「Rename」と表示されるのでクリックすると変更可能です。pushする前に有効です。
ブランチを作成したい場合は画面の一番上の「New Branch」を押下するとブランチの作成完了です！

## その他いろいろ
画面下にあるVersion ControlのLogタブで行える操作について紹介していきます。
ここではcommitの履歴を確認できます。

git操作を行いたいcommitした行にて右クリックすると以下のようにモーダルが表示されます。
この中からよく使用している操作を紹介していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/f16fab4f-5726-a5d9-ec42-ad2873063fcd.png)

### Cherry-pick
違うブランチから一部のcommitのみ取得したい場合に使用します。
「Cherry-pick」を押下するとすぐcommitしてくれ、残すはpushのみという感じなので非常に楽です。

### Compare with Local
これはリモートのブランチとローカルのブランチの差分を確認できます。これもなかなか便利です:point_up_tone1:

### Undo Commit
commitを取り消したい時に使用します。pushする前だと使えます！
間違ってcommitした時はドキッとしますが、これがあるので安心しています:relaxed:

### Reword
commitメッセージを修正したい場合に使用します。こちらもpushする前だと使えます！
一瞬で修正可能です！

## Branch 'origin'/ブランチ名 → Merge into Current
今いるブランチに対してマージできます。
ただ、commit履歴が残らないケースもあるので注意が必要です:cold_sweat:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/d1da0d23-63a7-f95c-8e5d-6b9c3546ffd1.png)

他はあまり使用していません。
「Reset Current Branch to Here」と「Revert Commit」はまだ使いこなせていません。。
操作方法が間違っている可能性がありますが上手く動作しないケースがあり、revertなどはGitBashを使用しコマンドで頑張っています。IntelliJでもコマンドを入力できますが、なぜかGitBashでないと動かない場合があるので。。

# さいごに
約２年間で身につけたIntelliJでのgit操作の紹介でした。かつてはSourcetreeを使用しgitの操作を行っておりましたが、IntelliJも負けず劣らず使いやすいと思います！
上記の内容で一通りgit操作は行えるので良ければ参考にしてください:raising_hand_tone1:
C# FixFormatなき世界で生きる（c#のフォーマッターをカスタマイズする）

## C# FixFormatがない

久々に作りかけのUnity Projectを開き、拡張機能を覗くとあれまビックリ、C# FixFormatが消えていた。
調べてみるとdotnet-formatというCLIツールが良いらしいのだが、仕事でガッツリ書くわけでもないため楽をした。

## omnisharp.json

プロジェクトルートにomnisharp.jsonというファイルを作り、FormattingOptionsで設定をカスタマイズできる。
[設定項目一覧](https://docs.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.csharp.formatting.csharpformattingoptions?view=roslyn-dotnet)。

例：if文などの末尾にある中括弧を同じラインに置きたい。

```json:omnisharp.json
{
  "FormattingOptions": {
    "NewLinesForBracesInLambdaExpressionBody": false,
    "NewLinesForBracesInAnonymousMethods": false,
    "NewLinesForBracesInAnonymousTypes": false,
    "NewLinesForBracesInControlBlocks": false,
    "NewLinesForBracesInTypes": false,
    "NewLinesForBracesInMethods": false,
    "NewLinesForBracesInProperties": false,
    "NewLinesForBracesInObjectCollectionArrayInitializers": false,
    "NewLinesForBracesInAccessors": false,
    "NewLineForElse": false,
    "NewLineForCatch": false,
    "NewLineForFinally": false
  }
}
```

## prettierを使っている

JSなどを書いてるとdefaultFormatterをprettierに設定していることもあるだろう。
その場合はこうする。

```json:settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[csharp]": {
    "editor.defaultFormatter": "ms-dotnettools.csharp"
  }
}
```
[Unity]2021.2.0bから使えるSDF Bake ToolでVFXを楽しもう！

# はじめに
[Unity2021.2.0b](https://unity3d.com/jp/beta/2021.2b)は2021年06月28現在ベータ版としてリリースされている最新のUnityバージョンで，今回のリリースでいくつかの修正やUIなどにも若干の変更が加わっています．
今回はその中でも，VFX用の新機能であるSDF Bake Toolを使ってみます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/5ee17868-e91a-08ed-c7f4-6fd247a76f79.png)


# 今回解説しないもの
- HDRP環境の構築
- VFXの基本的な使い方
- SDFそのものについての説明

# SDF Bake Toolについて
VFXグラフには今までもSDFを利用するためのブロックが用意されていましたが，肝心のSDFについては外部ツールや，有志の作成したUnityアセットを利用して用意する必要がありました．
が，今回のアップデートからついにSDFの生成についても公式で対応されたため特異なことをしない限りはUnity内でフローが完結するようになりました．(嬉しい)

# Toolの出し方
SDF Bake Toolは`Window`->`Visual Effects`->`Utilities`->`SDF Bake Tool`からUIを表示できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/99c00680-83ef-4d26-2aac-86e9e24707b0.png)
↓ SDF Bake Tool
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/c824f3f7-e1e4-cad2-bd35-9c39794a70cd.png)

# とりあえずスザンヌのSDFを作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/0b715b11-bbce-f20b-f2dd-bb816cf95091.png)

適宜Blenderでスザンヌをfbxで用意してもらうとして，`Mesh`の項目にスザンヌのメッシュを指定します．
そうしたら，一個上にある`Fit cube to Mesh`を押します．
上手くいけば↓画像のように指定したメッシュの情報とともに`Save SDF`という項目が出現します．
これを押下するとAssetとしての保存先を聞かれるので保存先を指定すれば完了です．(簡単...)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/f650c4f0-a2cf-925e-fd1a-b899afa9085e.png)
あとは生成したSDFをVFX内で利用するだけです．(↓の画像はトップの方に掲載したスザンヌの画像のものです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/193f86c2-99d1-8179-544c-682977b130e3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/fd8ca0b7-de92-bbe4-dac5-adb3dd71cc0b.png)


# 簡単解説
## 各種項目について
### Max resolution
SDFは3Dテクスチャのような形で情報を格納するためXYZそれぞれの解像度の意味を持ちます．値が高ければ高いほど精密なSDFが生成されます．
### Box Center
SDFを計算するボックスの位置を決めます．
値を変えるとプレビューでボリュームの位置が変わるのでわかりやすいはず．
例↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/76e148a9-b505-708e-fb2b-08c48efa7a97.png)

### Desired Box Size
SDFを計算するボリュームの大きさを決めます．

### Actual Box Size
そもそもいじれないので詳しくは暇があったら

### Live Update
Onにすると警告がでる．

```
リアルタイムでメッシュをベイクすると、解像度やサインパス数が高い場合に、速度低下や不安定性が発生することがあります。
```
Meshをいじったりする場合にこれがOnだと恐らく自動で同じAssetファイルに焼き直してくれるので使う人はOn

### Fit box to Mesh /Fit Cube to Mesh
正方形の形でBakeするかどうかとも取れる．それぞれの事情でお好みに．ちなみにVFXで使う際は基本的にFit Cubeを選択しないとVFXはスケールを0~1でしか扱わないので圧縮された見た目になります．(一応VFX内のConform to SDFでスケール変えれば対策出来る)

### Bake Mesh
Saveせずに結果のみ見たい場合はこっちを押す．

### Save SDF
計算結果をアセットとして保存する．

### プレビュー
プレビュー要素として，地味に嬉しいスライスデータや，SDFそのものが見れる.外製のものを使うと結果がUnityに持っていくまでわからなかったりするので作業が捗る．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411974/bea4a083-47d1-ab31-f7bf-01bb9dc00080.png)