OmniAICreator/Qiita-1.07M huggingface dataset:
[C#] de Paformance data helper using.

やりたいこと
---
　C＃でパフォーマンスデータを読み取りたい。。
　Ｃ＃では.Netフレームワークが提供するカウンタークラスは
　ライブカウンター値の読み取りと書き込みには役立ちますが、
　パフォーマンスログにバインドすることができないようです。。
　なので、PDH APIを使用しパフォーマンスログへのバインドを実現させます。

定義
---
PDH_FMT_COUNTERVALUE structure (pdh.h)

    [StructLayout(LayoutKind.Explicit)]
    public struct PDH_FMT_COUNTERVALUE
    {
        [FieldOffset(0)]
        public UInt32 CStatus;
        [FieldOffset(1)]
        public int longValue;
        [FieldOffset(1)]
        public double doubleValue;
        [FieldOffset(1)]
        public long longLongValue;
        [FieldOffset(1)]
        public IntPtr AnsiStringValue;
        [FieldOffset(1)]
        public IntPtr WideStringValue;
    }

PdhOpenQueryA function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern UInt32 PdhOpenQuery( string szDataSource, IntPtr dwUserData,out PdhQueryHandle phQuery);

PdhOpenQueryH function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhOpenQueryH(PdhLogHandle hDataSource,IntPtr dwUserData,out PdhQueryHandle phQuery);

PdhBindInputDataSourceA function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhBindInputDataSource(out PdhLogHandle phDataSource,string szLogFileNameList);

PdhCloseLog function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhCloseLog(IntPtr hLog,long dwFlags);

PdhCloseQuery function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhCloseQuery(IntPtr hQuery);

PdhRemoveCounter function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhRemoveCounter(IntPtr hQuery);

PdhAddCounterA function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern UInt32 PdhAddCounter(
            PdhQueryHandle hQuery,
            string szFullCounterPath,
            IntPtr dwUserData,
            out PdhCounterHandle phCounter);

PdhCollectQueryData function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhCollectQueryData(PdhQueryHandle phQuery);

PdhCollectQueryData function (pdh.h)

    [DllImport("pdh.dll", SetLastError = true)]
    public static extern UInt32 PdhGetFormattedCounterValue(
            PdhCounterHandle phCounter,
            PdhFormat dwFormat,
            IntPtr lpdwType,
            out PDH_FMT_COUNTERVALUE pValue);

実装
---

    UInt32 result = PdhApi.PdhOpenQuery(null, IntPtr.Zero, out query);
　　※szDataSource（第一引数）は、NULLでなければならない。。

    string counterName = @"\Processor(0)\% Processor Time";    
    result = PdhApi.PdhAddCounter(query, counterName, IntPtr.Zero, out counter);

.

    result = PdhApi.PdhCollectQueryData(query);
    PDH_FMT_COUNTERVALUE value;
    result = PdhApi.PdhGetFormattedCounterValue(counter, PdhFormat.PDH_FMT_DOUBLE, IntPtr.Zero, out value);
    ※複数のサンプルを必要とする場合は、CounterValueを使用して取得する。

Acknowledgments
--
 Development Errata
  http://adamserrata.blogspot.com/2009/01/how-to-use-c-to-read-performance-data.html
> tanner,thank you.
Terraformでcountやfor_eachを使って定義したリソースをTerraform管理下から外す方法

# はじめに

みなさん、こんにちは。今回は既存のリソースを`terraform state rm`コマンドを使ってTerraform管理下から外す際の小ネタの紹介です。

Terraformで実装する際、たとえば複数複数のリージョンやアベイラビリティゾーンに同様のリソースを配置する際などのユースケースにおいてcountやfor_eachを活用されている方も多いかと思います。このcountやfor_eachを活用して定義したリソースに対して素直に`terraform state rm`コマンドを実行すると次のようにコマンドがエラーになってしまいます。今回はそんなときの解決方法を紹介したいと思います。

```txt:エラー時の出力例
$ terraform state rm google_compute_subnetwork.private["tokyo"]
Acquiring state lock. This may take a few moments...
╷
│ Error: Index value required
│ 
│   on  line 1:
│   (source code not available)
│ 
│ Index brackets must contain either a literal number or a literal string.
╵

Releasing state lock. This may take a few moments...
```

# countやfor_eachで定義したリソースを管理外にする方法

結論から言いますと **「'(シングルクォーテーション)で定義したリソース名を囲む」** が1つの解となります。  
出力例のように、Terraformリソース名を'(シングルクォーテーション)で囲んであげると期待通りに既存のリソースがTerraform管理外になる動きとなります。めでたしめでたし。

```txt:成功時の出力例
$ terraform state rm 'google_compute_subnetwork.private["tokyo"]'
Acquiring state lock. This may take a few moments...
Removed google_compute_subnetwork.private["tokyo"]
Successfully removed 1 resource instance(s).
Releasing state lock. This may take a few moments...
```

# 終わりに

いまさらの情報でしたがいかがだったでしょうか。「え、こんなユースケースなくない？」と思われるかもしれませんが、「ついつい、うっかり既存環境を間違って違うリソースにインポートしちゃいました」といったケースもあるかと思います。そんなときの手助けになれば幸いです。

以上、`terraform state rm`コマンドを使ってTerraform管理下から外す際の小ネタの紹介でした。

---

- Terraform は、HashiCorp, Inc. の米国およびその他の国における商標または登録商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
Winter '23 レコードトリガーフローが便利になっていた！関連レコードの更新やってみる

# はじめに

https://admin.salesforce.com/blog/2022/learn-moar-in-winter-23-with-flow-enhancements?utm_source=trailhead&utm_medium=trailmix&utm_campaign=learn_moar_winter_23&_ga=2.168438753.190521205.1667719829-1546668006.1603647587

Winter ’23のアップデート内容である、レコードトリガーフローに`関連レコードの更新`追加が個人的に気になっていたので試してみます。

https://qiita.com/takaHAL/items/fa228f5de923f9d137eb

:::note
検証に使う環境は、Trailheadのハンズオン組織です。
データに関してもデモデータ + 検証で作ったデータしか入っていません
:::

# この記事で詳しく書かないこと

この機能の利用者がFlowを使ったことがあると思いますので詳しく1から作成手順は書きません。

# 何が変わるのか？

更新するレコード条件や項目の値セットがシンプルになったので、
以前より関連レコードを更新するやり方が、UIからわかりやすくなっていいと思います。
個人的にはレビュワーが読みやすくなったのがいいと思ってます。

|アップデート前	| アップデート後|
|---|---|
|![](https://user-images.githubusercontent.com/39574826/208128240-47eaf118-e9f4-4483-a137-1fa0aab37678.png)|![](https://user-images.githubusercontent.com/39574826/208136208-bf2b2dbe-9056-4ac6-a766-96a1c6b29852.png)![](https://user-images.githubusercontent.com/39574826/208128545-e35aded3-ed50-465c-89f6-b0563149ec6c.png)|

# 関連するレコードを全て更新

取引先に関連する取引先責任者の`リードソース`の値を`Web`に更新してみます。

![](https://user-images.githubusercontent.com/39574826/208134167-6aa7e96e-2e91-4360-834d-887d5248727b.png)


関連するレコードを更新する際は、検索条件を　`なし-すべての関連レコードを更新`を選択し

更新したい値を設定すればOKです。

![](https://user-images.githubusercontent.com/39574826/208129591-b295d925-c843-4240-9073-d0e640276c85.png)

## 実行してみる

関連するレコードのリードソースが全てWebに変わりました！

![](https://user-images.githubusercontent.com/39574826/208135218-f1398bd9-914f-4e02-85bc-dd5467c987a4.png)

# 特定条件の関連するレコードを更新

取引先に関連する取引先責任者の`Level`が`Primary`の人の`リードソース`を`Other`に更新します。

![テスト取引先1-Salesforce](https://user-images.githubusercontent.com/39574826/208137252-eb584215-3864-4d78-91ae-8f67849fc813.png)

検索条件を設定で関連レコードの項目で絞り込みたい条件を追加します。

![関連レコード更新テスト-V2](https://user-images.githubusercontent.com/39574826/208138122-d6a43b5e-73a6-4c53-9c65-736b84ad1fa7.png)

## 実行してみる

取引先責任者の`Level`が`Primary`の人の`リードソース`が`Other`に変わりました。

![テスト取引先1-Salesforce (1)](https://user-images.githubusercontent.com/39574826/208138663-0b140f01-62ab-46cb-b094-f08e8fd0ca47.png)

# さいごに

https://qiita.com/takaHAL/items/fa228f5de923f9d137eb

In/Not In 演算子のサポートほど衝撃的なアップデートではありませんでしたが、純粋に使いやすくなったと感じるので
よいアップデートだったのではないでしょうか？
レコードトリガーフロー以外でも同一のUIで更新設定ができると始めたばかりの人に優しいかもですね

# 参考

https://admin.salesforce.com/blog/2022/learn-moar-in-winter-23-with-flow-enhancements?utm_source=trailhead&utm_medium=trailmix&utm_campaign=learn_moar_winter_23&_ga=2.168438753.190521205.1667719829-1546668006.1603647587


https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements_data_update.htm&type=5
AWS WAFを有効化したCloudFrontやAPI Gatewayに対する8KBを超えるリクエストに失敗した件について

# はじめに

みなさん、こんにちは。AWS WAFを有効化したCloudFrontやAPI Gatewayに対する8KB以上のリクエストがブロックされてしまうといった事象に遭遇したので、今回はこちらの事象の原因と解決方法について紹介していきたいと思います。

# リクエストがブロックされた原因

WAFのログを確認すると、そのままズバリAWS WAFのコアルールセット(CRS)マネージドルールグループ `AWSManagedRulesCommonRuleSet`の`SizeRestrictions_BODY`ルールに合致したため8KB(8,192バイト)を超えるBodyを持つリクエストがブロックされていることがわかりました。

余談ですが、なぜ8KBという制限が存在するかというとそもそもAWS WAFで検査できるBodyは最初の8KBという制限があります(おそらく性能の観点で)。そのため、8KBを超えるBodyを持つ(=全文検査ができない)リクエストをデフォルトでブロックしているのではないか、と個人的には考えております。

![01-aws-managed-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613908/9c4ec5d9-4ac8-e879-05b7-64bea234ffdc.png)

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-baseline.html

# 解決方法

次の例のように`SizeRestrictions_BODY`ルールのデフォルトアクションを`Block`から`Count`へ変更することによって、8KBを超えるBodyを持つリクエストがブロックされず、ちゃんと扱えるようになりました。めでたしめでたし。

![02-override-action.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613908/3817eaee-9581-fbca-8279-8cbf32ab75cb.png)

# 余談、Terraformで設定する場合は

managed_rule_group_statementブロック内のexcluded_ruleブロックへ除外したいルールの名前を定義することで実装することが可能です。本定義を利用したサンプルコードを書いてみましたので興味のある方は次の記事をご参照いただければと思います。

https://qiita.com/chacco38/private/20553b8967d77028a8c5

# 終わりに

API Gatewayを扱ってきた方からするとなにを今更いってんだか…といった内容かもしれませんが、こんな情報でも誰かの役に経っていただければ幸いです。なお、今回ご紹介したマネージドルールを抜きにしても、AWS WAFにはBody以外にもHeaderやCookieにもサイズや数の制限がありますので、それを超えるリクエストを扱う場合は次のサイトを参考にしていただければと思います。

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-statement-oversize-handling.html

以上、AWS WAFを有効化したCloudFrontやAPI Gatewayに対する8KBを超えるリクエストがブロックされた事象の原因と解決方法のご紹介でした。

---

- AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
Azure Virtual DesktopからAWSのCloudFrontやAPI Gatewayへのアクセスがブロックされた件について

# はじめに

みなさん、こんにちは。AWS WAFを有効化したCloudFrontやAPI Gatewayに対するアクセスがAzure Virtual Desktop(AVD)からだとブロックされてしまうといった事象に遭遇したので、今回はこちらの事象の原因と解決方法について紹介していきたいと思います。

# アクセスがブロックされた原因

WAFのログを確認すると、AWS WAFの匿名IPリストマネージドルールグループ `AWSManagedRulesAnonymousIpList`の`HostingProviderIPList`ルールに合致したためAVDからのアクセスがブロックされていることがわかりました。うーむ、現状だとAzure Virtual Desktopはエンドユーザトラフィックのソースになる可能性が低いと判断されてしまっているということですね…^^;

![01-aws-managed-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613908/032d52ed-7dc2-f76b-2cd8-d42d9c6654bc.png)

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-ip-rep.html

# 解決方法

ホワイトリストを作る(特定のIPアドレスだけ許可する)などのいくつか解決方法はありますが、ホスティングサービスやクラウドサービスを活用して仮想デスクトップを構築・利用しているケースなどもそれなりにいることを考慮すると、このルールで無条件ブロックしていたホスティングサービスやクラウドサービスからの攻撃については別の異なるルールで保護することを前提に、デフォルトアクションを`Block`から`Count`へ変更してしまうという判断もありかと思います。

ということで、次の例のようにデフォルトアクションを変更することで、Azure Virtual Desktopからのアクセスがブロックされないようになりました。めでたしめでたし。

![02-override-action.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613908/7f72a5c0-e4dd-8539-9083-e5ac8b8baf89.png)

# 余談、Terraformで設定する場合は

managed_rule_group_statementブロック内のexcluded_ruleブロックへ除外したいルールの名前を定義することで実装することが可能です。本定義を利用したサンプルコードを書いてみましたので興味のある方は次の記事をご参照いただければと思います。

https://qiita.com/chacco38/private/20553b8967d77028a8c5

# 終わりに

今回はたまたまクライアントとしてAzure Virtual Desktopを利用していましたが、マネージドルールの内容を見るかぎり、AzureやGoogle Cloudなどの(AWS以外の)クラウドサービス全般からのアクセスはことごとくブロックされてしまう可能性があるようにも読めます。もしAWS上のWEBサービスに対して特定ユーザからのアクセスができないようで困っています、といった方は可能性の1つとして同件か疑ってみても良いのかなと思います。

以上、Azure Virtual DesktopからAWSのCloudFrontやAPI Gatewayへのアクセスがブロックされた事象の原因と解決方法のご紹介でした。

---

- AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
- Microsoft Azure は，Microsoft Corporation の商標または登録商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
baserCMSの管理画面でどのサブサイトにいるか迷った時に使えるプラグイン

# baserCMS専用 サブサイトメニュー表示プラグイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/e7de1c41-fd87-b13a-ba6b-56083041992b.png)

https://github.com/katokaisya/SubsiteMenu

## baserCMSのサブサイト機能
baserCMSでは、標準でサブサイト機能がついており、一つの管理画面から複数のサイトを管理することが可能です。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/9c50d0e3-1c90-299c-b83e-4f6e0da85671.png">
メインサイトとサブサイトでテーマを分けたり、サブサイトにサブドメインをあてたり、多言語サイトとして使用したり
さまざまな用途で活用できます。
### サイトの切り替えは、コンテンツ一覧から行います。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/e128be63-5d80-5e87-70f7-4414ee17fdbe.png">

### サブサイト機能の使いにくいところ
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/8c2d0bd6-8cff-5769-d6fe-7925ba64e20c.png">
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/7e1067d7-fc97-54ca-3a9b-bed9c8312f23.png">

この2枚の画像、同じ「NEWS」ブログとなっていますが、
片方がメインサイトのもので、もう片方がサブサイトのものです。
ただし、管理画面を見ても、どちらが、サブサイトのものか判別がつけづらいです。

サブサイトが一つ増えただけでもわかりにくい状況なのに、いくつもサブサイトがあったら、管理者にとっては「メインサイトのブログに記事を追加したつもりが、違うサブサイトのブログに記事を追加していて、投稿し直さなければならなくなった」といった事が発生してもおかしくなくなってきます。

また、サブサイトの切り替えがコンテンツ一覧からしかできず、頻繁にそれぞれのサブサイトのコンテンツを更新する必要がある時は、かなり面倒と感じる方もいるのではないかと思います。

そこで、自分は今どこのサイトにいるのかわかりやすくして、管理画面のどこからでも簡単にサブサイトへの切り替えができる機能を開発し、プラグイン化してみました。

# SubsiteMenu の使い方
プラグインを[ダウンロード](https://github.com/katokaisya/SubsiteMenu/archive/refs/heads/main.zip)してきて、圧縮を解凍します。
解凍してできた　SubsiteMenu-main　というフォルダを SubsiteMenu にリネームして、使用したいbaserCMSの/app/Plugin/フォルダの中に配置します。

管理画面「プラグイン一覧」より、インストールボタンをクリックして、有効化すれば、即使用が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/25aa6416-109b-3cbf-2dc4-b069d32ab723.png)
サブサイトを使っていれば
ツールバー上にセレクトボックスが表示され、今いるサイトが選択された状態となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/393835ee-4926-3055-fd69-294deb64f2f8.png)

セレクトボックスでサブサイトを選択すると、サブサイトのコンテンツ一覧へと遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/b64241e7-7133-9226-7a83-3e01fcec6065.png)

これでもう自分がどのサイトのブログを更新しているか迷わずに済みますね・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/20acbb32-ce5c-6ec5-bf5f-22e8b849dcc2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553367/5d79a8a6-4a5b-907a-9f69-fd396ca31f62.png)

:::note alert
管理画面のみが対象となり、公開側のページで表示されるツールバーには表示されません。
:::

また、ユーザーグループやユーザーごとに更新できるブログを絞った運用している場合、全てのユーザーでメインサイトや他のサブサイトが見えてしまったりすると都合が悪い場合もあるため、Config/setting.phpにて、ユーザー・ユーザーグループを絞り込めるようにしています。
デフォルトでは下記のように、ユーザーIDが1のユーザーか、ユーザーグループが1か３のユーザーだけに表示されるようになっています。

```ruby:/app/Plugin/SubsiteMenu/Config/setting.php
$config['SubsiteMenu'] = [
	// 表示するログインユーザーのID
	'loginUser' => [1],
	// 表示するログインユーザーグループのID
	'loginUserGroup' => [1, 3],
];
```
ここを調整して、見せるユーザーと見せないユーザーを分けるようにすると良いと思います。

# まとめ
普段baserCMSでサイトを開発している人たちに少しでも楽をしてもらおうと開発したプラグインですが、
評判が良ければ、baserCMS本体の機能に取り込んでもらえるといいな〜と思います。
プログラミングの勉強を1年半して思ったこと。

## 概要
忙しい人用に要点だけ書いておきます。尚、あくまで個人の感想、気づきにしかすぎないので、それを踏まえた上で、お読みください。
* コピペコードは最終的に誰も救わない。
* 同時並行して学べるのは一つまで。
* 技術発信は定期的にやることによって、自分のモチベーションが上がる。
でもQiitaとか、ブログとか書く時間がない。そんな時はTwitteとかでもつぶやくとモチベかなり上がります。
* モチベーションが上がらない時や、行き詰った時は環境を変えるというのも一つの手段。
* 聞ける先輩、師匠を作る。
* あと地味にモニターdisplay今月初めて使ってみたんですが、最高です。作業スピードとモチベ上がります。
![64127.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1972788/09c2cb13-743c-fe24-7cbe-0b4c5b34a5dd.jpeg)

## コピペコードは誰も救わない。
1年半やってきたからこそ理解できることですが、コピペコードは最終的に自分を傷つけます。
コピペコードで動いた時、達成感はすごくありますが、そのコードがなんで動いているのか、どうして、1行消すだけで止まるのか、そこの理解が曖昧なままだと最終的に、見返した時に０から書き直すということを嫌というほどやってきました。。
特に状態管理・データベース周りの処理をする際には、コピペコードは絶対に使わないほうがいいと感じました。
UdemyやQiitaなどの教材のコードをコピペしただけではダメで、コードを理解する必要があると強く感じました。なんでもググればいいというわけではないんです。
通常であれば、自分の頭でなぜ動くのか、動かないのかを考える必要があるんですが、コピペコードは、この手間を一時期は皆無にしてくれますが、最終的にどかっと一気に問題を吐いてきます。そして、途中から訳が分からなくなり、挫折するんです。
これを読んでるみなさんはとりあえず動けばいいやという感じで、コードを書いていないとは思いますが一応念のために書いてみました。


## 半年間Flutterを触らないでいたことをすごく後悔したこと
Flutterを触らず、他の言語を半年間試してみて、忘れたこと、やらかしてしまったことを、ひたすら話します。
半年前まではFlutterによる就職を目指していたので、Flutterしか勉強をしていなかった自分ですが、当時、Flutterエンジニアに求められるレベルが高く、個人開発で実績を作っていない自分にとっては、Flutterだけ書いててもなー、別にflutterのスペシャリストになりたいわけでもないしなーと逃げの考えをしていまい、他の言語に逃げてしまいました。別に、アーキテクチャや、状態管理の理解ができているならば、問題ないんでしょうが、そこの理解が曖昧なまま、でもなんとかRiverpodを用いた開発ななんとなくできるよー状態だったので、具体的な構造を理解できておらず、なんとなくのコピペコードばかりで対処していたレベルでした。
なので、久々にflutterを触ると、何がなんだかちんぷんかんぷん
本当にこれまで自分は何をやっていたんだと、後悔しました。
Firebaseの使い方も、忘れてしまっていて、ありとあらゆる記事や、公式ドキュメントを読むことで、なんとか当時の理解に戻すことができました。

本当にあの頃の自分に言いたいことが多くて、まず、動けばいいやのコードは絶対書くな！と一言言いたいです。
後々、自分がなんでこのコード書いてるんだと本当に悩んで、最終的に全消しして、書き直すなんてこともザラにあるからです。

次に、自分のキャパを考えろとも言いたいです。
複数の言語を同時進行して、学べるほど僕の頭は良くないのにも関わらず、Python、React、Java、JavaScript　こんなに学んでも身についたものは
ほぼ皆無でした。
なんとなく、書き方の違いとか、Hello Worldレベルのものを作る方法は理解できたんですが、それ以上先は理解できておりませんでした。

そんなこんなで、flutterしか勝たん状態になり、今急いで、勉強し直しています。
就活もやっぱflutterがええとなって就活し直してるんですが、今の時期新卒採用をしてくれている会社は少なく、大体が、技術力重視の企業のため、半年前に戻りたいと後悔しております。
とりあえず、今の目標はflutterで個人アプリのリリースを目指して、頑張ります！！
みなさんも中途半端で、flutterをやめるのは勿体無いと思うので、1年くらいやって自分にあってないと思っても、意外と続けてみる方が、得策だったりするかも知れませんよ。
## 初学者におすすめな勉強方法（体験談をもとに）
### 身銭を切る
*　Udemyやzenなどの教材を購入してやる。
身銭を切ってやらなければという意識を強くすることで、多少やる気がなくてもやるようになります。
### エンジニアの環境に自分を置く
* エンジニアコミュニティーに所属する。
* エンジニアの友達・エンジニアを目指している友達を作る。
* 勉強会に参加する。
* 学生であれば、長期インターンに参加する　など
### 聞けるエンジニアの師匠を作る。
一番はこれなのかもしれません。コミュニティーに所属したり、勉強会に参加したり、Twitterで質問したりして、周囲にエンジニアを置き、いつでも聞ける環境を作ることが大切だと感じています。
今はオンラインでも色々聞く手段はありますが、やはり対面で聞ける方が圧倒的に聞きやすく解決しやすいと感じました。すでに就職済みの方はシェアハウスなどに入って、他のエンジニアに聞ける環境を作るというのも一つの手かもしれません。



# 終わりに
色々勉強してきて言えることをこれまで話してきましたが、僕はまだエンジニアとしてひよっこです。今でも息詰まること、エンジニアになりたくないと思うことは多々あります。だからこそ、常に勉強をするために、安定を求めてはいけないと思いました。
行き詰まって、もうやりたくない状態に陥っているのであれば、作業環境を変えるとか、コミュニティに参加するとか、自分の置かれている環境を変えるといいですよ。周りが同じ言語をやっている環境にいくことによって、少しでもやらなきゃとか、詰まった時とかに聞ける状態が作れるので、おすすめです。
[書評]サーバーレスを支える技術を読んだのでまとめてみる 技術書典13

# [書評]サーバーレスを支える技術を読んだのでまとめてみる 技術書典13

## はじめに

この記事では技術書典13で出典されていた[Serverlessを支える技術 第4版](https://techbookfest.org/product/np5LkgiRLfMg3bZ0YMFhi7?productVariantID=2FHYvsBxBBuVXaPfr5u4et)を読んだ感想や読んでいて学習の手助けになったことを書きます。

書籍内では複数のクラウドサービスから複数種類のサーバーレスサービスが登場していますが
各サービスの優劣をつけるような内容ではありません。

どっちが先にリリースしたからすごいとかこっちの機能が優れているとかって話は聞いていて心象が良くないですし、書いても誰も幸せにならないとは思います。
※そもそも要件に合わせてサービスを使うことが適切だと考えている為、サービスの単純比較はナンセンスです。

なお、本書籍では内容を理解する為の用語説明と各クラウドサービスにおけるサーバーレスサービスについて解説されています。


## 結論

今も昔もサーバーレスにまつわる技術はクラウド事業者の間で大きな成長を遂げている。
"全てをクラウド上で"とまではいかずともインフラの設計次第で概ねサーバーレスアーキテクチャに対応できる可能性がある。
これほどまでに大きなムーブメントが起きたのはやはり、FaaSという利用体系にある。
必要な時に必要な時だけリソースを提供する、いわゆるリソースの抽象化の代表例である。

## サーバーレスの定義

2012年頃に遡り、[Why The Future Of Software And Apps Is Serverless](https://readwrite.com/why-the-future-of-software-and-apps-is-serverless/)よりサーバーレスが登場します。

パブリッククラウドでサーバーレスなサービスを利用できるようになったのは2008年のGoogle App Engine(GAE)がプレビューリリースされてからでした。※諸説あり

サーバーレスという言葉はよく誤解されがちですが、サーバーレスというのはサーバーがないわけではなくサーバーを意識する必要がないということです。

サーバーレスが流行したある時からインフラは所有から利用へ転換します。
とりわけ、コンピューティングサービスを使用して、計算資源をオンデマンドで利用することから「計算機資源の抽象化」という発想が生まれました。

また、サーバーレスによって多くの開発者が管理を意識することなく、計算リソースを利用できるようになったことから
開発者がインフラのことを概ね気にすることなくプログラムの実装に集中できるようになります。

ここでインフラストラクチャの管理を意識しないということから`フルマネージド`という考え方も登場します。

## フルマネージドとは

`誰かに管理をアウトソースすることによって管理を意識しない`ということがフルマネージドの考え方です。
フルマネージドなサービスを利用するユーザーは

- サービス提供側が定義するサービス利用料のみを支払う(コスト管理)
- 利用したいミドルウェアをお店のメニューのように選択する

という実質、自分のやりたいことに専念できるようになります。

フルマネージドとサーバーレスという考え方は必要な時に必要なだけ管理されたリソースを呼び出すという「計算機資源の抽象化」という分野を確立します。それと同時にイベントドリブンという考え方が生まれます。

## イベントドリブンなアーキテクチャが生まれる

`必要な時に必要な時だけ計算リソースを呼び出す`というロジックととても相性が良いのが、`イベントドリブン`という概念です。

イベントドリブンというのは`何かが起きたら任意の処理を実行する`という動き方のことです。
例えば、S3に画像がPUTされたらLambdaによって画像を加工するという処理はイベントドリブンです。

このイベントドリブンを採用したアーキテクチャをイベントドリブンアーキテクチャと呼び、クラウドサービスをコンポーネントという単位で結合することによって一つのアプリケーションを構築することができるようになります。

アプリケーションが内包するそれぞれの機能(ファンクション)は疎結合であり、この文脈からマイクロサービスアーキテクチャというアーキテクチャの発想につながります。
※今回は記事の趣旨からはずれるorこの話題をテーマにするとそれこそ1記事になってしまうので割愛します。

機能が疎結合なアプリケーションがもたらしたメリットとしては`モノリシックなシステム構成`からの解放が挙げられると考えられます。

## サーバーレスの全体像

ここまででサーバーレスにまつわる用語をおさらいしてきましたが、サーバーレスとは計算機資源の抽象化です。

抽象化するということから以下のような図式が成り立つと考えられます。
サーバーレス = フルマネージドサービスの活用 + 疎結合な機能 + イベントドリブン

コスト次第ではあるが、サーバーレスは`どれくらいリソースが必要か`ということを気にする必要がないというである。

## おわり(所感)

技術書典13でなんとなく興味で購入した書籍でしたが、今回紹介した内容以外に多くのことが語られています。
今回は冒頭数十ページの紹介に留まりましたが、昨今のサーバーレス事情を一気にキャッチアップするのにはうってつけの内容だと思います。

ちなみに私はサーバーレスというサービスを初めて体感したのはAWS Lambdaでした。当時は本当に簡単にできるんだなと感動したのを覚えています。

今回は以上です。

## 参考

[Why The Future Of Software And Apps Is Serverless](https://readwrite.com/why-the-future-of-software-and-apps-is-serverless/)

[さくらのナレッジ](https://knowledge.sakura.ad.jp/20167/)
「Twitter for 〇〇」が消えたので発信元を見るだけのツールを作った

イーロンの改革の影響なのか、Twitterのツイートページにこれまで存在した「Twitter for Android」や「Twitter for iOS」「Twitter Web App」といったツイートの発信元が表示されなくなりました。

![for.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/6672a419-0b53-bd74-ef83-110c85a819a0.png)

しかし、**Twitter APIを叩いてみると普通に取得できる**んですよね。なのでそれを誰でも見られるようにするミニツールを作りました。

https://tools.ic731.net/twitter/for/

とはいえ、見られる環境と見られない環境があるようで、ブラウザでは消えているのですが、私のAndroid版Twitterではまだ表示されてるんすよね。そこらへんは色々兼ね合いがあるのでしょう。

### APIについて
今回はTwitter API v2をPHPを利用して叩いています。URLからツイートIDを抜き取って、`/2/tweets`へGETリクエストを投げるとツイート情報を返却してくれる流れです。
Twitter API界隈ではおなじみの`abraham/twitteroauth`を用いて操作しています。同ライブラリでv2系を使うには``が必要なのでそこだけご注意を。

```php
$connection = new TwitterOAuth($ck, $cs, null, $brarer);
$connection->setApiVersion("2");
$id = '123456789';
$params = [
  "ids" => $id,
  "tweet.fields" => "source"
];
// GET
$tweets = $connection->get("tweets", $params);
```

そして、今回の肝である「Twitter for 〇〇」は`$tweets->data[0]->source`に格納されています。以上簡単なアプリでした。是非使ってみてください。

技術的な話は基本的に[Zenn(@ichii731)で書くようにしました](https://zenn.dev/ichii731)のでこっちもよろしくどうぞ。
初心に戻ってIAP経由によるGCEへのSSH接続を試す

# はじめに
今までGCEへのSSH接続はAWSでやっているように、対象IPからのSSH接続を許可し、ユーザを払い出し、そこに対するリモート接続を行っていた。
※お客様用のIPを基本的には許可したい、という要件が多く、これを設定する機会がありませんでした
Security Engineerの試験を勉強していることと、当該技術を使う機会があったので、IAPを使ったSSH接続をおさらいする

# IAPに関する説明

## トップページの記載

https://cloud.google.com/iap?hl=ja

記載のとおり「ID とコンテキストを使用して、アプリケーションや VM へのアクセスを保護。」します。
ここでいうIDはCloud IAM を指しており、アプリケーションやVMへのアクセスを保護というのは、IAMのユーザを利用し、そのユーザやVMに対して権限が与えられている場合のみ、TCP転送をするような形になります。

## 仕組み
イメージとしてはこんな感じで、UserはIAPへHTTPSでアクセスし、IAPから対象まで22ポートで接続します。
ちなみにComputeEngineはExternalIPがなくても可能です。

![Untitled-2022-12-17-0011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/fb7e6305-621d-e084-aa23-64508be2f580.png)

これを行うために、Userはプロジェクト内のIAM権限が必要で対象の権限を付与する必要があります。
また22ポートで特定のIPアドレスからの許可が必要になるため、FWのポート開放も必要となります。

# 実際の手順

以下公式の手順です

https://cloud.google.com/iap/docs/using-tcp-forwarding?hl=ja

## FW設定

※VMは起動している前提です。
FWのポート開放を行います。
35.235.240.0/20 からの 22ポートの許可を対象インスタンスに対して行います。

![スクリーンショット 2022-12-17 0.30.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/e87f990a-1ea2-91c3-2cf7-d9efe82a95e1.png)


## IAM設定

「IAP で保護されたトンネル ユーザー」、「Compute インスタンス管理者（v1）」を追加します。

![スクリーンショット 2022-12-17 0.34.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/fa4c026a-a974-32ef-81f6-208e6cc4076e.png)


## SSH接続

以下の画像にあるような形でSSHを選択し接続します。

![スクリーンショット 2022-12-17 0.40.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/c38efdbb-d4d2-f9c7-72aa-4cb8dfb91dbf.png)


### 補足
- IAM権限の影響か一通り設定してもなかなか接続できませんでした。ただVMを再起動したところ接続することができ、その場合も焦らず再起動してみましょう。

# 所感
特に難しいこともなく踏み台を利用せずともPrivate環境のインスタンスへ接続することができました。
興味のある内容としてSSHキーはどうなるんだ？と思いましたが、インスタンスのSSH認証鍵箇所に接続時？に一時的なキーが払い出されており(以下参照)、SSHキーの管理部分も不要になり、よりセキュリティ的にも安心できることがわかりました。

![スクリーンショット 2022-12-17 0.44.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/924dc788-a72b-6652-da5b-cc6fe5fed5ca.png)
Unity2020から2021へ

このほど、Unityのバージョンを
2020.3.34f1から2021.3.15f1へ上げました。

# 上げた理由
 - サポートが切れないうちに上げたい
 - 2020はURP内部でGC.Allocしてる

# 2021.3.15f1について
 - それまでの2021はGraphics.DrawMesh系で描画したものがチラついていて、Graphics.DrawMeshInstancedによるGPUインスタンシングが実質的に使えなかった
 - それ自体は2021.3.10辺りで修正されたようだが、それ以外の所でバグがあった
 - 2021.3.15f1では一通り安定した模様

# バージョンアップに伴うトラップ
## パッケージインポートが止まらない
 - 2020.3.34f1用プロジェクトを2021.3.15f1エディタで起動するとWindows版ではパッケージインポートを繰り返していつまで経っても操作できない。Macは一回で止まってくれるが、フォーカスを切り替える度にインポートしなおしてしまって鬱陶しい。
 - Assetsフォルダ内のファイルだけでなく、Project Settings関連の.assetファイルも新しく保存し直すとWindows/Mac共に安定した。
 - ただ、ちょっとした拍子に同じ症状が出ることがある。変更したファイルを、reserializeしたりすると治る。
## 標準のシェーダーとマテリアルインスペクタの構造が大きく変化
 - SimpleLitを改造して使ってたシェーダーとそのマテリアルインスペクタは結局ほぼ作り直し。


ああ、来年2022に上げる時は楽でありますように…
OutSystemsからSAPのODataを更新する方法

# 本記事でやりたいこと
SAP S/4HANA のデータを更新できるアプリをOutsystemsで作成する

# アジェンダ
・ODataの公開
・OutSystemsのAPIとして登録
・更新処理の実装


# ODataの公開
## 方法１ API Managementの利用

https://qiita.com/nanaki11/items/7c8636cfc68768425acc#outsytems%E3%81%AEservice-center%E3%81%A7%E7%A2%BA%E8%AA%8D

こちらの過去記事を参考にODataをAPI化します
Integration Builderは使用してもいいですが、今回は使わずRestApiとして実装しようと思います

## 方法２ CAPアプリの作成

https://developers.sap.com/group.hana-cloud-cap-setup.html

https://developers.sap.com/tutorials/btp-app-ext-service-add-consumption.html

こちらの２つのチュートリアルを参考にS/4HANAのデータをOData化として公開するCAPアプリをBTP上で開発します
この２つのチュートリアルだけでは足りない部分もあると思いますが、気が向いたら更新します

## ２つの方法の比較
### コスト サービス利用料
CAPアプリのほうが安くなります
API Management（IntegrationSuite）はBTPサービスの中でも高額な利用料が発生します
CAPアプリはCF環境やBASの利用くらいでIntegrationSuiteに比べると少額です（月々数千円と数十万くらいの差額）

### コスト 開発コスト（工数）
API Managementのほうが安くなります
CAPはフレームワークですべての処理をコーディングする訳では無いとは言えIT知識も必要になります
基幹システムのデータをAPI化として公開する以上それなりのセキュリティ設定も必要になります

### 管理
API Managementのほうがよいです
資産としての管理はもちろん、APIの利用状況もモニター画面で確認できます

# OutSystemsのAPIとして登録
## GET METHODの追加
OutSystemsのServiceStudioの画面から
Logic＞Integration＞RESTと辿っていきSingleAPIを追加します

こんな感じでGET METHODを追加

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3133373938372f61653636616563362d303538342d663132312d663264652d3139323835356338626461652e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/3eef0943-9fa2-a3c2-78a0-1913888a2652.png)


## On Response処理の追加

On ResponseからAPIが実行後に動く処理を実装

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/f708347d-2a7a-3e87-3803-54e105805029.png)

自動でResponseの当てはめ処理が実装されますが、今回はこれだけでOK
更新処理でGETでResponse Headerで返ってくるSet-Cookieが明示的にこの処理をいれないと出てこない場合があるための対応です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/3085dca7-1da9-d1aa-b1c7-b4107244c8b0.png)

# POST METHODの追加

POST処理はこんな項目をRequest Headerに設定
if-matchはODataの種別的に要らなければ不要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/65e8b0f6-36df-9d9f-b229-c867e85b04d3.png)





# 更新処理の実装

更新処理はこんな感じでPOSTの前のGET処理を実行する
GET処理は特に特別なことはなく認証情報など必要に応じて処理を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/dddbb8ad-2066-e2fa-5722-ea281d93335d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/e6a2b2ce-740d-b2ef-032d-1e954372dfd9.png)

## x-csrf-tokenとCookie
前のGET処理でResponseHeaderで帰ってきた値を設定
この２つはS/4HANAのセキュリティの問題で必要な設定です
S/4HANAの設定を変更することでなしにすることも可能ですがセキュリティの問題が発生するため非推奨です
## If-match
こちらのブログを参考に設定
PoCなどであれば画像みたいに*でも可

https://blogs.sap.com/2020/12/17/etag-in-odata/


# 参考
## API Managementで更新処理を実装する場合
以下のブログを参考にAPI Managementを設定することでOutsystemsで実装したx-csrf-tokenとCookieの部分を解除することができます
しかし認証機能そのものが無くなってしまうため別途OAuth2.0認証などを追加してそれをOutsystems側で解除するなどセキュリティを担保することが必要です

https://blogs.sap.com/2021/09/18/csrf-token-handling-in-sap-api-management/

## HANA Cloud DBをOData化してAPI Managementに登録する
過去の類似記事

https://qiita.com/nanaki11/items/8211e77407329ecd3860
2022年度PAGS・DDBJ合同 中級者情報解析講習会の感想

# はじめに
今年度の本講習を受けた感想とこれから何が必要か振り返る自己満足記事となってます．

# 講習内容
全てjupyter notebookで学びます
1日目
- 文字列処理・ファイル読み書き
- Biopython
- Numpy
- Pandas
２日目
- matplotlib, seeqborn
- 統計的仮説検定
- 多変量解析
- シングルセルRNA-seq解析

# 個人的に良かった点
#### バイオインフォマティクス基本的操作を学べた
自分は微生物系研究室の院生なのですが，バイオインフォマティクスを教えてくれる先輩がラボにはいないです．そのため，基礎固めに苦難していました．今回の講習を受けたことで，Biopythonなどの操作を辞書的に学ぶことができました．用いたコードが今後の参考書になると思います．

#### 先生方のコードをタダでもらえた
遺伝研の先生など，バイオインフォマティクスの最先端を行っている方々のコードを頂けたことが良かったです．

# 個人的に難しかったこと
#### そもそも機械学習についてよくわかっていない
機械学習とpythonコードの結びつきが，自分の中でよくわかっていないようです．おそらく，そもそも機械学習のプロセスを理解していないからだと思います．一度調べてみて，再度今回のコードを実行したいと思います．

#### RNA-seq
RNA-seqで**正規化**や**TPM**といった単語が出てきました．RNA-seqしたことある人は当たり前の単語だと思いますが，自分はやったことなかったので，調べながら講習を聞いてました．

# 自分の課題
- 機会学習勉強しよう
- RNA-seq解析のコード練習しよう

以上です．
Amazon SageMaker Studio LabでNimをGoogle Colaboratory風に使う

# はじめに

最近気になっている言語Nim。この言語は書きやすさと読みやすさ、実行速度の速さに魅力がある(参考：[Nimを知ってほしい2022](https://zenn.dev/dumblepy/articles/b475b3b4f7d0da))。記事で比較対象に挙がっていたPythonにはGoogle Colaboratoryというオンラインサービスが存在しており、自分のパソコン上で環境構築しなくてもプログラミングできるというメリットがある。今回はNimでもGoogle Colaboratoryのように気軽にプログラミングができるオンライン環境を作ってみる。別記事でArraymancer(Nim版のnumpy+α)とNimData(pandas風)等をそれぞれ比較する記事を作成予定。

# 使用ツール

今回は**Amazon SageMaker Studio Lab**というサービスを使用した。簡単に言うとアカウントを作成しただけで無料で利用できるJupyterLab環境である。アカウントの取得方法は容易なため解説しないが、[【Amazon SageMaker Studio Lab】オンラインでPython/機械学習しよう(無料)](https://qiita.com/ku_a_i/items/088b7383f2d96f5bc739)などを参考にしてみるといい。
また、NimをAmazon SageMaker Studio Labに対応させるためのツールとして[Jupyter Nim](https://github.com/stisa/jupyternim)を使用した。

# 設定方法

この設定を行うにあたって[無料でRustのJupyterLab機械学習環境を作る in AWS](https://zenn.dev/hinastory/articles/475095df067f1f)が非常に参考になった。

まずランチャーからTerminalを立ち上げ、Nimをインストールする。condaが使えるので、
```shell
conda install nim
```
でインストールするのが楽。次にJupyterNimをインストールする。動かすためには更にZeroMQが必要なようなので、
```shell
conda install zeromq
nimble install jupyternim -y
```
を行う。
参考記事の通り、このままではNimカーネルは認識されていない。`jupyter kernelspec list`で表示してみると、
```shell
(studiolab) studio-lab-user@default:~$ jupyter kernelspec list
[ListKernelSpecs] WARNING | Config option `kernel_spec_manager_class` not recognized by `ListKernelSpecs`.
Available kernels:
  python3           /home/studio-lab-user/.conda/envs/studiolab/share/jupyter/kernels/python3
  jupyternimspec    /home/studio-lab-user/.local/share/jupyter/kernels/jupyternimspec
(studiolab) studio-lab-user@default:~$ 
```
となっていた。[参考記事](https://zenn.dev/hinastory/articles/475095df067f1f#%E6%9C%80%E7%B5%82%E7%9A%84%E3%81%AB%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%A3%E3%81%9F%E6%96%B9%E6%B3%95)の通りに以下のコマンドを用いて対応する。
```shell
conda create -n <my-lab-env>
mkdir -p ~/.conda/envs/<my-lab-env>/share/jupyter/kernels
cp -rf ~/.local/share/jupyter/kernels/jupyternimspec  ~/.conda/envs/<my-lab-env>/share/jupyter/kernels
ln -s ~/.conda/envs/studiolab/nim/bin/nim ~/.conda/envs/<my-lab-env>/bin
```
この作業によってランチャーを開くとNimの環境が追加されるようになる（図は参考記事によりRustも追加されているが、上記のコマンドだけ実行するとNimのみが追加される）。
![Launcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1120826/bf0ad361-ebb8-1b22-9d08-88da5d32f73d.png)

## 問題点: 実行に時間が掛かる

Nimのプログラムはコンパイルする必要があるため、コンパイル時間まで含めるとセルの実行には多少時間が掛かってしまう。しかし、普通にファイル作成する形式と比べ、markdown形式によるメモなどが同じファイル上で行えるという良さがあり、需要も多少はあると思う。
NginxリバースプロキシでALBやS3などへのルーティング設定をした際に499エラーが発生した件について

# はじめに

みなさん、こんにちは。Nginxでリバースプロキシを立ててパスベースルーティングなどでALBやS3などのURLへ振り分け設定をしていたところ、Nginxが499を返してくるという事象が発生したので、今回はこちらの事象の原因と解決方法について紹介していきたいと思います。

# 499が発生した原因

事象発生時のリバースプロキシ設定は次のような定義となっていたのですが、この定義だとNginxのproxy_passに指定しているURLの名前解決はNginx起動時のみに行われ、それ以降はそのIPアドレスを使い続けるという挙動となってしまうことがわかりました。

```txt:499を発生させてしまう/etc/nginx/conf.d/*.confの例
server {
    :
  (省略)
    :

  location /api/ {
    proxy_pass http://XXXXXXXX.ap-northeast-1.elb.amazonaws.com/;
  }
}
```

そのため、何らかの要因でALBやS3などのIPアドレスに変更が生じたものの、それにNginxが追従できずに古いIPアドレスへの転送を続けてしまったため499を返してくるという事象へと至っておりました。

# 解決方法

名前解決をNginx起動時のみにしていることが原因だったため、次の例のように`resolver`ディレクティブを定義し、`valid`オプションを使って適宜キャッシュの時間を調整することによって解決することができました。めでたしめでたし。

```txt:IPアドレス変更に追従できる/etc/nginx/conf.d/*.confの例
server {
    :
  (省略)
    :

  location ~ /api/(.*) {
    resolver    ${NAMESERVER} valid=30s;
    set         $endpoint_url http://XXXXXXXX.ap-northeast-1.elb.amazonaws.com/;
    proxy_pass  $endpoint_url$1$is_args$args;
  }
}
```

:::note info
setで変数化している理由ですが、proxy_passへは変数で指定しないと名前解決をしに行かない、といった事例があったためsetにて変数化を行っています。
:::

:::note info
locationおよびproxy_passの指定値が変わった理由ですが、setで変数化したことによって/api/以降の文字列がすべてなかったことにされてしまう挙動となったため、それを解決するためにlocationおよびproxy_passの指定値を変更しています。
:::

# 終わりに

Nginxでリバースプロキシを立てていて原因不明の499エラーがでて困ってます、といった方はぜひ参考にしてみてはいかがでしょうか。以上、NginxリバースプロキシでALBやS3などへのルーティング設定をしていたときに発生した499エラーの原因と解決方法のご紹介でした。

---

- AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
- NGINX は NGINX, Inc. の登録商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
Design Solution Forum 2022（DSF2022)でTatamiRacer（畳レーサー）を作ったよ

# TatamiRacerとは？
畳Racerは畳サイズのコースを自動運転するミニ四駆になります。
Githubで部品リストや3Dデータなどが公開されており、自分で作る事も可能です。

https://github.com/covao/TatamiRacer/blob/master/README_JP.md
# ミニ四駆とラズベリーパイ、OSSのDonkeyCarを使ったDIY自動運転

https://speakerdeck.com/covao/minisi-qu-torazuberipai-ossnodonkeycarwoshi-tutadiyzi-dong-yun-zhuan

今回、__Design Solution Forum 2022（DSF)__ の特別企画「AIカー製作体験」を受講しました。
# 講師紹介
今回の協賛である京都マイクロコンピューターの辻さんと製作者の小林弘一さん
![IMG_20221125_132426.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/704742bb-f16b-ed50-aace-dbe2e12391d2.jpeg)
# 部品
![IMG_20221125_131443.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7a731935-f5d1-ed64-bc8a-36e9b73231df.jpeg)
シャーシはもちろんミニ四駆です。
![IMG_20221125_132715.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ff236b25-026a-bd01-329d-96a84c9a154b.jpeg)
３Dプリンタの部品はDMMに製作依頼したそうです。
![IMG_20221125_132735.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/989a99f1-440f-c118-90ec-7af52fc286d3.jpeg)
## 組み立て中の様子
![IMG_20221125_140859.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7f158391-3faa-a6d1-7e71-18d5efa1574d.jpeg)
## TatamiRacerのコース
今回の為に製作したTatamiRacerのコースになります。
TatamiRacerのコースはもちろん畳サイズです。
![IMG_20221125_172740.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/17675c4f-ebe1-39b2-75fd-10b781956079.jpeg)
## TatamiRacerのコントロール画面
![Screenshot_2022-11-25-17-28-01-315_com.android.chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/9a04ce73-9418-49b7-a39d-8cf97206d45e.jpeg)
## Design Solution Forum 2022 優秀講演賞
今回のTatamiRacerはDesign Solution Forum 2022 優秀講演賞に選ばれました。
![IMG_4472.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f14999f0-f625-a346-09d4-d960dedc315b.jpeg)
仮想マシンの復元とファイルの回復

●仮想マシンの復元とファイルの回復
■仮想マシンの復元オプション
・新しい仮想マシンを作成する
新しい仮想マシンを作成して、そこに復元ポイントの内容を反映する方法。すでにバックアップ元の仮想マシンが削除されている場合や、バックアップ元の仮想マシンに影響を与えずに復元結果を確認したい場合に適している。

・ディスクを復元する
ディスク単位で復元する方法。復元したディスクは既存の仮想マシンまたは別途作成する新しい仮想マシンに接続可能。「新しい仮想マシンを作成する」オプションでは基本的な構成しかできないため、それ以外のカスタム構成が必要な仮想マシンを作成する場合に適している。

・既存の仮想マシンのディスクを置換する
ディスクを復元し、バックアップ元の仮想マシンのディスクを置き換える方式。バックアップ元の仮想マシンが存在する必要があり、すでに削除されている場合には使用不可。

※ファイルレベルの回復のために生成したスクリプトは、インターネットに接続され、なおかつバックアップ元の仮想マシンと同じOSまたは互換性のあるOSが動作するコンピューターで実行する。
log_success_msg: command not found

# `/opt/lampp/bin/mysql.server: line 262: log_success_msg: command not found`

```bash
/opt/lampp/bin/mysql.server: line 262: log_success_msg: command not found
```

XAMPPを起動するとなんか出る`/opt/lampp/lampp start`

`/opt/lampp/bin/mysql.server`を確認すると、**log_success_msg関数**が実行されてないことが原因。

**log_success_msg関数**を実行させればおい

```bash:/opt/lampp/bin/mysql.server
     92 #
     93 # Use LSB init script functions for printing messages, if possible
     94 # Include non-LSB Red Hat init functions to make systemctl redirect work
     95 init_functions="/etc/init.d/functions"
     96 lsb_functions="/lib/lsb/init-functions"
     97 if test -f $lsb_functions; then
     98   . $lsb_functions
     99 fi
    100 
    101 if test -f $init_functions; then
    102   . $init_functions
    103 else
    104   log_success_msg()
    105   {
    106     echo " SUCCESS! $@"
    107   }
    108   log_failure_msg()
    109   {
    110     echo " ERROR! $@"
    111   }
    112 fi
```


変更後

```bash:/opt/lampp/bin/mysql.server
     92 #
     93 # Use LSB init script functions for printing messages, if possible
     94 # Include non-LSB Red Hat init functions to make systemctl redirect work
     95 init_functions="/etc/init.d/functions"
     96 lsb_functions="/lib/lsb/init-functions"
     97 if test -f $lsb_functions; then
     98   . $lsb_functions
     99 fi
    100 
    101 if test -f $init_functions; then
    102   . $init_functions
    103 else
    104   log_success_msg()
    105   {
    106     echo " SUCCESS! $@"
    107   }
    108   log_failure_msg()
    109   {
    110     echo " ERROR! $@"
    111   }
    112 fi
    113 
    114 log_success_msg()
    115 {
    116   echo " SUCCESS! $@"
    117 }
    118 log_failure_msg()
    119 {
    120   echo " ERROR! $@"
    121 }
```
Google Cloudのサブネットには有効なIPアドレス範囲に制限があるのでご注意を

# はじめに

みなさん、こんにちは。Google Cloudのサブネットにはソフトウェア的に割り当てを制限されてはいないものの、実際に割り当ててしまうと通信障害などを起こしてしまう割り当てはいけないIPv4アドレス範囲があるのをご存じでしょうか。

今回は意外と見落としがちなGoogle Cloudのサブネットで有効なIPv4アドレス範囲、および範囲外のアドレスを割り当ててしまった際にはこんな事象が起きましたよ、という実体験について紹介していきたいと思います。

# 有効なIPv4アドレス範囲とは

それでは早速ですが、次の一覧（[公式ドキュメント]より抜粋）が有効なIPv4アドレス範囲の答えとなっています。なお、特段の要件がない限りは、基本的に★マークをつけた「[RFC1918]」に準拠する形でサブネットの設計をしていただくのが無難かと思います。

[公式ドキュメント]: https://cloud.google.com/vpc/docs/subnets?hl=ja#valid-ranges

||有効なIPv4アドレス範囲|ソース|説明|
|:---:|:---|:---|:---|
|★|**10.0.0.0/8<br>172.16.0.0/12<br>192.168.0.0/16**|**[RFC1918]**|**プライベートIPアドレス**|
||100.64.0.0/10|[RFC6598]|共有アドレス空間|
||192.0.0.0/24|[RFC6890]|IETF プロトコルの割り当て|
||192.0.2.0/24 (TEST-NET-1)<br>198.51.100.0/24 (TEST-NET-2)<br>203.0.113.0/24 (TEST-NET-3)|[RFC5737]|ドキュメント|
||192.88.99.0/24|[RFC7526]|IPv6 から IPv4 へのリレー（サポート終了）|
||198.18.0.0/15	|[RFC2544]|ベンチマーク テスト|
||240.0.0.0/4	|[RFC5735]<br>/ [RFC1112]|将来の使用（クラス E）|

[RFC1918]: https://tools.ietf.org/html/rfc1918
[RFC6598]: https://tools.ietf.org/html/rfc6598
[RFC6890]: https://tools.ietf.org/html/rfc6890
[RFC5737]: https://tools.ietf.org/html/rfc5737
[RFC7526]: https://tools.ietf.org/html/rfc7526
[RFC2544]: https://tools.ietf.org/html/rfc2544
[RFC5735]: https://tools.ietf.org/html/rfc5735
[RFC1112]: https://tools.ietf.org/html/rfc1112

# 範囲外を設定してしまうと、、、

## 事象1. VPCピアリングによるVPC間通信ができないことがある

VPCピアリングを双方向で設定するとステータス上は「有効」と表示されるものの、内部で自動的に作成されるはずのルートリソースができておらず、通信が各々のVPCへルーティングできないといった事象が確認されています。

なお、本事象発生時にCloud Consoleから手動でルートの作成を試みたものの、自動作成されるルートと同じ内容のモノをあとからユーザが手動で作成する、というのは叶わずの状況でした。（ネクストホップとしてVPCピアリングリソースを指定することができなかったため）

そのため、この事象に対する有効な対処方法としては、結局のところ「有効なIPアドレス範囲に変更したサブネットへ作り直してください」となってしまうのかなと思います。

# 終わりに

普段から「(RFCは良く知らないけど)プライベートIPアドレスは "おまじない" の意味も込めて10.0.0/8、172.16.0.0/12、192.168.0.0/16の範囲から指定するようにしています」という慎重派の方には無縁の問題ではございますが、中には「プライベートネットワークなんだからIPアドレスは何を指定しても良いでしょ」という方もいるかと思います。

今回ご紹介したとおりGoogle Cloudでは、いくつかのRFCを元に有効なIPアドレス範囲が定義されており、それを逸脱すると諸問題が起きてしまう可能性がありますのでぜひご留意いただければと思います。

---

- Google Cloud は、Google LLC の商標または登録商標です。
- その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。
Azure Cloud ShellのBashモードやGoogle Cloud Shellにてlessコマンドからviエディタを起動する方法

# はじめに

みなさん、こんにちは。今回はCloud Shellに関連する小ネタのご紹介です。

Linux環境でちょっとしたファイル参照にlessコマンドを利用する方もいるかと思いますが、Azure Cloud ShellのBashモードやGoogle CloudのCloud Shellでは、lessコマンドでファイル参照中に内容を編集しようと `v` キーを押してエディタを起動するとemacsが立ち上がってきます。

もちろんemacsも良いエディタなのですが、Red Hat系のLinuxに慣れている方からすると「lessで `v` を押したらviが起動してきてほしい！というか、moreはviが起動するのになんでlessはviじゃないんだよ～！」と思う方もきっといるはずです。今回はそんなときの解決方法を紹介していきたいと思います。

# エディタを切り替える方法

それでは解決方法ですが、環境変数 `VISUAL` に起動したいコマンド(今回はvi)を指定してください。これでlessからviエディタを起動させることができるようになります。

**実行例）**

```bash
export VISUAL="vi"
```

# 起動時に自動で設定する方法

とはいえ、Cloud Shellを起動するたびに毎回環境変数の設定をするのは面倒です。そんなときは設定ファイル `~/.bashrc` の末尾に次の1行を追記しましょう。これでCloud Shellが起動した際に自動で適用されるようになります。めでたしめでたし。

**作成例）~/.bashrc**

```txt
export VISUAL="vi"
```

# 終わりに

いまさらの情報でしたがいかがだったでしょうか。lessがなんか使いにくいんだよなとお困りの方は参考にしていただければと思います。以上、Azure Cloud ShellのBashモードやGoogle Cloud Shellにてlessコマンドからviエディタを起動する方法でした。

---

- Microsoft Azure は，Microsoft Corporation の商標または登録商標です。
- Google Cloud は、Google LLC の商標または登録商標です。
- その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。
Ubuntu Linux で Illustrator  AI 形式ファイルを読む

# 環境

Ubuntu 22.04 LTS

# 方法

以下の2つの方法で読めました。

- GIMP
- XnViewMP

しかしながらAIファイルの保存方法によってはうまくいきませんでした。

# GIMP で読んでみる

とあるファイルを読もうとしたら、ダメでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d7c00b2d-7a9b-9c3e-8df5-c28303e872e4.png)

保存方法に依存するのかな?
消防庁にあったAIファイルを使って試してみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/15aaf16e-8fe5-5ea1-92be-75cf043bf00d.png)

解像度など指定して、ビットマップ化するようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/11642cb4-474e-9469-6e56-6b7411e14c79.png)

読めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5fd39268-77b0-d3f7-894c-54a0d151348a.png)


# XnView Mp で読んでみる

マルチプラットフォームの画像ビューワです。500種類のフォーマットに対応しているらしいです。
https://www.xnview.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c55b5df7-05b2-4765-3edb-c0205177bba1.png)


個人、教育用途には無償で利用できるらしいです。


XnViewMP-linux-x64.deb をダウンロードします。

インストールしようとすると・・・
```
$ sudo dpkg -i XnViewMP-linux-x64.deb 
.
.
.
dpkg: 依存関係の問題により xnview の設定ができません:
 xnview は以下に依存 (depends) します: libgdk-pixbuf2.0-0 (>= 2.22.0) ...しかし:
  パッケージ libgdk-pixbuf2.0-0 はまだインストールされていません。
.
.
.
```
libgdk-pixbuf2.0-0 をインストールしようとすると依存を解消する必要があります。
```
$ sudo apt install libgdk-pixbuf2.0-0
.
.
.
以下のパッケージには満たせない依存関係があります:
 libgdk-pixbuf2.0-0 : 依存: libgdk-pixbuf-xlib-2.0-0 (>= 2.40.2-2build4) しかし、インストールされようとしていません
E: 未解決の依存関係です。'apt --fix-broken install' を実行してみてください (または解法を明示してください)。
```
fix-broken install を行ってみました。

```
$ sudo apt --fix-broken install
```
これで libgdk-pixbuf はインストールされたみたいです。
```
$ sudo apt install libgdk-pixbuf2.0-0
.
.
.
libgdk-pixbuf2.0-0 はすでに最新バージョン (2.40.2-2build4) です。
.
.
.
```
改めて deb ファイルをインストールします。

```
$ sudo dpkg -i XnViewMP-linux-x64.deb 
```

実行します。

```
$ xnview 
```

初期設定画面をOKします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/218b8842-3526-338d-14e9-26ff55f732c6.png)
GIMPでダメだったファイルはこちらも同様にダメでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ec302d1e-1106-4081-066b-18b2b331c83f.png)

消防庁のAIファイルはこちらでも無事読めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b4240948-18ce-a5ce-9013-7111e3f054fd.png)

こちらは残念ながら解像度指定などはできないようです。
980円/月でパワ美ちゃんと仲良くなる方法

# パワ美ちゃんと仲良くなりたい……！
ここでいう「パワ美」ちゃんとは何か？
そう、「Power Automate」のことです。

なぜ擬人化めいた名称で呼んでいるかって？
それは「**仲良くなりたい**」から！

何を言っているのか分からない方もいらっしゃるかもしれませんが、少々お付き合いいただければと思います！
（そのうち、このノリにも慣れてくると思います😁）
# 仲良くなるための手段
「仲良くなる」ためには、相手のことを「よく知る」のが一番です。
どうやって相手を知ればいいのか……パワ美ちゃんと仲のいい人々は往々にして囁いてくるのです。

「 [**Microsoft Learn**](https://learn.microsoft.com/ja-jp/ "Microsoft Learn") はいいぞ……」

https://learn.microsoft.com/ja-jp/power-automate/

よし、物は試しだとページを開くと、ほぼ文章で構成されたドキュメントが！😱
……私はおもむろに、そっとページを閉じてしまいましたね。
体系的にまとめられていて情報が豊富なのは最高なのですが、それらに目を通す気力がないのでございます💦

かといって、好き嫌いしていても一向にパワ美ちゃんと仲良くなれるはずもなく。

次に勉強会に参加しまくるという手段に出ました。
特にPower Automate愛の強いこちらの勉強会はおススメ！

https://kimamani.connpass.com/

各メンバーの個性も強く、こんなことが出来るのか～！と感心しきりですごく楽しく勉強は出来るのですが……。
みんなPower Automateガチ勢だし知識スゴすぎて、なんだか気後れしちゃう～💦
何とか食らいつきながらも、なんとなくパワ実ちゃんとは仲良くなりきれていないと感じる自分がいたのでした。

そしてつい最近、こんなツイートを見つけたのです！

https://twitter.com/R_t_A_n_M/status/1603338947899187201?s=20&t=HWbBJSvGPn1shJ3Sk4HunA
# よく知っている人に紹介してもらえば、すぐに仲良し！
せや！Microsoft MVPの [**りなたむさん**](https://twitter.com/R_t_A_n_M) に教えてもらえばええんや！
と何も考えず、とりあえず受講してみることにしてみました😁

ちなみに2022年12月現在、**年末限定クーポン** なるものがあって、12/31までに申し込んだら初月分無料というキャンペーン中。（通常プレミアムプランは **980円/月** かかります。）

https://schoo.jp/news/2022/2022-12-01-17-00-00

これは試してみるしかあるまい！ということで早速プレミアム会員に登録🎶
からの～、りなたむ先生の受講をポチーしてみた次第でございます。

https://schoo.jp/course/7381

実際に拝見したところ……何とかついていけそう？！
概要説明も分かりやすかったし、ハンズオンのパートも、画面も大きく表示されているので細かい操作内容も分かりやすい😊
まだアウトプットは出来ていませんが、授業内容はよく理解できたし受講してよかったと思える内容でした✨
（アウトプットしたら続きを書きますね💦）

ちなみに清水優吾先生のPower BIの授業もあるので、これを機にBI氏とも仲良くなろうと思います😁

https://schoo.jp/course/7134

# 最後に
仲良くなる方法はまだまだある！
ということで、つい最近解禁された情報などもお知らせしてみるなど。

どちらも気になります！
さらにパワ美ちゃんと仲良くなりたい方は要チェックですね👍

https://twitter.com/sennosukerpa/status/1603660566689562629?s=20&t=HWbBJSvGPn1shJ3Sk4HunA

https://twitter.com/aachan5550/status/1603593590185218048?s=20&t=HWbBJSvGPn1shJ3Sk4HunA

以上、パワ実ちゃんと仲良くなる方法でした♪
Unityにおけるnullチェック(3) - A is nullとA == null

以下の続きの記事になります。

https://qiita.com/tanikura/items/b57f6b92371026307c0b

https://qiita.com/tanikura/items/69a5ac3b1491723e756b

簡単におさらいするのでこの記事だけ読んでも問題ないとは思いますが、お時間があれば是非(1)、(2)の記事もお読み下さい。

# 検証内容のおさらい

* `UnityEngine.Object`では等値演算子`==`(及び非等値演算子`!=`)がオーバーロードされている
* オーバーロードされた等値演算子では`Object.CompareBaseObjects`メソッドに判定処理を委譲している

```CS
public static bool operator ==(Object x, Object y) => Object.CompareBaseObjects(x, y);

public static bool operator !=(Object x, Object y) => !Object.CompareBaseObjects(x, y);
```

* `Object.CompareBaseObjects`メソッド内では純粋な`null`チェックや`InstanceID`の等値判定に加えて、渡されたオブジェクトが「破棄」されていないか(Unityフレームワーク上で生存しているか)をチェックする`Object.IsNativeObjectAlive`メソッドが実行されている

* Destroy実行前後で、検証対象メソッドの戻り値は以下のように変化した(`UnityEngine.Object`に生えている静的な非公開メソッド)

|  | IsNativeObjectAlive | DoesObjectWithInstanceIDExist | GetCachedPtr |
| :-: | :-: | :-: | :-: |
| 破棄前 | true | true | インスタンス固有の値 |
| 破棄後 | false | false | 0 |

# nullチェックの記法
インスタンスがnullでないことを確認する書き方はいくつかあります。

```CS
// 1. 標準的なnullチェックの書き方
if (sampleMonoBehaviour != null)
{
}

// 2. UnityEngine.Object→boolへの暗黙的な型変換が定義されているため、こう書いても1と同じ意味
if (sampleMonoBehaviour)
{
}

// 3. C# 7.0で導入された「is」と、C# 9.0で導入された「not」を使ったnullチェック
// これは1と2とは挙動が異なる
if (sampleMonoBehaviour is not null)
{
}
```

1番目の書き方は最も一般的なnullチェックの書き方だと思います。
これがどのような挙動を示すかは、記事(1)と(2)で検証し、[この記事のおさらい](#検証内容のおさらい)にも書きました。
2番目は[記事(1)の余談](https://qiita.com/tanikura/items/b57f6b92371026307c0b#%E4%BD%99%E8%AB%87-if-hogecomponent-%E3%81%A8%E3%81%84%E3%81%86%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)でも触れましたが、暗黙的な型変換演算子がオーバーロードされているために許容される記述です。

問題は3番目の書き方です。
これは、C# 7.0で導入されたパターンマッチングという文法で`is`演算子の拡張(元々`is`は型の一致判定を行う用途などに使われていた)が行われたことによって実現できるようになった記述です。
この場合`null`「でない」ことをチェックしているため、`is not`のように書いていますが、`not`がこの形で使えるようになったのはC# 9.0以降でそれ以前は`!(A is null)`のように記述していました。
直感的には1番と3番は同じ意味に見えますが、`is`演算子は等値演算子`==`と異なり**ユーザがオーバーロードした演算子を考慮しません**。
つまり、`is`は「**その変数に本当にnullが代入されているか**」を確認します。
この挙動は使用している多くの型が等値演算子をオーバーロードする`UnityEngine.Object`を継承しているUnityの場合だと大きく問題になります。
以下のようなテストコードを書いて見ます。

```CS:SampleTest.cs
using System.Collections;
using UnityEngine;

public class SampleTest : MonoBehaviour
{
    private IEnumerator Start()
    {
        SampleMonoBehaviour sampleMonoBehaviour = gameObject.AddComponent<SampleMonoBehaviour>();

        Debug.Log("Destroy前");
        Debug.Log($"{nameof(sampleMonoBehaviour)} == null: {sampleMonoBehaviour == null}");
        Debug.Log($"{nameof(sampleMonoBehaviour)} is null: {sampleMonoBehaviour is null}");

        Destroy(sampleMonoBehaviour);
        // 1フレーム待つ
        yield return null;

        Debug.Log("Destroy後");
        Debug.Log($"{nameof(sampleMonoBehaviour)} == null: {sampleMonoBehaviour == null}");
        Debug.Log($"{nameof(sampleMonoBehaviour)} is null: {sampleMonoBehaviour is null}");
    }
}
```

実行結果は以下のようになります。
![スクリーンショット 2022-12-16 235315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987563/b10205b9-1e19-0cf3-fdfd-4b75ede64f56.png)

このように、「破棄」されているかの判定を実装している`==`を無視することで、破棄後も`破棄されたインスタンス is null`が`false`を返してしまうことが確認できました。
このため、`UnityEngine.Object`に対する`null`チェック(および破棄判定)は`is`は用いないほうが良さそうです。
[ゲノム解析] ゲノムファイルからリバースコンプリメント（逆相補的配列）を取得しよう

# リバースコンプリメントを取得したい！
マルチプルアライメントを行う際、個体によってリバースコンプリメントを用意する必要がありますよね。

相補配列をマニュアルで確認して・・・それを逆に書いて・・・
そんなのやってられるか！！！

さて、今回はFASTA形式からリバースコンプリメントをワンラインで取得する方法を紹介します。

# `seqkit`で解決！
ここでも出ました。`seqkit`です。
以下コマンドで完了です。
```
seqkit seq -pr input.fasta > output.fasta
```
`-p`：相補配列を表示
`-r`：配列を逆転

# どういう場合にリバースコンプリメントを用意するの？
以下の説明は自身の備忘録も兼ねてます。
知っている人は飛ばしてください。

### そもそも2本鎖DNAのFASTAは一方のDNA鎖の配列が記載されている。
当たり前の話ですよね．ですが諸学者の落とし穴でもあります．
例えば、遺伝子gene1というものがあったとします。
2本鎖DNAの場合、α鎖かβ鎖のどちらが読まれるかわかりません。
シーケンサーによって、gene1は以下の4パターンで解読されます。
```
>gene1_α #一方の
aaaggtgcctgacg
>gene1_α_reverce
gcagtccgtggaaa
>gene1_β
tttccacggactgc
>gene1_β_reverce
cgtcaggcaccttt
```
無茶苦茶ですよね．
アライメントする時に，　自分の比較したい遺伝子配列が，正の向きにあるのか確認しておく必要があります．
マッピングなどでも同様です．適宜リバースコンプリメントの取得が必要となるでしょう．

#　終わりに
リバースコンプリメントの概念を理解することは，ゲノム解析における成長段階の一つだと思う．