OmniAICreator/Qiita-1.07M huggingface dataset:
WinFormsのTableLayoutPanelの行数列数をコードで動的に増減する際の注意点

## 前提
- WinFormsでTableLayoutPanelを使っていて行数列数を動的に変更させたい人向け
- 私が引っかかったので共有

## やりたいこと
Winformsで手軽に均等分割などができるコントロールであるTableLayoutPanel。
その行数列数をコードで動的に増減したい。
今回は3x3と2x2のレイアウトをトグルで切り替える。

## 罠
均等分割ならパーセントで50%と33.333%あたりを入れ替えればいいだろう。

ん？
TableLayoutPanelにColumnCount, RowCountというset可能なプロパティが有るぞ。
→よしせっかくなのでついでにこいつにも列数行数を代入してみよう。
~~~c#
private void ToggleLayout()
{
	IsQuarterLayout = !IsQuarterLayout;
	const float half = 50f;
	const float thirds = 33.333f;
	var count = IsQuarterLayout ? 2 : 3;
	tableLayoutPanel.ColumnCount = count;
	tableLayoutPanel.RowCount = count;
	tableLayoutPanel.ColumnStyles[0] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.ColumnStyles[1] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.ColumnStyles[2] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? 0 : thirds);
	tableLayoutPanel.RowStyles[0] = new RowStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.RowStyles[1] = new RowStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.RowStyles[2] = new RowStyle(SizeType.Percent, IsQuarterLayout ? 0 : thirds);
}
~~~
![cap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432434/c7eb2e61-a57a-a558-69e2-677ded85beda.gif)

一見うまくいったように見えるが、ウィンドウを縦に伸ばし一定の高さを超えると謎の行が下に現れる。

は？

## 解決方法
ColumnCount, RowCountには代入してはいけない。
~~~c#
private void ToggleLayout()
{
	IsQuarterLayout = !IsQuarterLayout;
	const float half = 50f;
	const float thirds = 33.333f;
	tableLayoutPanel.ColumnStyles[0] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.ColumnStyles[1] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.ColumnStyles[2] = new ColumnStyle(SizeType.Percent, IsQuarterLayout ? 0 : thirds);
	tableLayoutPanel.RowStyles[0] = new RowStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.RowStyles[1] = new RowStyle(SizeType.Percent, IsQuarterLayout ? half : thirds);
	tableLayoutPanel.RowStyles[2] = new RowStyle(SizeType.Percent, IsQuarterLayout ? 0 : thirds);
}
~~~
![cap2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432434/4d909c4a-7e4c-55b5-5fbe-79100ce97397.gif)
これで縦に伸ばしても謎の行が表示されたりはしない。

## 教訓
なんかそれっぽい名前だからといってよく分からないプロパティに代入してはいけない。
Cloud Run→Cloud Storageの画像保存

メモはたくさんあるのですが、まとめる時間がないです。

## とどいた案件
「Google Cloud（以下GCP）でWebアプリ走らせて」

お、おう、、、

## このタイミングで
いずれAWSかGCPに取り組まなきゃと思ってましたが、まさかのこのタイミングで、、

## 環境
PHP7 Laravel8.x　Dockerつかってます


## Cloud Runここが困ったぞ

コストカットのために未使用時はサーバがすぐに止まる設定にしているのですが、**アップロードした写真など**はアクセス終了後に消える仕様らしい。

なので、デプロイ後にアプリからアップロードしたプロフィール写真や、発行したPDFなどはサーバがお眠りになると消えるらしい。

で、いろいろググると、S3か、FTP（SFTP）がオススメらしいと。

S3は別のバックアップで使っているのですが、お客様にまたS3を契約してもらうのは億劫なので、**Google Cloud Storage**を利用することにしました。

## Cloud RunからCloud Storageにどうやってアップするの？
### よくわかない
いろいろ検索した結果、、、よくわからない。

非エンジニア＋個人開発の限界です。

### これが使えた
別プロジェクトの方にお尋ねして、教えていただいた記事からリポジトリをたどって、以下にたどりつきました。

[https://github.com/Superbalist/laravel-google-cloud-storage](url)

ちょっと古いけれど、Laravel8.xコンパチと書いてる。

ほかにもいくつかあるのですが、PHP8が必須でこちらの環境（php7）には適合せず。

### インストール
**キーのJSONが取得済み**であることが前提です。

アプリ側のコンソールで、Laravelのsrc内に入り

`composer require superbalist/laravel-google-cloud-storage`

### 初期設定
laravelApp/src/laravelapp/config/filesystems.phpに以下を追加します。

```php:config/filesystems.php
'gcs' => [
    'driver' => 'gcs',
    'project_id' => env('GOOGLE_CLOUD_PROJECT_ID', 'GCPのプロジェクトID'),
    'key_file' => env('GOOGLE_CLOUD_KEY_FILE', null), //キーのJSONファイルへのパス
    'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET', 'バケット名'),
    'path_prefix' => env('GOOGLE_CLOUD_STORAGE_PATH_PREFIX', null), // optional: /default/path/to/apply/in/bucket　設定していない
    'storage_api_uri' => env('GOOGLE_CLOUD_STORAGE_API_URI', null), // see: Public URLs below　一応設定しています
    'visibility' => 'public', // optional: public|private　エラーでたっぽいんで使っていません
],
```

### bladeに追加
つぎにフォームの設定です。該当のbladeに以下を追加しました。

```html:post.blade.php
<form action="{{route('save')}}" method="post" enctype="multipart/form-data">
    @csrf

    <!-- 画像保存 -->
    <div class="pt-2">
    <input id="image_path" type="file" name="image_path" >
    </div>
  
    <div class="pt-2">
    <input class="btn btn-info p-2" type="submit" value="作成">
    <a type="button" class="btn btn-success p-2" href="/nanika_view">キャンセル</a>
   </div>
```
saveが来るとControllerに飛ばすようweb.phpに設定済みです。

### Controllerに追加
Controllerに以下を追加しました

```php:ImageController.php
public function save(Request $request)
    {
        // バリデートは省略
        

    $input_content = new Image_lists();
    $input_content->image_name = $request['image_name'];

    // 画像ファイルの保存場所指定
    if(request('image_path')){
        $filename=$request->image_path->getClientOriginalName();//今回は元のファイル名を使用

        //Cloud Strageを定義
       // $disk = Storage::disk('gcs');

        // ファイル名を指定して保存の場合、3つめのgcsをつけないとローカル保存（＝時間がたつと消える）になる
        $url = request('image_path')->storeAs('保存フォルダまでのパス', $filename, 'gcs');
        //↑ハッシュ保存の場合はputでOK

        // データベースに保存するファイルパス用 
        $path = 'https://storage.googleapis.com/（バケット、保存フォルダまでのURL）';
        $path .= $filename; // $urlの意味が無い、、

		//DB保存用に絶対パスを保存内容に入れる
        $input_content->image_path = $path;
    }
	//DB保存
    $input_content->save();
 
    // 保存後にimagelist viewの画面へリダイレクト
    return redirect(route('imagelist'));
    }
```

おつかれさまでした。
SANSの研修でコイン貰いました

<h1>SEC542: Web App Penetration Testing and Ethical Hackingに参加してきました。</h1>

<p>
  <h2>　■　どんな研修なの？ </h2>
　SANSが提供しているセキュリティの研修です。<br>
　昨今セキュリティ事故が起こり情報漏洩などを引き起こした事例を見かけます。<br>
　この研修では、攻撃者よりも早くシステムの欠陥に気づき、対処できるように<br>
　なることを目標にペネトレーション試験の方法や攻撃手法を学ぶことができます。

</p>

<p>
  <h2>　■　最終日にあるCTF</h2>
　研修の最終日には、CTFというコンテストが開催されます。<br>
　これには、受講者同士でチームに分かれて参加するのですが、<br>
　このコンテストで優勝したチームには、ある景品が与えられるのです。
</p>

<p>
  <h2>優勝した時に届いたコイン</h2>
　私が先日参加した時に、優勝した時に頂いたコインが以下です。<br>
</p>

![S__65363970.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/798622/8fadf411-e879-5cc1-e529-6c8d82e3a709.jpeg)
![S__65363972.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/798622/2bbf0f14-5a04-bdac-48a3-22f986f1255e.jpeg)

<p>
  <h2>私の感想</h2>
　かっけー－！！<br>
　しょうもない感想ですいませんでした。。。<br>
　みなさんもSANSの研修参加する際はコイン獲得目指して頑張ってくださいね！笑<br>
</p>
LaravelのCashierでwebhookをイベントリスナでアレコレしようとして困った話

## ■ はじめに

当記事は

https://qiita.com/smtwtfs/items/daffbacd54f1dbc3df7b

↑この記事からの続きです。

Stripeのwebookのことについて書きますが、
Laravelでwebhookをどうやって使えるようにするかの詳細や、
ngrokでwebhookをテストできるよ、ということなどについては
既にたくさん良い記事がありますので
（記事を書いて下さった皆様大変お世話になりました🙇‍♀️）
当記事ではLaravelでStripeからwebhookを受けることができるようになったという前提で、
その後イベントリスナを活用しようとして
少し困ったことがあったので、そのときのことを備忘録的に残しておきたいと思います。

## ■ ありがとうCashier、ありがとうwebhook
LaravelのCashierではStripeからのwebhookを受けて色々な処理をしてくれます。
Cashierでwebhookを処理できるようにするには、
>[Laravel 8.x Laravel Cashier (Stripe)](https://readouble.com/laravel/8.x/ja/billing.html#handling-stripe-webhooks)
Stripeコントロールパネルで有効にする必要があるすべてのWebフックの完全なリストは次のとおりです。
・ customer.subscription.created
・ customer.subscription.updated
・ customer.subscription.deleted
・ customer.updated
・ customer.deleted
・ invoice.payment_action_required

指定のwebhook6つをStripeのコントロールパネルで有効にする必要があるとのことで、
指示に従いそのように設定。
ちなみに

```
php artisan cashier:webhook
```

上記のコマンドを実行すると、`.env`に`APP_URL`で定義されているURLに対して
さきほど挙げた指定のwebhook6つをいっぺんにまとめてスコーンと通してくれます。
Stripeのコントロールパネルから地道にぽちぽちせずに済みます。親切！

そしてわたしはサブスクリプションの決済ができるようにしようとしていたところだったのですが、
Stripe上でサブスクリプションの決済が行われた結果をwebhookで受け取り、

- subscriptionsテーブル
- subscription_itemsテーブル
- Stripeのcustomerを扱うテーブル（前回の記事でいうとcompaniesテーブルです）

受け取ったものがこれらのテーブルに入るようになっていました。
webhookを有効にしていさえすれば決済の結果を自動でテーブルに入れてくれるなんて
とってもありがたいですよね〜

## ■ webhookイベントで追加の処理をしたかった
さて、
webhookがとっても便利なので、`webhookを受け取ったついで`に他にもやりたいことを思いつきまして。

そのうちのひとつに、
**webhookを受け取ったタイミングで、customerのサブスクリプション状態が有効かどうか？を取得したい**
ということがありました。

>[Laravel 8.x Laravel Cashier (Stripe)](https://readouble.com/laravel/8.x/ja/billing.html#defining-webhook-event-handlers)
Cashierは課金の失敗やその他一般的なStripe Webフックイベントによる、サブスクリプションキャンセルを自動的に処理します。ただし、追加でWebフックイベントを処理したい場合は、Cashierが発行する以下のイベントをリッスンすることで可能です。
・ Laravel\Cashier\Events\WebhookReceived
・ Laravel\Cashier\Events\WebhookHandled

これ↑を読んだわたしは「よーし！リッスンしちゃお！」とウキウキで
リッスンするためのコードやらリッスンしたときにやりたいことのコードやらをせっせと書いたわけです。

...なのですが...

サブスクリプションが有効なのかどうかを全然正しく取得できません...困った...
なんでー？？💦


結論を申し上げると、
`Laravel\Cashier\Events\WebhookReceived`をリッスンしていたからなのでした！
これですと
受け取ったwebhookをまさしく受け取ったタイミング、かつ、それが**処理される前**に動いてしまっていました。

わたしはwebhookが**処理された後**、それが反映された状態を取得したかったため
このような場合は
`Laravel\Cashier\Events\WebhookHandled`をリッスンしなければならなかったのです〜

WebhookHandledのほうで書き直してみると、ようやく得たい結果を得ることができました。
ああスッキリ！

備忘録的な内容ではありますが、この記事がどなたかのお役に立ちましたら幸いです☀️
お読み頂きましてありがとうございました！

## ■ まとめ
LaravelのCashierでwebhookイベントをデフォルトの処理に追加してアレコレしたい場合は、
・ Laravel\Cashier\Events\WebhookReceived　（webhookが処理される前）
・ Laravel\Cashier\Events\WebhookHandled　（webhookが処理された後）
アレコレの内容にあわせて上記2つのうち適している方をリッスンする👂

## ■ 参考記事
- [https://readouble.com/laravel/8.x/ja/billing.html](https://readouble.com/laravel/8.x/ja/billing.html)
- [https://github.com/laravel/cashier-stripe/issues/803](https://github.com/laravel/cashier-stripe/issues/803)
postmanで連想配列を渡す方法

`postman`を使っているときに、連想配列を渡す方法に少し詰まった。

解決してしまえばシンプルなことだったが、自分用の備忘録として残しておく。

## POSTメソッドで配列・連想配列を渡す方法

以下の画像の通り、 `[Body] > [raw] > [JSON]` を選んで、を選んで、配列や連想配列を渡せば良い。
![スクリーンショット 2022-03-30 18.36.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208065/17a8e3df-c6ed-eac6-1e93-8bfdcacf543a.png)

## 関連記事

ついでに、ググっていて以下の記事の内容も初めて知ったのでメモ。
 
<br>

↓ `PUT`, `DELETE`メソッドの場合は、`form-data` の形式ではデータを渡せない。
確かに試してみると`405`(`Method Not Allowed`)のエラーとなった。

https://qiita.com/wjtnk/items/eb2ddcc0642dc3197671

<br>

↓ `GET`メソッドの場合は、`POST`の場合にシンプルにJSON形式で書いたのとは異なり、`KEY`,`VALUE`を上手く使って書く必要があるらしい。

https://qiita.com/yama-t/items/a4f940ecd7d79f27232a
iptablesコマンドなどでlinuxサーバのセキュリティ対策をする 導入編

# linuxサーバのセキュリティ対策

サーバーでセキュリティ対策を色んな方法がありますが
一般的なiptablesを用いたセキュリティ対策を使ってみます。

# インストール方法
まず、yumでiptablesをインストールします。
```
# yum install iptables-services
```
インストールされているかパッケージを確認します。
```
# yum list installed | grep iptables
# -> インストールされていれば以下のように帰ってきます。
 list installed | grep iptables
iptables.x86_64                              1.4.21-35.el7           @base
```
設定ファイルの場所は以下の場所にファイルが基本的に置いてあります。
```
/etc/sysconfig/iptables
```
iptablesの設定を確認します。
```
# iptables -L
```
# 基本的な設定方法
```
# iptables -I INPUT -s 攻撃IP -j DROP
```
上記コマンドで攻撃IPをブロック対象として設定します。

下記コマンドでiptablesの設定を設定ファイルに保存します。
```
# service iptabels save
```
設定を反映させるためにiptabelsを再起動します。
```
# service iptabels save
あるいは
# systemctl start iptables
```
# 設定の確認方法
```
# cat /etc/sysconfig/iptables
```
で設定ファイルに記載されているか確認します。

```
iptables -L
```
でiptablesが設定されているか確認します。

# 攻撃元の確認方法の一例
```
# lastb -20 -i 
```
サーバにログインしようとして失敗したIPやホスト名を表示するコマンドです。

```
# cat /var/log/messages
```
ログファイルを読み、不審なアクセスないか確認します。
```
ss -at
```
ネットワークのソケットの情報を出力して特定の送信元から多数のアクセスがないか確認します。


他にも色々なiptabelsで不正アクセスを防ぐ設定方法と不正アクセスの突き止め方があるので勉強していきたいと思います。
Hyper-Vで外部仮想スイッチを作ったらネット速度が遅くなる問題の解決方法

# はじめに
Hyper-Vで外部仮想スイッチを作るとホスト側も仮想マシン側もインターネット速度が非常に遅くなる（下りが1/100程度まで低下）ことがある。この問題を解決したときの方法をまとめる。

# 仮想スイッチの設定内容と症状の内容

## 設定内容
仮想スイッチマネージャで次のように外部スイッチを作る
1. 仮想スイッチの作成で「外部」を選択し「仮想スイッチの作成」を押下
1. 接続の種類で、外部ネットワークの選択。さらに無線カードを選択。ネットワークアダプタの共有にチェック。その後「適用」を押下

こうすると、仮想マシン側も物理ネットワークにアクセスできることは確認できる。（次の通り速度は遅いが。。）

## 症状
ホスト側のインターネット速度を計測すると下りが1/100程度にまで低下する。
自分の環境だと、仮想スイッチ作成前：340Mbps, 仮想スイッチ作成後:2.4Mbpsとなってしまった。
仮想マシン側も、現段階では比較はできないものの同様にスピードが全然出ない状況。

なお、手前味噌ですが、インターネット速度計測方法については下記参照いただけると嬉しいです。

https://qiita.com/purple_jp/items/0905c933f9d1a28c6313

# 解決方法
次の2つ記事を参考に、作成したvEthernetのoffload設定を無効にした上でWindowsを再起動する。（私も無線を共有設定したので、無線との相性が悪いのかも？）

https://www.piesik.me/2020/08/12/HyperV-IntelWiFi/#

https://community.intel.com/t5/Wireless/Hyper-V-External-Virtual-Switch-Bridge-Mode-Slow-download-speeds/td-p/1222149

## 手順

1. 設定→ネットワークとインターネット→状態→アダプターのオプションを変更する、の順に進める
1. Hyper-Vで仮想スイッチを作成した名称のvEthernetのプロパティを開く
1. ネットワークタブを開き、「構成」を押下する
1. 詳細設定タブを開き、Large Send Offload Version 2など、offload関連の設定を全てdisabledにして「OK」を押下する。
1. Windowsの再起動をする。
1. 再度ネット速度を計測して、解決を確認

上記のサイトには、Large Send Offloadのdisabledにしか触れていないが、下記によると、他のoffload関連もdisabledにした方が良い旨が記載されているので採用。また、offloadについての説明もあり。

https://atmarkit.itmedia.co.jp/ait/articles/1201/20/news145.html

> オフロード機能とは、IPパケットやTCP／UDPパケットのヘッダ中に格納するチェックサム値の計算を、ホストのCPUではなく、NIC上のコントローラ・チップで行う機能である。これにより、ホストCPUの負荷が軽減され、ネットワーク処理やシステム全体のパフォーマンスが改善する

ここにバグなどがあるということ？？

ひとまずこれで問題は解決。

# 参考文献
- [Slow external connection using Hyper-V + Windows 10 and Intel WiFi cards](https://www.piesik.me/2020/08/12/HyperV-IntelWiFi/#)

- [Hyper-V External Virtual Switch Bridge Mode - Slow download speeds on 8265AC](https://community.intel.com/t5/Wireless/Hyper-V-External-Virtual-Switch-Bridge-Mode-Slow-download-speeds/td-p/1222149)

- [WindowsのHyper-Vで仮想マシンのネットワークが遅くなる問題を回避する](https://atmarkit.itmedia.co.jp/ait/articles/1201/20/news145.html)


# 実行環境
- ハードウェア: Minisforum EliteMini HX90
- OS: Windows 10 Pro(21H1)
Aspects of Multivariate Statistical Theory (ROBB J. MUIRHEAD) 定理2.1.14 (Qiita練習)



定理$2.1.13$から，
```math
(d Z)=\prod_{i=1}^{m} t_{i i}^{n-i}(d T)\left(H_{1}^{\prime} d H_{1}\right)
```
また，
$A=Z^{\prime} Z=T^{\prime} T$であるから，定理$2.1.9$を用いて，
```math 
    (d A)=2^{m} \prod_{i=1}^{m} t_{i}^{m+1-i}(d T)
```
となる．この式を$(d T)$について解くと，
```math 
    (d T)=2^{-m} \prod_{i=1}^{m} t_{i i}^{-m-1+i}(d A)
```
この$(d T)$を代入すると，
```math 
\begin{aligned}
(d Z) &= \prod_{i=1}^{m} t_{i i}^{n-i}2^{-m} \prod_{i=1}^{m} t_{i i}^{-m-1+i}(d A)\left(H_{1}^{\prime} d H_{1}\right) \\
&=2^{-m} \prod_{i=1}^{m} t_{i i}^{n-m-1}(d A)\left(H_{1}^{\prime} d H_{1}\right) \\
&=2^{-m}(\operatorname{det} A)^{(n-m-1) / 2}(d A)\left(H_{1}^{\prime} d H_{1}\right) \\

\end{aligned}
``` 
このとき，$T$は上三角行列だったから，行列式は対角成分の積になることがわかるので
```math
\Pi_{i=1}^{m} t_{ii}=\operatorname{det}T=\left(\operatorname{det}T^{\prime}T\right)^{1/2}=(\operatorname{det} A)^{1 / 2}
```
が成り立つことを利用した．
IBM Cloud: VPCのVSIをIPアドレス指定(reserved IPを利用)でプロビジョニングする方法

# 1. はじめに
[以前はCLIやAPIでIPアドレスを指定してVSIのプロビジョニングを行なっていた](https://qiita.com/testnin2/items/337bc02892024fb684a3)が、最近ではIBM CloudのVPCでは、予めIPアドレスを予約しておき(reserved IP)、そのIPアドレスを使ってサーバーのプロビジョニングなどに指定することが可能になった。
https://cloud.ibm.com/docs/vpc?topic=vpc-managing-ip-addresses&interface=ui

本稿では、そのReserved IPの使い方を紹介する。

# 2. VSIプロビジョニング時に利用する方法

## 2-1. Network -> Subnetsからサブネットを作成する
（省略）

## 2-2. サブネットメニュー内で、Reserved IPを作成

- サブネットメニューで、`Reserved IPs`タブに移動。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ef057d25-aaa4-148f-4565-228ff99df9eb.png)
- `Select an IP address for me`を選択すると、IBM Cloudが自動的にIPアドレスを選出する。IPアドレスは利用者が明示的に選出したいことの方が多いと思うので、`Let me specify`を選択し、IPアドレスとその名称を指定する。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/89ced44c-fc28-3644-7fdb-324847ac8f1a.png)
- 作成された。`Auto Delete`はデフォルトでDisabledになっている。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/306a0f24-7a83-0c29-4376-6720f49146d6.png)


## 2-3. VSI作成時にReserved IPを指定する。
- VSI作成時に、適切なVPCを選択した後、Network Interfaceの編集ボタンを押す。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ea0e5667-7f59-bbb2-9327-d27994b4cd15.png)
- 先ほど作成したReserved IPを選択。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/15827894-b132-9294-d7be-76cb96706128.png)

# 3. その他補足

1. VSI作成時に`Type an IP address`からIPアドレスを指定してReserved IPを作成することも可能。ただし、こちらの方法でReserved IPを作成するとデフォルトでは`Auto Delete`は有効になっているため、このままではVSIを削除するとIPアドレスは解放されることに注意。また、このReserved IPにはシステムが名称を割り当てるため、後から独自に命名したい場合はサブネットメニューで編集する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/94efd11d-10fc-3041-8dbc-7989493ac8a5.png)
2. VSI注文メニューを見ると、今まではReserved IPを使っていなかったが、Reserved IPを使うように仕様変更されたかのように思われそうだが、今までは「`Auto Delete`が有効になっているReserved IP」が使われていたと考えると良い。過去に作成されたVSIで`Auto Delete`が有効になったReserved IPを使っていることは、Reserved IP一覧からもわかる。
3. [ここ](https://cloud.ibm.com/docs/vpc?topic=vpc-about-networking-for-vpc#addresses-reserved-by-the-system&locale=en)に記載されているシステム予約のIPアドレスも、Reserved IP一覧から確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ac90eba0-cd1b-f9f0-ad49-1a39dcd861c8.png)
4. 新規に作成されたVPC ALBなどもreserved IPとして登録されることがわかる（ただし、既存のVPC ALBのIPはreserved IPとして表示はされてもリソース名にはまだ紐づいていない。既存のALBに対しては今後紐付けを行う作業が行われると聞いている） ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/153776a3-47e3-0596-dc07-435fe20ad205.png)
Crowd Counting用の自作データセットの画像に正解ラベル（アノテーション）を付与する

# 概要
本記事では、機械学習による群衆カウント（Crowd Counting）の中でも、MCNNやCSRNetに代表される、**CNNベースの密度推定モデル**を使用する際に利用するデータセットを自作するための**アノテーションツール**を紹介します。
今回紹介するアノテーションツールは**Matlab**を使用します。

# Crowd Counting用のデータセット
密度推定モデルとは、群集の画像から密集度をヒートマップとして表現した群集密度マップ（density map）を作成し、ピクセル単位で数の計測を行うモデルです。ここ最近の機械学習による群衆カウント（Crowd Counting）モデルの大半は**CNNベースの密度推定モデル**であり、CNNベースの密度推定モデル向けのデータセットもたくさん発表されています。（代表的なデータセットの詳細は[こちら](https://deepsquare.jp/2020/04/cloud-counting/#outline__4 "群集カウントの最新サーベイ論文（2020年3月末時点）")）
CNNベースの密度推定モデルは教師あり学習なので、ラベル（アノテーション、正解）付きのデータセットが必要です。密度マップ推定のための Crowd Counting 用データセットの大半は、研究者などの人の手によって手動でアノテーション（正解ラベルの付与）が行われています。今回は自分で用意した画像をCNNベースの密度推定モデルの学習に使用するためのラベル付けの方法を説明します。

# アノテーションツール
今回紹介するのは、GitHub上でオープンソースコードとして公開されているCrowd Counting用アノテーションツールの[princenarula222/Crowd_Annotation](https://github.com/princenarula222/Crowd_Annotation)です。このアノテーションツールを使用することで、自作した群衆画像データに対し、mat 形式の教師データを手動で付与することができます。UCFやShanghaiTechなど、有名な密度マップ推定モデルのCrowd Counting 用群衆画像データセットの多くはこの mat 形式の教師データによってラベル付けされています。ラベル（アノテーション）の内容は群衆内の人の頭部の座標データです。

# 使用方法
アノテーションツールの使用方法はREADMEに英語で書かれていますが、ここでは日本語で説明します。
##### 1
まずはgit cloneコマンドで上のアノテーションツールのリポジトリをローカルに複製してください。
それができたら、gt_mat_gen.mなどを移動させ、以下のようなディレクトリ構成にしてください。（元からあるground-truthやimagesのフォルダは中にサンプル画像などが入っているので、使用しない場合はサンプルデータを消すか、data_annotation下に新たに別のground-truthやimagesの空のフォルダを作成してください。以下の説明でground-truthフォルダやimagesフォルダはdata_annotation下のものを指します。）


```
crowd_annotation/
            │
　          ├ data_annotation/
　          │            ├ gt_mat_gen.m
            │            ├ ground-truth/
　          │            └ images/
            │
　          ├ LICENSE　　
　          └ README.md
```
##### 2
次に、用意したラベル付けをしたい群衆画像データをimagesフォルダ下に置きます。このとき、画像データの名前は'IMG_(num).jpg'のようにリネームします。（方法は「ファイル リネーム 一括」などで検索してください）
例１.　新たにデータセットを作る場合 → 'IMG_1.jpg', 'IMG_2.jpg', 'IMG_3.jpg', 'IMG_4.jpg'...
例２.ShanghaiTech Dataset Part_Bの学習データ400枚に追加する場合 → 'IMG_401.jpg', 'IMG_402.jpg', 'IMG_403.jpg'...

##### 3
MATLABでgt_mat_gen.mを開き、15行目のt = の部分に例１の場合は0、例２の場合は400を入力します。
15行目を変更できたら、gt_mat_gen.mを実行します。

##### 4
画像が順番に表示されるので、カーソルを人の頭部に合わせてクリックすることでアノテーションを付与します。画像内全ての人の頭をクリックしてラベル付けが完了したらEnterキーを押し、次の画像に進みます。あとはこれを繰り返します。全ての画像のラベル付けが終わったら終了ですが、途中で中断しても、例えばgt_mat_gen.mをt=600で実行すれば'IMG_601.jpg'の画像からラベル付けを再開できます。
![スクリーンショット (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325940/16077033-95a2-c86a-162e-f639800fa590.png)
ラベル付けをしている最中の画面のスクリーンショットです。

##### 5
ラベル付けが終わった画像の正解データ（mat 形式の教師データ）はground-truthフォルダに生成されます。

# 参考文献
[github - princenarula222/Crowd_Annotation](https://github.com/princenarula222/Crowd_Annotation)
Googleスプレッドシートで3分APIメイキング

# はじめに
LINEbotなどを作っていて、こういうAPIを自分で作りたいけど、そのためだけに自分で用意するのは手間だなぁと思っている方、GoogleスプレッドシートとSteinというサービスを利用することで、スプレッドシートにまとめた情報を手軽にAPIにできます！

:::note warn
公開したらマズいデータ、勝手に編集・削除されると困るデータはやめましょう
:::

# 使い方
## Googleスプレッドシートにデータを用意する
![スクリーンショット 2022-03-31 3.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/a18dc016-544d-600d-e0cd-f08c8a6fae55.png)

共有ボタンを押して
![スクリーンショット 2022-03-31 3.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/eaa39159-0503-33c4-d7ba-bd7e575251ac.png)

公開できるようにしてリンクをコピーします
![スクリーンショット 2022-03-31 3.07.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/80c70497-9ebe-8ba3-35e1-502fd81c161b.png)

:::note
コピーしたリンクは後で利用するので、メモ帳などに保存しておきましょう
:::

## Steinに登録する
[Stein](https://steinhq.com/) にアクセスし「Sign up free」をクリック
![スクリーンショット 2022-03-31 2.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/4da4c7e1-2cd9-24ef-e4c6-2f63c90b6cd6.png)

認証のため「許可」をクリックします
![スクリーンショット 2022-03-31 3.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/16ec3608-02d5-dd64-f4f1-e5ec694104ba.png)

利用目的などを聞かれるので、適当に答えます
![スクリーンショット 2022-03-31 3.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/f17a6f2c-6388-9c8f-7b13-9fe7fbb1fb72.png)

先ほど保存したスプレッドシートのリンクを貼り付け「Create API」をクリック
![スクリーンショット 2022-03-31 3.06.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/ca6292c8-ca2e-46bb-fdca-5899d820ec10.png)

これでAPIの完成です！！
![スクリーンショット 2022-03-31 3.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/b2003569-8494-ef5b-4920-3ba240efcd47.png)

[デジモンAPI](https://api.steinhq.com/v1/storages/62449c14bca21f053e86c5d4/%E3%82%B7%E3%83%BC%E3%83%881)

# 使い方
[公式ドキュメント](https://docs.steinhq.com/introduction)

## 一覧を確認
![スクリーンショット 2022-03-31 3.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/cd899acb-7fbc-89e1-c37f-1b47a70313b8.png)

データが返却されます！
![スクリーンショット 2022-03-31 3.09.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/1291e909-2d84-d5a2-ec24-46683fe8268d.png)

シート名つけないとエラーになります
![スクリーンショット 2022-03-31 3.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/8e450970-cda2-d8f3-950e-96ab0986793c.png)

## 検索してみる
URLに ?search={ヘッダー名: 条件} という形式を加えると検索ができます

たとえばレベルが成長期のデータだけ欲しいという場合には
```
?search={"レベル":"成長期"}
```
と付けます

![スクリーンショット 2022-03-31 3.44.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/87047a28-56bc-7641-fda2-11e551553a4e.png)

## データの追加・削除
ブラウザからはやりにくいので割愛しますが、データの追加・削除も行えます

# データの追加・削除もできちゃうの？？
そうです。気軽に使える反面、取り扱いには気をつけましょう。
APIとして公開したいけど使えるユーザーは限定したい場合には、パスワードをつけることができるので活用してもいいかもしれません。
https://docs.steinhq.com/authentication
等価演算子のあれこれ  == ===

# はじめに
typescriptでデータ比較したいときにやらかしたので等価演算子についてアウトプットします。
当たり前だろって部分だと思いますが、一瞬戸惑ったのでサッと書きますw

# 等価演算子 == ===

等価演算子って```==```,```===```これになると思いますが、新人エンジニアらしい？ミスをしましたので共有しておきます。

皆さんご存じだと思いますが```=```は代入ですw
if文こんな感じに書くこと多くてスッと頭から抜け落ちてしまいましたが、新人エンジニアらしいミスとして```=```を等価演算子だと思ってしまってました。w（言い訳をするならこの瞬間だけ抜けていた...(・・?）)
なので一度等価演算子を調べ直したいと思います。そのアウトプットです。
```
if(hoge){
 a = 1
 b = 1
}
```

```==```は2つの変数の型を変換して比較を行う。
```===```は型を変換しないで厳密に比較を行う。

```
console.log(5 == "5"); // true  
console.log(5 === "5"); // false 
```

なので上記ではNumber型とstring型の型が違うため```==```では比較を行う前に文字列を数値に変換してくれています。
一方```===```は型変換を行わないのでエラーとなるわけです。

## 等価　==
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Equality

## 厳密等価
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Strict_equality

もっと詳しく知りたい方はこちらでしっかり書いてあります。
ちなみに...これらのサイトで出てくるオペランドとは、数式を構成する要素のうち、演算の対象となる値や変数、定数などのことです。

## 構造の比較
```==```,```===```は2つのオブジェクトを比較したい場合は使えませんのでご注意ください。
その際は[deep-equal](https://www.npmjs.com/package/deep-equal)というものを使うようです。

```
import * as deepEqual from "deep-equal";

console.log(deepEqual({a:123},{a:123})); // True
```

# 最後に
自分の認識としては```==```,```===```は=が多い方が厳しく比較するんだろうなぁぐらいでしたので等価演算子調べ直せてとても良かった
きっかけは```=```で困惑したことでしたが等価演算子について深く知ることができました！！

[こちらも参考](https://typescript-jp.gitbook.io/deep-dive/recap/equality)
React 公式の Ref の記事を簡潔にまとめました：DOM操作編

## Manipulating the DOM with Refs

[前回](https://qiita.com/ItsukiN32/items/2e4a120fec1823229fdd)の続きです。
今回は `ref` による DOM操作に関する記事です。

https://beta.reactjs.org/learn/manipulating-the-dom-with-refs

## `ref`がよく使われるケース

- ノードにフォーカスする、ノードまでスクロールする、ノードのサイズやポジションを測定するなど

## 使い方

`<div ref={myRef}>`　のようにしてDOMに `ref` を移植するだけです。
これでDOMに対して 以下のようなAPI を使用して操作が可能

https://developer.mozilla.org/ja/docs/Web/API/Element

例えば、`myRef.current.scrollIntoView()`でそのノードまでスクロールできます。

## 自作のコンポーネントに `ref` を使う場合


`<input ref={inputRef} />` のような一般的なDOMに対してブラウザから操作する要素にrefを指定するのは問題ありません。

一方で自分で作ったコンポーネントの場合、下記の例のように何も考えずに `<MyInput ref={inputRef} />` のようにすると `inputRef.current.focus()` はエラーになります。

``` jsx
import { useRef } from 'react';

function MyInput(props) { // ここで refを受け取れていない
  return <input {...props} />; // このDOMに ref を渡さないといけない
}

export default function MyForm() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus(); // エラーになる
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

原因は`<myInput />` が `<input>`をラップしていて、この状態では `ref` を子に渡せていないからです。
デフォルトでは子コンポーネントに`ref`を渡すようになっていません。

そうした場合は、下記のように`forwardRef()`を使って記述することで子に `ref` を渡すことができ、これによって操作が可能になります。

``` jsx
const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});
```

## `ref` の操作を制限する

また、子に渡した`ref`を使うと、さまざまなAPIが使えてしまいますが、以下のように
`useImperativeHandle()` を使うことで、`ref` の操作を限定することができます。
下の例では使用できるAPIを`focus()`のみに限定しています。

``` jsx
const MyInput = forwardRef((props, ref) => {
  const realInputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    // Only expose focus and nothing else
    focus() {
      realInputRef.current.focus();
    },
  }));
  return <input {...props} ref={realInputRef} />;
});
```

## ステートと `ref` の変更が反映されるまでの時間の違い

ステートの変更は待ち行列で処理され、即時に評価されません。
一方で `ref` はすぐに評価されるため、ステートの処理より先に評価されてしまいます。
そのため、以下のようなコードは一番最後の要素にスクロールされません。

``` jsx
setTodos([ ...todos, newTodo]);
listRef.current.lastChild.scrollIntoView();
```

### 処理されるタイミングを合わせるには

上記のような問題に対処するには `flushSync` を使います。
ステートの変更を待つように指定することができるのです。
以下の例ではコードは一番最後の要素にスクロールできます。

``` jsx
import flushSync from react-domして、

flushSync(() => {
  setTodos([ ...todos, newTodo]);
});
listRef.current.lastChild.scrollIntoView();
```


## `ref`　の注意点

Reactで管理されているDOMに `ref` の使用はできるだけ避けた方がよいそうです。
特に子要素を持つnodeには注意。
しかし、全く操作してはいけないというわけではないそうです。
MTGのカード検索アプリを作る with AAC

# はじめに
MTG（Magic: The Gathering）のAPIを使うことで、カードデータを取得することができます。
今回はそのAPIを使ってカード検索をするAndroidアプリを作りました。
ついでに一からアプリを作るということで、Android Architecture Components（AAC）での設計、実装をしました。

# 使ったAPI
[Magic: The Gathering API](https://docs.magicthegathering.io/)
MTGのカードやフォーマット等の情報を取得することが出来るAPI。
取得できる情報量が多い + 多言語のカードも取得できるAPIになっています。

このAPIは`https://api.magicthegathering.io/<version>/<resource>`の形式でのREST APIを提供しているので、今回はこちらを使って以下のリクエストでカード検索を行いました。

```
https://api.magicthegathering.io/v1/cards?language=japanese&name=$カード名
```

# 設計
全体の設計は以下のような形になっています。AACを意識してみました。
![スクリーンショット 2022-03-31 1.33.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/5b47b306-d2be-72a4-4969-7f3ae029a3e6.png)


# できたもの
![スクリーンショット 2022-03-31 2.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/a613ab42-78b8-7676-41d2-c51d1e890087.png)


# 学べたこと
- REST APIの結果をGsonを用いてパースする際のモデルを一から作成できた
- Android Architecture Componentsでの設計

# 今後の拡張予定
- AWS Lambda, Firebaseとの組み合わせ
実はAWS Lambdaとの組み合わせは途中まで作っていたのですが、実際の作成物に組み込むまで進めることができず...
これは完成まで持っていきたい

- 検索方法の自由度アップ
今回はREST APIをAndroidから呼び出し -> 結果をパースして表示をメインにしていたのでカード名のみでの検索になりましたが、他の条件（マナコスト、色との組み合わせで検索とか）でも自由に検索できるようにしたい

- 多言語設定
日本語に特化したものを作ってしまったので、クライアント側から言語切り替えしたりできたら楽しそう...

- デザイン
後回しにしすぎてほぼデフォルト状態。せっかくなので新しいMaterial Designである`androidx.componse.material3`をフルに使ったものにしたい
TypeScirptの環境設定

##　はじめに
TypeScirptの環境設定をしなければならなかったのでメモとして残します。


## yarnとnpmでインストールする


**ローカルの場合**
```shell 
npm install -D typescript
or
yarn add typescript --dev

npm install -D ts-node
or
yarn add ts-node --dev

npm install -D tslib @types/node
or
yarn add tslib @types/node --dev
```

グローバルの場合

```shell 
npm install -g typescript
or
yarn global add typescript

npm install -g ts-node
or
yarn global add ts-node

npm install -g tslib @types/node
or
yarn global add tslib @types/node
```

> https://www.npmjs.com/package/ts-node

参考になれば幸いです！
【IE11】InternetExplorer.Applicationは Edge にリダイレクトされる仕様は撤回

Microsoftから2022年6月にInternet Explorer 11デスクトップアプリケーションのサポートが終了されます。
それに伴い、IE11デスクトップ アプリのサポート終了後に下記の仕様が検討されていました。

1. MHT は IE モード内で表示できる
2. HTA は引き続きサポートする
3. IHTMLDocument によるドキュメント操作は引き続きサポートする
4. オートメーションによる IE11 起動はできず、Edge にリダイレクトする
5. ShellWindows で IE モードは列挙できない

そんな中、2022年01月07日にマイクロソフトのブラウザー (Microsoft Edge / IE) の中の人である ユスキィ さんが方針変更のツイートをしています。

https://twitter.com/ms_yuhara/status/1479315373803864067

よって、引き続き IE を使い続ける事ができます。
[デスクトップアプリとしてのIEは終了するが、2029年までは完全に無くなるわけではない](https://ascii.jp/elem/000/004/056/4056944/)

```vb
Set objIE = CreateObject("InternetExplorer.Application")
Or
Set objIE = New InternetExplorer
```

:::note alert
これは既にオートメーションによる自動化のシステムを運用中のシナリオの救済を意図した変更とのこと
:::


Windows 11 については、以下の FAQ に記載の通り、KB5007262 (2021年11月22日のオプションの非セキュリティ更新プログラム) 以降を適用した環境であれば、既にオートメーションで IE11 を起動できるように変更されています。

https://blogs.windows.com/japan/2022/02/21/internet-explorer-11-desktop-app-retirement-faq/

よって、2021年12月28日のQiitaの記事を発端に2022年01月07日には下記のような記事が話題になったわけです。

https://forest.watch.impress.co.jp/docs/serial/yajiuma/1378907.html

```vb
CreateObject("InternetExplorer.Application").Visible=true
```

```powershell
$app = New-Object -ComObject InternetExplorer.Application; $app.Visible = $true
```

Windows 11のビルドバージョンが`22000.376`以降であれば、オートメーションによる IE11 でエラーにならないで起動できたとの報告がありました。

https://randol-news.net/day/20220108-1.html

※2022年01月08日時点では駄目だったが、2022年01月22日では起動できるようになった。
Anaconda+VScode+Blackでフォーマッターが使えなかった件

## 結論
blackのバージョン

# バージョン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169721/31fbd084-e702-3dae-5fee-982db57619a9.png)
```text:バージョン
Windows:21H2 （ビルド19044.1586）
Anaconda:4.10.3
Python:3.10.3

```

## 前提
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169721/7b4b537f-de47-281f-fe92-f19112422d24.png)
このようにsettings.jsonを作成してもフォーマッター（black）が動いてくれなかった。

## 原因
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169721/58083d41-bea8-c6ea-0bfd-7b20aa5b1afd.png)
anaconda navigatorでインストール or 「pip install black」でインストールを行うとバージョン「19.3.b0」がインストールされる。おそらく、これがだめだった。

## 解決法
```console:Anaconda
pip install black==22.3.0
```
以上のようにして、最新のものをインストールしたら、無事に動作した。
【Rails】RSpecマッチャー一覧

## はじめに
　本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## RSpecマッチャー一覧

```:マッチャー一覧

マッチャー名                         機能
-----------------------------------------------------------------------
be_valid                          有効であるか
-----------------------------------------------------------------------
be_invalid                        無効であるか
-----------------------------------------------------------------------
include                           指定した値が配列に含まれているか
-----------------------------------------------------------------------
find                              要素の検索
-----------------------------------------------------------------------
click                             クリックする
-----------------------------------------------------------------------
have_content                      文字列が存在するか
-----------------------------------------------------------------------
have_link                         指定した値のリンクが存在するか
-----------------------------------------------------------------------
eq                                期待値と値を比較して一致するか
-----------------------------------------------------------------------          
have_selector                     HTMLタグおよびCSSに指定した文字列が存在するか
-----------------------------------------------------------------------
have_field                        入カフォームが存在するか
-----------------------------------------------------------------------
find_all                          ページ上の指定のHTMLタグを全て取得する
-----------------------------------------------------------------------
match                             matchメソッドを使用して期待値と一致するか
-----------------------------------------------------------------------
have_button                       ページ上に指定したボタンが存在するか
-----------------------------------------------------------------------
click_button                      指定したボタンをクリックする
-----------------------------------------------------------------------
have_current_path                 パスを取得する
-----------------------------------------------------------------------
change                            ある動作Aに対してBが変動するか

```
UnityでSmart Merge(UnityYAMLMerge)を使用してPrefabの競合を解決する

Unityで同一のPrefabやSceneファイルを、異なるブランチで編集してマージすると、確実にコンフリクトします。
ですがUnityYAMLMergeというUnity公式のマージツールを使用すると、多くの場合自動でコンフリクト解消することができます。

# ツール設定方法
UnityYAMLMergeはUnity本体と同時にインストールされます。
Macの場合は以下のパスにツールが存在します。
```bash
/Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge
```
Unity　Hub経由の場合はパスは下記になります。（バージョン番号は適宜変更してください）
```bash
/Applications/Unity/Hub/Editor/2018.4.16f1/Unity.app/Contents/Tools/UnityYAMLMerge
```

パスがわかったら `~/.gitconfig`末尾にツール設定を追加します。
YAMLMergeへのパスは適宜変更してください。
```bash:~/.gitconfig
#...既存の設定
[merge]
	tool = unityyamlmerge
[mergetool "unityyamlmerge"]
	trustExitCode = false
	cmd = '/Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
```
これでツールの設定は完了です。

# コンフリクト解消手順
まず下記のようにマージした結果コンフリクトが起きたとします。
```bash
$ git merge feature/prefab_conflict_branch
Auto-merging XXXXX.prefab
CONFLICT (content): XXXXX.prefab
```

この状態で`git mergetool`を実行すると、YAMLMergeがコンフリクト解消を試みてくれます。
```bash
$ git mergetool
Merging:
XXXXX.prefab

Normal merge conflict for 'XXXXX.prefab':
  (local): modified file
  (remote): modified file
Conflicts:
Conflict handling:
```

上記のような形でメッセージが出れば、解消成功なのでそのままマージを進めればOKです。
```bash
$ git merge --continue
```

# ツールでも解消できない場合
ツールも万能ではなく、例えば同じTransformコンポーネントを編集した場合、この部分は手動で解消する必要があります。

`git mergetool`実行後に手動解消が必要な場合、さらに設定されたmergetoolが起動します。
Macの場合は標準のopendiffが立ち上がるので、それで解消していくわけですが、
これの相性が悪くp4merge等の別のmergetoolを設定しておく必要があります。

p4mergeの設定方法はインストール後、下記のようにUnityYAMLMerge設定ファイルに記載します
```bash:/Applications/Unity/Unity.app/Contents/Tools/mergespecfile.txt
#
# Default fallbacks for unknown files. First tool found is used.
#

* use "Applications/p4merge.app/Contents/MacOS/p4merge" %b %l %r %d
```

これで手動解消での対応も可能になりました。
CentOS-7 の OpenJDK-8 を 11 に

既に 8 がインストールされている環境を 11 にする。

バージョンを確認
```
$ java -version
openjdk version "1.8.0_322"
OpenJDK Runtime Environment (build 1.8.0_322-b06)
OpenJDK 64-Bit Server VM (build 25.322-b06, mixed mode)
```

11 をインストール
```
$ sudo yum install java-11-openjdk
```

このままでは、まだ 8 を見ている状態なので、11 に切り替え
```
$ sudo alternatives --config java
```

バージョンを確認
```
$ java -version
openjdk version "11.0.14.1" 2022-02-08 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.14.1+1-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.14.1+1-LTS, mixed mode, sharing)
```
Macでスリープ復帰時に何か処理させたい

# やりたい事
MacBookの蓋を閉じるとスリープ状態になりNASの接続が切れてしまう。
切れてもいいが、蓋を開けてスリープから戻ったらNASの接続も戻って欲しい。
スリープが解除されたら何かコマンドを実行できないか。という仕掛けを考えたという投稿です。

# コード

```sleepWatcher.pl
#!/usr/bin/perl
################################################################################
# sleepWatcher.pl
# pmset ログ出力を読み取り、スリープからの復帰を処理する。
################################################################################
use strict;
use warnings;
STDOUT->autoflush(1);

################################################################################
# pmset -g pslog を読み取りオープン
################################################################################
my $fh;
my $rec;

open $fh, "pmset -g pslog |";
while( $rec = <$fh> ) {
    chomp($rec);

    if( $rec =~ /HasPoweredOn/ ) {
        #
        # スリープ状態が解除された時の処理
        #
        `say -v ava -a "MacBook" "Good morning \`whoami\`"`;
        

    }elsif( $rec =~ /Sleeping/ ) {
        #
        # スリープ状態に移行した時の処理
        #
    }
}

close $fh;  # 到達することはないけれども
```

# Mac起動時に自動実行させておく
```
$ crontab -e
@reboot 配置パス/sleepWatcher.pl
```
とことん掘り下げてイメージを共有していくヒアリング

システム開発にしてもWeb制作にしてもインフラ構築にしてもなんにしても一番初めに来るのがヒアリング。そして、失敗すると後々けっこう大変になるのもヒアリングの精度によるものです。

私は主にWebサイトのプランニングや上流工程の部分でのグランドデザインを行うことが多いですが、ヒアリングを行う中で気にしているポイントを５点記載します。新規顧客を想定した時のパターンを書きます。

**１．顧客に関する情報をひたすら確認する。**

これはもう当たり前ではありますが、顧客の企業情報をしっかり確認します。これをやることで顧客が話している内容でよくわからないという事が格段に減ります。それが下の項目です。

・企業の基本情報（所在地、従業員数、業界、事業など）
・どのような事業をしているか、またどの事業が中心となっているか
・企業理念や行動指針などの企業の考え方
・現状のWebサイトの状況
・顧客の業界における競合の調査
・顧客の業界の状況
・上場企業であればIR情報
・顧客の採用サイト（企業の考え方がわかりやすく掲載されている）

これらを広く浅くでも確認しておくとまず会話に困りません。事前に顧客の求めていることを知らなくてもほとんど会話に困りません。むしろこれがなかったら広い視点で顧客を理解できず、地獄のようなヒアリング時間になることもあります。


**２．疑問点や不明点は持ち帰らない**

顧客が考えていることは、往々にしてざっくりしてますよね。「え？それで終わり？」みたいなことも当然あります。そうするともうこちらから聞かないと話にならないわけです。そこで登場するのが、１で調べた内容です。

そこから出てくる質問としては、
・他社ではこんな風に展開していますが、御社ではそのようなことはお考えではないですか？
・他社ではこのような情報の優先順位を取っていますが、同じようにはなりますか？
・このような業界だとデータをしては、〇〇のような流れで処理されるかと思いますがいかがですか？
・このシステムは御社の組織のどの範囲で使われるものですか？
などなど

事前情報があれば、その時の話に合わせていくつか自動的に気になることが出てくるようになります。当然経験値も必要になりますが、経験値は先輩や社内の有識者に事前に確認しておくといいでしょう。


**３．聞くだけでなく議論をする**

ヒアリングは、顧客との接点の中で初めて膝を付け合わせて具体的な会話ができる場です。せっかくのその場で話を聞いて「うんうん、なるほど。わかりました。検討します！」って帰ってくるのはもったいなさすぎます。そして、一番ダメなパターンである「あの人たち本当にわかったのかな」という事を顧客に感じられることです。

議論というと大げさかもしれませんが、意識するのは「こちらの見解を確認する」という事です。
デザイン一つとっても「かっこいい」の選択肢は無数にありますし、システム構築にしても「使いやすい」はいくつもあります。これらの１つの単語をいかに明確にしていくかがポイントで、手を変え品を変えこちらからボールを投げて、バンバン打ってもらいます。投げては打ってそれを拾ってまた投げての繰り返し。

そうするとほとんどの確率で、こんな言葉が出てきます。
「いや、そうじゃなくてこう」
「そう、そんな感じ」
「いや、うちの社内ではこういう事があってここには気を付けてほしい」
「実はこんな事情があってこの部分の調整は時間がかかりそう」

こうなってくると要件の粒度やスケジュールで気にしなければならないこと、社内の政治上気にしなければならないことなど、様々なことが炙り出されてきます。そうすると**１回の打合せの重みが格段に変わってきます。**

**４．目的を明確化し、「どんな状態になる」のがいいことなのかを知る**

受託開発の場合には、ものを作って終わりではありません。その先には必ず使う人や見る人が存在して、その人がどのような動きをすること、またその動きによってどんな状態になるかという事が本来の目的のはずです。

ほとんどの場合は「〇〇を改善したいのでこのシステムを作りたい」とか「こんなことをしたいからサイトを新しくしたい」など、**モノを使ってこうしたい**という話で持ってこられます。

では、改善した先に何があるのか、やりたいことをやった先に何があるのか。
そこが見えなければ、そもそも顧客が話しているやりたいことが本当に正しことなのかわからないですよね。
私たちの目的は、「顧客の作りたいものを作る」のではなく、私たちが作ったもので顧客の事業に何かしらの形でコミットする事です。

そう考えると目の前にある作るモノの先に顧客が成功と思う状態がどのような状態なのかを知らないと正しい判断はできませんよね。**なぜならITのプロはお客様ではなく私たちなのですから。**


**５．見えるようにメモを書く、手書きでイメージを共有する**

打合せの中で会話だけしていてもなかなか思考というものはまとまってくれません。
なので、極力目に見える形で共有していくことが大切です。
１～４の工程を進めていくと何かしらの形が見えてきますが、視覚的に見ていかないと人の頭では情報処理がしきれません。（天才は除外）

私がよくやるのが、内容をテキストで残し、頭で浮かんできたフローやデザインイメージを手書きで書いたり、PowerPointやExcelで図にしたりして、こんな感じでイメージしてますっていうのを共有します。
ここまでくると最終段階ですが、またこれを元にあーでもないこーでもないと話をしてきます。

これらをやっていくとA4のよくわからん紙切れ１枚のRFPから始まったヒアリングから提案書の概要が出来て、７合目から登山をしていくような形で次のアクションを進めることが出来るようになります。

ここまで５つのポイントについて記載しましたが、このラインまでくるとお客様としてはめちゃくちゃちゃんと考えてくれて、アドバイスもくれて「ちゃんとやってくれそう！」というイメージを持ってもらうことが出来、**信頼貯金を獲得することが出来ます**。もしかしたらこれが一番の収穫かもしれません。

という事で色々と書いてきましたが、正直すべての顧客でこれが成功するわけではありません。
しかしながらこれをやることでコンペの勝率や細かい粒度での提案を作ることが出来るのは間違いありません。（経験上）
とにかく、**やれる事はしっかりやろう**という事ですね。

どなたかの参考になれば幸いです。
それではまた。
SQLiteでテーブル作成時に制約をつける

SQLiteで制約の付け方がわかりづらかったので備忘も兼ねて書きます。

## 制約をつける
主要な制約を全部入れるとこんな感じ。
```
CREATE TABLE table1(
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL DEFAULT '' CHECK(name IN ('hoge', 'fuga')),
  param1 TEXT UNIQUE,
  param2 INTEGER REFERENCES table2(id)
);
```
NOT NULL、PRIMARY KEY、DEFAULTはそこまま書くだけです。
注意が必要な項目だけ解説します。

### AUTOINCREMENT
MySQLだとAUTO_INCREMENTですがアンダーバーなしのAUTOINCREMENTで指定します。遅くなるので必要なければ付与しないことが推奨されています([ソース](https://qiita.com/Tokeiya/items/3df15a729eec1aa0c7ed))。

### CHECK
CHECK(条件)で指定します。条件は
`カラム名 IN ('hoge', 'fuga')`や、`カラム:名 < 100`のように指定します。

### ユニーク制約
カラム単位ではUNIQUEをつけるだけでOK。
複数カラムでユニークにしたいときは、Create文の最後に`UNIQUE ({カラム名1}, {カラム名2})`をつけます。

### 外部キー制約
まずは下クエリを実行して有効化する必要があります。有効化しなくても一応制約は登録されてますが、違反してもエラーが出ず登録できてしまいます。互換性の関係で初期設定がオフになっているらしいです([ソース](https://www.sqlite.org/foreignkeys.html))。
```pragma foreign_keys = ON;```
  
パラメータの指定方法はこの記事が分かりやすいです。
[SQLite3構文　列制約（foreign key references）](https://ytyaru.hatenablog.com/entry/2021/06/22/000000)


### その他注意点
- 基本的に順不同ですが、AUTOINCREMENTはPRIMARY KEYの後など、一部ルールがあったりします。[こちら](https://www.sqlite.org/lang_createtable.html)が参考になります。
- 既存のテーブルに制約をつけたい場合、SQLiteでは後から制約を付与する機能はないようで、新しくテーブルを作り直す必要があるようです。試せてないですが下記記事が参考になりそうです。
[SQLite: Unique Constraints](https://www.techonthenet.com/sqlite/unique.php#:~:text=Drop%20Unique%20Constraint,data%20into%20this%20new%20table.)

### 余談
- version 3.37.0 (2021-11-27)から厳格な片付けモードのサポートが開始されたようです([ソース](https://www.sqlite.org/stricttables.html))。
- ドキュメントにDECIMAL(数字,数字)と指定できることは書かれてあるのですが、指定によりどのような制約がかかるのか記載がありませんでした。書いても格納できるデータが変わらないという話がありました([参考1](https://stackoverflow.com/questions/32178435/sqlite-type-name-with-two-optional-signed-numbers-what-does-it-mean)、[参考2](https://stackoverflow.com/questions/65444111/sqlite-how-to-store-decimal-0-00-and-1-10-instead-of-0-and-1-1))。なぜ実装されたのか謎です。
EC2を活用したFormer2の利用手順

# Former2とは
最初からCloudFormationを使って環境構築を行っていればいいのですが、手組みで行ったPoC環境や既存の環境が存在していた場合、CloudFormationのテンプレートを作るのはなかなか面倒くさかったります。こんなときにサクッと構成をエクスポートできたらなと思いますよね。はい、というわけでFormer2の出番です。

Former2でエクスポート可能なテンプレート形式は以下のとおりです。
- CloudFormation
- Terraform
- CDK
- CDK(Terraform)
- Pulumi
- Diagram
- Raw Output(Debug)

今流行りのCDKがサポートされているのは非常にアツイですね。

# 設定方法
[former2のサイト](https://former2.com/)にアクセスしてサービスとして利用することも可能ですが、外部のサービスから社内環境にアクセスしてデータを引き抜かれるのは何かと心配なものです。そこで、今回は対象AWSアカウントのVPC内にEC2を立てて、そこにFormer2のdockerを起動する方法について記載します。

- EC2を作成する。
    - SecurityGroupを作成するところまでは画面通り。
    - SecurityGroupで許可するSSHはアクセス元をに絞っておくこと。
        - アクセスキーは新規につくればOK。既存のキーペアを持っているならそちらでも。

- EC2にログインする。
    - Teratermを用意。設定→プロキシを以下に設定しして保存しておく。
        - Type  HTTPを選択
        - Hostname  プロキシのURLを入力
        - Portnumber  8080

- EC2にログインする際は、Teratermのホスト名にEC2のパブリックDNS名をコピペして利用する。
    - ユーザ名：ec2-user
    - RSA/DSA/ECDSA/ED25519鍵を使う → 秘密鍵にEC2を作成したときのキーペアを選択 

> (補足)Teratermが面倒であれば CLoudShellでもOK)
> CloudShellのグローバルIPを調べてセキュリティグループに設定する。
```
curl https://ifconfig.io
```
> ダウンロードしたキーペア(pemファイル)をCloudShellにアップロードして、pemファイルのパーミッションを変更する。

```
chmod 400 hogehoge.pem
ssh -i hogehoe.pem ec2-user@ec2-xxxxxx.ap-northeast-1.compute.amazonaws.com
Are you sure you want to continue connecting (yes/no)? yesを入力すると、EC2にログイン成功。
```

- EC2にGitをインストールする。
 ```
 $ sudo yum update
 $ sudo yum install git
 $ git version
 ```
- EC2にDockerをインストールする。  
```
 $ sudo yum -y install docker
 $ sudo systemctl start docker
 $ sudo systemctl enable docker
```

- EC2に docker-compose をインストールする。
バージョンは以下で確認する。最新でいいはず。
https://github.com/docker/compose/releases

```
 $ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
 $ sudo chmod +x /usr/local/bin/docker-compose
 $ docker-compose --version
```

- former2を入手する
```
 $ git clone https://github.com/iann0036/former2.git
```

- docker-composeを実行する
```
 $ cd former2
 $ sudo /usr/local/bin/docker-compose up -d
   動作確認
 $ sudo docker ps ※実行中のコンテナ
 $ sudo docker images ※存在しているコンテナ
```

- former2はデフォルトで127.0.0.1:80で起動するのでSSH転送する。
  # ポートとか変えたいなら、docker-compose.ymlの中身を変更
    - TeratermでSSH転送の設定を行う。設定→SSH転送、追加を選択。
    - ローカルのポート：適当。自分のPCであいているポートを指定。
    - リモート側のポートは、デフォルトだと80を指定

- 自分のブラウザから「localhost:ローカルのポート」 でアクセスすればEC2上のformer2へのアクセスが可能。
    
- ReadOnlyAccessのIAMユーザーを新規に作成してセキュリティ認証情報を利用
    - IAM ユーザ(former2)を作成。
    - ポリシーに、ReadOnlyAccessをアタッチ。
    - IAMユーザのアクセスキーとシークレットアクセスキーを入力。
hygen のテンプレートで変数を使ってみる

## 始めに

hygen では変数を利用することで、柔軟にファイルの作成を行うことが可能です。
今回はそれを実際に使ってみようと思います。

以前の hygen 導入までの記事はこちら

https://qiita.com/fussy113/items/66ca5985bf974eba6835

## 変数の埋め込み方

hygen を導入した時に自動で生成される`hello.ejs.t` に実はすでに変数が使用されています。

````_templates/new_template/hello/hello.ejs.t
---
to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
---
---
to: app/hello.js
---
const hello = ```
Hello!
This is your first hygen template.

Learn what it can do here:

https://github.com/jondot/hygen
```

console.log(hello)
````

二行目に記載されている、`<%= name >`、`<%= action || 'new' %>` がそれに該当します。
`name`、`action` を変数として受け取って、展開する書き方になります。
また、`<%= hoge || 'fuga'` のように記述することで、デフォルト値を設定することも可能なようですね！

ファイルをどこに生成するかを、変数によって柔軟に設定できるようになっています。

## コマンドラインで変数に値を渡す

hygen は変数の渡す方法が2種類あります。

1. コマンドラインで渡す
1. 対話形式で入力して渡す

今回は、コマンドラインから渡してみましょう
基本はこんな形になります。

`yarn run hygen Generator名 Action名 --変数名 値`

どのGenerator、Action からファイルを作成するかを選択肢、オプションで変数名を渡すといった感じです。

`yarn run hygen generator new --name new_template --action hello`

```
$ yarn run hygen generator new --name new_template --action hello
yarn run v1.22.17
$ /workspaces/hygen-sample/node_modules/.bin/hygen generator new --name new_template --action hello

Loaded templates: _templates
       added: _templates/new_template/hello/hello.ejs.t
Done in 2.87s.
```

`_templates/nameで渡した値/actionで渡した値/hello.ejs.t` が無事に作成されましたね。

## 変数の使い方Tips

### ファイル名などを埋め込む

`<%= hoge %>` みたいな形で、テンプレートのファイル上で変数を展開できます。

### 条件分岐

テンプレート自体はejs なので、if文といった構文も利用することができます。

- 初期値(変数が渡されてない時に代わりに使われる値)を設定することができる

`<%= fuga || 'piyo' %>`

- if文を使った条件分岐

```
<% if (name) { %>
  <h2><%= name %></h2>
<% } %>
```

ある値が渡されたら、この文を追加する、場合わけするみたいな感じで色々活用ができそうですね。

## 終わりに

今回はhygen でのテンプレートでの変数の使い方を簡単に紹介しました。
ファイルを作る際に変数を使うことができるので、より柔軟なテンプレートを作れる感じがして良いですね。

次は対話形式でファイルを作るというのを調べてまとめようと思います:muscle:
Redmica 1.2 から 2.0 にアップデートした件

- OS: Ubuntu 20.04 LTS
- RedMica 1.2.1.stable
- 2022/3/31

https://blog.redmine.jp/articles/mica-2_0/new-features/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/61328ba2-a4c8-d835-2e1d-3350aae99357.png)

### ■ソースのダウンロード　仮の場所で解凍
https://github.com/redmica/redmica/releases

~~~
cd usr/locar/src
wget https://github.com/redmica/redmica/archive/refs/tags/v2.0.0.tar.gz
sudo tar -xf ./v2.0.0.tar.gz
mv ./redmica-2.0.0 /var/lib/
~~~

### ■現データ：files,log,plugins フォルダのコピー
~~~
sudo cp -ra /var/lib/redmine_old/files/* /var/lib/redmica-2.0.0/files/
sudo cp -ra /var/lib/redmine_old/log/* /var/lib/redmica-2.0.0/log/
sudo cp -ra /var/lib/redmine_old/plugins/* /var/lib/redmica-2.0.0/plugins/
~~~

### ■設定ファイルのコピー
~~~
sudo cp /var/lib/redmine/config/configuration.yml /var/lib/redmica-2.0.0/config/
sudo cp /var/lib/redmine/config/database.yml /var/lib/redmica-2.0.0/config/
~~~

### ■インストール設定のコマンド入力
~~~
cd /var/lib/redmica-2.0.0
#Redmineの実行に必要なgemをインストール
sudo bundle install --without development test
#新しいセッション保護用の秘密鍵を生成
sudo bundle exec rake generate_secret_token
#データベースの内容を更新
sudo bundle exec rake db:migrate RAILS_ENV=production
#プラグインに関しても更新
sudo bundle exec rake redmine:plugins:migrate RAILS_ENV=production
#キャッシュのクリア
bundle exec rake tmp:cache:clear RAILS_ENV=production
#redmica-2.0.0 フォルダの所有者変更
sudo chown -R www-data:www-data /var/lib/redmica-2.0.0
~~~


### ■Apacheの設定ファイルの変更

設定ファイル：/etc/httpd/conf.d/redmine.conf
/var/lib/redmine/　→　/var/lib/redmica-2.0.0/　へ変更

~~~
<Directory "/var/lib/redmica-2.0.0/public">
  Require all granted
</Directory>
...
<Directory /var/lib/redmica-2.0.0/public>
    Allow from all
    Options -MultiViews
    Require all granted
</Directory>
...
Alias /redmine /var/lib/redmica-2.0.0/public
<Location /redmine>
  PassengerBaseURI /redmine
  PassengerAppRoot /var/lib/redmica-2.0.0
</Location>
~~~

### ■以上の設定が終われば、Apacheの再起動で完了
~~~
apache2ctl configtest
sudo service apache2 reload
~~~



■参考
http://guide.redmine.jp/RedmineUpgrade/#step-3-
https://vertys.net/redmine-upgrade-to-421/
https://blog.redmine.jp/articles/3_4/install/ubuntu/
基本情報技術者試験対策　20日目

基本情報技術者試験勉強　20日目
-
この記事の目的
-
今年の5月に基本情報技術者試験を合格するために、過去問で間違えた箇所をただまとめる自分のための記事

プロフィール
-
・文系大学の３年生
・ITパスポートは保有
・ウェブアプリやサイト作成を個人で行ったことがある程度
・猫好き

今日の目標
-
マネジメント系を50問取り組む。

間違った箇所
-
1、再入可能（リエントラント）
複数のタスクから同時に呼び出されても、それぞれに正しい結果を返す

2、RARP(Reverse Address Resolution Protocol)
機器固有のMACアドレスから対応するIPアドレスを取得するプロトコル

3、クラッシング
クリティカルパス上のアクティビティに資源を追加投入して短縮を図る

4、ファストトラッキング
当初の計画では順番に行う予定だったアクティビティを並行して行うことによって、短縮を図る

5、クリティカルチェーン法
クリティカルパス法をベースに人員、設備などのリソースを制限したスケジュール管理

6、ファンクションポイント法
外部入出力や内部論理ファイル，外部照会，外部インタフェースなどの個数や特性などから開発規模を見積もる。

7、プログラムステップ法
開発するプログラムごとのステっプ数を換算し、開発規模を見積もる

8、標準タスク法
開発プロジェクトで必要な作業のWBSを作成し、各作業の工数を見積もる。

9、類推見積法
過去の類似例を探し、その実績や開発するシステムとの差異などを分析、評価して開発規模を見積もる


振り返り
-
今日はマネジメント系を30問取り組んだが、プロジェクトマネジメントの割合が低い。問題自体も初めて解く内容が多かったため、もっと問題数を解く必要がある。
>引用
基本情報技術者試験ドットコム
https://www.fe-siken.com