OmniAICreator/Qiita-1.07M huggingface dataset:
プログラミング言語の選定基準

# はじめに
- 仕事で言語の選定基準をまとめることがあったので折角なので投稿してみました。
- 実際にこの選定基準を基に言語を選定したことはありません。
- 独自で考えた基準ではなく、色々なネット記事を調べてまとめました(少し前にまとめたのでどの記事から引用したのかは忘れました)。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [プログラミング言語の選定基準](#プログラミング言語の選定基準)
1. [プログラミング言語の選定方法](#プログラミング言語の選定方法)
1. [まとめ](#まとめ)

<!-- 各チャプター -->
<a id="#プログラミング言語の選定基準"></a>
# プログラミング言語の選定基準
## 実行速度
文字列を扱う速度、演算速度、分岐評価の速度はどれくらいか
## 汎用性
フロントエンドで使用できるか。
REST API を開発できるか。特定の処理を行うシステムやプログラムを開発できるか。
スマホアプリを開発できるか。...etc
## 可読性
エンジニアの熟練度によらず、誰でも可読性が高いコードを書けるか
(例えば、同じ処理を書く際に複数の書き方ができる場合は、パッと見でどのような処理をしているのかわからない場合があるため可読性は低くなる場合がある)。
## 将来性
リリース・パッチの頻度、(OSSの場合)コミッターの数
## 開発環境
対応しているエディタ・IDE、dockerの有無
## データベース接続
主要なデータベースエンジンへの対応状況、使いやすさ
## エンジニアの確保
言語を習得している社内のエンジニアの人数、言語の習得難易度、求人数
## 生産性
以下の要素を含めた開発速度
- 開発環境(IDE, dockerなど)の有無、使いやすさ
- フレームワークの有無、使いやすさ
- 日本語の公式ドキュメントの有無、読みやすさ
- ネットの記事の量

<a id="#プログラミング言語の選定方法"></a>
# プログラミング言語の選定方法
## 1. プロダクトの要件を明確にする
まずはそのプロダクトの要件を明確にする必要があります。
いきなり選定基準に当てはめて評価しても「実行速度が速いからこの言語がいい！」というように、なんとなくで選ぶことになってしまいます。

## 2. 選定基準の各項目に優先度を付ける
プロダクトの要件を明確にしたら、選定基準の各項目のうち、何を重要視するかを決めて優先度を付けます。
要件が明確になっていれば自ずと優先度は付けられるはずです。
例えば REST API を開発するプロダクトの場合は、フロントやスマホアプリを開発できる言語を選ぶ必要はないため、「汎用性」の優先度は低くなると思います。
実行速度を求められるプロダクト(およびサービス)の場合は「実行速度」が最優先事項になる場合もあると思います。

## 3. 候補となるプログラミング言語を選定基準に沿って評価する
優先度を付けたら、候補となるプログラミング言語を選定基準に沿って評価します。
「可読性」や「生産性」は人によって評価が異なると思うので、プロダクトのエンジニア複数人で評価するのが良いかもしれません。「この言語がいい！」「いやこっちの方がいい！なぜなら…」と議論するのも面白そうです。

<a id="#まとめ"></a>
# まとめ
プロダクトの要件がなければ言語は選べないと思います。
プログラミング言語はプロダクトの要件を満たす「手段」だと認識しています。
「とにかく速ければいい」「バグは許されないシステムだから枯れている言語がいい」「大人数で開発できる必要がある」など、プロダクトごとに求められることは様々です。
これは言語に関わらず、様々な技術を選ぶ上で基本的かつ当たり前なことだと思っています。

でも趣味で何かを作る分にはそんなことは考える必要はないので、好きな言語を脳死で選びましょう！(一番言いたかった)
[AUTOSAR] Dcm リプロ時の振る舞い

# はじめに
AUTOSARを扱う仕事に従事していて、
Dcm（Diagnostic Communication Manager）のリプログラミングの振る舞いについて、AUTOSARの仕様（4.2.2）について確認した結果を残しておく。

# 入力文書
AUTOSAR 4.2.2

https://www.autosar.org/fileadmin/standards/classic/4-2/AUTOSAR_SWS_DiagnosticCommunicationManager.pdf

# 確認したいこと
UDS SID:0x10 subfuncID:0x02でリプログラミングセッション移行をECUに要求したときの、Dcmの振る舞いはどうなるのか？
※状態を遷移して、リセットしているのはなんとなくわかっている。

# 確認結果
Dcmのコンフィグによって、Dcmの「DcmEcuReset」という状態が「JUMPTOBOOTLOADER」 or 「JUMPTOSYSSUPPLIERBOOTLOADER」に遷移し、それがBswMに通知される。
その後、コールアウト関数「Dcm_SetProgConditions」が成功し、リプロの条件が整ったあと、「EXECUTE」に遷移し、bootloaderにジャンプする。

:::note info
bootloaderへジャンプするときにユーザが何かしたいなら、
「JUMPTOBOOTLOADER」 or 「JUMPTOSYSSUPPLIERBOOTLOADER」への遷移を掴むこと
:::



# 状態定義
* 7.4.1.4 Diagnostic mode declaration groups

Dcmは、「DcmEcuReset」という状態を持つ。
状態は、以下の7つあり、初期状態はNONE。
NONE,
HARD,
KEYONOFF,
SOFT,
JUMPTOBOOTLOADER,
JUMPTOSYSSUPPLIERBOOTLOADER,
EXECUTE
![スクリーンショット 2023-02-23 18.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/785b5d29-e171-3343-b4f1-bd2f092eda0a.png)


# 7.4.4.1 Jump to Bootloader
ブートローダへのジャンプは4種類のユースケースがある。

1. APLはPRCを即返し、bootloaderへジャンプ
1. APLはNRC:0x78(ResponsePending)を返したあと、PRCを返し、bootloaderへジャンプ
1. APLはレスポンスを返さず、bootloaderへジャンプ（bootloaderでPRCを返す）
1. APLはNRC:0x78(ResponsePending)を返したあと、bootloaderへジャンプ。（bootloaderでPRCを返す）

※suppressPosRspMsgIndicationBitフラグがtrueの場合は、1.と3.はPRCを返さない。（suppressPosRspMsgIndicationBitフラグがtrueの場合はUDS仕様参照。簡単に言うとPRCを返さなくするためのフラグ）

コンフィグパラメータ：DcmDspSessionForBootがbootloaderへのジャンプの設定されている場合は、「DcmEcuReset」は「JUMPTOBOOTLOADER」に遷移する。

:::note info
Dcmはbootloaderへのジャンプを準備するためBswMにモードスイッチ（「JUMPTOBOOTLOADER」への遷移）を通知する。
:::

※JUMPTOSYSSUPPLIERBOOTLOADERへ遷移するようにも設定することが可能。

DcmSendRespPendOnTransToBootがtrueなら、Dcmは、コールアウト関数Dcm_SetProgConditionsを呼び出して、bootloaderへのジャンプ条件が整っているか確認する。

bootloaderへのジャンプ条件が整っている（Dcm_SetProgConditionsの戻り値が「E_OK」）場合、「DcmEcuReset」は「EXECUTE」に遷移する。
※Dcm_SetProgConditionsがE_NOT_OKを返すときは、bootloaderへジャンプしません。状態も「EXECUTE」に遷移しない。


# 7.4.4.3 Jump from Bootloader / ECUReset

DCM の初期化時に、ブートローダ/ECUReset からのジャンプの結果であるかどうかを知るためにコールアウト関数Dcm_GetProgConditions() を呼び出す。

:::note warn
Dcm_GetProgConditionsにて、不揮発に保存している値を確認するのはインテグレータの責務。
時間がかかりすぎてスタートアップシーケンスに影響するかなど確認が必要。
:::

DCM初期化時に、ブートローダ/ECUReset からのジャンプの結果である場合、
DCM は ComM_DCM_ActiveDiagnostic(NetworkId) を呼び出し、ComManager にフル通信モードを要求しなければならない。

DCMの初期化がbootloaderからのジャンプであり、APLが更新(Dcm_ProgConditionsType.ApplUpdated == True)されている場合、
DCMはBswM_Dcm_ApplicationUpdated()を呼び出し、アプリケーションが更新された旨をBswMに通知しなければならない。

# 7.4.4.4 Flags management
あんま新しい情報なし

# 9.3.2.6 Process Jump to Bootloader
Dcm内部からDcm_SetProgConditionsがどう呼び出されるか、なのであまり見なくて良い。


# 関連コンフィグパラメータ
* DcmDspSessionForBoot
bootloaderにジャンプするのか、ジャンプするならAPLとbootloaderのどちらでレスポンスを返すのかを設定。

![スクリーンショット 2023-02-23 18.31.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/2e63e219-7810-7031-29f6-263735e1cae7.png)

* DcmSendRespPendOnTransToBoot
bootloaderに遷移する前にNRC:0x78を返すかどうか設定。
Dcm_SetProgConditions()を呼ぶためにはtrueに設定しておく。
![スクリーンショット 2023-02-23 18.45.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/cb9185de-a5a0-3c0c-03b8-04961d7b4696.png)
ransackで"Ransack needs attributes explicitly allowlisted..."のエラー解消法

# 概要
ransackの[4.0.0のアップデート](https://github.com/activerecord-hackery/ransack/releases/tag/v4.0.0)でBreaking Changesがあり、そのうちの1つに

- [SECURITY] Require explict allowlisting of attributes and associations
が含まれています
このアップデートの影響で関係するモデルにホワイトリストを登録しなければいけなくなりました。

## エラーログ
ransackを使用しているページにアクセスすると以下のエラーが表示されてしまいました。。。。
```
ActionView::Template::Error (Ransack needs HogeModel attributes explicitly allowlisted as
    | searchable. Define a `ransackable_attributes` class method in your `HogeModel`
    | model, watching out for items you DON'T want searchable (for
    | example, `encrypted_password`, `password_reset_token`, `owner` or
    | other sensitive information). You can use the following as a base:
    | 
    | ```ruby
    | class HogeModel < ApplicationRecord
    | 
    |   # ...
    | 
    |   def self.ransackable_attributes(auth_object = nil)
    |     ["id", "hogehoge_1", "hogehoge_2", "hogehoge_3", "updated_at"]
    |   end
    | 
    |   # ...

```

## 解消法
エラーログにも書かれていますが、ransackで検索対象にしているモデル内にホワイトリストを登録するメソッドを作成し、検索に使用するカラムを記述する必要があります。

例えばメールアドレス検索と名前検索を使用している場合は


``` ruby:HogeModel
def self.ransackable_attributes(auth_object = nil)
    ["email", "name"]
end
```
と書く必要があります。


## 子モデルで検索している場合どうするか
hogeとfugaが1対1のアソシエーションが組まれていて（fugaが子とする）、hogeの検索にfuga内のカラムが必要な場合
例えば電話番号検索機能があり、電話番号はhogeではなくfugaカラムにある場合は以下のように記述します

``` ruby:HogeModel
def self.ransackable_associations(auth_object = nil)
    ["fuga"] #アソシエーション先を記述
end
```


``` ruby:FugaModel
def self.ransackable_attributes(auth_object = nil)
    ["phone_number"]
end
```

以上です！

## 参考
[公式ドキュメント](https://activerecord-hackery.github.io/ransack/going-further/other-notes/#authorization-allowlistingdenylisting)
[リリースノート](https://github.com/activerecord-hackery/ransack/releases/tag/v4.0.0)
Springポートフォリオを作成する 決定版

# 最初に
以前、TODOリスト×RPGというWebアプリを作成したいと考え、似たような記事を書いたのですが、余りにも機能が https://habitica.com/ に似てしまったため、作成するWebアプリを根本から考え直しました。

なので、この記事は新たに作るWebアプリの要件定義になります。

# Springでポートフォリオを作成する
本日からSpringを用いてポートフォリオを作成する過程を投稿していきたいと思います。
今回は、まず始めに要件定義を書いていきます。

# 要件定義
## プロジェクト名
*StudyQuest*

勉強にRPG要素を組み合わせたWebアプリを作成していこうと思います。

## プロジェクト概要
- [ ] 楽しみながら勉強できる 
- [ ] 勉強時間を管理し、勉強の継続を図る  

本来であればつまらない勉強にRPG要素を含めることで、勉強の継続化を図る目的があります。

## 現状の問題点
### 自分
- [ ] 勉強を習慣化することができない 
- [ ] 楽しみながら学習をすることができない 

## ゴールの設定(本来あるべき状態、目指す状態)
### 自分
- [ ] 目標を設定することで勉強の継続ができる  
- [ ] RPG要素を入れることで楽しみながら勉強できる 

### 勉強×RPG
- [ ] 楽しみながら勉強ができ、勉強の習慣化に繋がる  
- [ ] 使いやすさ、わかりやすさ 
- [ ] 勉強するごとに自分(アバター)が成長していく 
- [ ] 自分の学習状況を把握することができる  

## 現状とゴールのギャップ(解決すべき課題の洗い出し)
- [ ] 技術不足(サーバーへのアップロード、Batch処理、デザイン、設計ノウハウ、その他諸々) 

## ヒアリング(システムに何を求めるか？)
- [ ] ユーザー目線 
    - [ ] 一目見て分かる操作性 
    - [ ] 処理速度 
    - [ ] デザイン性、面白さ 
    - [ ] セキュリティの高さ
    - [ ] 不具合のなさ 

今回は個人開発なので、この部分に関しては予測して書いております。

## 達成するゴールを数値で明確化
- [ ] 基本設計(画面レイアウト、DB、必要機能の洗い出し):2ヶ月 
- [ ] 開発:2ヶ月 
- [ ] テスト(仕様書作成、単体/結合テスト)、サーバーへのアップ:2週間 

今回はシステム開発を行い、事業をするわけではないので売り上げなどの目標があるわけではないです。なので、開発期間をゴールに定めました。

## クリアすべき課題に分解 
- [ ] サーバーへのアップロード方法
- [ ] Batch処理(必要か未定)
- [ ] DBの設計 
- [ ] UIを高める画面設計
- [ ] 保守性の高いコード 
- [ ] 処理速度

## ゴールの達成条件をSMARTに沿って整理 
- [ ] Specific（ゴールが具体的か？）→OK 
- [ ] Measurable（進捗を数値で測れるか？）→OK 
- [ ] Achievable（達成可能か？）→OK 
- [ ] Relevant（当初の困りごとが解決するか？）
    - [ ] 勉強の習慣化→OK
    - [ ] 楽しみながら勉強できるか→OK　 
- [ ] Time-bound（期限が明確か？）→OK 

## システムに実装したい機能 

### 勉強要素 
- [ ] 目標を設定することができる
- [ ] 習慣、TODO学習に分ける 
- [ ] 日、週、月ごとの勉強時間、時間配分がわかる 

### RPG要素 
- [ ] 学習を行うと難易度に応じたポイント(経験値)やお金が貰える 
- [ ] 目標などが達成できないとポイント(経験値)やお金が減る
- [ ] 一定のポイントを貯めるとLevel Up 
- [ ] お金で装備やアイテムを買える 
- [ ] モンスターを倒す 
- [ ] ストーリを進められる 
- [ ] 仲間を集めてパーティーを作れる 
- [ ] 職業を選べ、変更できる 

実装したい機能を書き出しましたが、おそらく全て実装することは技術的にも時間的にも現実的ではないので、最初はこの中からいくつか選択して実装していこうと思います。
また、サーバー側はSpring、クライアント側はReactを用いて開発することを考えています。

# 最後に
今回の要件定義はUdemyの以下のコースを受講した際の資料を参考に書いてみました。

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

また、今回は参考にしたアプリがあるので載せておきます

https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica&hl=ja&gl=US
新卒エンジニアが【Pythonエンジニア認定基礎試験】の模試を受けてみたら、、、④

こんにちは。

前回の記事はこちらから
①→https://qiita.com/asukitt/items/35ae0bbbc0b06a10509f
②→https://qiita.com/asukitt/items/26ece254b03afcdc2421
③→https://qiita.com/asukitt/items/e5516b4bdeba4aa9c231

今回のスコアは、、、

73 点 / 100点満点

前回より下がってしまった、、、、でも合格圏内なのでセーフ！
前回より下がった原因としては、第2回の復習をしてから手を付けれず久しぶりに受験したからです。
受験まであと4日なのでしっかりと詰めていこうと思います。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
◆模試で間違えたところの記録◆

【pop】
pop()は末尾指定
pop(1)は2番目の要素を削除

【sort関数について】
sort()は引数にkeyを指定するとそれについて並べ替えてくれる

```test.py
pairs = [(3, 'b'),(1, 'c'),(2, 'a')]
pairs.sort(key =lambda arg : arg[1])
print(pairs)
#[(2, 'a'), (3, 'b'), (1, 'c')]

pairs = [(3, 'b'),(1, 'c'),(2, 'a')]
pairs.sort(key =lambda arg : arg[0])
print(pairs)
#[(1, 'c'), (2, 'a'), (3, 'b')]

```

【remove】
「remove」は引数に指定した値の要素を削除。複数ある場合は先頭の1つだけ削除します。

【map】
調べる

【try-else】
try文中のelseはtryが成功すると必ず実行する

【その他】
・デフォルト設定ではユーザーディレクトリの「.python_history」ファイルにヒストリが保存される。ヒストリは対話型インタープリタセッションで利用できる。

・拡張された対話型インタープリタとしてBpython・Ipythonがある。これはオブジェクト探索、高度なヒストリ管理などの機能を持つ。
[OutSystems]モバイルアプリケーションのApp Identifierをプログラムで取得する

OutSYstemsのモバイルアプリケーションに自動で付与されるApp Identifierを取得するJavaScript APIが追加されているようなので動作確認してみる。

（SAML認証をモバイルアプリケーションにも提供する[Single Sign-On Mobile Plugin](https://www.outsystems.com/forge/component-overview/14284/single-sign-on-mobile)の実装を見ているときに存在に気づいた）

# 結論から
モバイルアプリケーションへのDeep linkに使うApp IdentifierをJavaScript API「OutSystemsNative.ApplicationInfo.getAppPackageIdentifier」を利用することでプログラムから取得できるようになった（MABS9から）。

# 環境情報
Personal Environment(Version 11.18.1 (Build 37884))
Service Studio(Version 11.53.39)
MABS 9.0

# App Identifier

Service CenterのApplicationページ > Distributeタブ > Configure
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/e3d3831b-96a4-04b4-2faa-ce6d31a0aa01.png)

で開いたページで、App Identifier項目を確認できる。
設定可能項目であるが、デフォルトで、「(hostを.区切りで逆順にしたもの).モジュール名」というフォーマットの値が入っている。

# Deep link
モバイルアプリケーションの特定の画面へのリンク（Deep link）は

「App Identifier://モジュール名/画面名」

の形式。このApp Identifierが今回問題としているもの。
[モバイルアプリのディープリンクの設定](https://success.outsystems.com/ja-jp/documentation/how-to_guides/development/how_to_define_mobile_app_deep_links/)

# App Identifierを取得する新API（MABS 9）
[MABS 9で追加された機能](https://success.outsystems.com/support/release_notes/mobile_apps_build_service_versions/mabs_9_release_notes/mabs_9.0/#new_in_mabs_2022-11-23)にJavaScriptの新しい関数「OutSystemsNative.OSApplicationInfo.getAppPackageIdentifier」というものがあり、App Identifierを取得できる。

> It is now possible to obtain the application package identifier using the js method OSApplicationInfo.getAppPackageIdentifier. (RNMT-5784)

使い方は、Client Actionのフロー内にJavaScript要素を配置し、以下のように記述する。

```
function Success(appId) {    
    $parameters.AppIdentifier = appId;
    $parameters.Success = true;
    $resolve();
}

function Fail(message) {
    $parameters.ErrorMessage = message;
    $parameters.Success = false;
    $resolve();
}

OutSystemsNative.ApplicationInfo.getAppPackageIdentifier(Success, Fail);
```

OutSystemsNative.ApplicationInfo.getAppPackageIdentifier関数に成功時のコールバックと失敗時のコールバックを渡す。成功すると、成功時のコールバック（1つ目）が動作し、その引数にApp Identifierが渡ってくる。

ただし、今のところドキュメントが無いようなので、公開で利用して良いものかどうかは不明。
公式サポートプラグインである[Single Sign-On Mobile](https://www.outsystems.com/forge/component-overview/14284/single-sign-on-mobile)では利用していた。

## 動作確認
実際にJavaScriptを組み込んで動作確認してみた。

PWAの場合、以下のエラーメッセージが表示される（つまり、OutSystemsNativeはPWAでは未定義になる）。
```
Can't find variable: OutSystemsNative
```

Native (android)ではService Centerで設定してあったApp Identifierが正しく取得できた。

## 用途
Single Sign-On Mobileでやっているように、外部の認証サーバーに認証をリクエストし、認証成功後アプリケーションに戻ってくる時に使う。

外部の認証サーバーにリクエストする際に、戻ってくる画面へのパスをDeep linkで渡すのにApp Identifierが必要になる。
私も、OpenID Connectの実装をする際にApp Identifierが必要になったことがある。そのときはこのAPIが利用できなかったために、利用側でApp Identifierを設定値として保持してもらった。このAPIが利用できれば、設定値が不要になりちょっと楽ができる。
翻訳単位と名前空間と`using`

※初歩的な勘違いをしていたのでメモ



# 次のコードは動かない
といっても**リンクができない**だけで分割コンパイルはできる（できてしまう）

```hoge.hpp
#pragma once
namespace Hoge{

typedef float hoge;
hoge setHoge();
void getHoge(hoge value);

};
```

```hoge.cpp
#include <iostream>
#include "hoge.hpp"
using namespace std;
using namespace Hoge;

hoge setHoge(){
    return ((hoge)10);
}
void getHoge(hoge value){
    cout << value << endl;
}
```

```main.cpp
#include <iostream>
#include "hoge.hpp"
using namespace Hoge;

int main(){
    hoge x = setHoge(); // x = 10
    getHoge(x);  // print 10
    return 0;
}
```

```makefile:makefile
make:
	clang++ -std=c++20 -c hoge.cpp main.cpp
	nm hoge.o > hoge.sym
	nm main.o > main.sym
	clang++ hoge.o main.o -o test
```

```zsh
clang++ -std=c++20 -c hoge.cpp main.cpp
nm hoge.o > hoge.sym
nm main.o > main.sym
clang++ hoge.o main.o -o test
Undefined symbols for architecture x86_64:
  "Hoge::getHoge(float)", referenced from:
      _main in main.o
  "Hoge::setHoge()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [make] Error 1
```


## なぜか？
上のスクリプトで分割コンパイルすると，それぞれ`#include "hoge.hpp"`が展開された上で翻訳単位として`hoge`と`main`の2つが発生して，それぞれが処理されてシンボルテーブルを持つオブジェクトとして出てくる
`main`側は`Hoge`周りの実装をしていないため，`hoge.hpp`の宣言した内容に期待して，名前空間`Hoge`を含めたシンボルをあらかじめ設定する
ゆえに`hoge`側は名前空間`Hoge`を含めたシンボルを実体に持つような実装が期待されており，そうでなければリンク時に名前を解決できず失敗する

ソース側で`using namespace Hoge`を利用して（名前空間の解決の記法を省略して）実装することは不可能であり，それはコンパイラが名前空間の探索と適切な配置よりも先に勝手に大域的な配置をしてしまうためである…
なんでそうなのかは知りませんが，歴史的な経緯とかあるのでしょうか？やっぱり外部リンケージがデフォルトな言語だからなんですかね，`extern`と`const`も難解すぎてこのままでは`static`おじさんになってしまう…

### `hoge`側

`nm hoge.o | grep Hoge`

```c
0000000000000010 T __Z7getHogef
0000000000000000 T __Z7setHogev
```

### `main`側

`nm main.o | grep Hoge`

```c
                 U __ZN4Hoge7getHogeEf
                 U __ZN4Hoge7setHogeEv
```



# 解決策


## `namespace Hoge{}`の中に実装を書く
多分これが一番楽だと思います，ただしクソデカネストが許容できる場合の話，俺は辛い耐えられない


```hoge.cpp
#include <iostream>
#include "hoge.hpp"
using namespace std;
using namespace Hoge;
namespace Hoge{

hoge setHoge(){
    return ((hoge)10);
}
void getHoge(hoge value){
    cout << value << endl;
}

}
```

## 実装の名前に必ず`Hoge::`をつける
`using namespace Hoge;`しつつクソデカネストを使わないなら，多分これが一番楽だと思います
また宣言された`typedef`や`class`の名前スコープを無視できる，人によっては折衷案に見える？

```hoge.cpp
#include <iostream>
#include "hoge.hpp"
using namespace std;
using namespace Hoge;

hoge Hoge::setHoge(){
    return ((hoge)10);
}
void Hoge::getHoge(hoge value){
    cout << value << endl;
}
```
maya python get all keyframe

```python
def GetMinMaxFrame(selType="joint"):
    import math
    joints = GetAllByType(selType)
    minKey = 10000
    maxKey = 0
    for joint in joints:
        all_keys = sorted(cmds.keyframe(joint, q=True) or [])
        if all_keys:
            if all_keys[0] < minKey: minKey = all_keys[0]
            if all_keys[-1] > maxKey: maxKey = all_keys[-1]
    return math.floor(minKey), math.ceil(maxKey)

def set_playback_range_to_fit_keyframes():
    start_frame, end_frame = GetMinMaxFrame()
    pm.playbackOptions(minTime=start_frame)
    pm.playbackOptions(maxTime=end_frame)
```
【 Java 】JUnitを使ったFizzBuzzゲームのテスト



## ■情報
・Eclipse： Version 2022-12 (4.26.0)
・Java　： Version 17
・JUnit4

## ■FizzBuzzクラスのソース
```java:FizzBuzz.java
public class FizzBuzz {
	private int inputNum;
	public FizzBuzz(int num) {
		this.inputNum = num;
	}
	
	public String FizzBuzzGame() {
		if (inputNum % 15 == 0) {
			return "FizzBuzz";
		} else if (inputNum % 5 == 0) {
			return "Buzz";
		} else if (inputNum % 3 == 0) {
			return "Fizz";
		} else {
			return Integer.toString(inputNum);
		}
	}
}
```

##  ■テストクラスのソース
```java:FizzBuzzTest.java
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;

public class FizzBuzzTest {

	@Test
    // 3の倍数の期待値「Fizz」が返ってくるかテスト
	public void case1() {
	    FizzBuzz fizzBuzz  = new FizzBuzz(3);
	    assertThat(fizzBuzz.FizzBuzzGame(), is("Fizz"));
	}
	
	@Test
    // 5の倍数の期待値「Buzz」が返ってくるかテスト
	public void case2() {
	    FizzBuzz fizzBuzz  = new FizzBuzz(5);
	    assertThat(fizzBuzz.FizzBuzzGame(), is("Buzz"));
	}
	
	@Test
    // 3と5の倍数の期待値「FizzBuzz」が返ってくるかテスト
	public void case3() {
	    FizzBuzz fizzBuzz  = new FizzBuzz(15);
	    assertThat(fizzBuzz.FizzBuzzGame(), is("FizzBuzz"));
	}
	
	@Test
    // 上記以外の期待値「数値」が返ってくるかテスト
	public void case4() {
	    FizzBuzz fizzBuzz  = new FizzBuzz(16);
	    assertThat(fizzBuzz.FizzBuzzGame(), is("16"));
	}

}
```
##  ■動作検証
**１：FizzBuzzTestクラスのファイルを右クリック**
![スクリーンショット 2023-02-20 0.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192922/e5b8aef7-ba31-bd23-b2af-499373248d7e.png)


***

**２：実行の上にカーソルを移動**
![スクリーンショット 2023-02-20 0.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192922/d28e0cd8-5f55-4838-f104-c2334142f852.png)


***

**３：JUnitテストを押下**
![スクリーンショット 2023-02-20 0.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192922/9a485fb4-9f66-9654-2f00-882f6949b89c.png)


***

**４：コンソールにテスト結果が表示される**
※今回4ケーステストコードを作成したので、実行が「4/4」と表示されています。
また全て期待値通りの結果が返ってきているためエラーが「0」となっています。
右側の緑色のバーは「正常」を意味し、赤色の場合「異常」を意味します。
![スクリーンショット 2023-02-20 0.35.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192922/9ae2fece-4ba9-049d-096e-354d9dfacb77.png)



##  ■最後に
今回はJUnitを使ってFizzBuzzゲームのソースをテストしてみました。
今回テスト結果の判定に使ったメソッド等は、@opengl-8080さんの「[HamcrestのMatchersに定義されているメソッドの使い方メモ](https://qiita.com/opengl-8080/items/e57dab6e1fa5940850a3)」という記事を参考に使ってみました。
Adaptive Cards を React で表示する

[Adaptive Cards](https://adaptivecards.io/) は JSON 形式でカード状の UI コンテンツを取り扱う仕様です。マイナーなフォーマットではありますが、[Microsoft Teams の WebHook](https://learn.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#send-adaptive-cards-using-an-incoming-webhook) でも採用されているので見覚えがある方もいらっしゃるのではないでしょうか。[^1]

[^1]: その他 Outlook の[アクション可能メッセージ](https://learn.microsoft.com/ja-jp/outlook/actionable-messages/)や Cortana さん、Windows タイムラインなどで利用可能ですが、いずれもメジャーになりきれなかったり廃止されたりしています。

Adaptive Cards は Microsoft が主導してはいますがオープンな仕様であり、各種プラットフォームにもライブラリが提供されています。本稿では React 向けのポートである [adaptivecards-react](https://www.npmjs.com/package/adaptivecards-react) をご紹介します。[^2]

[^2]: この他にはバニラ JS 用の [adaptivecards](https://www.npmjs.com/package/adaptivecards) や、サードパーティ製の Vue 2/3 向けポートである [adaptivecards-vue](https://www.npmjs.com/package/@madewithcards/adaptivecards-vue) が存在します。

## デモページ

実際に `adaptivecards-react` を利用したサンプルプロジェクトを用意してみました（React + TypeScript + Vite + SWC）。[^3]

[^3]: 完全に余談ですが、このデモの制作で Vite + SWC パターンを初体験しました。小規模プロジェクトとはいえ噂に違わぬ爆速さ！　で驚いてしまいました。また、GitHub Actions を利用した GitHub Pages へのデプロイもほぼコピー&ペーストで済むよう整備されており、開発者体験の良さが感じられました。今後のプロジェクトでも積極的に採用したいですね。

![adaptivecards-react-example.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463374/b9e385b0-b911-5e2d-b82e-5b6ba9022d73.jpeg)

* [デモページ](https://yokra9.github.io/adaptivecards-react-example/)
* [レポジトリ](https://github.com/yokra9/adaptivecards-react-example)

見ていただければ分かるように、`adaptivecards-react` は React 上に要素を出力するところまでを担当しており、[Fluent UI](https://developer.microsoft.com/ja-jp/fluentui) に則ったデザインが適用されている訳ではありません。Adaptive Cards は配信先のアプリで周囲の環境に適応した UI へ変換されることを期待していますので、React プロジェクト側のスタイルに合わせれば良いでしょう。

## `adaptivecards-react` の使用方法

使用方法は非常に単純で、Adaptive Cards の JSON を `payload` 属性に、フォント等のコンフィグを `hostConfig` 属性に設定するだけです：

```html
<AdaptiveCard payload={card} hostConfig={hostConfig} />
```

注意点として、v1.1.1 時点で `peerDependencies` として `"react": "^17.0.2"` が指定されており、React 18 プロジェクトにはうまく導入できません。本稿の執筆動機は「Adaptive Cards ってオープンな仕様っぽいけど他にはどこで使われてるんだろ～？　おっ React でも使えるじゃん！　試してみよう」くらいのノリです。正式リリースが約一年前の React 18 に非対応となると、実プロジェクトでは採用を迷うべきでしょう。なお、本流の [adaptivecards](https://www.npmjs.com/package/adaptivecards) は継続的にメンテナンスされているようですので、Adaptive Cards を利用したい場合はこちらを使用できます。

## 参考リンク

* [Adaptive Cards](https://adaptivecards.io/)
* [パートナー](https://learn.microsoft.com/ja-jp/adaptive-cards/resources/partners)
* [Schema Explorer](https://adaptivecards.io/explorer/)
* [adaptivecards-react](https://www.npmjs.com/package/adaptivecards-react)
* [npm v7で`ERESOLVE unable to resolve dependency tree Could not resolve dependency:`](https://qiita.com/masato_makino/items/06011fcecc91be583636)
* [他人の Outlook に Adaprive Cards （Actionable Email）を送信する方法](https://qiita.com/MiyakeMito/items/5ffdf4224d179ba98556)
WindowsからGitにSSHで繋がるときに躓いたポイントのメモ

ssh-keygenを使って、公開鍵をアカウントに登録する同時に、Ｗｉｎｄｏｗｓは以下のように~/.ssh/フォルダにあるconfigファイルを書く必要がある：


Host github
  HostName github.com
  IdentityFile #秘密鍵へのパス
  User git


また、Git Bashで作った鍵のペアしか通れないっぽい（？）
WindowsのPowershellで作った鍵ペアはどうしても通れなくて、GitBashで作ったやつは一発で通れた。
Dockerfileを始めよう!

### はじめに
Dockerfile（設計図）を`build`して、Dockerimageを作る。
（Dockerimageを`run`して、コンテナを作る）
**Dockerfileを使えるということはDockerを使えるということ。**

Dockerfileは`INSTEUCTION arguments`の形で記載する。
(INSTEUCTIONに対して、引数を入れる)

### `INSTEUCTION`を見ていこう!
`FROM`ベースイメージをDockerhubから選択する。
 https://hub.docker.com/
(latestは最新版のことで開発するときはバージョンを指定すること、alplineは軽量、これを使うとよい。)
ほとんどのケースではOSをする。

`RUN`ベースイメージの上にレイヤーとして命令を作る。
※Linuxのコマンドを使うにはLinuxのOSがいる。

<details><summary>メンテナンス時</summary>

pakageを追加したとき
また`build`をし直さないといけない。→　また`aptget update` と `aptget install`をしないといけなくなる。

ゼロからビルドすることはないで、時間節約になる。

解決方法：
レイヤーを分けこと、イメージが作成済みならchcheを使う。

最後に：
テストが終われば、レイヤーをまとめること。

</details>

<details><summary>レイヤー</summary>

レイヤーは最小限にしよう!
レイヤーを作るのは`RUN` `COPY` `ADD`
`RUN`が特に問題になる。

例
Ubuntuではaptgetというコマンドでパッケージ管理する。

`apt-get update`
新しいパッケージリストを取得
`apt-get install`
をインストール
`apt-get update`
をしないと古いpakageをインストールしてしまう。

`RUN`でのコマンドは`&&`で繋げることでレイヤーを少なくする。→　imageが小さくなる。
</details>


(`FROM`で指定したイメージの上にコマンドが実行される。)
(リナックスのコマンドを実行するにはリナックスOSのイメージがいる）
このレイヤーで独自のコンテナを作ろう!
`CMD`ここで定義されているコマンドがコンテナを立ち上げた時（docker run）に最初に実行されるコマンド
コンテナ作成時にエントリーポイントに渡す引数、コマンドを指定する


`RUN`イメージからコンテナを作成してコマンドを実行（pythonインストールなど）
`COPY`ローカルからファイルをコンテナ内にコピーする
`WORKDIR`コンテナでの作業用のディレクトリを指定




`ADD` COPYコマンドと同じく、ファイルやディレクトリをホストマシンからコンテナにコピーしますが、自動的にURLからファイルをダウンロードすることもできます。

`ENV` 環境変数を設定します。
`EXPOSE` コンテナが使用するネットワークポートを指定します。
`ENTRYPOINT` CMDと同様にコンテナが起動するときに実行されるコマンドまたはスクリプトを指定しますが、コマンドライン引数を受け取ることができます。
`VOLUME` コンテナ内のディレクトリをボリュームとしてマークし、ホストマシンのディレクトリと永続化することができます

### `RUN`と`CMD`の違い
`CMD`はDockerイメージのデフォルトのコマンドを指定する。
`RUN`はレイヤーを作る。



### 最後に

`docker build .`：ドッカーファイルでなくフォルダごと指定する。
`docker build -t <name> <directory>`：名前を付けてコンテナを付ける。
`docker images`：Dockerimageを確認する。







`docker build` することで、
build contextとしてdocker daemonに渡している。

docker daemonは


DockerはLinuxのOSのコンテナ技術を使っている。
LinuxはUnixOSの派生されたオープンソース。

macはUnixベースだから
macとLinuxのコマンドは似ている

------

`docker ps` 動作中のコンテナを表示
`docker ps -a` 終了したコンテナ含めて、表示
`docker rm <コンテナID>`　指定したコンテナを削除
`docker start <ID>or <名>`コンテナ開始
`docker stop <ID>or <名>` 動作中のコンテナを終了
`docker kill <ID>or <名>`　動作中のコンテナを終了


`docker build -t <タグ名>`　現在のフォルダ上のDockerfileからイメージをビルド。

`docker system prune`　コンテナ全削除
`docker image prune` イメージ全削除
open-graph-scraper で取得した YouTube サムネイル画像とタイトルをブラウザで表示する


## 経緯
[open-graph-scraper](https://github.com/jshemas/openGraphScraper) を使って、YouTube のサムネイル画像とタイトルを取得し、それをブラウザに表示する実装をしました。

その中でハマったところがあったので、これから同じような実装を検討している人の参考になればと思い、書いていきます。

## 開発環境

- Vue3
- Nuxt.js
- TypeScript

## open-graph-scraper はブラウザでの使用がサポートされていない

以下 README 参照

> A simple node module for scraping Open Graph and Twitter Card info off a site.
> Note: open-graph-scraper doesn't support browser usage at this time.

> 翻訳: Open Graph と Twitter カードの情報をサイトからスクレイピングするための単純なノード モジュール。
注:open-graph-scraper 現時点では、ブラウザの使用はサポートされていません。

はい、最初からしっかり README を読んでいれば、ハマらずに済みましたね。
(使い方しか見てなかった。。)

使い方は簡単で、以下のスクリプトに取得したい YouTube の URL を入れてあげれば OK です。

```sample.js
const ogs = require('open-graph-scraper');
const options = { url: 'http://ogp.me/' }; // <= ここにYouTubeのURLをいれる。
ogs(options)
  .then((data) => {
    const { error, result, response } = data;
    console.log('error:', error);  // This returns true or false. True if there was an error. The error itself is inside the results object.
    console.log('result:', result); // This contains all of the Open Graph results
    console.log('response:', response); // This contains the HTML of page
  })
```

README のサンプルは`js`で書かれていますが、もちろん`ts`でも大丈夫です。

ぱっと思いつく実装としては、

1. module として、上記スクリプトを書いて`export`する
2. ブラウザ側のコンポーネントから`import`してボタン要素をクリックしたら実行する
3. 取得したサムネイル画像とタイトルを表示する
   こんな感じをイメージしてました。

で、何が問題なのかというと、`open-graph-scraper`はブラウザでの使用がサポートされていないので、`import`して使おうとすると、build エラーになることです。

`open-graph-scraper`の install は問題なくできるのですが、ブラウザ側で呼び出そうとした瞬間、build すらできなくなりました。
(当初原因わからなく、ここでだいぶハマった)

結論として、Nuxt の [serverMiddleware](https://nuxtjs.org/docs/configuration-glossary/configuration-servermiddleware/) を使うことで、この問題を解決しました。

## serverMiddleware を使用する

使用方法はいたってシンプルです。
今回は`src`ディレクトリ内に`api`ディレクトリを作成して、その中のファイルに API の記述をしていきます。

serverMiddleware の設定は`nuxt.config.ts`に追加します。

```nuxt.config.ts
const nuxtConfig: NuxtConfig = {
  serverMiddleware: ['~/api/index.ts'], // <= 今回ファイル名はindex.tsとします。
}
```

続いて`index.ts`ファイルに API の記述をします。

```index.ts
import express from 'express'
import ogs from 'open-graph-scraper'

const app = express()
app.use()

app.post('/', async (req, res) => {
  try {
    const options = { url: req.body.url }

    await ogs(options).then((data) => {
      const { result } = data
      res.send(result)
    })
  } catch (error) {
    console.log(error)
  }
})

module.exports = {
  path: '/api/',
  handler: app,
}

```

記述はこんな感じで OK です。
あとはブラウザ側で`/api`(今回は POST )を叩けば`open-graph-scraper`が実行され、YouTube のサムネイル画像やタイトル、その他データを取得してくれます。

## まとめ

- `open-graph-scraper`はブラウザ側での使用はサポートされていない
- serverMiddleware を使用し、`open-graph-scraper`を実行することで解決できる

build エラーになる原因に気づいてからは、比較的スムーズに解決できました。
同じような原因で詰まっている方の解決策として、参考にしていただけるとうれしいです。

## 参考資料
[The serverMiddleware property](https://nuxtjs.org/docs/configuration-glossary/configuration-servermiddleware/)
[Nuxtに「serverMiddleware」を設定して、API サーバ的な動きをさせてみた](https://liginc.co.jp/438249)
NeurIPS2022の量子化論文 (1)

# 概要

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

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


# Leveraging Inter-Layer Dependency for Post -Training Quantization

https://openreview.net/forum?id=L7n7BPTVAr3

- 概要：学習ベースPTQの改良
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/56c59028-ff4d-b519-4931-8185aac38676.png)
- 新規性：Network-wiseなPTQで、過学習と離散最適化の課題を解決する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/709c1ab3-636e-09fc-15a6-641531489fae.png)
- キモ：(1) Activationの正則化を入れる。(2) Activationのロスをアニーリングで連続緩和する。
- 評価：4bit以下、ImageNetで実験した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/44f262d6-8cf0-c522-21f2-7a4a6cb0744b.png)


# Outlier Suppression: Pushing the Limit of Low-bit Transformer Language Models

https://openreview.net/forum?id=yW5zeRSFdZ

- 概要：Transformerの量子化
- 研究機関：SenseTime
- 新規性：量子化時のOutlierの課題に対して、LayerNormがOutlierを増幅することを見つけた。
- キモ：LNで$\gamma$倍するのをやめる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/d1725375-cae6-9801-5839-905310ed8b40.png)
- 評価：GLUEで評価した。


# XTC: Extreme Compression for Pre-trained Transformers Made Simple and Efficient

https://openreview.net/forum?id=xNeAhc2CNAl

- 概要：XTC. NLP向け低ビット量子化
- 研究機関：Microsoft
- 新規性：効率的に量子化するパイプラインを提案
- キモ：従来の方法だとバイナリ量子化では事前学習が学習不十分。レイヤを減らしたりビット量子化したりすると大きく軽量化できることを示した。
- 評価：GLUEで評価した。


# Q-ViT: Accurate and Fully Quantized Low-bit Vision Transformer

https://openreview.net/forum?id=fU-m9kQe0ke

- 概要：Q-ViT
- 新規性：ViTのフル量子化
- キモ：ViTのQATの精度劣化は、Attentionの情報劣化による。
Information Reactive Module (IRM) とDistibution Guided Distillation (DGD) で学習。
IRMはAttentionのエントロピー最大になるように決める。DGDは、レイヤ、ヘッド毎に蒸留する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/cf678796-67be-fdbd-125a-e0ba2c806a5b.png)
- 評価：DeiTやSwin Transformerで実験した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/f5a78392-5ae7-e885-b59b-9b962c627329.png)
VSCodeのコンソールを開く時にpyenvのエラーが表示される

心当たりはないのですが、いつからかVSCodeのターミナルを開くたびに最初にエラーが発生するようになっていたので対応しました。

## エラー内容

```
pyenv: shell integration not enabled. Run `pyenv init' for instructions.
```

## 解決法

以下を`.zshrc`に追加
`eval "$(pyenv init -)"`

以下参考にしました

https://stackoverflow.com/questions/71594920/vscode-pyenv-not-integrated
Android StudioでRunしようとすると、Error: Please select Android SDKと表示される

Android StudioでRun（実行）をすると、「Error: Please select Android SDK」と表示されてしまった場合の対処方法です。私は`Clean Project`で解決しました！

## クリーン/リビルド
- `Build > Clean Project` の実行
- `Build > Rebuild Project` の実行

## Sync Project with Gradle Files
- `File > Sync Project with Gradle Files` の実行
Python で ツイキャスAPI の OAuth認証 をした

ツイキャス公式でPHPとRubyのサンプルソースはあるのだが、Pythonしかわからないので自分で作ってみた。

HTTPリクエストのPOSTメソッドには、urllibライブラリを使う。
HTTPリクエストヘッダーに```application/x-www-form-urlencoded```を指定するので、パラメータはURLエンコードしなければならない。この辺で結構つまづいた。


## 引用資料

### 開発API - ツイキャス

https://twitcasting.tv/indexapi.php

### TwitCastingのAPIv2ドキュメント

https://apiv2-doc.twitcasting.tv/



## 環境

+ Python 3.11.1 64-bit



## アプリケーションの登録

ツイキャス公式サイト[開発API](https://twitcasting.tv/indexapi.php)ページに準じて、アプリケーションを登録する。

> 開発の流れ
> 
> まず、開発者向けページからアプリケーションを登録します。CreateNewApp から必要な情報を入力して、Createします。

[開発者向けページ](https://twitcasting.tv/developer.php)へアクセスする。
ログインを求められたらログインする。

Create New Appを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630831/eb99a5d8-9329-3111-7108-644826900e93.png)

Name,Descriptionは適当で良い。
Callback URLには```http://localhost:8000/```を指定する。
Createを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630831/76af1171-bc33-58a2-d84e-05e362ebfa35.png)

登録が完了したら、ClientID, ClientSecretが発行される。



## ブラウザで連携アプリの許可

[APIドキュメント](https://apiv2-doc.twitcasting.tv/#authorization-code-grant)に準じて、ブラウザでアプリ許可を得る。

>Step1
>
>以下のURLにブラウザでアクセスし、アプリ許可確認画面で「連携アプリを許可」または「キャンセル」を選択します。
>URL
>```https://apiv2.twitcasting.tv/oauth2/authorize?client_id={YOUR_CLIENT_ID}&response_type=code&state={CSRF_TOKEN}```


```{YOUR_CLIENT_ID}```の部分を上記で取得したClientIDに読み替える。
```{CSRF_TOKEN}```は不要なので```&state=```以降を削除した。

例）ClientIDが```AAA```の場合は以下のようになる。

```
https://apiv2.twitcasting.tv/oauth2/authorize?client_id=AAA&response_type=code
```

このURLをブラウザのアドレス欄に貼り付けて移動する。

連携アプリを許可を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630831/6638b8ab-ab24-131a-50bf-cc90b5537c0c.png)

ブラウザでエラー画面等が出るが、気にせずアドレス欄のURLをコピーする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630831/6405fdb3-03e2-c546-4437-7c2bfa424a8f.png)

アドレス欄のURLは以下のようになっている。

```http://localhost:8000/?code={CODE}```

codeパラメータが取得できた。



## アクセストークンの取得

[APIドキュメント](https://apiv2-doc.twitcasting.tv/#authorization-code-grant)に準じて、OAuth認証でアクセストークンを取得する。

>Step2
>許可後にコールバックに渡された code パラメータを使用してユーザのアクセストークンを取得します。

```{CODE}``` ```{YOUR_CLIENT_ID}``` ```{YOUR_CLIENT_SECRET}```はそれぞれ上記で取得したものに読み替える。

```py:get_access_token.py
import json
import urllib.request
import urllib.parse

url = 'https://apiv2.twitcasting.tv/oauth2/access_token'
headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
}
params = {
    'code': {CODE},
    'grant_type': 'authorization_code',
    'client_id': {YOUR_CLIENT_ID},
    'client_secret': {YOUR_CLIENT_SECRET},
    'redirect_uri': 'http://localhost:8000/',
}
data = urllib.parse.urlencode(params).encode('utf-8')

req = urllib.request.Request(url, data=data, headers=headers, method='POST')
with urllib.request.urlopen(req) as res:
    data = json.load(res)
print(data)
```

```py:結果
{'token_type': 'Bearer', 'expires_in': 15552000, 'access_token': 'BBB'}
```

アクセストークンを取得できた。

有効期限は180日間となっていた。

なお、アクセストークンを再度取得しようとすると404エラーとなる。
メモし忘れた場合などは、[開発者向けページ](https://twitcasting.tv/developer.php)からClientIDを再発行してやり直せば良い。
S3のGetObjectでAccess Deniedがでる

## 原因

存在しないパスのオブジェクトを取得しようとすると、403 Access Deniedが出る

## ひとこと

権限が無い場合とエラーメッセージが同じなので、とても紛らわしい・・・
権限に問題があると思い調べていたので結構ハマりました :sob:
TypeScript: Union型はあまりに複雑な型は表現できない

# せつめい
人間から見るとそんなに複雑ではないように見える定義でも、結果的に膨大な量の列挙になってしまうような型を定義しようとするとエラーになるようです。

## エラーになったコード
`#FF8800`というようなカラーコードを表現する型を定義しようとしたのですが、ムリでした。
どうやら、`#000000`～`#FFFFFF`の16,777,216‬個ぶんすべての型を単純に結合したUnionを定義することになってしまうようです。
（…カラーコードの横に自動で色が表示されてる！？）
```ts
type NumChar1 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
type HexChar1 = NumChar1 | "a" | "b" | "c" | "d" | "e" | "f";
type HexChar2 = `${HexChar1}${HexChar1}`;
type ColorCode6 = `#${HexChar2}${HexChar2}${HexChar2}`;  // エラーになる
type ColorCode3 = `#${HexChar1}${HexChar1}${HexChar1}`;  // エラーにならない
```
```:tscで出力されるエラー
test.ts:5:19 - error TS2590: Expression produces a union type that is too complex to represent.

5 type ColorCode6 = `#${HexChar2}${HexChar2}${HexChar2}`;
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
```:VSCode上のポップアップ1
type ColorCode6 = any
```
```:VSCode上のポップアップ2
type HexChar2 = "dd" | "aa" | "ab" | "a0" | "a1" | "a2" | "a3" 
| "a4" | "a5" | "a6" | "a7" | "a8" | "a9" | "ac" | "ad" | "ae" 
| "af" | "ba" | "bb" | "b0" | "b1" | "b2" | "b3" | "b4" | "b5" 
| "b6" | "b7" | ... 228 more ... | "ff"
式は、複雑すぎて表現できない共用体型を生成します。ts(2590)
```
なお、`#F808`の4ケタまでならなんとか大丈夫みたい。5ケタからエラーになります。
```ts
type ColorCode4 = `#${HexChar1}${HexChar1}${HexChar1}${HexChar1}`;
```
```:VSCode上のポップアップ
type ColorCode4 = "#2343" | "#aaaa" | "#aaab" | "#aaac" | "#aaad" 
| "#aaae" | "#aaaf" | "#aaa0" | "#aaa1" | "#aaa2" | "#aaa3" 
| "#aaa4" | "#aaa5" | "#aaa6" | "#aaa7" | "#aaa8" | "#aaa9" 
| "#aaba" | ... 65517 more ... | "#9999"
```

## 今回の対処法
先頭に`#`がついてる`string`はぜんぶカラーコード扱いにすることで妥協しました（かなしみ）
```ts
type ColorCode = `#${string}`;  // #[0-9a-f]{6} だとエラーになる
const notColorString: ColorCode = "######🤪🤪🤪";  // 特にエラーにならない
```


# 参考ページ
https://typescriptbook.jp/reference/values-types-variables/union

https://stackoverflow.com/questions/42584228/how-can-i-define-a-type-for-a-css-color-in-typescript
debug, irb gem は最新の Ruby にしなくても使える

[irb](https://rubygems.org/gems/irb/), [debug](https://rubygems.org/gems/debug) gem は Ruby の標準ライブラリですが、それ単体で Rubygems からインストールすることができます。なので、最新の Ruby でなくても、以下のコマンドで最新の irb, debug gem を利用することが可能です。

```console
$ gem install irb debug
```

Bundler を利用している場合は以下の方法でインストールします。

```console
$ bundle add irb debug # お好みで --group "development, test" をつけると良いです
```

(※ debug gem は bundled gem のため、 そもそも Bundler で利用する場合は Gemfile に書く必要があります)

## debug, irb は近年のアップデートでかなり便利になってきたのでおすすめ

debug, irb は近年のアップデートで大きな改善、開発がされており、 (VSCode からのデバッグ、シンタックスハイライト等) 非常に便利になっています。おすすめです。

https://techlife.cookpad.com/entry/2021/12/27/202133

https://techracho.bpsinc.jp/hachi8833/2023_01_16/126191

https://k0kubun.hatenablog.com/entry/2021/04/02/211455


これらは Ruby のアップデートの話とセットで語られることが多いため、最新の Ruby に更新しないと利用できないとうっかり勘違いすることもあるかもですが、単体で gem として配布されているため、対応バージョンであれば単体でインストールすることができます。 (自分も恥ずかしながら勘違いしてました。。。)

## Ruby の標準ライブラリは殆どが gem 化されている

irb や debug gem に限らず、Ruby の標準ライブラリはその殆どが Default gem や Standard gem として gem 化されています。

どの標準ライブラリが gem 化されているか、 Ruby の各バージョンにどのバージョンが添付されているかなどは、以下のページに掲載されています。

https://stdgems.org/

(また、 https://bugs.ruby-lang.org/projects/ruby/wiki/StdlibGem で gem 化の動機などがまとめられています)

Default gems や Standard gems に関しては以下の記事に詳しく解説されています。 :information_desk_person: 

https://blog.agile.esm.co.jp/entry/2021/01/27/192030

https://zenn.dev/shuichi/articles/bundled-gem-with-gemfile
Fortranの基本配列順序（メモするまでもないが）

本当に基礎的なメモ。

Fortran の配列は（C と逆という覚え方がよいかどうかはわからないが）先の添字が速く回る。

```bash:
$ cat try.f
      integer:: a(2,2)
      a(:,1)=(/1,2/)
      a(:,2)=(/3,4/)
      open(10,form='UNFORMATTED',access='STREAM')
      write(10) a
      end
$ gfortran try.f
$ ./a.out
$ od -td fort.10
0000000           1           2           3           4
0000020
$
```
Laravel9 でLaravel BreezeでCSSが効いてない

### Laravel Breezeのインストール時のメモ

##### ViteのCSSが適用されない

**前提**

MIXを使っている訳ではない。

BreezeをインストールしたらLogin画面でCSSが効いてない。（LaravelのLogo画像が巨大化）

##### 解決策（結論）

*vite.config.jsを修正する*

server:

​			host=’IPアドレス　V4形式で指定して



を追加して「npm  run  dev」を実行

vite.config.jsサンプル：

```
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    host: '192.168.0.xxx',
  },
  plugins:[
    vue(),
    laravel({
        input: [
            'resources/css/app.css',
            'resources/js/app.js',
        ],
    
        refresh: true,
    })
]
})

```

※上記例はvueも使えるようになってます。

##### 原因

FireFoxの開発ツールで見てみると、IPV6の形式になっている。以下

```
GEThttp://[::1]:5173/@vite/client
GEThttp://[::1]:5173/resources/css/app.css
GEThttp://[::1]:5173/resources/js/app.js
```

なので、vite.config.jsを修正して　npm  run  dev でサーバーを再起動し、同様にFireFoxでソースを確認（画面はもうCSSがあたっているが）

```
GEThttp://192.168.0.XXX:5173/@vite/client
GEThttp://192.168.0.XXX:5173/resources/js/app.js
GEThttp://192.168.0.XXX:5173/resources/css/app.css
GEThttp://192.168.0.XXX:5173/resources/js/bootstrap.js
```

※「XXX」は実際のIPアドレスの第4オクテットってやつです。

⇒画面はCSSがあたった状態正しいと思われる状態になりました。

##### 途中経過

vite.config.jsの server: {
    host: '192.168.0.xxx',
  },

ここを”0.0.0.0”にとするサイトもありましたが、FireFoxの開発ツールでみるとソース上はIPV4形式でポート5173を見に行くソースにはなっているが当然、リンク先のCSSファイル取得できず。

CSSが読み込まれない現象は解消されません。

（⇒勉強不足ですが理屈ではなく、実をとってこれで解決。それでいいのか？）

尚、IPV4の第４オクテットに指定したIPは当該のマシンに振ってある固定IPと同様のIPを振っています。下記画像は、「npm run dev」した際の応答結果です。
黒消ししていますが第4オクテットは当該マシンの固定IP5137ポートです。
一方「→APP＿URL：`http://192.168.0.XX`”」はなぜか、当該マシンのIPアドレスの第四オクテットの数字+1で起動しています。（理由は不明です。）

![viteserver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192917/f305ff73-b594-2171-bb6e-d4d5c805cf7f.png)

取り敢えず今回はここまで
2023/02/23
GitHub CodespacesでArduinoデバイスのリモート開発を行う

Webアプリでは、コンテナー技術で環境を整えるのがとても楽なCodespaces。

最近はWebアプリだけでなく、LED照明や鍵のコントロールも統合して行いたいためデバイスプログラミングも行っています。

codespacesをVScodeで動かした場合、画面はローカルに見えますが、実態はクラウド上にあるため、シリアル通信はできません。

そのため少し仕掛けが必要です。
ArduinoIDEは使えないため、PlatformIOを使います。

coodespacesで拡張機能でPlatformIOをインストール。
デバイスを使うローカルにはpythonとPlatformIO CLIをインストール。


https://asukiaaa.blogspot.com/2020/05/platformio-remote.html
こちらを参考にしました。

デバイスをリモートでスタートさせます。
```
> pio remote agent start
```
PlatformIO画面にリモートがあるのでこちらでUploadすればOK
![スクリーンショット_20230223_173309.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157360/03e2dec3-3c30-68cf-ee16-f801f0fafcd3.png)

```
pio remote device monitor
```
でシリアルモニターも見れます。すごい！！
![スクリーンショット_20230223_173734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157360/4a151b64-af0f-5542-cce6-ca2464e4a5e8.png)
【 Python 】QRコードを作成する

<h2>はじめに</h2>
当記事は、プログラミング初心者である筆者の備忘録となります。<br>
間違い等ありましたら、ご指摘ください。


<h4>〜流れ〜</h4>
<h6>①ライブラリのインポート</h6>
<h6>②QRコード生成コードの作成</h6>


<h2>①各種ライブラリを使うためインポートを行う。</h2>
・テキストボックスやボタン作成のため<font color="LimeGreen">「streamlit」</font><br>
・QRコードを作成するため<font color="LimeGreen">「qrcode」</font><br>
・画像を出力するため<font color="LimeGreen">「Image」</font>

```script.py
    import streamlit as st
    import qrcode
    from PIL import Image
```

<h2>②QRコード生成コードの作成</h2>

```script.py
#「タイトル」の設定
st.title('QRコード作成アプリ')

#テキストボックスに入力された内容をURLという「変数」に代入
URL = st.text_input('変換URL入力')

#URLをQRコードに変更
#QRコードをローカルに保存
#ローカルに保存したQRコードを「img」に代入
#st.imageでQRコードを出力
if st.button("QRコード生成"):
    _img = qrcode.make(URL)
    _img.save('qrcode.png')
    img = Image.open('qrcode.png')
    st.image(img)
```
javascriptのサンプル

どうもミックです。IT系に転職を考えています。
今は勉強を始めて3ヶ月になります。
今はjavascript,phpを主に勉強しているので今やってることを記事に書いていきます。独学なのでコードは下手くそなのでご了承ください。
udemyのjavascriptのコースを勉強してみた。

```html:index.html
<body>
  <div class="container">
    <div class="panel active" style="background-image: url('https://images.unsplash.com/photo-1624138784614-87fd1b6528f8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2066&q=80');">
      <h3>Explore The World</h3>
    </div>
    <div class="panel" style="background-image: url('https://images.unsplash.com/photo-1629259634957-e32a0c5c4f47?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1469&q=80');">
      <h3>Explore The World</h3>
    </div>
    <div class="panel" style="background-image: url('https://images.unsplash.com/photo-1598298388182-76077d53c943?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80');">
      <h3>Explore The World</h3>
    </div>
    <div class="panel" style="background-image: url('https://images.unsplash.com/photo-1545251142-f32339076e6d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80');">
      <h3>Explore The World</h3>
    </div>
    <div class="panel" style="background-image: url('https://images.unsplash.com/photo-1606503391282-df793e79b892?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80');">
      <h3>Explore The World</h3>
    </div>
  </div>
</body>
```

```css:style.css
* {
  box-sizing: border-box;
}

body {
  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

.container {
  display: flex;
  width: 90vw;
}

.panel {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  height: 80vh;
  border-radius: 50px;
  color: #fff;
  cursor: pointer;
  flex: 0.5;
  margin: 10px;
  position: relative;
  transition: flex 0.7s ease-in;
}

.panel h3 {
  font-size: 24px;
  position: absolute;
  bottom: 20px;
  left: 20px;
  margin: 0;
  opacity: 0;
}

.panel.active {
  flex: 5;
}

.panel.active h3 {
  opacity: 1;
  transition: opacity 0.3s ease-in 0.4s;
}

@media(max-width: 480px) {
  .container {
    width: 100vW;
  }

  .panel:nth-of-type(4),
  .panel:nth-of-type(5) {
    display: none;
  }
}
```

```javascript:script.js
const panels = document.querySelectorAll('.panel');

panels.forEach((panel) => {
  panel.addEventListener('click', () => {
    removeActiveClasses()
    panel.classList.add('active')
  })
})

function removeActiveClasses () {
  panels.forEach( panel => {
    panel.classList.remove('active')
  } )
}
```

画像をクリックすると大きく広がるモーションになっています。

参考文献
>https://unsplash.com/
>udemy
神クラスを利用する

# 神クラスというか邪神クラス
神クラスというプログラミングにおけるアンチパターンがあります。全体で使えるユーティリティクラス(神クラス)などを作ってしまうと、様々なところからアクセスされるようになってしまいます。その結果、神の気まぐれ(仕様変更)によって発生する影響範囲が大きくなって大変なことなってしまうというものです。
疎結合に違反する状態になってしまうアンチパターンです。

詳しくは、有名なアンチパターンなのでネットで調べてみてください。

**まさに極悪、世界を破壊する邪神だ！神を作るな！神を滅ぼせ！**

# 生まれたときは心優しき神だった
神クラスは、本当に作ってはいけない存在なのでしょうか？神クラスは誕生したときには、すべての願いに答えてくれる素晴らしい存在でした。神クラスさえ理解すれば実装できるので幸福な状態だったはずです。

**神を信じましょう。神が我々を幸せにしてくれる**

# 優しき神は邪神へ変わる
神クラスは、とてもやさしいクラスです。誰からの願いもかなえようと姿を変えていきます。神クラスはどんどん願いを叶えていくと、次第に最初の願いを裏切るような願いを叶えてしまいます。その結果、神に裏切られた人が増えていき憎しみを抱き邪神扱いされてしまったのです。

**神は私を裏切った。だからあなたは、邪神なのだ。**

# 神を分化させる
我々は神クラスすら作り出せる改変させる創造主であることを忘れてはいけません。神が幸福をもたらしている間は１つの神に任せ、あなたが願うときに邪神となるならその時に神を分化させてしまえばいいのです。
分化した神は、またそれぞれに幸福をもたらすでしょう。

**太陽の神は大地を暖め、雨の女神は日照りを潤す**

# 神は新たな名を得る
神クラスを分化させたら、そこにはもう元の神クラスは存在していません。それぞれの神クラスに新しい名前を授けましょう。名前は神クラスの力を理解させてどの神クラスに願えばいいかわかりやすくなります。

**神を崇めよ！神を利用せよ！あなたこそが神なのだから！**

:::note info
要約：神クラスもリファクタリング前提で作れば悪くないんじゃないか？というお話でした。
:::
新卒が１か月でAWSクラウドプラクティショナーを取得した勉強法

## この記事のまとめ
* 試験対策本を買って一冊勉強すれば600-700点は保証される
* 問題慣れは多少必要
* 勉強に飽きてきた頃に資格試験を受けるといい感じ

## 背景
* 新卒一年目、新人研修が終わり、配属前に資格取っておくかなぁというテンションで勉強開始
* 基本情報処理の資格を入社前に取得済
* 学生時代は生物系。ITの知識は基本情報ぐらい  

## 資格習得までの時間
* 約20時間
* 約一か月


## 勉強法
1. 試験対策本を一冊読み込みました。
2. 問題集を一通り解きました。

### 1. 試験対策本を一冊読み込む
以下の本が大大大おすすめです。 というか、正直**これ一冊で試験対策は十分**。

[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403)

### 2. 問題集を一通り解く
以下の問題集を解きました。  
(~~Udemyで1800円程ですが、それだけの価値があるかは微妙、、、~~）

[この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（8回分520問）](https://www.udemy.com/course/aws-4260/) 

八回分ありますが、正直**1-2回分で十分**だと思います。  
AWSの試験は問題文の用語が独特で、理解するのにある程度慣れが必要です。

> (7) システム管理者がユーザーの AWS Management Console にログインセキュリティレイヤーを追加するには、どう
すればよいですか。<br>  
  A) Amazon Cloud Directory を使用する。  
  B) AWS Identity and Access Management (IAM) ロールを監査する。  
  C) Multi-Factor Authentication (MFA) を有効化する。  
  D) AWS CloudTrail を有効化する。  

こんな感じの文章が十分理解できる位になれば十分です。  
ただ正直、試験対策本についてくる問題集でも十分かなという印象。。  
問題を見て、理解が足りない部分を再勉強するのがいいかなと思います。ここまで勉強すれば、十分合格は出来ると思います。

## 試験の心得
試験場でテストを受ける際の心構えのようなものがいくつかあるので、参考になればと思います。　　
* **問題文の意味が分からなかったら英語文に切り替える**  
  →たまにすごく分かりにくい文章が出てきたりする。その場合は英語と日本語を照らし合わせて内容を理解するのが吉。

* **大抵時間が余るので、分からなかったら後で確認するフラグをつけて、すぐ飛ばす**  
→基本70分くらいで解き終わってしまう。問題も分かるか、分からないかなので、あまり考える余地がない。長時間で疲れるので、分からなかったら積極的に飛ばそう。
* **試験終了後のアンケートは帰りたくても焦らない。**  
→アンケート後に合格の発表がある。(2022年8月時点)試験で疲れていると飛ばしてしまうことがあるので注意。（見逃すと、２-３日後にメールで車でで待たないといけない。）

## さいごに
ネットでは１０時間で受かっている人もいますが、基本的に一夜漬けなどはお勧めしません！普通に難しいです。（ギリギリ合格だった。。。）  
かといって、がっつり勉強するなら上位資格のAWS ソリューションアーキテクトアソシエイトを勉強する方がおすすめなので、20時間を目途に一度受けてみてください。いつでも受けられる試験なので！Good Luck!
Pull Reqに最新のmain branchを反映してって言われたら

pull reqを上げたら、reviewから「コードは良さそう！最新のmain branchだけ反映しといて」って言われて「？？？」となった人向けの解説記事です。

チームで日々開発してきてGitに慣れている先輩目線だと当たり前になってしまい、説明すらしないことが多いですが、開発初心者やこれまでチームでの開発をしてこなかった開発者は混乱することも多いと思うので、書いておきます

## branchが「遅れてる」ってどういうこと？

チーム開発では複数の開発者が同時に開発します。しかし、同時に開発を行うと同じファイルを別々の開発者が変更したかった時など不都合が生じます。
そこでGitを使って、branchを分けて開発することで互いを意識することなく開発できるわけです。

この時に、main branchにすでに反映されている変更（コミット）が自分のbranchに反映されていない時に「遅れている」というわけです。

実際の開発の各段階でGitがどういう状態にあるのか？を整理していきましょう。

自分のlocal PCを`my local`、他の開発者のlocal PCを`their local`と言いましょう。
最初は、`remote`（GitHubなど）から`git clone`してくることで、`my local`・`their local`共に、main branchが作られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/65cd5bca-0071-aea5-a320-05ab077750e6.png)

それぞれのlocal PCでbranchを切り、そのブランチで開発を行いコミットしていきます。
（自分は`my-feat`というbranch、他の開発者は`their-feat`というbranchを作ったとします）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/5c28f9e3-5fa0-606a-f8ab-014f99e454c4.png)

それぞれ開発が完了したので`git push`して、それぞれの変更を`remote`にuploadしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/ad2fc488-9ab3-958a-bd2c-6a172b75408c.png)

このタイミングではまだ`remote`の`main` branchには何も変更がないです。
ここで、それぞれの変更を`main` branchに取り込むために、`their-feat` branchと`my-feat` branchからpull reqが作られます。

さて、自分のpull req（`my-feat`→`main`）がmergeされる前に他の開発者のpull req（`their-feat`→`main`）がmergeされたとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/6f256453-9989-fe63-2dcf-e2143dea68b0.png)

ここで、`main` branchに新しく作られたcommitは`my-feat`には存在していません。これが「branchが遅れている」という状態です。

この状態だと、自分のpull req（`my-feat`→`main`）はmergeできたりできなかったりします。他の開発者が同じ箇所を変更している場合などはconflictが発生して、mergeできません。
また、チームの方針として必ずmain branchを反映してからmergeするというルールになっていることも多いと思います。

そこで「最新のmain branchを反映しといて」って言われるわけです。

## 最新のmain branchを反映する方法

まず、自分のlocal PCにmain branchの最新の状態を持ってくる必要があります。
`git fetch`コマンドでdonwloadしてきましょう。
```shell
$ git fetch
```

すると、`origin/main`というbranchにremoteの`main`の最新の状態が反映されます。

参考： [【初心者向け】git fetch、git merge、git pullの違いについて](https://qiita.com/wann/items/688bc17460a457104d7d)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/4d9f91e2-7abb-52a9-0c5a-d123c0fa388f.png)

次に、この`origin/main` branchをlocalの`my-feat` branchにmergeしていきます。

```shell
$ git merge origin/main
```

（もし`my-feat` branchにいない場合は、最初に`git checkout my-feat`しましょう）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/77469b65-95b7-47b2-3228-7c29f8f4ebb5.png)

`my-feat` branchの先頭にorigin/mainをmergeしたcommitが作られます。

ここで、`my-feat`をremoteにpushしてあがれば、remoteの`my-feat` branchに最新の`main` branchが反映されました。

```shell
$ git push origin my-feat
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109543/82961e86-e449-d56d-de9b-c7b03d3487eb.png)

こうなれば、`main` branchへのpull reqをmergeできるようになります。