OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Cloudwatchの用語要点まとめ（自分用メモ

Amazon CloudWatch
サービスを継続して運用するために、管理者は例えばストレージがすべて使い切られる前に余剰を確保しておいたり、負荷が高くなり機能不全に陥る前に追加のリソースを用意したりと、状況に応じた適切な処置を行う必要があります。
Amazon CloudWatchは、AWSサービスやオンプレミス（自社運用）のシステムを監視し、しきい値（境界値）を超える・下回るなどした場合に管理者に通報するなど、サービスのリソース（CPU使用率やストレージの使用状況など）の状態に応じたアクションを取らせることができます。管理者はCloudWatchを利用することにより、サービスの安定した運用やパフォーマンスの向上、サービスの改善に役立てることができます。

CloudWatch3つの機能：

・CloudWatch
CloudWatchが監視する様々なリソースの情報は「メトリクス」と呼ばれます。インスタンスのCPU使用率やディスクの使用状況（読み取り・書き込みの量）など、予め定義されているメトリクスを標準メトリクスと呼びます。標準メトリクスはサービスごとに提供されており、CloudWatchのダッシュボードから確認することができます。

標準メトリクスとして監視可能な項目の例
EC2・・・CPU使用率、ディスクの読み取り・書き込み量
S3・・・バケットサイズ、オブジェクト数
ELB・・・リクエスト数、リクエスト応答時間
RDS・・・ストレージの空き容量、秒間の読み取り・書き込み操作の量

CloudWatchではこれらのメトリクスに対してアラームとアクションを設定できます。例えば「EC2インスタンスのCPU使用率が80%を超えたとき」というアラームに対して「管理者宛にメール通知」というアクションを設定すると、条件を満たしたときにアクションが実行されます。なお、メール通知はSNS（Simple Notification Service）というメッセージングサービスと連携して実現。
EC2インスタンスについては、メール通知だけではなく、インスタンスの再起動・停止・終了・復旧というアクションも用意されています。例えば、必要な処理が完了したらインスタンスを停止・終了することでコストを削減できます。また、復旧アクションを選択すると、ハードウェア異常が発生した際に自動的に新たなインスタンスで復旧します。
なお、これらの監視間隔はデフォルトで5分です（基本モニタリング）。1分間隔で監視を行いたい場合は「詳細モニタリング」を有効にします。基本モニタリングは無料ですが詳細モニタリングは有料です。

●カスタムメトリクス
標準メトリクスとして用意されていない項目を監視したい場合、管理者は「カスタムメトリクス」を定義します。
EC2インスタンスにおいて、CPU使用率やディスクの読み取り・書き込み量（bytes）などは標準メトリクスとして用意されていますが、メモリ使用量やディスクの空き容量（使用状況）に関する項目はありません。このような項目を監視したい場合、EC2インスタンスへ「CloudWatchエージェント」をインストールし、AWS CLIコマンドやAPIを用いて監視項目をCloudWatchへ送信します。
以下はEC2インスタンスの代表的な監視項目です。

標準メトリクス・・・ネットワーク使用量、ディスクI/O、CPU使用率
カスタムメトリクス・・・メモリ使用量、ディスク空容量、プロセス情報

・CloudWatch Logs
AWSサービスやEC2インスタンスのOSやアプリケーションのログを収集し、一元管理するサービス。収集したログは、メッセージの内容をフィルタリングして管理者に通知させることができます（。
なお、EC2インスタンス上のアプリケーションやOSのログを収集するには、対象のEC2インスタンスへ「CloudWatchエージェント」をインストールする必要があります。

更に、フィルタリングしたログをAmazon KinesisやAWS Lambdaなどの別のサービスへ転送し、ログをリアルタイムに解析したり、ログの内容に応じてプログラムを実行させる、といった連携も可能。

・CloudWatch Logs Insights
2018年に追加された機能で、収集したログのインタラクティブな検索や分析を行うことができます。CloudWatch Logsの管理コンソールでは単語検索によるフィルタリングを行えますが、CloudWatch Logs Insightsではクエリの実行にも対応しており、例えば「特定のアプリケーションが一定期間に出力した"Error"を含むメッセージをカウントする」など柔軟なログ解析が可能。


・CloudWatch Events（Amazon EventBridge）
CloudWatch Eventsは、AWS上のリソースの状態変化やスケジュールに応じてアクションを実行することができるサービス。CloudWatch Eventsを利用すると、管理者は以下のような運用ができます：
・EC2インスタンスが起動状態（running）から停止状態（stopped）になったとき、再起動する
・毎日決まった時刻にアプリケーションのログを収集・圧縮するLambda関数を呼び出す
これらのイベントルールを定義する際、トリガーとなるものを「イベントソース」と呼び、行う処理のことを「ターゲット」と呼びます。


ターゲット（アクション）としては、既に定義されているAPI（"EC2:RebootInstances"など）を呼び出したり、他サービスと連携したアクションをとることができます。特にLambda関数を使えばアクションを独自に定義することができますから、例えば毎日定時に決められたスクリプトを実行する、というルールを作成することも可能です。

また、CloudWatch Eventsは、AWS環境の脅威を検知するサービス「Amazon GuardDuty」と連携することもできます。脅威を検知した際に管理者宛にメール通報をさせたり、特定した脅威に対してアクションをとるLambda関数を定義して呼び出す、といった運用を行うことで、AWSサービスやAWSアカウントのセキュリティを高めることができます。

なお、CloudWatch Eventsは「Amazon EventBridge」というサービスになっています。EventBridgeはCloudWatch Eventsをベースに機能が追加されているため、CloudWatch EventsのAPIやルールなどは継続して利用できます。
【#19 エンジニア転職学習】Git/Github基礎　プルリクエスト

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

昨日は夜すぐに寝てしまいましたので、本日2回投稿します。
引き続きGit基礎に関して進めていきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
昨日はGitのプルリクエストに関する基礎を学習しました。

* **プルリクエスト　←Topics!!**
* リベース全体像

# プルリクエスト
チーム開発する際に他の人に**コードレビューしてもらい**→リリース用ブランチに取り込んでもらうための機能です。

ざっくり手順
1. 開発用ブランチ作成・編集
1. 変更を`commit`してGitHubに`push`
1. GitHub上のプロジェクト内「**Request**」タブで「**pull request**」を新規作成
1. 指定した相手から**OKがもらえたらbaseブランチにmerge**していく

使用している教材はこちら↓


https://www.udemy.com/course/unscared_git/


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
AWS ElastiCacheの要点まとめ（自分用メモ

Amazon ElastiCache
Amazon ElastiCacheは、AWSが提供するデータベースサービスの一つ

フルマネージド型のインメモリデータベースサービス。
インメモリデータベースとはデータストレージにメモリを使用するデータベースのことです。HDDのようなディスクストレージよりも高速・安定したアクセスが可能で、主にパフォーマンスを重視するアプリケーションに利用されています。RDSやRedshiftなど他のデータベースサービスと連携し、クエリの結果をElastiCacheにキャッシュさせることで全体的なパフォーマンスを向上させる、というような使い方ができます。
また、ElastiCacheはフルマネージド型のサービスですので、データベースの拡張や障害の検出・復旧、バックアップなどはAWSによって管理されています。

【ElastiCacheのデータベースエンジン】
ElastiCacheにはKVS（Key-Value Store:Key-Value型のデータストア）型のデータベースエンジンが2つ用意されており、データベースを構築する際に選択することができます。
※Key-Value型 ... 保存するデータ（Value）とそれを特定するためのキー（Key）がペアになった構成のデータセット

Memcachedにはデータの永続保持やバックアップ機能はありませんので、障害や再起動などが発生した場合はデータは残りません。保持しておかなければならないデータはストレージや他のデータベースサービスへ保存しておき、アプリケーションの高速化を目的としてキャッシュとして利用する、といったケースに向いています。

RedisはMemcachedよりも高機能なデータベースエンジンです。スナップショット機能によるバックアップ・リストアが可能で、データを永続的に保持しておくことができます。
また、耐障害性の機能として「自動フェイルオーバー」「マルチAZ」があります。
自動フェイルオーバー機能により、プライマリインスタンスに障害が発生した場合は自動的にレプリカインスタンスがプライマリインスタンスへ昇格します。またマルチAZではAZを跨いだレプリケーションが可能なため、プライマリインスタンスが存在するAZに障害が発生した場合でも、別のAZのレプリカインスタンスを昇格させることにより運用を継続することができます。

※ElastiCacheにおいて各ノードは「キャッシュノード」と呼ばれます。キャッシュノードのうち、プライマリノードは更新・参照などを行えるノード、レプリカノードは参照のみを行えるノード（リードレプリカ）です。

さらに、RedisにはMemcachedにはない機密性があります。保管しているデータの暗号化やSSL/TLSによる通信の暗号化、クライアントをパスワードで認証するRedis認証を行うことができます。これらを利用するには、ElastiCacheのデータベース作成時に「Redis」を選択し、暗号化を有効にする必要があります。

「送信中の暗号化」を有効にするとredis認証を有効にできる。
学び直しのJS ~ スプレッド構文・分割代入編 ~

学び直しシリーズ第三弾！
今回はスプレッド構文と分割代入編です！

## スプレッド構文
スプレッド構文は**配列**や**オブジェクト**の要素を分解してくれる構文です。
スプレッド構文を配列とオブジェクトに使って例を紹介します。

### 配列
```javascript
const array1 = ["cat", "dog"];

// array1のコピー(参照ではない)
const array2 = [...array1];

// 要素を追加して新しい配列を生成
const array3 = [...array1, "mouse"];

// 配列を結合して新しい配列を生成
const array4 = [...array1, ...array2];
```

### オブジェクト
```javascript
const user = {
  name: "Mike",
  age: 18
};

// userのコピー(参照ではない)
const copyUser = { ...user };

// プロパティを追加した新しいオブジェクトの生成
const newUser = { ...user, hobby: "soccer" };

// オブジェクトを結合して新しいオブジェクトを生成
const mergeUser = {...user, ...{hobby: "soccer", comment: "Hello World"}}
```

## 分割代入
配列やオブジェクトの中から一部だけ取り出して使いたい時に分割代入を使用します。

### 配列
```javascript
const array = ["cat", "dog", "mouse", "monkey"];

// aには"cat"、bには"dog"が代入されます
[a, b] = array;

// cには"cat"、dには"dog"、eには["mouse", "monkey"]が代入されます
[c, d, ...e] = array;
```

### オブジェクト
```javascript
const user = {
  name: "Mike",
  age: 18
};

// nameに"Mike"、ageに18が代入されます
const { name, age } = user;

// 分割代入する際、変数名とキー名にしたくない場合
// namaeに"Mike"、nennreiに18が代入されます
const { name: namae, age: nennrei } = user;
```
分割代入はパッケージからある機能だけ使いたい時によく用いられる構文なのでしっかり押さえておきましょう！
Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails

Herokuへデプロイ中にタイトル通りのエラーが発生しました。

# 原因
おそらく、テーブルのカラムを変更したことです。ローカル環境では、rails db:rollbackでしっかりとテーブルをダウンさせた上で、テーブルの設計を変更していましたが、heroku上でrollbackすることまで考えが及ばなかったです。

# 解決
①手っ取り早く、Heroku上でテーブルをリセットします。
```:ターミナル
heroku run rails db:reset
```
注意点：リセットすると、登録されていたデータが全て消えます。

②以下のエラーが発生します
```
rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1
```
内容は「本当にDBをリセットしていいんですか？いいなら、”variable:”以降ののコマンドをさっきのコードに付け加えてください」というものです。

③再度、コードを実行
```:ターミナル
heroku run rails db:reset DISABLE_DATABASE_ENVIRONMENT_CHECK=1
```
以上でHeroku上でのDBリセット完了です。
学び直しのJS ~ アロー関数編 ~

学び直しシリーズ第二弾！
今回はアロー関数です。

ES6をちゃんと勉強せずVueの勉強をはじめてしまったせいで、`import`や`() => {}`の意味がわからなくて挫折したことがあります。
VueやReactなどのモダンな技術に触れようとする心意気は非常に大事だと思うのですが、同じような経験をしてほしくないのでこの記事でざっくりとイメージを掴んでもらえたらなと思います！

## アロー関数
解説に入る前にまずは従来の方法と見比べてみます。

```javascript
// 従来の書き方
function square(x, y) {
  return x * y;
}

// アロー関数
const square = (x, y) => {
  return x * y;
};
```

### 特徴１
アロー関数は **無名関数(匿名関数)** と同じように、関数を定義した段階では関数名が定まっていません。

### 特徴2
アロー関数の処理が１行の場合は`{}`と`return`を省略することができます。
```javascript
// アロー関数
const square = (x, y) => x * y;
```

### 特徴3
アロー関数内で`this`を用いるとグローバルオブジェクトが参照される。
Web制作をしている方はここを理解しておかないとイベントの時の処理がうまくいかないことになります。


```html
<button id="btn">Click Me</button>
<script>
  const btn = document.getElementById("btn");

  btn.addEventListener("click", function () {
    console.log(this);
  });

  btn.addEventListener("click", () => {
    console.log(this);
  });
</script>
```

アロー関数ではない無名関数の方の`this`にはクリックしたbuttonのDOMを参照しています。
一方、アロー関数で書いた方の`this`はグローバルオブジェクト、つまり、<font color="red">Windowオブジェクトを参照する</font>ので注意が必要です。

まだJavaScriptにそんなに慣れていない方は特徴1と特徴2を理解できればOKです！
「ポストモーテム みずほ銀行システム障害 事後検証報告」をこのタイミングで読んでみた

[ポストモーテム みずほ銀行システム障害 事後検証報告 | 日経コンピュータ |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4296110918)

![](https://images-fe.ssl-images-amazon.com/images/I/51I35bz8K5L._SY291_BO1,204,203,200_QL40_ML2_.jpg)


## 感想

- [みずほ銀行システム統合、苦闘の19年史 史上最大のITプロジェクト「3度目の正直」 | 日経コンピュータ, 山端 宏実, 岡部 一詩, 中田 敦, 大和田 尚孝, 谷島 宣之 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4296105353/)
    - 前著、この本を出す中でコンポーネントのつながりを疎にしたことを説明した責務から、このポストモーテムを出版するとのまえがき...

> 根本的な問題は「分散トランザクションを採用した」＆「分散トランザクションのトランザクションログを(意図せず)インメモリ管理にしてしまった」

- 端的にはAmazon書評の↑のとおり。
- 事実の記載に関してはとても詳細。
- ひとまず結論が知りたいので結論から読んだ。
- 「みずほ銀行は～だった。しかも～だ。」という文が続くと胃が痛くなる。
- 一方「運用監視の環境があまりに貧弱だったためである」などという原因分析があるが、「あまりに貧弱」がどう貧弱だったのかまでは踏み込まれていない。他行のフローや環境に比べてなのだろうか、単なる指差し確認であるからなのか、等、ちょっともどかしい... 
- 全体として、ポストモーテムと言いつつ、責任の所在を探る論の匂いが見え隠れする部分で、感情移入すると冷静になれない本である...




## 要点
### 
- 第1章 前代未聞、12カ月で11回のシステム障害
    - 頭取はネットニュースでトラブルを知ったという。
    - KDDIは、すごいなと感じる。

https://twitter.com/voluntas/status/1543446997960728582?s=20&t=gCJ02Y9thXg01G_oCEQLug

- 第2章 行内で何が起きたのか、システム障害の真相
- 第3章 なぜ障害は拡大した、15個の疑問点
    - なぜデータベースは更新不能になったのか
    - なぜDBの更新不能がATMのカード取り込みにつながったのか
    - なぜ「二重エラー」が発生したのか
    - なぜ一度減ったATMのカード取り込みが急増したのか
    - なぜ警告やエラーは見逃されたのか
    - なぜ障害の規模や原因を見誤ったのか
    - なぜ頭取に情報が届かなかったのか
    - なぜ営業店での顧客対応が遅れたのか
    - なぜe-口座への一括切り替え処理を2~3月に実施したのか
    - なぜインデックスファイルをメモリーに置いたのか
    - なぜインデックスファイルのリスクを見逃したのか
    - なぜSOAなのに被害が拡大したのか
    - 2月28日はどの不手際が致命傷になったのか
    - 8月20日はなぜDBをすぐに復旧できなかったのか
    - なぜハードウエア障害が頻発したのか
- 第4章 金融庁が分析する「原因」「背景」「真因」
- 第5章 障害を繰り返す歴史
- 第6章 なぜ何度も障害が起きるのか
    - [なぜみずほ銀行でシステム障害が繰り返されるのか、その問いかけにある2つの側面 | 日経クロステック（xTECH）](https://xtech.nikkei.com/atcl/nxt/column/18/01972/030300001/)
    - [3大メガバンクの「みずほ」だけシステム障害が頻発する理由（2021年9月6日）｜BIGLOBEニュース](https://news.biglobe.ne.jp/economy/0906/jbp_210906_4844990912.html)
    - [【感想・ネタバレ】みずほ銀行システム統合、苦闘の19年史　史上最大のITプロジェクト「3度目の正直」のレビュー - 漫画・無料試し読みなら、電子書籍ストア ブックライブ](https://booklive.jp/review/list/title_id/715543/vol_no/001)

### まとめ
- [【読書感想文】『ポストモーテム　みずほ銀行システム障害　事後検証報告』｜猫のフレディ|日々の思考発信｜note](https://note.com/freddy_cat/n/n79cdc3a8bfec)
- [【感想・ネタバレ】ポストモーテム みずほ銀行システム障害 事後検証報告のレビュー](https://booklive.jp/review/list/title_id/1104781/vol_no/001)
- 再発防止策: https://www.mizuhobank.co.jp/release/pdf/2022_status.pdf
- [障害報告書を書こう！ - Qiita](https://qiita.com/Ping/items/7cc93bcae87583184121#%E5%AF%BE%E5%BF%9C%E5%86%8D%E7%99%BA%E9%98%B2%E6%AD%A2%E7%AD%96)
- [「Hey QA、なぜそのバグを見つけられなかった？」 - Qiita](https://qiita.com/e99h2121/items/c6293b65237b4c56baa4)
- [「次から気をつけます」に対抗する、反省文よりは効果が上がる再発防止、学びの機会 - Qiita](https://qiita.com/e99h2121/items/be9247563fb936b77511)
 
メモがてら以上です～。
2022/7/5主にITとかセキュリティの記事

KDDIの通信障害、約2日半ぶりにほぼ復旧
https://www.security-next.com/137839

5月はDDoS攻撃が微増、50Gbps超の攻撃も - IIJレポート
https://www.security-next.com/137732

フィッシングサイトの半数がクレカ事業者を偽装 - 銀行装うケース大きく縮小
https://www.security-next.com/137783

防災局メルアカ乗っ取り被害、スパムの踏み台に - 新潟県
https://www.security-next.com/137818

日経BP医療サイト、不正アクセスで一時停止(7/3)
https://www.nikkei.com/article/DGXZQOUE031YV0T00C22A7000000/

県と市町村共同運用のサービス　メールアドレス流出(7/2)
https://www.akita-abs.co.jp/nnn//news93rnobvuvy8xww2fvi.html

CT Analysis第32回レポート『Ethereum 2022年夏 次期アップグレード「The Merge」とその後のロードマップを理解する』を無料公開(7/1)
https://crypto-times.jp/ct-analysis-32/

【Eye Spy】政府関係者までハッキングに関与
スマホの情報を丸ごと搾取　イタリア製のスパイウェアが恐ろしく高性能だった(7/2)
https://courrier.jp/columns/293116/

知ってる？マイナンバーカードに施されているセキュリティー対策(7/3)
https://dime.jp/genre/1417512/

中国公安部、各地で警察と連携し通信ネットワーク悪用の詐欺グループ集中捜査(7/2)
https://news.nicovideo.jp/watch/nw11123347

Web3は日本の好機になり得る　巨大IT支配崩す可能性(7/3)
https://www.nikkei.com/article/DGXZQODK272AR0X20C22A6000000/

FIDO（Fast Identity Online）(7/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600009/062800118/

サイバー専門家ら集う　「白浜シンポ」現地報告(7/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600014/062800120/

「EDR」で被害の拡大を防ぐ(7/4)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/092100119/062000010/

尼崎市のUSB紛失事件を機に「ニセ名刺」問題を考えた、本当に悪い奴は誰だ(7/4)
https://xtech.nikkei.com/atcl/nxt/column/18/00148/062900233/

「貯蓄から投資へ」の加速なるか、みずほ信託銀行がデジタル証券に参入(7/4)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/06922/

次世代のインターネット環境を構築へ、「Web 3.0」とは(7/4)
https://xtech.nikkei.com/atcl/nxt/column/18/01679/052700062/

テレワーク実施率に地域差　都市と地方の経済格差が拡大へ(7/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/092400133/062800081/

「最も意識する経済圏」首位は楽天　依存度が高いのはNTTドコモ(7/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600010/062700117/
NTPの実装まとめ(ざっくり)

# ntpd

- NTP(Network Time Protocol)のバージョン4の実装
- ntpdは以下のような問題点を抱えている
    - ネットワーク等が不安定な環境下では時刻同期にかなりの時間を要したり、場合によっては時刻同期が行われなくなる
    - 常に動作させていなければならない等の理由から、CPUやメモリのリソースを多く消費する
    - Step方式で時刻同期をする際に、一度デーモンを停止させなければならない
    - ハードウェアクロックとの同期が不可

# chrony

- NTPのバージョン3の実装
    - ちなみにバージョン3とバージョン4は完全互換である
- 近年ではntpdの代わりに採用されることが多い
- ntpdに存在した数々の問題を改善している
    - ネットワーク等が不安定な環境でも効率よく、高速に時刻同期できるような仕組みを備えている
    - 動作時のみCPUを利用する等の理由から、CPUやメモリのリソースの消費が少ない
    - ハードウェアクロックとの同期が可能
    - 時刻同期の方式であるStep方式とSlew方式の切り替えや挙動を細かく設定できる
    - ポート番号の変更が可能(123番以外も可能)
- 公式サイト: https://chrony.tuxfamily.org/

# systemd-timesyncd

- SNTP(Simple Network Time Protocol)と呼ばれるNTPのクライアント機能のみを持ったプロトコルの実装
- 近年ではntpdの代わりに採用されることが多い
Bash / PowerShell / Pythonの変数の扱い・処理の違いを確認する

### 3つのスクリプト型言語の変数の違いを理解する

+ **Shell** **Script** : Linuxを運用する上では必須
+ **PowerShell** : 主にWindowsで利用。オープンソース化でLinuxやmacOSでも使える
+ **Python** : データ分析やAI/ML系で人気のスクリプト

環境に合わせて3つのスクリプト型言語を使っていると、色々混乱してくるので忘備録を兼ね、まとめてみた。

#### 変数の宣言・定義

``` ShellScript.sh
User:~$ name='Mash'
User:~$ echo $name
Mash

User:~$ name=Mash
User:~$ echo $name
Mash

User:~$ $name                
コマンド 'Mash' が見つかりません。
```
**Shell Script**
+ 変数名と値の間の "=" の両脇にスペースを入れてはダメ
+ 変数の値が文字の時でも、クォーテーションの有る無しに関わらず定義可能
+ 変数 **$name** を展開するためには**echo**が必要



```PowerShell.ps1
PS C:\Mash> $name = 'Mash'
PS C:\Mash> $name = Mash
Mash: The term 'Mash' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

PS C:\Mash> $name
Mash
PS C:\Mash> Write-Host $name
Mash

```
**PowerScript**
+ 変数の頭に$が必要
+ 値にはシングルクォーテーションもしくはダブルクォーテーションが必要
+ 変数 **$name** の展開は、変数をそのまま、もしくはWrite-Hostなどのコマンドで表示する両方のパターンに対応


``` Python.py
>>> name = 'Mash'
>>> name = Mash
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Mash' is not defined. Did you mean: 'hash'?

>>> name = 'Mash'
>>> name
'Mash'
>>> print(name)
Mash

```

**Python**
+ 変数をする際に$のような記号は不要
+ 変数に文字を指定するときは必ずクォーテーション もしくは ダブルクォーテーションが必要
+ 変数 $name の展開は、変数をそのまま、もしくは **print( )** などのコマンドで表示する両方のパターンに対応

#### 変数に入れた数値の計算

``` ShellScript.sh
User:~$ number1=4
User:~$ number2=2
User:~$ echo $((number1 + number2))
6
User:~$ echo $((number1 * number2))
8
User:~$ echo $((number1 / number2))
2
User:~$ echo $((number1 - number2))
2

User:~$ $number1 + $number2
1: コマンドが見つかりません

User:~$ echo ($number1 + $number2)
-bash: 予期しないトークン `$number1' 周辺に構文エラーがあります
```
+ 変数1 + 変数2 のような式では計算できない。

``` PowerShell.ps1
PS C:\Mash> $number1 = 1
PS C:\Mash> $number2 = 1
PS C:\Mash> $number1 + $number2
2
```
``` Python.py
>>> number1 = 1
>>> number2 = 1
>>> number1 + number2
2
```
#### 変数と変数、変数とテキストの結合

``` ShellScript.sh
User:~$ str1="Scripting"
User:~$ str2=" is intersting!" 
User:~$ str=$str1$str2
User:~$ echo $str
Scripting is intersting!

User:~$ str1="Scripting"
User:~$ str="${str1} is intersting!"
User:~$ echo $str
Scripting is intersting!

```
+ 変数とテキストを結合する際は、変数を{ }で囲んでテキストの中に入れる


``` PowerShell.ps1
PS C:\Mash> $str1 = "Scripting"
PS C:\Mash> $str2 = " is interesting"
PS C:\Mash> $str = $str1 + $str2
PS C:\Mash> $str
Scripting is interesting

PS C:\Mash> $str1 = "Scripting"
PS C:\Mash> $str = $str + " is interesting"
Scripting is interesting
```
+ 数字と同じように＋記号で結合できる
+ 前か後ろにスペースを入れておく必要あり。例では" is"のように後ろに入れている

``` Python.py
>>> str1 = 'Scripting'
>>> str2 = ' is interesting'
>>> str = str1 + str2
>>> str
'Scripting is interesting'
>>> str = str1,str2
>>> str
('Scripting', ' is interesting')

>>> str = str1 + ' is interesting'
>>> str
'Scripting is interesting'
```

#### 結論
+ **PowerShell** と **Python** は変数の定義方法、数値計算、文字列の結合についてほぼ同じように扱える
+ **Shell** **Script** は 異なっているので注意が必要
【MySQL】[ERROR] [MY-012585] [InnoDB] Linux Native AIO interface is not supported on this platform. Please check your OS documentation and install appropriate binary of InnoDB.解消法【Docker】

## 状況
M1Macを使用してDockerでMySQLのコンテナを起動した際に以下のようなエラーが発生しました。
```:ターミナル
[ERROR] [MY-012585] [InnoDB] Linux Native AIO interface is not supported on this platform.
 Please check your OS documentation and install appropriate binary of InnoDB.
```

エラーの内容は以下のとおりです。
```
Linux Native AIOインターフェースは、このプラットフォームではサポートされていません。
OS のドキュメントを確認し、適切な InnoDB のバイナリをインストールしてください。
```

## 解消法
Linux の非同期 I/O サブシステムを使用しないように設定することで解消できます。

具体的には`my.cnf`か`docker-compose.yml`に以下を追記します。

```my.cnf
innodb_use_native_aio=0
```

```docker-compose.yml
services:
  db:
    command: mysqld --innodb_use_native_aio=0
```

https://dev.mysql.com/doc/refman/8.0/ja/innodb-parameters.html#sysvar_innodb_use_native_aio


> ただし、OS の非同期 I/O サブシステムに問題があるために InnoDB を起動できない場合は、innodb_use_native_aio=0 を使用してサーバーを起動できます。
【SwiftUI】入力値チェック

# はじめに
入力フォームに値が入力された時にボタンをクリックできる実装について説明していきます。
それに加え、ボタンの色を変化させる方法について初めて知ったのでメモとして残しておきます！
テキストフォーム、ボタンの作成方法についてはここでは説明しませんので悪しからず。

# 環境
Xcode 13.4.1
Swift 5.6.1
MacOS 12.4

# 入力値チェック

## 書き方
``` swift:
.disabled(変数名.isEmpty) 
```
`.isEmpty`により文字列が空かどうかをbool値として扱う。
この値がtrueならばクリック不可となり、falseならばクリック可能となる。

## ボタンの色を変える

三項演算子を用いることでif文のように処理を分けることが可能である。
これによりViewの挙動を容易に変化できる。

`bool値 ? trueの場合 : falseの場合`


入力フィールドに文字列が書かれていない時、ボタンの背景色はグレーで文字の色は黒。文字が入力された時、背景色は青色で文字の色は白になるようにする。

```swift
.foregroundColor(name.isEmpty ? Color.black : Color.white)
.background(name.isEmpty ? Color.gray : Color.blue)
```
### 結果
テキストが入力される前
<img width="400" alt="Simulator Screen Shot - iPhone 13 - 2022-07-05 at 00.46.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708930/1f6a7e5f-7752-8d0c-9225-3f02feb428d6.png">
テキストが入力された後
<img width="400" alt="Simulator Screen Shot - iPhone 13 - 2022-07-05 at 00.54.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708930/75b9d668-40c7-45d7-66d1-056dc22764b1.png">



# 最後に
最後まで読んでいただきありがとうございました。
Qiitaの書き方などまだまだ未熟ですので、アドバイスいただけると幸いです。
SpringBootにおけるバッチ処理

https://qiita.com/kazuki43zoo/items/47ed3b15077773f02448
上記記事を参考にさせていただきました

SpringBootで何らかのバッチ処理を作る際に高機能でジョブを制御する仕組みがあるSpringBatchを使いたくないようなケースがあります（例えばジョブスケジューラーなどを利用していてジョブは実行するだけにしたい場合など）。その場合はJavaコマンド実行してリターンコードで結果を返すようなシンプルな構造にしたい。

## やりたいこと
・SpringBootでコマンド実行して指定した処理を動かす
・機能ごとにクラスを分けてどの機能を動かすか？は引数で指定する
・ジョブの成功／失敗はコマンド実行のリターンコードで判断する

### 構成

実行コマンドイメージ

```sh
java exec:<実行したいクラス名> -jar filename.jar
```


コマンド実行した際の最初にコールするクラス

```Java:Application.java
package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
  public static void main(String[] args) {
    System.exit(SpringApplication.exit(SpringApplication.run(SpringBootTestBatchApplication.class, args)));
  }
}
```

mainから呼び出すクラス

```Java:SpringBootTestBatchApplication.java
package com.example.springboot;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.boot.ExitCodeGenerator;

@Component
public class SpringBootTestBatchApplication implements ApplicationRunner, ExitCodeGenerator {
	private int exitCode = 0;
	@Override
	public void run(ApplicationArguments args) {
		String execFuncion = "";
		for(String value : args.getNonOptionArgs()) {
			if(value.startsWith("exec:")) execFuncion = value.substring(4);
		}
        // 実行するクラスの処理
		return;
	}
	@Override
	public int getExitCode() {
	  return exitCode;
	}
}
```

設定

```application.properties
spring.main.banner-mode=off
spring.main.web-application-type=none
```


引数を読み取り、その入力によって実行するクラスを決めます。実行結果を整数で受け取りリターンコードに入れ込みます。

### VScodeにおける引数の指定方法
以下のように「構成の追加」からlunch.jsonを編集可能です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/dc488e83-0f93-3d17-149d-92fa9538b7a5.png)

argsという項目に引数に指定したい文字列を設定すれば、以降VScode上で実行時に引数付きで実行できます

```json:lunch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Launch Application",
            "request": "launch",
            "mainClass": "com.example.springboot.Application",
            "projectName": "spring-boot-test",
            "args": "exec:Testfunc"
        }
    ]
}
```

上記のように指定した場合は以下のようなコマンド実行となります

```sh
java exec:Testfunc -jar SpringBoot.jar
```
管理者機能実装後におけるデプロイ時の注意点

こんばんは、プログラミング初学者"fujitacoma"です！

今回は、以前に投稿しました記事、
”管理者ユーザー機能の実装[Ruby, Rails]”の後日談のようなものを、
備忘録として書いていきたいと思います！

”管理者ユーザー機能の実装[Ruby, Rails]”はこちらからどうぞ↓
https://qiita.com/fujitacoma/items/974d18fbebf8c73c411c

# はじめに
使用クラウドサービスはHerokuです。

# 起こったこと

それは、管理者ユーザー機能を実装及びデプロイ完了後に、
嬉々として本番環境で確認をしようとした際に起こりました、、

管理者用のアドレスとパスワードでログインできない、、、！！
冷や汗。

# 原因調査
なぜ？意味なく開発環境のdbも確認する。
ちゃんと管理者用のアドレスとパスワードは保存されている。(当然)

db/seed.rbに管理者ユーザー情報が記述されているか確認する。

次はデプロイのログを隅々まで確認する。
ちゃんと、
```
git push heroku master
```
も
```
heroku run rails db:migrate
```
も実行してるよな、、
、、、、、、、、、、、、、、、ん？
db:~って、他でもなんかやったような気がする。
と記憶を辿ってみると、
```
#ターミナル
 rails db:seed
```
これでした。

# 解決
```
heroku run rails db:migrate
```
このコマンドではテーブル内の情報までは保存されないため、
ローカル環境での開発時同様、情報を追加してあげる必要があります。

それがこちらのコマンド。
```
heroku run rails db:seed
```
実行後、本番環境にて再度ログインを試したところ、、、
無事、管理者アカウントにログインができました！

# 振り返り

冷静に考えるとそうだよなと思いますが、
焦った時は冷静に自分が行った操作や記述した内容を振り返る。
それでも分からなければ検索するのが一番ですね。

# 最後に

ここまでお読み頂き、有難うございました！
初学者なりに調べつつ記載しておりますが、
ご指摘やアドバイスがあればコメント頂けますと幸いです！
ICML2022の枝刈り論文 (1)

# 概要

この記事では、[ICML2022](https://icml.cc/)の枝刈り論文を紹介します。[^1]

[^1]: 画像や数式は論文から引用しています。


# PAC-Net: A Model Pruning Approach to Inductive Transfer Learning

https://arxiv.org/abs/2206.05703

概要：PAC-Net. Inductive Transfer Learning (10~100など非常に少量データでの転移学習)の手法。
研究機関：Samsung
新規性：Inductive Transfer LearningでSOTA。
キモ：Pretrained modelを刈って空いた所に新しいタスクを学習させる。その際正則化項をつける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/87b106d3-5d48-d318-b28e-9681cc8f9f27.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/d22aa324-f93a-8451-027a-d2378aa6f923.png)
微分方程式でバネ・マス・ダンパ系を学習する例だと、基本的な運動をsourceで、ダンパの寄与をtargetで学習する。
評価：微分方程式や回帰問題で実験した。
firebaseでムームードメインで取得した独自ドメインを使えるようにしたい

絶対に未来の自分は忘れてしまうので
自分向けのメモです。
口調がライトですみません。

がんばれ自分！絶対できる！

〜以下、未来の自分向けメモ〜

# firebase consoleから、独自ドメインの追加操作を行う。
開発しているfirebaseのプロジェクトの「Hosting」画面から、追加したい独自ドメインの追加操作をする。
表示される「TXT」の値をコピーする。
※ https://console.firebase.google.com/project/（あなたのプロジェクト名）/hosting/sites?hl=ja から操作

# ムームードメインのコントロールパネルから、以下の操作を実行

１）「ドメイン操作 > ムームーDNS > hogehoge.com（対象のドメイン） > 変更」
２）「設定2」の「サブドメイン」の設定画面で、
　　　
２−１）ムームードメインの管理画面に
　　　　サブドメイン: 空　種別: `TXT` 内容: `google-site-verification=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
２−２）上記設定したら、firebase console 側で認証する。（少し時間がかかる）
２−３）認証が完了したら、firebase console 上に表示されるIPアドレスを
　　　　ムームードメインの
　　　　「設定2」の「サブドメイン」の設定画面に追加する。
　　　　サブドメイン: 空　種別: `A` 内容: `xxx.xx.xxx.xxx`
２−４）firebase側で「www」がつくドメインを転送する設定をした場合は
　　　　サブドメイン: `www`　種別: `A` 内容: `xxx.xx.xxx.xxx`　をムームードメインのコントロールパネルから追加登録する。

---

以上！


※ google auth を使っている場合は
独自ドメイン対応のための設定の追加・編集を忘れずに。

参考：firebaseで独自ドメインでもGoogle Authでログインできるようにする
https://qiita.com/AyakoKataoka/items/d79c9c8806e5f1b8cedf

追記：
結局、設定は無事にできたものの、メールアドレスの設定を追加する際に諸々面倒になって
ムームードメイン → Google Domains に移管しました。（firebaseと相性がよいだろうので…）
が、ムームードメインさん、解約時の体験がスムーズで素晴らしかったです。
1時間内に移管完了した気がします。
また条件が合う案件の際にはお世話になります。🙏ありがとうございました。
ICML2022の量子化論文 (1)

# 概要

この記事では、[ICML2022](https://icml.cc/)の量子化論文を紹介します。[^1]

[^1]: 画像や数式は論文から引用しています。


# Overcoming Oscillations in Quantization-Aware Training

https://arxiv.org/abs/2203.11086

概要：QAT時にグリッドの2点を振動する現象の分析とQATの改良
研究機関：Qualcomm
新規性：QAT時の振動現象を初めて詳しく調べ、精度劣化を防ぐ方法を提案した。
キモ：まず、Depthwise Convなどで値が量子化の協会に集まり振動していることを確認した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/894cb457-9c62-3093-dd0f-7b716a77d365.png)
これを改善する方法として、振動を弱めるロスを提案。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/523b0a75-319d-8ff5-c7c4-29f17cdb6ee3.png)
また、weight freezingを提案。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/315a724f-e307-4067-58c0-ee6c4ff54297.png)
評価：MobileNetやEfficientNetでLSQと組合せて実験した。


# SDQ: Stochastic Differentiable Quantization with Mixed Precision

https://arxiv.org/abs/2206.04459

概要：SDQ. 混合精度量子化で量子化精度改善
研究機関：Meta
新規性：強化学習やNASを使わずに混合精度のビット数を自動最適化する方法を提案した。
キモ：確率的量子化とし、Gumbel Softmaxで混合精度のビット数を選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/672cf667-64b6-b052-9072-3f3c0d2646f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/5378025e-c6e9-05cb-534d-547a10d22f5b.png)
ロスに量子化誤差を加えて最適化する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/8181d57c-420f-64a2-5192-fc65f9e6dbfb.png)
評価：ResNetやMobileNetV2で評価した。


# Optimal Clipping and Magnitude-aware Differentiation for Improved Quantization-aware Training

https://arxiv.org/abs/2206.06501

概要：OCTAV. QATの改良。
研究機関：NVIDIA
新規性：クリッピング量をMSEで最小化する。
キモ：MSE $J$ に対するニュートン法でクリッピング幅を最適化する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/50f89055-27d8-c4ec-3c7f-5166bfb2ee09.png)
評価：ResNetやMobileNetで評価した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/3a6d96bc-9e80-dc9f-944d-f6fa67276d21.png)
Quaternionの順序/Unity


Ｘ軸（赤）回転
```
    IEnumerator test3()
    {
        int i = 0;
        while (true)
        {
            var rot1 = Quaternion.AngleAxis(1, new Vector3(1, 0, 0));

            //元々の回転軸で回転させたい 場合、かけたい回転(rot1)をみぎ
            m_target.transform.localRotation = m_target.transform.localRotation *rot1; 

            // 固定の回転軸で回転させたい
            m_target2.transform.localRotation =rot1 *  m_target2.transform.localRotation ; 
            if (i >= 360) break;
            i += 1;
            yield return new WaitForSeconds(0.01f);
        }
    }
```

m_target2.transform.localRotation =rot1*m_target2.transform.localRotation ; の場合、UnityEditorでrot_xのみが変化する。
![0705_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/e0cc97b4-0b36-a68e-7fbd-cb72a22a012f.gif)


Y軸回転（緑）
UnityのHierarchyはAxisを選択している。ｘ、ｙ、ｚが変化している。
```
![0705_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/d68f208c-0a14-33f5-0d76-cc56e325fb00.gif)
   IEnumerator test4()
    {
        int i = 0;
        while (true)
        {
            //var rot1 = Quaternion.AngleAxis(1, new Vector3(1, 0, 0));
            var rot2 = Quaternion.AngleAxis(1, new Vector3(0, 1, 0));

            //元々の回転軸で回転させたい 場合、かけたい回転(rot1)をみぎ
            m_target.transform.localRotation = m_target.transform.localRotation * rot2;

            // 固定の回転軸で回転させたい
            m_target2.transform.localRotation = rot2 * m_target2.transform.localRotation;
            if (i >= 360*2) break;
            i += 1;
            yield return new WaitForSeconds(0.01f);
        }
    }
```



![0705_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/983b17b9-ca90-59a0-8dc1-ffb37ba31b27.gif)

参考）
https://virtualcast.jp/blog/2019/11/quaternion/
https://qiita.com/yaegaki/items/4d5a6af1d1738e102751

動画からアニメGIF
https://qiita.com/Bacillus/items/4c733c4c5f7b06dce462
Datadogに物理機器のMIBファイルを取り込んでSNMP監視する

# 前提

* Datadog経由で物理機器、例えばNW機器をSNMPを使ってメトリクス収集させたい
* datadog agentにはSNMP Intergrationがデフォで備わっているので簡単に実現可能
    * ref. https://docs.datadoghq.com/ja/integrations/snmp/
* しかし大体の機器は独自なOID実装をしていて、当然そういったメトリクスも取得したい
    * 各社が公式に提供しているMIBファイルを取り込んで、独自OIDを使ったSNMP GETを実現させたい！
* datadog agentはテキストなMIBファイルのインポートはサポートしておらずpythonで書かれたpysnmpの形式でないとインポートできない

# 注意

* datadog agentそのものインストールやセットアップについて言及しない
* 公式的なはっきりとした手順がないので、以下が唯一無二の方法！っていうわけではない。まぁやり方はいくつか考えられると思う。

# 手順

* 自分の端末でpysnmpをインストール

```bash
$ pip3 install pysnmp pysnmp-mibs
```

* MIBファイルをダウンロード
    * 今回は以下を対象にして成功

|対象|URL|
|-|-|
|YAMAHA|http://www.rtpro.yamaha.co.jp/RT/docs/mib/index.php|
|HPE iLO|https://support.hpe.com/connect/s/softwaredetails?language=ja&softwareId=MTX_49b4f94b79d64f259eaa527f18|
|NEX IXシリーズ|https://jpn.nec.com/univerge/ix/Manual/index.html?#crm|

* 展開してpysnmp形式に変換

```bash
$ unzip yamaha-private-mib.zip
$ mibdump.py ./*
```

* これで `~/.pysnmp`にpythonとして変換されたMIBファイルが生成される

* 変換したMIBファイルを各OSの所定パスに配置
    * Windows: `C:¥programdata¥datadog¥conf.d¥snmp.d¥mibs/`
    * Linux: `/etc/datadog-agent/conf.d/snmp.d/mibs/`
* 以下のようにコンフィグファイルを設定
  * `python形式であることを明示指定`
  * `配置したMIBを読み込むようにパスを明示指定`
  * instancesセクション配下で対象とする機器の接続先とコミュニティ名、必要に応じてMIB情報を指定する
    * この時バージョン問題かどうかわからないが、 `metrics`を指定した場合、標準MIBでサポートされる範囲のSNMP GETができないケースに見舞われた
    * あえて標準MIBだけでmetrics指定を持たない指定と、拡張MIBを前提としたmetrics指定のみの2つを書くことでどちらも取得できた
    * 環境起因かバージョンなのか、はっきりとしたことがわからないが、一応そういった事象が発生した旨とその対象について述べておく、誰かの役に立てば良いが。
  * ref.https://docs.datadoghq.com/ja/agent/guide/agent-configuration-files/?tabs=agentv6v7

```/etc/datadog-agent/conf.d/snmp.d/conf.yaml
init_config:
    loader: python
    mibs_folder: /etc/datadog-agent/conf.d/snmp.d/mibs

instances:
  - ip_address: 192.168.0.254
    community_string: private
  - ip_address: 192.168.0.254
    community_string: private
    metrics:
      - MIB: YAMAHA-SW-HARDWARE
        symbol: yshMemoryUtil
      - MIB: YAMAHA-SW-HARDWARE
        symbol: yshCpuUtil5min
      - MIB: YAMAHA-SW-HARDWARE
        symbol: yshInboxTemperature
```

* あとはDatadog側で確認すれば、これらの値が取得できていることが確認できるはず

# トラブル

mibdump.pyにはぶっちゃけ問題がある。
ref. https://github.com/etingof/pysmi/blob/master/scripts/mibdump.py

mibBorrowerというある種のキャッシュ機構のような機能があり、既に世に知れたMIBファイルであればわざわざ生成処理をしなくても対象MIBと同じものが既にアップストリームで保持されているならそれを信用して使う、というものっぽい。ちなみによく調べていないのでもしかしたら全然違うかもしれない。

この機能が悪さしている。
実装コードを見てもらえればわかるが、↑の処理では `http://mibs.snmplabs.com/pysnmp`にアクセスする。
このFQDNは既に使われていない。正確にはどこかに買われて、不適当な状態で残置されている。

そのせいか、mibBorrowerの処理の最中にわけわからんhtmlを変換後のMIBだと勘違いしてダウンロードしてくる。
当然、MIBなんかじゃない。見ればわかるが、クソみたいなhtmlだ。MIBとして読み込めない。

これを回避する方法はいくつか考えられるが、サクッとこの機能を無効化するのが良いと思う。
バージョンなどによって行位置は異なると思うので、皆さんそれぞれでよく確認して欲しいが、私のv0.3.4環境だとこんな感じ。

```/opt/homebrew/bin/mibdump.py
234    # borrowers = [PyFileBorrower(x[1], genTexts=mibBorrowers[x[0]][1])
235    #             for x in enumerate(getReadersFromUrls(*[m[0] for m in mibBorrowers], **dict(lowcaseMatching=False)))]
...
355    #    mibCompiler.addBorrowers(*borrowers)
```

ptyhonなのでコメントアウトして保存して再実行すればmibBorrowerの機能を使わず毎回生成して正しくpythonなMIBへと変換してくれるはず。
firebaseで独自ドメインでもGoogle Authでログインできるようにする

# firebaseを使った自作アプリで独自ドメインを使いたい

そんな私が「はじめての自作アプリデプロイ🥺」をしてみた結果、
独自ドメインでgoogle Authによるログインができなくて困ったので
絶対に忘れる未来の自分に向けてメモを残す。

がんばれ！絶対できる！

#### 〜以下、（絶対忘れる）未来の自分へ。〜

発生したおこられ：
```
エラー 400: redirect_uri_mismatch

このアプリは Google の OAuth 2.0 ポリシーを遵守していないため、ログインできません。

このアプリのデベロッパーの方は、Google Cloud Console でリダイレクト URI を登録してください。
```

## googleログイン認証が本番環境で出来なかった原因は：
deploy後、認証が失敗していたのは、「独自ドメイン」用の設定をしていなかったから。
（認証のソースコード自体には問題はなし。）

### 対策１）firebaseのコンソールから独自ドメインを「承認済みドメイン」に追加
https://console.firebase.google.com/project/（あなたのプロジェクト名）/authentication/providers
から、「承認済みドメイン」にも『hogehoge.com』（独自ドメイン）を追加した。

### 対策２）ソースコード内の`authDomain`を独自ドメインに変更
main.js 内の config 内の `authDomain` を変更。

例）
`authDomain: "hogehoge.firebaseapp.com",` を
`authDomain: "hogehoge.com",` （独自ドメイン）に変更

### 対策３）google cloud consoleから、リダイレクトURIに独自ドメインを追加
https://console.cloud.google.com/apis/credentials?project=（あなたのプロジェクト名）
から、「認証情報 > OAuth 2.0 クライアント ID」内で、
「Web client  (auto created by Google Service)」の
承認済みのリダイレクト URIに『https://hogehoge.com/__/auth/handler』を、追加した。
ついでに「承認済みの JavaScript 生成元」にも独自ドメインを追加した。
また、「0Auth 同意画面 > アプリ登録の編集」画面から、「承認済みドメイン」に独自ドメインを追加した。

---

以上！

参考：
https://firebase.google.com/docs/auth/web/google-signin
GithubにSSH接続できるのに、Git操作時にエラーが出る場合の確認ポイント

最近新しいMacにしました。
移行アシスタントで丸ごとコピーしたのですが、なぜかgit pullができず困っていました。
しかしやっと原因が分かったので、メモを残します。

移行後いつも通りgit操作を行うとするとエラーになる。

```bash
$ git pull origin develop 
Username for 'https://github.com': tar-xzvff
Password for 'https://tar-xzvff@github.com': 
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/****/****.git/'
```

でもSSH接続はできる。

```bash
$ ssh -T git@github.com
Hi tar-xzvff! You've successfully authenticated, but GitHub does not provide shell access.
```

SSH公開鍵を登録し直したり、PATを再生成してMacに設定するも同じエラーが出続ける。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token

```bash
$ git pull origin develop 
Username for 'https://github.com': tar-xzvff
Password for 'https://tar-xzvff@github.com': 
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/****/****.git/'
```

# 確認&解決方法
remote urlを確認したところhttpsになっていた。
```bash
$ git remote -v
origin  https://github.com/****/****.git (fetch)
origin  https://github.com/****/****.git (push)
```

git remote set-urlコマンドでurlをsshに変更。
※GitHubのリポジトリのトップからgit cloneする時のsshのurlをコピペした方がお手軽です。
```bash
git remote set-url origin git@github.com:****/****.git
```

ワンライナーで行う場合は以下。
```bash
git remote --verbose | grep fetch | grep -Eo "http(s?)://(\w|:|%|#|\$|&|\?|\(|\)|~|\.|=|\+|\-|/)+" | sed -e 's/https:\/\//git@/g' | sed -e 's/\//:/' | xargs -L1 git remote set-url origin 
```

urlがsshになっていることを確認。
```bash
$ git remote -v
origin  git@github.com:****/****.git (fetch)
origin  git@github.com:****/****.git (push)
```

これでgit pullなど操作が今まで通りできるようになりました。
そもそも今までhttpsでなぜ操作ができていたのかはわからないですが、おそらく移行後のキーチェーンアクセス周りの設定が不十分だったのかなと思います。

めでたしめでたし　完
[pandas] Pandas Dataframe, Seriesの備忘録

以前のNumpyからだいぶ期間が開きましたが、pandas関係の内容についても

# 公式のdocumentation
- [User Guide -- pandas 1.4.3 documentation](https://pandas.pydata.org/docs/user_guide/index.html)

# 目次
- 動作環境
- Series、Dataframeの作り方

# 動作環境
|種類             |バージョン       |
|:---------------|:--------------|
|MacBook Air     |Monterey12.4.  |
|python          |3.8.9          |
|jupyter notebook|6.4.10         |
|pandas          |1.4.3          |

まずはパッケージのインポートから
```python:
import pandas as pd
```
pandasを扱うときはpdが慣例だそう

# Series、Dataframeの作り方
## Series
試しに簡単なリストで例を示す。
```python:
data = [1, 2, 3, 4, 5]
se = pd.Series(data)
print(se)
# 0    1
# 1    2
# 2    3
# 3    4
# 4    5
# dtype: int64
```
リストを使うとこのような形でSeriesを作れる。
ここで、1列目はindex(デフォルトは0, 1, 2, 3, ・・・)、2列目が指定した配列の要素になる。
なお、indexは直接指定することもできる。
```python:
data = [1 ,2 ,3 ,4 ,5]
se = pd.Series(data, index=['A', 'B', 'C', 'D', 'E'])
print(se)
# A    1
# B    2
# C    3
# D    4
# E    5
# dtype: int64
```



## DataFrame
試しに簡単なリストで例を示す。
```python:
data = [[1, 2, 3], [4, 5, 6]]
df = pd.DataFrame(data)
print(df)
#    0  1  2
# 0  1  2  3
# 1  4  5  6
```
リストinリストの形の行列でDataFrameは作れる。
縦(0 1)がindex、横(0 1 2)がcolumnと言う。両者ともデフォルトはやはり0開始の整数列で表される。
index, columnを指定するにはいくつか方法がある。
まずはパラメータとして直接指定する書き方。
```python:
data = [[1, 2, 3], [4, 5, 6]]
df = pd.DataFrame(data, index=['A', 'B'], columns=['apple', 'orange', 'lemon'])
print(df)
#    apple  orange  lemon
# A      1       2      3
# B      4       5      6
```
次に、辞書的な指定方法。columnを辞書で指定し、indexは別で指定する。
```python:
df = pd.DataFrame({'apple': [1, 4], 
                   'orange': [2, 5], 
                   'lemon': [3, 6]}, index=['A', 'B'])
print(df)
#    apple  orange  lemon
# A      1       2      3
# B      4       5      6
```
ちなみに逆はできなかった。
```python:
df = pd.DataFrame({'A': [1, 2, 3], 
                   'B': [4, 5, 6]}, columns=['apple', 'orange', 'lemon'])
print(df)
# Empty DataFrame
# Columns: [apple, orange, lemon]
# Index: []
```






# 参考にしたURL
- [pandas.DataFrameの行名・列名の変更](https://note.nkmk.me/python-pandas-dataframe-rename/)
ARアプリ開発入門Any% RTA 00:05:15

# はじめに

AR界隈、Geospatial API等のVPS登場に伴い、さらに盛り上がってきましたね。

盛り上がりの熱に当てられ、ふと触ってみたくなった折に、ARアプリ開発の入門Any%においておそらく好成績を残したので、手順を記録します。多分これがいちばん早いと思います。

10分くらいでサクッとUnity, ARアプリ開発に入門できる時代なんですねえ。
手順らしい手順もないし、コードも書かないのでご興味ある方は入口として是非。

## 書くこと・書かないこと

* 書くこと
  * 最速入門の手順
  * タイム

* 書かないこと
  * 技術的な詳説
  * なんらかの新規性

## 環境

```
User Client: iPhone13 Pro

Dev. Client: MacBook Pro 2021 M1 Chip 16GB

UnityHub: 2021.3.5f1
```

## レギュレーション

実空間上への3D Objectの配置を行う任意のARアプリをビルドし、iPhone実機上で動作すること。

今回は最小構成として、ビルド時点でStaticな3D Cubeを実空間に配置し、撮影可能なアプリケーションの開発を目標とします。

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/ed409d5b-8a63-8131-302f-f3c6630dfa5e.gif)


# 手順

## Project作成

Unity Hubで[AR] Templateを選択し[Create Project]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/aa705f49-9a78-3f14-c3d4-709d6b4fa1bc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/25b5d7de-e694-c7c7-0551-b1ba59abb212.png)

## キューブの配置

Unity上でCubeを作成、Positionを`(x, y, z) = (0, 0, 1)`, Scaleを`(x, y, z)=(0.4, 0.2, 0.2)`に設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/d6bd89e9-064e-fd45-183d-fda23e1bb484.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/65c3feef-ad8b-53df-3a5b-c4c8bd18a8a0.png)

Rotationをエモい感じにして確定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/f54f7e03-6937-ba44-e732-9232bf38890f.png)

## ビルド設定

iOS向けのビルドを行うため[Switch Platform]
[XR Plug-in Management]の[Plug-in Providers]において、[ARKit]にチェック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/734d4662-8277-fbdc-4e7c-9bf3c17a939d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/393bb47e-92eb-ea01-4705-19620e6d8de0.png)

設定が終わったらビルド。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/5dfcfb13-5d8a-54a5-63b4-f7516f527e35.png)

## XCodeで実機向けビルド

Unityビルド結果のXCode Projectを開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/71eabf18-37d9-1c1a-2d83-5aacc28f1680.png)

[Sigining & Capabilities]に必要事項を記載。（Apple Accountへログインも必要）
iPhone実機をMacに有線接続。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/aaf8159b-183e-301b-523e-4e381fba1e2a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/c2aaa346-62cc-85e1-b546-9b3a769c0f8f.png)

ビルド実行。
M1 Proチップ、ビルドが速い！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/33e8cad8-48b5-d1b6-7745-17a2186d6d77.png)


## 動作確認・タイマーストップ

iPhoneを開いてビルド後のAppを実行。タイマーストップ。

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131633/ed409d5b-8a63-8131-302f-f3c6630dfa5e.gif)

# 終わりに

AR ProjectのテンプレートがUnity側で用意されているので、非常に簡単にサンプルアプリの実行まで進むことができます。
結局新しいものを触る時の一番の壁って、最初に動くものを作ることですが、こうして赤絨毯が引かれていると楽で良いですね。

画像ばっかりのエントリになってしまいましたが、誰かの興味のきっかけにでもなれば嬉しいです。
【Python】os.path.isfile(path)を使ってファイルの存在をチェック

### os.path.isfile(パス名)[<sup>[1]</sup>](#参考にしたサイト)
引数で指定したパスが実在するファイルかどうかを判別する関数。
実在しファイルであればTrueを返す。

---
### ファイルが存在しない場合に新規作成をする

#### ファイルの存在と中身を確認する
~~~unix:【ターミナル操作】ファイルと中身の確認
~ $ ls
test.py    names.txt
~ $ cat names.txt 
Hakase
~ $ 
~~~

#### ファイルが存在しない場合に新規作成、既に存在している場合はメッセージの表示

~~~python:test.py ファイルが既に存在している場合
# osモジュールのインポート
import os

file_name = "names.txt"
# 『os.path.isfile(file_name)』引数で指定したパスが実在するファイルかどうかを判別する。
# ファイルが実在する場合Trueを返す。
# if not もしファイルが存在しないとき、ファイルを新規作成する。
if not os.path.isfile(file_name):
# mode="x" ファイルの新規作成
    with open(file_name, mode="x") as f:
# Shinonomeと書き込む。\nは改行するという意味。
        f.write("Shinonome\n")
# ファイルが存在する場合「既にファイルは存在していますよ！！！」と表示。
else:
    print("既にファイルは存在していますよ！！")
~~~

#### コードを実行してファイルが上書きされていないかを確認する
ファイルが既に存在するためメッセージが表示される。
names.txtの中身は変わっていない。
~~~unix:【ターミナル操作】 実行
~ $ python test.py
既にファイルは存在していますよ！！
~ $ cat names.txt 
Hakase
~ $ 
~~~

#### 存在しないファイル名に変えてみる
~~~python:test.py ファイルが存在しない場合
import os
# 存在しないファイル名に変えてみたよ
file_name = "names_1.txt"

if not os.path.isfile(file_name):
    with open(file_name, mode="x") as f:
        f.write("shinonome\n")
else:
    print("既にファイルは存在していますよ！！")
~~~
新しいファイルが新規作成されている。
~~~unix:【ターミナル操作】 実行・ファイルの確認
~ $ python test.py
~ $ ls
test.py      names.txt    names_1.txt
~ $ cat names_1.txt 
shinonome
~ $ 
~~~
---
### 参考にしたサイト
[1] https://techacademy.jp/magazine/31132
レスポンシブデザインに欠かせないデバイス判定について

## はじめに

- レスポンシブデザインに欠かせないデバイス判定を行う方法をメモしていきます。

## 画面幅による切り替え

### window.matchMedia

```javascript
if (window.matchMedia("(max-width: 768px)").matches) {
  // ここにビューポート768px以下の挙動を記述
} else {
  // ここにビューポート769px以上の挙動を記述
}
```

- ビューポートを基に判定し、考え方としては css のメディアクエリと同じです。
- `matchMedia`は`MediaQueryList`オブジェクトを返し、オブジェクトが持っている`matches`プロパティは渡した引数に対して`boolean`の値を返します。
- 上記のコードの場合、引数に渡した`max-width: 768px`に対してビューポートが 768px 以下だったら`matches`プロパティから`true`が返ってきます。

### window.innweWidth

```javascript
if (window.innerWidth <= 768) {
  // ここにビューポート768px以下の挙動を記述
} else {
  // ここにビューポート769px以上の挙動を記述
}
```

- `innerWidth`はスクロールバーを含むウインドウ幅を値で返します。
- 数値で返ってくるので直感的にわかりやすいです。

## おわりに

- `matchMedia`は css と同じ記述ができ、返ってくる値も`true`か`false`なのでわかりやすいです。
- `innerWidth`はスマホの場合だと`onresize`が頻繁に起こり、端末への負荷が大きくなるようです（参考：[window.matchMedia をそろそろ活用してもいい頃](https://qiita.com/amamamaou/items/a29b29f5267196a5e4ea)
- `matchMedia`は IE9 以下は対応していないということですが、IE のサポートが 2022 年 6 月 15 日で終了するとなると`matchMedia`（一択？）がよさそうです。
業界未経験エンジニアはランチェスター戦略で生き残れ！

## はじめに
業界未経験でエンジニアに転職してみたいけど、本当に生き残れるのだろうか？
業界未経験でエンジニアに転職してみたけど、周りの経験者が強すぎて、どうしよう〜。

こんな悩み、ありますよね？
1年前の自分も全く同じことを思ってました。

そんな不安のあるあなたにおすすめなのがランチェスター戦略。
弱者の戦略でITエンジニアの世界を生き延びましょう！

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- 業界は未経験だけど、社会人経験はそこそこある人

## 結論

- 弱者(業界未経験)は**点で**勝つ！
- 強者(経験者)は**面で**勝つ！

## ランチェスターの法則とは
ランチェスターの法則とは、第一次世界大戦の時代に、イギリスのエンジニアであったF.W.ランチェスターが考案した戦争に勝利するための法則と戦略論です。
彼は戦闘機の開発に従事しており、「いかに敵機に打ち勝つか」を研究した理論の集大成と言えます。
現代でも、競争を生き抜くためのノウハウとして、ビジネスマンに愛されています。

ランチェスターの法則は局地戦のための第一法則と、広域戦のための第二法則で成り立っています。
それでは、それぞれについて解説しましょう。

### ランチェスター第一法則
ランチェスター第一法則は局地戦のための法則です。
ざっくりいうと「タイマンで殴り合ったらどうなる？」というイメージです。
敵味方の戦力を下記の指揮で求めます。

:::note
ランチェスター第一法則
**戦力 = 武器の性能 × 兵力数**
::: 

良い武器と兵力が多い方が勝つ、というシンプルなものです。
自分よりも強い相手と戦う場合は、この第一法則を意識しましょう。
局地戦に勝つなら、武器の性能を上げるか、兵力を増やすしかありませんね。

### ランチェスター第二法則
ランチェスター第二法則は広域戦のための法則です。
ざっくりいうと「大軍同士で戦争したらどうなる？」というイメージです。
敵味方の戦力を下記の指揮で求めます。

:::note
ランチェスター第二法則
**戦力 = 武器の性能 × 兵力数<sup>2</sup>**
::: 

第一法則に比べて、兵力数の影響が大きくなっています。
大軍で戦う場合は、武器の性能を上げるよりも、兵力数を整える方が効率的と言えます。
強者が弱者と戦う場合に勝利をさらに確実にする際には第二法則を意識しましょう。

## ランチェスター戦略をITエンジニアのキャリア戦略に活用

これを、エンジニアのキャリア戦略に置き換えてみると、下記の通りです。

:::note
**武器の性能 = 保有スキルの習熟度**
**兵力数 = 保有スキルの数**
:::

そして、

:::note
**弱者 = 業界未経験エンジニア**
**強者 = 業界経験ありエンジニア**
::: 

とすると考えやすいのではないでしょうか。

### 【弱者の戦略その1】保有スキルの習熟度で一点突破
弱者(業界未経験エンジニア)の勝利への道の一つは武器の性能(スキルの習熟度)で勝負することです。
とはいえ、経験者と競争していくわけですから、技術力で勝負するのは負けが見えています。
そこで、「技術力以外のスキルで勝負」するのがおすすめです。

業界未経験とはいえ、社会人経験はそこそこ積んでいるのが未経験エンジニアの良いところ。
しかも、新卒からITエンジニアだった人よりも、いろんな経験を積んでいるはずです。
下記のような、ITエンジニアが苦手だけど業務に必要なスキルに強みがあれば、一点突破で勝利することも可能です。

:::note
接客力
文章力
営業力
プレゼン力
マネジメント力
体力
:::

### 【弱者の戦略その2】保有スキルの数で勝負
弱者の戦略はその1の一点突破が基本です。
しかし「そこそこのスキルだけど、数揃えられるで〜」という器用貧乏？なあなたはスキル数で攻めるのもありです。
もちろん、それぞれのスキルがそこそこのレベルであることが前提です。

ちなみに筆者は「文章力」と「マネジメント力」を活かして未経験で入社して早々にSE的ポジションを任され、半年でチームリーダーを任された、という実績があります。

### 【強者の戦略】とにかく面で攻め、他者を寄せ付けない
弱者が局地戦で勝利を続けると、スキルのレベルと保有数が徐々に増えていきます。
「そろそろ強者になってきたかも？」と思ったら、それまでと戦略を切り替えていきましょう。
個々のスキルの習熟度を上げるよりも、スキルの数を増やし、他者を寄せ付けないように活躍できるでしょう。
最終的にはテックリードやCTOのような責任がありマルチに活躍するポジションを狙えるはずです。

## おわりに
競争に勝つために有用なランチェスターの戦略についてまとめました。

## 参考記事
[スキルの乏しいビジネスパーソンのキャリア戦略。ランチェスター戦略でのしあがれ。](http://sg-bizadvisor.com/2020/06/02/%E3%82%B9%E3%82%AD%E3%83%AB%E3%81%AE%E4%B9%8F%E3%81%97%E3%81%84%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%91%E3%83%BC%E3%82%BD%E3%83%B3%E3%81%AE%E3%82%AD%E3%83%A3%E3%83%AA%E3%82%A2%E6%88%A6%E7%95%A5/)
コロケーションサービス とは

## 勉強前イメージ

場所的な話ではありそう

## 調査

### コロケーションサービス とは

データセンターの利用方法でデータセンターの共同スペースにサーバを設置することを指します。
データセンターにサーバを設置することで地震や災害に耐えられる作りをしているので
社内で管理するより安全と考えられています。

### DCならハウジングサービスってのもあった気がする

コロケーションと大体同義でコロケーションは通信事業者が利用する共同スペースですが
ハウジングは様々な事業者が利用します。

イメージとしてはコロケーションはスペースをかりる、ハウジングはラックをかりる用な感じです。

### それならホスティングは？

ホスティングはハウジングの対義語で
データセンター内にサーバを持って、サーバの機能をユーザに使ってもらいます。
ホスティングでは自社のサーバを置いてますが
ホスティングはサーバを置いて、それを違う会社の人(ユーザ)に使ってもらうレンタルサーバーになります。

### それぞれまとめ

それぞれの用語のイメージのまとめです。

- コロケーション : データセンターのスペースを借りる(大規模なイメージ)
- ハウジング : データセンターのラックを借りる(ラック単位の小規模なイメージ)
- ホスティング : データセンターにあるサーバを別のユーザに貸す

## 勉強後イメージ

コロケーション以外は聞いたことあった。
DCの10Fを借りたりするのがコロケーション、
10FのAラックを借りるのがハウジング、
10FのAラックのNo.1サーバを貸すのがホスティングってイメージ

## 参考

- [コロケーションとは？ほかのデータセンターサービスとの違いも解説](https://it-trend.jp/data_center/article/53-0024)
- [コロケーションとは？サービス形態の違い・メリット・選び方を紹介](https://www.nttpc.co.jp/column/data_center/collocation.html)
Component definition is missing display name を解決する

`forwardRef` を実装中にeslintのエラーが出てしまいました。
![スクリーンショット 2022-07-04 22.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206790/c633051f-ff0b-728d-2f3b-85f6c364aae1.png)

全てのコンポーネントに名前を付けることが推奨されています。
これはデバッグの際、問題を特定しやすいようにするためです。[参考](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md)

今回は `名前がない` と教えてくれていますので、名前を付与しましょう。


#### 解決方法1

```diff
export const Textbox = forwardRef<
  HTMLInputElement,
  ComponentPropsWithoutRef<"input">>(({ className, ...props }, ref) => {
  return (
    <input
      type="text"
      {...props}
      ref={ref}
      className={clsx(className, styles.module)}
    />
  );
});

+ Textbox.displayName = 'Textbox'
```

#### 解決方法2

アロー関数ではダメなので、関数名をつけるようにします。

```diff
export const Textbox = forwardRef<
  HTMLInputElement,
  ComponentPropsWithoutRef<"input">>
- (({ className, ...props }, ref) {
+ (function TextboxBase({ className, ...props }, ref) {
  return (
    <input
      type="text"
      {...props}
      ref={ref}
      className={clsx(className, styles.module)}
    />
  );
});

```
[bootstrap][table]bootstrapを使用したTableを印刷すると背景色が表示されない

# はじめに
bootstrapとtableを使用して作成した表を印刷した時、
tableに設定したbackgroundcolorが表示されず苦しめられたので、
原因と解決策を記載します。

# 前提
印刷するのは以下のような表です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727564/646c217d-4989-a286-001f-b8fa3ab0541c.png)

印刷すると以下のようにtableに設定したbackgroundcolorが無効になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727564/f0df4170-2086-2fa3-7b48-4dda58a52e62.png)


環境
・CDN:bootstrap4.3.1

# 原因
bootstrapの仕様です。
@media printを使用し、強制的にbackgroundcolorを白に設定しています。
```boostrap.css:bootstrap.css
@media print {
  *,
  *::before,
  *::after {
    text-shadow: none !important;
    box-shadow: none !important;
  }
  a:not(.btn) {
    text-decoration: underline;
  }
  abbr[title]::after {
    content: " (" attr(title) ")";
  }
  pre {
    white-space: pre-wrap !important;
  }
  pre,
  blockquote {
    border: 1px solid #adb5bd;
    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr,
  img {
    page-break-inside: avoid;
  }
  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }
  h2,
  h3 {
    page-break-after: avoid;
  }
  @page {
    size: a3;
  }
  body {
    min-width: 992px !important;
  }
  .container {
    min-width: 992px !important;
  }
  .navbar {
    display: none;
  }
  .badge {
    border: 1px solid #000;
  }
  .table {
    border-collapse: collapse !important;
  }
  .table td,
  .table th {
    background-color: #fff !important;
  }
  .table-bordered th,
  .table-bordered td {
    border: 1px solid #dee2e6 !important;
  }
  .table-dark {
    color: inherit;
  }
  .table-dark th,
  .table-dark td,
  .table-dark thead th,
  .table-dark tbody + tbody {
    border-color: #dee2e6;
  }
  .table .thead-dark th {
    color: inherit;
    border-color: #dee2e6;
  }
}
```

## 解決方法
解決方法は以下の2つ
・CDNを使用せず、bootstrapをダウンロードして使用する。問題箇所の!Importantを削除する。
・htmlのtableタグにてstyle属性を使用しbackgroundcolor; !importantを設定する。

## 終わり
@Media printはデバッガで追いにくいので気づくのに時間がかかりました。


# 参考文献
- [HTMLの背景色印刷で詰まった話](https://www.kuzilla.co.jp/blog/160627_bootstrap)