OmniAICreator/Qiita-1.07M huggingface dataset:
Googleデジタルマーケティング＆Eコマース：YouTube広告

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

# 2種類のYouTube広告

毎日何百万もの動画がアップロードされる動画共有プラットフォームYouTubeは、ブランドにとって世界中の様々な視聴者にリーチする絶好の機会を提供しています。

YouTubeに広告を出すことのメリットについて学ぶ前に、YouTubeには2種類の広告があることを知っておくことが重要です。

- ディスプレイ広告
- TrueView広告

### 1.ディスプレイ広告

ディスプレイ広告は、Webサイトやアプリケーションに配置された視覚的な広告フォーマットです。彼らは、ディスプレイキャンペーンを使用してGoogle広告で作成された静的な広告です。

ディスプレイ広告は、Webサイト、ビデオ、およびアプリのグループであるGoogleディスプレイネットワークを使用しています。

YouTubeでは、これらの広告は、ストリーミングビデオの横に表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/01109994-909c-101c-e727-0edcad5b640d.png" width="700">

### 2.TrueView広告

一方、TrueView広告とは、動画広告のことです。誰かが閲覧することを選択した場合にのみブランドが支払いを行います。これらの広告もGoogle広告で管理されますが、広告主はキャンペーンを作成する前に、まずYouTubeチャンネルに動画をアップロードする必要があります。

動画広告をブランドのチャンネルにアップロードした後、さまざまな異なる広告フォーマットの中から選択することができます。

- スキップ可能な動画広告
- スキップ不可能な動画広告
- オーバーレイ広告
- インフィード広告

などです。

#### <font color="MediumBlue">スキップ可能な動画広告</font>

スキップ可能な動画広告では、視聴者は5秒後に広告をスキップすることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/ced3c1cf-04f9-d3de-b226-243da561b35e.png" width="700">

#### <font color="MediumBlue">スキップ不可能な動画広告</font>

スキップ不可の動画広告は、動画を視聴する前に視聴する必要があります。彼らは、地域の基準に応じて、15〜20秒の間に実行されます。スキップ不可の広告のサブカテゴリは、バンパー広告です。

#### <font color="MediumBlue">画像広告やテキスト広告のオーバーレイ</font>

オーバーレイ画像広告またはテキスト広告は、動画の下部 20%の部分に表示されます。他のTrueView広告とは異なり、オーバーレイ広告はコンピュータでのみ表示され、モバイルデバイスでは表示されません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/443af962-b848-5072-d614-1fcb0313e316.png" width="700">

#### <font color="MediumBlue">インディスプレイ広告</font>

インディスプレイ広告は、YouTubeの検索結果で、関連するトピックの動画クエリに表示されます。この広告には、動画のサムネイル、タイトル、説明が含まれます。ウェブページのリンクの代わりに動画が表示される検索広告とお考えください。選択すると、他のビデオとは別に、フルで視聴することができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c746c917-1d92-02a9-92c9-1c4098f45815.png" width="700">

# YouTubeでの広告掲載のメリット

#### <font color="Darkcyan">安価である</font>

動画広告の制作費は企業によって異なりますが、YouTube広告は比較的安価に運用することができます。YouTubeの広告は、ペイ-パー・ビュー、またはペイ-パー・クリックのモデルで実行されます。これは、特定のアクションが実行されるまで、ブランドは広告のために支払う必要がないことを意味します。

平均して、これらの広告は、ビューまたはアクションごとに0.10〜0.30ドル（米ドル）の費用がかかります。正確なコストは、視聴時間、視聴者ターゲット、キャンペーンの目的などの要因に依存します。低コストは、低予算のブランドや、多くの広告を制作しようとする高予算のブランドにとって有用です。

#### <font color="Darkcyan">視聴者にリーチする</font>

YouTubeは、ブランドや製品に関連するトピックを検索しているさまざまな視聴者にリーチする機会を提供します。ブランドは、特定のトピック、キーワード、または人口統計を使用して顧客をターゲットにすることができます。

また、ブランドの動画は、他の動画の提案された動画フィードに表示することができます。つまり、関連する視聴者が見る人気のある動画に広告を表示することができます。


#### <font color="Darkcyan">YouTube広告の効果</font>

多くの視聴者がいれば、視聴者があなたのブランドと対話する機会も増えます。実際、広告を見た人は、その広告の背後にあるブランドと関わりを持つ可能性が10倍高くなります。これは、ブランドの認知度向上と販売促進には最適です。
CGRectについて簡単にまとめてみた

## CGRectとは
- 長方形の位置とサイズを保持する構造体である。
    - [こちらの記事](https://capibara1969.com/2712/)にてプロパティや構造体について分かりやすく記載されています
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915639/8cf89fd1-c3a8-73cc-6895-3bab13f8d5ee.png)


## ソースコード
- CGRectを用いて、適当な位置とサイズにボタンを配置 
    - 座標の基準は長方形の左角 
```swift:Swift
//ボタンの位置とサイズを下記の位置とサイズに編集
rectTestButton.frame = CGRect(x: 20, y: 150, width: 200, height: 100)
```
![Simulator Screen Shot - iPhone 14 Pro - 2023-03-05 at 20.59.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915639/300255a7-03ad-6016-52a9-f4d16a1b1178.png)



- ボタンを画面いっぱいに広げる
```swift:Swift
//xとyが0以上のとき、指定したView分のwidhやheightは固定されるが、x座標とy座標は動く
rectTestButton.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
```
![Simulator Screen Shot - iPhone 14 Pro - 2023-03-05 at 20.59.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915639/c54f610d-535c-6c5a-948c-a643d8154722.png)



## おわりに
記事に誤り等ございましたらコメント欄にてご指摘ください。
## 参考記事
[CGRect | developer apple documentation](https://developer.apple.com/documentation/corefoundation/cgrect)

[【Swift】CGRectの使い方
](https://capibara1969.com/2712/)

[【Xcode/Swift】端末の画面サイズ(ポイント)や解像度(ピクセル)、倍率(スケール)を取得する方法](https://ios-docs.dev/screensize/)
## 開発環境
- Xcode-13.4.1
- Swift version 5.7
【Unity】VRMモデルの視線を動かそうとしたけど動かない！ってなった話

VRMのブレンドシェイプで表情を変えられるが、目（瞳）の位置は変えられない。
何もしなければ正面を向いたままである。

作っているゲームの都合でどうしても目を特定方向に向かせたいのだけど、ブレンドシェイプじゃダメ。
じゃあ考え方を変えて、指定した物（位置）を見るようにすればいいのでは？
ググってみたら視点の指定はUniVRMに最初からある機能でした。
VRM Look At Headコンポーネントを使えばいいらしい。

・参考：VRMモデルの視線制御（目の可動範囲）の設定方法
https://qiita.com/OGOG_Ogura/items/46a1f82553c5f6501636

で、やってみたところ動きませんでした。
なので何となく対象のモデルのAnimator Controllerを外してみたら、視線が動くようになりました。

アニメーションに問題があるのかと思って、ヒューマノイドに適用する際の設定にある目のボーン指定を外してみたけど、それは関係無いらしい。（UniVRM以外のVRMモデルは知らないけど）
ググっても特に情報は無く、最終的にUniVRMのGitHubにバグとして投げてやろうかなとか考えていたところ、既にそういった質問は投げられていたらしい。
で、解決策も書かれていました。

・VRMLookAtHead and VRMLookAtBoneApplyer should prioritize over animator #612
（Google訳：VRMLookAtHead と VRMLookAtBoneApplyer はアニメーターよりも優先する必要があります）
https://github.com/vrm-c/UniVRM/issues/612

で、その中にこの投稿が。
「Animator overwrite all Transform between update and lateUpdate.Please try use lateUpdate.」
（Google訳：Animator は update と lateUpdate の間のすべての Transform を上書きします。lateUpdate を使用してみてください。）

というわけで、VRM Look At HeadのUpdate Typeを「Late Update」に変更したところ、Animator Controllerとかは関係なくちゃんと視線が動くようになりましたとさ。

これで半日潰れた。
【その１】RPA初心者と歩むPower Automate活用日記【ポイ活】

無料で使用できるPower Automateを何かに活用しながら学びたい。
ただ、学び目的だけでは飽きが来る。

そこで遊び心を持ちながら、学ぶため
なにかユニークな題材を自動化させようと考えた結果

自動でポイ活を行わせてみよう　に至る。

※本記事は初回投稿のため、技術面に関する内容は次回以降になります。


# ◆Power Automateのダウンロードについて
以下リンク先よりダウンロード可能
[Power Automateダウンロード先](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/install "Power Automateダウンロード先")





# ◆ポイ活対象の選定について

以下項目を押さえておきたい。

　①利用規約に反しないもの
　②周りがあまり自動化を進めていなそうなもの
　③簡易処理で出来そうなもの
　④Excel利用しないもの


#### ①利用規約に反しないもの
➡利用規約に反していないか、
【自動】や【ロボット】、【負荷】についての記載内容の確認を行う。

#### ②周りがあまり自動化を進めていなそうなもの
➡周りが既に進めているのは面白みに欠けると感じたため
有名どころのポイ活サイトは敬遠する。

#### ③簡易処理で出来そうなもの
➡難易度が高い処理は途中離脱しかねないため
極力簡易処理（クリック）を使用する。

#### ④Excel利用しないもの
➡実行端末にExcelが入っていないため
Excelへのデータ取り込み抽出を行わずにできるものを考える。




# ◆次回　【その２】ポイ活対象の決定、処理確認
（PHP）boolean型の true false を文字列の 'true' 'false' にキャストしたかった

先日投稿した記事において、

https://qiita.com/class_kouta/items/4b521f578490b800c205

結論として、

**boolean型は文字列の 'true' 'false' に直してからインサートしようぜ！**

と締めた。
そこで、boolean型を文字列型にキャストしようと思ったのだが、それもまた苦戦したって話を書く。


## true false を文字列型にキャストしてみた結果

文字列型でキャストしたら 'true' 'false' になるって普通思うじゃん？

```php:文字列型にキャストしてみた結果
$true = true;
$false = false;

var_dump($true); // bool(true)
var_dump($false); // bool(false)
var_dump((string) $true); // string(1) "1"
var_dump((string) $false); // string(0) ""
```

true  → "1"
false → ""

になった()

## 結論
true → 'true'
false  → 'false'

にしたい場合は、もうif文とか三項演算子で変換しよう（他にやり方あればコメントください）


## ついでに数値型にキャスト

```php:数値型にキャスト
$true = true;
$false = false;

var_dump((int) $true); // int(1)
var_dump((int) $false); // int(0)
```
こっちは直感的でわかりやすい
[AWS Q&A 365][S3 Glacier]AWSのよくある問題の毎日5選 #2

# 1. Amazon S3 Glacierとは何ですか？
回答：Amazon S3 Glacierは、データアーカイブと長期バックアップのために設計されたクラウドストレージサービスです。

# 2. Amazon S3 Glacierを使い始めるにはどうすればよいですか？
回答：Amazon S3 Glacierを使い始めるには、AWSアカウントを設定し、適切なAWS SDKをダウンロードし、ボルトを作成し、ボルトにアーカイブをアップロードする必要があります。

# 3. Amazon S3 Glacierに適用されるコンプライアンスプログラムは何ですか？
回答：Amazon S3 Glacierは、サードパーティの監査人によって評価され、複数のAWSコンプライアンスプログラムに含まれています。これには、System and Organization Controls（SOC）、Payment Card Industry Data Security Standard（PCI DSS）、Federal Risk and Authorization Management Program（FedRAMP）、Health Insurance Portability and Accountability Act（HIPAA）が含まれます。

# 4. Amazon S3 Glacierは、どのようにデータ保護を確保していますか？
回答：Amazon S3 Glacierは、データアーカイブと長期バックアップのための高い耐久性のクラウドストレージを提供しています。S3 Glacierは、複数のAWSアベイラビリティーゾーン（AZ）と各AZ内の複数のデバイスにデータを冗長保存しています。耐久性を高めるために、S3 Glacierは、成功したアップロードを確認する前に、複数のAZ間でデータを同期的に保存します。

# 5. Amazon S3 Glacierのセキュリティとコンプライアンスの機能にはどのようなものがありますか？
回答：Amazon S3 Glacierは、厳格な規制要件を満たすのに役立つ包括的なセキュリティとコンプライアンスの機能を提供しています。たとえば、S3 Glacier Vault Lockを使用すると、ボルトロックポリシーで個々のS3 Glacierボルトにコンプライアンスコントロールを簡単に展開して強制することができます。AWSコンプライアンスリソースには、あなたの業界や地域に適用されるさまざまなワークブックやガイドがいくつか用意されています。
[AWS Q&A 365][S3 Glacier]Daily Five Common Questions #2

# 1. What is Amazon S3 Glacier?
Answer: Amazon S3 Glacier is a cloud storage service designed for data archiving and long-term backup. 

# 2. How do I get started with Amazon S3 Glacier?
Answer: To get started with Amazon S3 Glacier, you need to set up an AWS account, download the appropriate AWS SDK, create a vault, and upload an archive to the vault. 

# 3. What are the compliance programs that apply to Amazon S3 Glacier?
Answer: Amazon S3 Glacier is assessed by third-party auditors as part of multiple AWS compliance programs, including System and Organization Controls (SOC), Payment Card Industry Data Security Standard (PCI DSS), Federal Risk and Authorization Management Program (FedRAMP), and Health Insurance Portability and Accountability Act (HIPAA).

# 4. How does Amazon S3 Glacier ensure data protection?
Answer: Amazon S3 Glacier provides highly durable cloud storage for data archiving and long-term backup. It redundantly stores data in multiple AWS Availability Zones (AZ) and on multiple devices within each AZ. To increase durability, S3 Glacier synchronously stores your data across multiple AZs before confirming a successful upload.

# 5. What are the security and compliance capabilities of Amazon S3 Glacier?
Answer: Amazon S3 Glacier provides comprehensive security and compliance capabilities that can help you meet stringent regulatory requirements. For example, S3 Glacier Vault Lock allows you to easily deploy and enforce compliance controls for individual S3 Glacier vaults with a vault lock policy. AWS Compliance Resources provide several different workbooks and guides that might apply to your industry and location.
うちのPC紹介-ASUS Core i5-12450H君

新しいPCが家に来たので紹介します。

## 12450H君
・ASUS TUF Dash F15 FX517ZM (FX517ZM-I5R3060BEC)
　（紹介リンク：https://jp.store.asus.com/store/asusjp/ja_JP/pd/productID.5618019600）
・CPU：Core i5-12450H
　・第12世代インテルCore i5
　・8コア12スレッド
　・ベースパワー：45W
　・[詳しくはここ](https://www.intel.co.jp/content/www/jp/ja/products/sku/132222/intel-core-i512450h-processor-12m-cache-up-to-4-40-ghz/specifications.html)
・メモリ：16GB（DDR5-4800）
・SSD：512GB（NVMe）
・GPU：GeForce RTX 3050 Laptop 6GB
・OS：Windows 11 Home
・ディスプレイ：15.6インチFullHD
・重量：2.0kg
・モットー：GPUありでコスパ重視
・こいつの良いところ
　・GPUありIntel系で15万円
　　・Intel第12世代CPU✕Geforceでこの値段はオトク♪
・こいつの悪いところ
　・思ったほど回らない
　　・軽くベンチマークしてみたら、思ったほどは回らないかも。
　　・日常使いには問題ないけど、デスクトップほどは回らないかも。
・感想（2023/3/12）
　　コスパ重視のデスクノートで買いました！！！
　　そこそこ3D動いてくれそう。
　　ただちょっと熱的に夏心配かなぁ。
　　ACアダプタが200Wでびっくりしました。


### ベンチマーク結果
購入すぐのベンチ（実施予定）
SSD換装後のベンチ（実施予定）

### 用途
2023年～
・メインPC
　・普段作業
　・開発
X68000用にコードを書く際に最適化で気にしていた点

# はじめに

「X68000 Z」が話題になったようなので、当時の最適化で気にしていた点をいくつか思い出してみた。

# sin, cos

当時は浮動小数点演算はコプロセッサで実装されてたが、残念ながらコプロセッサは標準搭載ではなかった。
sinとかcosを使う必要があるたびに値を求めていたのでは時間がかかる。
そこで、最初から一周分のsinとかcosを求めておいてテーブルを作っておく。
値が必要ならテーブルから読み出すだけだから処理が省ける。
そして、角度を常にバイトとして扱い、どう加減算してもテーブルの範囲外を指さないように構成すると、いろいろ省けてお買い得だ。

# 固定小数点

そもそも浮動小数点の扱いが重いから避けたいという話になる。
そこで固定小数点を採用する。
整数部と小数部を合わせて32ビットあれば対応できることも多い。
もし数値の範囲が狭くて荒い精度で良いなら、合計16ビットでも問題ない場合がある。

# ループ

例えば、処理を16回繰り返したい場合、次のように書くのは最速ではない。
```C
int i;
for(i = 0; i < 16; i++)
{
    //  ループの中身
}
```
コンパイルするとdbra命令が使われるように書くと速い。ループカウンタの操作/条件分岐が1命令になるので。
更に言うと、可能であれば処理を必要回数だけ並べたほうが速い。ループカウンタの操作/条件分岐が不要になるので。
当時は命令プリフェッチ程度はあったかもしれないがキャッシュはなかったので、キャッシュに納めることを考える必要はない。

# スーパーバイザモード

モトローラの68000には非常に単純なメモリ保護があった。
ユーザーモードとスーパーバイザモードがあり、重要な領域は保護されており、スーパーバイザモードではアクセスできてユーザーモードではアクセスできなかった。
VRAMなどにアクセスすることは多いと思うが、それは保護されてる領域へのアクセスとなる。
モード移行のオーバーヘッドを省くため、最初からスーパーバイザモードに移行しておき、スーパーバイザモードのまま走り抜ける場合もあった。
行儀の良い振る舞いではないが、速度を稼ぐためには必要だった。

# 掛け算

モトローラの68000には掛け算命令があったが、あまり賢くない実装だったようで速くなかった。
速度が重要なら掛け算命令を使わずにシフトなどを組み合わせたりしてた。
なお、割り算も同様である。

# 16ビット

データレジスタもアドレスレジスタも32ビット幅なのでコードを書く側には32ビットCPUに見えるが、データの処理単位は16ビットだ。
だから、16ビットで収まるデータを扱ってるなら16ビットで計算したほうが速い。
Cで書くなら、速度が重要でないならintやunsigned intで構わないが、速度が重要ならshort intやunsigned short intを使う。

# コンパイラ

当時のコンパイラの最適化技術は今ほど賢くなかった。
速度が重要ならコンパイルされた結果を意識してコードを書いてた。
コードの意図がコンパイラに伝わらず最適化が甘い場合、インラインアセンブラを使う場合もあった。

# いまでも

いくつかは、いまでも同じ考え方が適用できる。
その処理はそこに必要なのか? 事前に処理して結果のテーブルを用意したほうが良くないか?
素直で分かりやすいコードは良い。だが、そこは速度より分かりやすさが必要な場面か? 別の方法を使うとわかりにくさと引き換えに速度が得られたりしないか?
そのオーバーヘッドは許容できるか? 省略できないか? もし省略するなら副作用を許容できるか?
できるだけ幅広く状況に応じて適切に判断することを心がけたいと思う。
【Android】アプリ内の音の音量を調整する【Kotlin】

# はじめに
最近の記事ではアプリ内で音を流すことについて書いていますが、今回は その音のボリュームを変更する方法を記事にします

# 
Androidのサウンド再生（アラーム音量やダイヤル音量、音楽再生音量など）の音量は**AudioManager**で行われていてそれぞれの音の種類ごとに指定して音量を変更できます。
下の表は設定できる音の種類の表です

|音の種類|説明|
|:---|:---|
|AudioManager.STREAM_MUSIC|音楽音量|
|AudioManager.STREAM_ALARM|アラーム音量|
|AudioManager.STREAM_DTMF|ダイヤル音量|
|AudioManager.STREAM_NOTIFICATION|通知音量|
|AudioManager.STREAM_SYSTEM|システム音量|
|AudioManager.STREAM_RING|着信音量|
|AudioManager.STREAM_VOICE_CALL|通話音量|

この音の種類を指定し
**setStreamVolume**で音量を設定、または、**setStreamMute**でミュートのON/OFFの設定できます

# 実践


        val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager　// 1

        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 5, 0)      // 2

        audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true)        // 3

説明していきます。
1.AudioManagerを取得する
2.""setStreamVolume""で引数に　音量を変更したい音の種類,設定したい音量,volume 設定時のインタラクションを指定します
3. ""setStreamMute""で引数に　ミュートを切り替えたい音の種類,ミュートをONにするためにtrueを設定します


# 参考
https://source.android.com/docs/core/audio/attributes?hl=ja

https://gaprot.jp/2017/04/17/android-system/
[Rails]  binstubとは

## はじめに
Everyday RailsでRSpecの学習をしていたところ、rspec binstubという言葉が出てきました。
```
$ bundle binstubs rspec-core
```
上記コマンドにより、bin/rspecファイルが作成され、今まで`bundle exec rspec`というコマンドが`bin/rpsec`のみで実行できるようになる。
と教材では書かれていたのですが、あまり理解出来なかったので掘り下げようと思います。

## `bundle exec`とは
まずは周辺知識から掘り下げたいと思います。
`bundle exec`を使用することにより、Gemfile内のgemのバージョンに基づいてコマンドを実行できる。
`bundle exec`をつけないと、システム共通のライブラリ保存場所にあるgemを使用するため、エラーが起きる場合がある。

### bundle installしたgemの保存先
`~/.rbenv/versions/\*/lib/ruby/gems/\*/gems/インストールしたgem

## binstubとは
例えば`gem install rspec-core`をした時、Rubygemsは以下のものを用意してくれる。
1. rubyバージョン/bin/rspec (RubyGems によって作られた binstub)
2. rubyバージョン/lib/ruby/gems/＊/gems/rspec-core-XX.YY/exe/rspec (オリジナル)

上記1は、上記2のファイルをラップするために作られたbinstub

そして、rbenvのコマンドであるrspecを実行した時、
shims　→ 　binstub　→ オリジナルの順にパスを探して実行する。

### rspecのbinstubを作成
```
$ bundler binstubs rspec-core
```
```ruby:bin/rspec
#!/usr/bin/env ruby
# frozen_string_literal: true

#
# This file was generated by Bundler.
#
# The application 'rspec' is installed as part of a gem, and
# this file is here to facilitate running it.
#

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

bundle_binstub = File.expand_path("bundle", __dir__)

if File.file?(bundle_binstub)
  if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
    load(bundle_binstub)
  else
    abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
  end
end

require "rubygems"
require "bundler/setup"

load Gem.bin_path("rspec-core", "rspec")
```
一番下の行の`load Gem.bin_path("rspec-core", "rspec")`によって、`bin/rspec`コマンドが呼ばれた際に、`rspec-core`ディレクトリの`rspec`実行ファイルが呼び出される？仕組みだと思います。

これにより、今までは`bundle exec rspec`コマンドでオリジナルのrspec実行ファイルを実行していたが、`bin/rspec`だけでオリジナルのrspec実行ファイルを呼び出すことができるようになっているのだと思います。

+ また、./binのパスを通せば`rspec`コマンドのみで実行できます
```
$ export PATH="./bin:$PATH"
```

## 参考サイト
[binstub について翻訳してみた](https://qiita.com/tanaka51/items/bc22c1c364202d3cce4e)
100万点を表示してみる（点群表示機能を自作してみる その３）

[「点群表示機能を自作してみる」](https://qiita.com/yumimatoba14/items/a89b01145b3af4ce9451)のその３です。
100万点を表示するところまでやります。GPU力押し（というほどでもない普通のコード）です。現在のハードでどこまで可能そうなのかを見積もります。

# 出来上がり図

[GitHub](https://github.com/yumimatoba14/DirectXMfc.git) 以下のリビジョンを参照してください。
> Revision: a735360988386ab09e39e5643b69be274f8888c5
Message:
added dense point cloud model.
modified to show duration time to draw view.



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/53ef92bb-f904-e395-4a4e-aef0eb7b35e8.png)

# 説明

高々100万点は余裕でGPUにのるサイズですので、初期化時にバーテックスバッファを作り描画させます。 それでもパフォーマンス的にはぎりぎりのようでした。
技術的には前回からの差異はありません。

## 描画パフォーマンス
1フレームごとの描画時間を画面に表示できるようにし、適当に操作して描画時間を観察するという程度の確認です。
今後のためにバーテックスバッファを可変にした場合も比べてみます。

| 点数 | 点サイズ | 頂点バッファ | 描画時間[ms/frame] |
|:-:|:-:|:-:|:-:|
|100万点| 0.001 | 固定 | 40～60 |
|100万点| 0.001 | 可変 | 40～60 |
|100万点| 0.1 | 固定 | 70～100 |
|100万点| 0.1 | 可変 | 70～100 |
|1000万点|0.001|固定|150～220|

どうも負荷の高い処理は、出力バッファのマージ的な処理のようです。
* 点のサイズを大きくすると遅くなる様子。
* 点が全て画面の外に出ると 0ms で描画される。(GetTickCount() を使っているので 15ms 以下と解釈できる。)

バーテックスバッファの固定・可変は `D3D11_BUFFER_DESC hBufferDesc` を以下のように変更します。
```C++:可変の場合
		hBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
		hBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
```
```C++:固定の場合
		hBufferDesc.Usage = D3D11_USAGE_DEFAULT;
		hBufferDesc.CPUAccessFlags = 0;
```
但しこの設定により速度的な違いは生じませんね。そういうものか。

`PointListSampleModel::OnCreateBuffer()` の nZ を10にすると1000万点になります。(以下のようなモデルになります。100万点の板10枚。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/3018a6d8-f11a-7d68-a48e-c2bca5348ae1.png)

速度的には20fps程度あるとまあまあレスポンスが良い感じがする。 10fps だとやや苦しい。 ということで以後1フレームで描画できる点数の目安として100万点と考えることにします。 (10億点の1000分の1。)
Lambda Layers(Node.js)のローカル開発でESLintもPrettierもJestも動かなくなった

# 起きた現象
複数のLambdaの関数とLambda Layersを含むリポジトリでローカル開発をしていたところ、関数の方はVSCodeのPrettierもESLintもJestも問題なく動作したが、Lambda Layersの方ではそれらが全く動作しなくなった
`〇〇.spec.ts`を`〇〇.test.ts`に変更したり`.vscode/settings.json`を配置しなおしたりしてみたがいずれも効果が無かった

# 環境
- Ubuntu20.04(WSL2)
- VSCode

# 結論
<font color="Red">__ディレクトリ名がnode_modulesだったから__</font>

# 詳細
以下のような構成で開発していたんですが、Lambda Layersのパスにnode_modulesが含まれてました
恐らくNode周りのツールはnode_modules以下のファイルを無視するというのをノーコンフィグで内部的に行っていると思われ、今回のLambda Layersは無視されてしまったということだと解釈

```bash:ディレクトリ構成
-- lambdaFunctions
   ├ 関数1
   ├ 関数2
   ├ ...以下同様
-- layers/nodejs/node_modules/myLayer
                                 ├ index.js
                                 ├ index.spec.js
                                 ├ node_modules
```

# 解決策
以下のようにLayers開発用ディレクトリとLayers配置ディレクトリを分けることで周辺ツールが開発時に動作するようになった
`layersDev`で開発した後、bashスクリプトかなにかで`myLayer`以下にビルドされたファイルが配置されるようにCI等で実行すれば従来通り動作する

```bash:新ディレクトリ構成
-- lambdaFunctions
   ├ 関数1
   ├ 関数2
   ├ ...以下同様
-- layers/nodejs/node_modules/myLayer
                                 ├ index.js
                                 ├ node_modules
-- layersDev
   ├ index.ts
   ├ index.spec.ts
   ├ node_modules
```
Windows環境(コマンドプロンプト)からLINE APIをcurlで叩く


# 概要
先人の記事([LINE APIをcurlで叩く](https://qiita.com/tokkun5552/items/c515f11b1d5496971459))をコマンドプロンプトから実施した。
実行するとACCESS TOKENで指定したボットからUserIDのユーザーへプッシュメッセージが送られる。

```
curl -X POST https://api.line.me/v2/bot/message/push" ^
     -H "Content-Type: application/json" ^
     -H "Authorization: Bearer <ACCESS TOKEN>" ^
     -d "{\"to\": \"<UserID>\",\"messages\": [{\"type\": \"text\",\"text\": \"Hello, user from api direct call!\"}]}"
```

# 注意点
- 各オプションはダブルクォートで囲む。シングルクォートはNG
- jsonの記述は`\`でエスケープする
- PowerShellの場合Invoke-WebRequestがエイリアスに指定されていて使えない。
```
 Get-Alias curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest
```


# 参考
https://qiita.com/tokkun5552/items/c515f11b1d5496971459

https://web-dev.hatenablog.com/entry/windows/curl/send-json

https://qiita.com/yamachan360/items/8c928738289cd518eec8

https://qiita.com/akane_kato/items/34b408336f4ec372b139
JetpackComposeでテキストサイズを固定するのに便利なKotlin Extensions

前にこちらを紹介いたしました。

https://qiita.com/yuta317/items/ca61f8ea472c2a2bc3a8

こちらをもっと便利に使用しやすくするためのKotlin Extensionsを紹介しようと思います。

```ComposeEx.kt
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp

// dp(Dp) → sp(TextUnit)
@Composable
internal fun Dp.dpToSp(): TextUnit {
    return (this.value / LocalDensity.current.fontScale).sp
}
```

こちらになります！

こちらを使用方法は


```Sample.kt
Text(
    text = "文字サイズ変わらない",  fontSize = 15.dp.dpToSp()
)
```

設定方法が簡単になるのでよかったら参考にしてください！
前処理入門

# 前処理について
仕事でモデルの学習に使用するデータの前処理を行うことになりましたので、前処理について軽くまとめたいと思います。

## そもそも前処理とは
データ分析の前処理とは、データ分析の準備のための処理です。
対象となるデータ分析は大きく下記の3種類に分けられます。

- 指標、表、グラフ作成
- 機械学習(教師なし学習)
- 機械学習(教師あり学習)

直近の仕事では、教師あり学習に使用するデータの分析を行うため、教師あり学習に関することのみまとめています。

## 教師あり学習
「教師あり学習」とは、既知の正解データ（教師データ）を用いてモデルを学習させる機械学習の手法のことです。

教師データは、学習データや訓練データとも呼ばれますが、厳密には学習データとは、教師あり学習の中で使用される教師データのうち、モデルの訓練に使用されるものを指します。

学習データは、機械学習モデルを訓練するために使用されます。モデルは、学習データに基づいてパターンを学習し、そのパターンを利用して新しいデータに対して予測を行います。予測対象のデータは、テストデータと呼ばれます。一方、適用データとは、機械学習モデルを運用する際に使用されるデータのことで、一般的には「本番データ」と呼ばれることがあります。

学習データと適用データの違いは、予測対象のデータが持っているかどうかにあります。学習データは、モデルを訓練するために正解データが必要ですが、適用データは正解データが与えられないため、予測を行うことが目的です。

また、テストデータは、学習データと同様に正解データを持っていますが、適用データと同様に、機械学習モデルに入力せずに、テストのためだけに使用されます。

## 教師あり学習へ入力するための前処理
教師あり機械学習モデルに利用する学習データ、テストデータ、適用データの3種類のデータを準備することが目的です。
学習データとテストデータは、適用データと同様の処理に加えて、予測対象のデータを追加することで実現できます。
また、学習データとテストデータは本質的に同じデータであり、準備したデータを分割することで学習データとテストデータにすることもできます。
さらに、機械学習モデルの種類に応じて、モデルが扱いやすいデータに変換する前処理も必要になります。

前処理の重要性は、データ分析の目的を明確にすることから始まります。
そして、目的を達成するためにどのような分析が必要なのか判断し、集計内容や利用する機械学習モデルの特性を考慮して、必要な前処理を実施することが重要です。

## 前処理の流れ
前処理の流れを把握するために、データの何を対象として変換するかによって、前処理を以下の2つに分類できます。

- データの構造を対象とした前処理
- データの内容を対象とした前処理

### データの構造を対象とした前処理
データの構造を対象とした前処理は、複数の行にまたがってデータ全体に及ぶ処理を指します。
大きなデータの操作となる処理が多く、データの前処理の中でも早い段階で実施されます。
特定のデータを抜き出す抽出処理や、データ同士を結合したり、あるルールに基づき複数の行を1行に集約したりすることがあります。

例えば、以下のような処理が挙げられます。

- ランダムサンプリングによって、ランダムに行を抽出
- 勾配レコードと商品マスタを商品IDをキーに結合して、商品情報を付与した購買レコードを生成
- 教師あり機械学習のモデルのために、学習データとテストデータを分割
- キャンペーンに反応するデータが少ないのでアップサンプリングによってデータを増やす

以上のような前処理を実施することで、データの構造を整え、モデルが扱いやすくなるため、正確な予測を行うことができます。

### データ内容を対象とした前処理
データ内容を対象とした前処理は、行ごとのデータ値に応じた処理です。
データ構造を対象とした処理と違い、行ごとに独立して処理できる小規模なデータ操作が行われます。
この種類の前処理は、データの前処理の流れの中でも後半で実施されることが多く、また条件を変えて繰り返し検討されることも多いです。
例えば、日時のデータ列を月のデータ列に変換したり、数値の列を組み合わせて計算して新たな数値列を生成したりすることがあります。

- 年齢の数値を年代を表す10刻みのカテゴリ型データに変換
- 日付のデータを曜日のデータに変換
- 2地点の緯度/軽度から地点間の距離を計算

### 前処理の順番
典型的な前処理のパターンでは、まず対象のデータの抽出によってデータ量を減らします。
これは、マスタデータの結合やデータ内容の変換を抽出前に行った場合、最終的に利用しないデータに対しても前処理を行ってしまい、無駄に計算コストが高くなってしまうためです。
ただし、結合するマスタデータが持つデータが集約後の値の条件やサンプルサイズによってデータの抽出対象が変わる場合は、データの抽出を後に行う場合があります。
スクラム開発 アーティファクト

## アーティファクトとは
アーティファクトとはスクラムで活用する成果物のようなものです。  

## Product Backlog 　プロダクトバックログ
スクラムでは、プロダクトへの要求を抽出し、順番に並べ替えた「プロダクトバックログ」と呼ばれるリストを作成します。
順番は、その要求が実現されたときに得られる価値やリスク、必要性などによって決定されます。プロダクトバックログは、以下のように説明できます。

- プロダクトの開発内容について優先順位をつけて何を実現するか記述したもの
- スクラムチームが行う作業の唯一の情報源となる

PBL＝Product Backlog Listの略称：PBIの一覧を示す(チケットの一覧)
PBI＝Product Backlog Itemの略称： １つの実現したい事を指す(チケット)

常に要求が変化する可能性があるため、常に最新の状態に保つ必要があります。開発チームは上から順に開発していく感じになります。

## Sprint Backlog　スプリントバックログ
スプリントバックログは、開発者による、開発者のための計画です。
開発者がスプリントで行う作業の一覧をリアルタイムに反映します。以下のように説明できます。

- チームがプロダクトインクリメントを作るのに必要な作業をすべて見える化している
- Sprint Planning (スプリント計画)で作成されます。
- スプリント内で開発チームが取り組むタスクの一覧のようなもの

スプリントバックログは、開発者による、開発者のための計画です。スプリントバックログには、スプリントゴールを達成するために開発者がスプリントで行う作業がリアルタイムに反映されます。
その結果、より多くのことを学ぶにつれて、スプリントの期間を通して更新されます。
スプリントバックログはデイリースクラムで進捗を検査できる程度の詳細さが必要になります。

## Impediment List　インペディメントリスト
インペディメントリストは、スクラムチームにとっての障害になっていることをリスト化したものです。以下のように説明できます。

- スクラムチームにとっての障害になっている事リスト 
- チーム、プロダクトオーナー関係者全員が閲覧可能で把握できる状態にする 
- 障害の優先順位はスクラムマスターが決める

## Definition of Done
チームで定義した、リリースまでに完了しなければならない基準についての説明です。

Done　（PBIの完了条件に含まれるもの）
　・毎スプリント（毎チケット）必ず実施すること（テストコードやレビューなど）
　・チームと合意した、毎回ぶれない基準を設定すること
　・プロダクトバックログには明記しないこと

Undone（PBIに個別に切りだしたもの）
　・毎スプリントで実施できないもの（リリースノートや統合テスト、セキュリティテストなど）
　・リリース前のどこかで実施すればよいこと
　・個別にプロダクトバックログアイテムが作成されること
スクラム開発 ロール

## はじめに
スクラムの概要について説明しました。今回はスクラムにおける役割である「ロール」について、簡単に紹介します。
※途中でてくるプロダクトバックログやスプリントプランニングなどは次回説明します。

## プロダクトオーナーとは
プロダクトオーナーは、プロダクトバックログの管理者であり、プロダクトの結果責任者です。プロジェクトには必ず1人必要で、プロダクトやコストに対する決定権を持ちますが、 **チームのプロセスやツール、メンバーに対しての口出しは出来ません。** 

## プロダクトオーナーの役割
プロダクトオーナーの最も重要な役割は、スクラムチームのROI（費用対効果）の最大化です。具体的には以下のようなことを行います。

- プロダクトのビジョンを明確にし、周りと共有する。
- おおよそのリリース計画を定める。
- 予算を管理する。
- 顧客、プロダクトの利用者や経営者などのプロジェクト関係者と、プロダクトバックログの項目の内容を確認し、つくる順番や実現時期を相談する。
- 既存のプロダクトバックログの項目の内容を最新の状態に更新する。
- プロダクトバックログの項目の内容を関係者が理解できるように説明する。
- つくられたプロダクトが要求に合っているかどうかを検査する。

また、プロダクトオーナーは、スクラムチームとステークホルダーとの橋渡し役を務め、ステークホルダーにはビジネス側や顧客などが含まれます。

## スクラムマスターとは
スクラムマスターは、プロダクトオーナーや開発チームを支援し、プロダクトをうまくつくるための役割を担います。

## スクラムマスターの役割
スクラムが適切に活用される状態を作り、スクラムが適さない場合はスクラム以外の方法を提案します。
また、スクラムのルールや成果物、進め方をプロダクトオーナーや開発チームに理解させ、効果的な実践を促します。
さらに、スクラムの外にいる人からの妨害や割り込みからプロダクトオーナーや開発チームを守る役割も担います。

以下はスクラムマスターがプロダクトオーナーや開発チームに対して行うことの一例です。

- わかりやすいプロダクトバックログの書き方をプロダクトオーナーや開発チームに教える。
- プロダクトバックログの良い管理方法を探す。
- プロダクトオーナーや開発チームにアジャイル開発やスクラムについて説明して理解してもらう。
- スプリント計画ミーティングやスプリントレトロスペクティブなどの会議の進行を必要に応じて行う。
- プロダクトオーナーと開発チームの会話を促す。
- プロダクトオーナーや開発チームの生産性が高くなるように変化を促す。

## 開発チームとは
開発チームは、機能横断的なメンバーで構成され、それぞれがバックログアイテムを実装するために作業を行います。機能横断的というのは、要件分析、設計、コーディング、サーバー構築、テスト、ドキュメンテーションなど、プロダクト作成に必要なすべての作業を行えることを意味し、特定のことにしか関与しないサブチームを作らないことが望ましいです。

メンバーごとにスキルや能力に差がある場合でも、個人がなるべく多くのことができるようになるよう、作業を進めていくことが求められます。

また、開発チーム内には年齢や役職による上下関係は存在しません。開発チーム全体で作業を進める方法は、開発チームのメンバーが合意した上で決定され、外部からの指示に従うことはありません。開発チーム全体が責任を持って作業を進め、自己組織化されたチームを目指し、継続的な能力向上を目指します。

## 開発チームの役割
- プロダクトオーナーが順位づけしたプロダクトバックログの項目を開発していき、動作するプロダクトを作る
- スプリントプランニングで決めたことを実現する
- 生産性を高める努力する
スクラム開発 概要

# はじめに
この記事はスクラム開発に関するものです。私がスクラムを1年間経験して感じたことや、アジャイル開発の背景、スクラムの原則について共有していきます。

## アジャイルって何？
スクラムはアジャイル開発の手法の1つですが、そもそもアジャイルとは何なのでしょうか。

アジャイルは、ソフトウェア開発における手法の1つであり、従来のソフトウェア開発手法とは異なる手法を実践することを目的としています。アジャイル開発の背景となっているのが「[アジャイルソフトウェア開発宣言](http://agilemanifesto.org/iso/ja/manifesto.html)」です。この宣言は、ユーザーのニーズ、プログラミングの手法や言語、ソフトウェアの設計などについて、17人のソフトウェア技術者が議論を通じて生み出しました。

アジャイルソフトウェア開発宣言には以下のように書かれています。

「アジャイルソフトウェア開発宣言」は下記の通りです。
> 私たちは、ソフトウェア開発の実践
> あるいは実践を手助けをする活動を通じて、
> よりよい開発方法を見つけだそうとしている。
> この活動を通して、私たちは以下の価値に至った。
> 
> プロセスやツールよりも **個人と対話** を、
> 包括的なドキュメントよりも **動くソフトウェア** を、
> 契約交渉よりも **顧客との協調** を、
> 計画に従うことよりも **変化への対応** を、
> 
> 価値とする。すなわち、左記のことがらに価値があることを
> 認めながらも、私たちは右記のことがらにより価値をおく。

また「[アジャイルソフトウェアの12の原則](http://agilemanifesto.org/iso/ja/principles.html)」というものもあります。
> 1. 顧客満足を最優先し、
> 価値のあるソフトウェアを早く継続的に提供します。
> 2. 要求の変更はたとえ開発の後期であっても歓迎します。変化を味方につけることによって、お客様の競争力を引き上げます。
> 3. 動くソフトウェアを、2-3週間から2-3ヶ月というできるだけ短い時間間隔でリリースします。
> 4. ビジネス側の人と開発者は、プロジェクトを通して日々一緒に働かなければなりません。
> 5. 意欲に満ちた人々を集めてプロジェクトを構成します。環境と支援を与え仕事が無事終わるまで彼らを信頼します。
> 6. 情報を伝えるもっとも効率的で効果的な方法はフェイス・トゥ・フェイスで話をすることです。
> 7. 動くソフトウェアこそが進捗の最も重要な尺度です。
> 8. アジャイル･プロセスは持続可能な開発を促進します。一定のペースを継続的に維持できるようにしなければなりません。
> 9. 技術的卓越性と優れた設計に対する不断の注意が機敏さを高めます。
> 10. シンプルさ（ムダなく作れる量を最大限にすること）が本質です。
> 11. 最良のアーキテクチャ・要求・設計は、自己組織的なチームから生み出されます。
> 12. チームがもっと効率を高めることができるかを定期的に振り返り、それに基づいて自分たちのやり方を最適に調整します。

アジャイルソフトウェア開発宣言には、プロセスやツールよりも個人との対話が重視されるべきだと明確に述べられていることがわかります。

簡単に進め方を説明すると以下のようになります。

- 関係者は目的の達成のためにお互いに協力し合いながら進める。
- 利用者の反応や関係者からのフィードバックを継続的に得ながら、計画を調整する。一度にまとめてではなく、少しずつつくる。
- そして実際にできあがったものが求めているものと合っているかを頻繁に確認する。

## スクラムとは何か？
スクラムとは、ラグビーのスクラムが語源となっている、アジャイル開発手法の1つで、プロジェクトの現状を把握するためのフレームワークです。チームのワークフローを管理するための規律的な手法で、軽量ながらきちんと組み立てられています。スクラムは、技術的なプラクティスを具体的に指定するものではなく、チーム内での作業の流れを定義し、チームが用いる具体的な役割（ロール）と作業を調整するプラクティスを規定しています

勘違いしては行けないのは **問題を解決するためのフレームワークでは無いということです。**    

### スクラムのルール
スクラムには様々なルールがありますが、最大で20個ものルールがあるため、今回は名前だけの紹介に留め、次回以降詳しく説明していきます。
必ずしも全てのルールを守らなければいけないわけではありません。初めてスクラムを始める際には、全てのルールを一度に実践するのではなく、スモールスタートして徐々に導入していくのがいいかなと個人的に思っています。

### スクラム3つの柱
今回は概要ということでスクラムの3つの柱について少しだけ説明していきます。
3つの柱はプロジェクトの現状を把握するために担保している必要要素です。

1. 検査 - Inspect   
進捗状況や作っているプロダクトが正しいか、作業の進め方に問題がないかどうかを定期的に確認すること
2. 適応 - Adapt   
やり方に問題があったり、もっとうまくできる方法があったりすれば、やり方そのものを変えること
3. 透明性 - Transparency   
正しい情報が1カ所に整理され、次の行動が誘発されることを担保すること

その他のスクラムのルールは、上記3つの柱を満たすためにあると言っても過言ではありません。
Wordで見出しレベルごとの連番を作成する方法


挿入タブのクイックパーツ > フィールドを選択するとフィールドを文書に埋め込むことができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/8996a547-d2a2-1d44-3ab7-0c078cf62245.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/f46b69b9-6222-acd8-5476-d5c691ca78dc.png)

もしくは、「Ctrl + F9」のショートカットを2つ押下してフィールドを2つ挿入した後に、以下のように入力すると[見出し番号]-[連番]という具合に見出しごとの連番を作成することができる。
```
{STYLEREF 1 \s}-{SEQ 任意の連番名 \S 2}
```


■完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/e77bc5c9-b315-7f7d-114d-4118e3e34b27.png)

■多段リストの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/a3440422-0aa5-4aec-ba91-a0408b15095e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/3adbba02-082b-4f3c-80de-34d28b76d753.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/21b9f137-b25c-42f0-9f44-d7be7e67ff1e.png)

■参考文献
http://office-qa.com/Word/wd610.htm
https://dtp.screen-cre.co.jp/dtp0039/
【kotless】gradleの設定でApi gatewayのバージョン名を指定する方法

# はじめに
現在も引き続きサーバーサイドの調整を行なっておりますが、deployした結果どのパラメータがどこに設定されるのか少しわかりづらいと感じています。
今回はapiGatewayで表示されているバージョン表記に該当するパラメータを備忘録的に記事にまとめたいと思います。

# 設定内容
ApiGateway上のバージョン名に該当する設定は以下になります。

```
webapp {
   deployment {
      version = "バージョン名"
   }
}
```

上記に設定したパラメータがdeploy先のバージョンの名称として設定されます。
よくある名称としては、v1などの表記ですね。
プロジェクトに合わせて表記を決めたら良いと思います。

# さいごに
今年の花粉は強烈ですね、みなさんお身体ご自愛ください、、、
【Laravel doctrine/dbalエラー】Laravel v6 is only compatible with doctrine/dbal 2

Laravel6でphp artisan migrate を行うと、composer require doctrine/dbalを行っていたにも関わらずmysqlで下記エラーが出たので、その対処法をメモ。

``` 
LogicException  : Laravel v6 is only compatible with doctrine/dbal 2, in order to use this feature you must require the package "doctrine/dbal:^2.6".
```

バージョンを変えて、もう一度comporserからダウンロード。

```
composer require "doctrine/dbal:2.*"
```

もう一度マイグレーションを行う

```
php artisan migrate
```

無事に成功

```
Migrating: xxxx_xxxx_xxxx.php
Migrated: xxxx_xxxx_xxxx.php (0.35 seconds)
```
Googleデジタルマーケティング＆Eコマース：ディスプレイ広告の紹介

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

# ディスプレイ広告

Webサイトやアプリケーションに配置された視覚的な広告フォーマットとして、ディスプレイ広告を考えてみましょう。

あなたがEコマース企業のデジタルマーケティング担当者だと想像してみましょう。あなたは、顧客と同じような関心を持っている訪問者がいるWebサイトに、自社製品の広告を掲載してもらいたいと考えています。

- 時間をかけてWebサイトに連絡し、広告を載せてもらえないか頼むこともできますが、それは大変な作業です。
- または、このようなGoogleディスプレイネットワークなどのディスプレイ広告ネットワークにサインアップすることができます。

# Googleディスプレイネットワーク

Googleディスプレイネットワークは、ディスプレイ広告を表示することができる200万人以上のWebサイト、ビデオ、およびアプリのグループです。ネットワークは、世界中のインターネットユーザーの90％以上に達します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/53845469-2625-722c-b841-44061de39348.png" width="700">

このネットワークの中で、ターゲティングを使って、

- 「アウトドア・ライフスタイル」や特定のWebサイトなど、特定の文脈で広告を表示させることができます。
- 若い母親や新しいセダンを買う人など、特定のオーディエンスに対して広告を表示することもできます。
- 検索者の位置や以前のWebサイト訪問者へのリマーケティングも同様に含めることができます。

ディスプレイ広告では、広告を適切な人々の前で取得することが重要です。検索広告と違って、ディスプレイ広告に出会う人は、あなたの商品やサービスを直接探しているわけではなく、ただ広告を見ているだけなのです。申し込みや購入といったアクションの可能性を高めるには、広告を見込み客に届ける必要があります。

# Googleディスプレイ広告の種類

### アップロード型

アップロード型広告では、広告グラフィックを作成し、必要な仕様を満たした上で、広告をアップロードする必要があります。このようなバナー、リーダーボード、およびスカイスクレイパーから選択するいくつかの広告のサイズがあります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e6751192-ae48-91af-42cb-eb1342cc0adc.png" width="700">

マーケティング担当者は、このようなカスタム広告を作成することを選択します。また、広告を作成するためのデザインリソースと時間が必要です。


### レスポンシブ型

レスポンシブディスプレイ広告では、画像、見出し、ロゴ、動画、説明文などのコンテンツをアップロードします。Google広告は、広告の組み合わせを自動的に生成します。これらの広告の組み合わせは、Webサイト、アプリ、YouTube、およびGmailのためのものです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4dfdf787-6366-9711-53c7-f60898ab4696.png" width="700">

広告がどのように見えるかについてのコントロールは少なくなりますが、このレスポンシブ広告の方が簡単なので好む人もいます。異なる広告サイズに基づいて広告グラフィックスを作成する必要はありません。Google広告がすべての作業を行います。

# レスポンシブ型のメリット

- **あなたの広告を最適化するためにGoogle広告のソフトウェアを使用します。**
    - このソフトウェアは、画像、見出し、ロゴなどの広告コンテンツの最適な組み合わせを使用し、潜在顧客に最高のパフォーマンスの広告を配信します。あなたは、組み合わせをテストする必要はないということです。Google広告が自動的に行ってくれるのです。
- **広告がより広い範囲に届きます。**
    - これは、あなたの広告がより多くの顧客に到達することを意味します。一部のWebサイトでは、広告のサイズの特定の種類のみをサポートしています。そのため、手動で広告をアップロードしている場合、特定の広告サイズをアップロードしないと、そのWebサイトでは広告が表示されません。あなたが応答性の高いディスプレイ広告を使用する場合、Googleはちょうど約あらゆる広告スペースに合うように広告のサイズ、外観、およびフォーマットを調整します利用可能。
- **動画を追加できる。**
    - 動画を追加すると、ディスプレイネットワーク上であなたのリーチを最大化します。あなたが動画をアップロードする場合、Googleは、あなたがアップロードした写真に対して動画をテストします。動画がより良いパフォーマンスを発揮すれば、可能な限り写真の代わりに表示されます。
- **時間の節約になります。**
    - レスポンシブディスプレイ広告を使えば、さまざまな種類の広告を集めた複雑な広告ポートフォリオの管理に費やす時間を短縮することができます。Google広告がそれを担ってくれます。パフォーマンス改善に多くの時間を割くことができます。


:::note info
検索広告と比較すると、ディスプレイ広告はよりビジュアルな広告であることがお分かりいただけると思います。広告をデザインして、Google広告で管理するのは難しいかもしれません。しかし、レスポンシブディスプレイ広告を利用すれば、その作業をより簡単にすることができます。
:::
JuliaにてC:ドライブ以外のJupyter Notebookにアクセスする

### 課題
デフォルトではCドライブを対象としたNoteBookが作られるが、別ドライブに保存したNoteBookを開くことができない。
### 方法
notebook(dir="D:\\\\")のように、初期ディレクトリにドライブを含むパスを指定した起動スクリプトを作り、"julia jupyter.jl"なるバッチを作る。

```julia:jupyter.jl
using IJulia
notebook(dir="D:\\src\\",detached=false)
```
### 参考　

https://qiita.com/yuqlid/items/9c1510eaa28ed33ee605

pathの設定 [大野周平:"Julia入門：インストールからHello World!まで"](https://zenn.dev/ohno/articles/cf2b4d09d4480e)
pathの確認 `println("PATH: ", ENV["PATH"])`
環境変数 
- JULIA_HOME i:\julia-1.8.1
- JULIA_DEPOT_PATH %JULIA_HOME%\pkg
  PKGDIRは廃止
-  CONDA_JL_HOME %JULIA_HOME%\conda\3
-
O’REILLY Learning 日本語書籍 2022・2023年発売書籍で読めるもの一覧

O’REILLY Learning 日本語書籍 2022・2023年発売書籍で読めるもの一覧
なかなかのラインナップです。

https://learning.oreilly.com/home-new/

## 2023年
- SQLではじめるデータ分析
- オブザーバビリティ・エンジニアリング

## 2022年
- 大規模データ管理
- マスタリング・ライトニングネットワーク
- マスタリングLinuxシェルスクリプト
- マイクロサービスアーキテクチャ
- UX戦略 第2版
- 実践 Keycloak
- ソフトウェアアーキテクチャ・ハードパーツ
- マイクロフロントエンド
- AIファースト・ヘルスケア
- 初めてのGo言語
- Lean UX 第3版
- 機械学習エンジニアのためのTransformers
- リーダーの作法
- 動かして学ぶAI・機械学習の基礎
- カオスエンジニアリング
- 初めてのTensorFlow.js
- 推薦システム実践入門
- 実用 Go言語
- 戦略的UXライティング
- システム運用アンチパターン
- Pythonからはじめるアルゴリズムトレード
- Sphinxをはじめよう 第3版
- データビジュアライゼーションの基礎
- ソフトウェアアーキテクチャの基礎
- ネットワーク自動化とプログラマビリティ
- SQLクックブック 第2版
- 実践 自然言語処理
- プログラミングRust 第2版
- エンジニアリングマネージャのしごと
- Go言語による分散サービス
[Flutter]httpを使ってAPIと通信する（データ取得編）

# 投稿の経緯
最近Flutterの勉強を始めたので記事にしていきます。
まずはAPI通信はできるようになりたかったので、今回は`http`を使ってみました。

類似する人気ライブラリである`dio`と迷ったんですが、利用者数が若干httpの方が多かったので今回はhttpを使っています。

使用したAPI↓

https://openweathermap.org/api/one-call-api 


# 環境
Flutter version：3.7.3
Dart version：2.19.2
IDE：Android Studio


# httpとは
Dartの標準ライブラリ。
これを使うことでAPIから簡単にデータを取得することができます。

https://pub.dev/packages/http


# httpを導入する
コマンドを実行してhttpを追加する

```
$ flutter pub add http                      
```

これにより`pubspec.yaml`に以下のコードが追加されます。

```
dependencies:
  http: ^0.13.5
```

次に追加したライブラリを取得する

```
$ flutter pub get             
```

取得したらhttpを使うファイルでimportを書きます

```
import 'package:http/http.dart' as http;
```

これでhttpをアプリで使うことができるようになります。（もしimportできない場合は Android Studio を再起動してみてください）


# APIと通信してみる
データを取得する関数を用意する

```.dart
void get() async {
    const lat = '35.65138';
    const lon = '139.63670';
    const key = 'xxxxx'; // この記事ではkeyを隠しています

    const domain = 'https://api.openweathermap.org';
    const pass = '/data/2.5/onecall';
    const query = '?lat=$lat&lon=$lon&exclude=daily&lang=ja&appid=$key';

    var url = Uri.parse(domain + pass + query);
    debugPrint('url: $url');
    var response = await http.get(url);
    debugPrint('statusCode: ${response.statusCode}');
    debugPrint('response: ${response.body}');
}
```


# 取得結果
```
response: {
    "lat":35.6514,
    "lon":139.6367,
    "timezone":"Asia/Tokyo",
    "timezone_offset":32400,
    "current":{
        "dt":1678618031,
        "sunrise":1678568265,
        "sunset":1678610717,
        "temp":288.71,
        "feels_like":288.12,
        "pressure":1022,
        "humidity":69,
        "dew_point":283.05,
        "uvi":0,
        "clouds":75,
        "visibility":10000,
        "wind_speed":4.63,
        "wind_deg":160,
        "weather":[
            {
                "id":803,
                "main":"Clouds",
                "description":"曇りがち",
                "icon":"04n"
            }
        ]
    }
}
```

データを取得することができました！

# おわりに
最後までご覧いただきありがとうございます！

今回はhttpを使ってAPIからデータを取得しました。
次回は取得したデータを使ってレイアウトを作成したいと思います。
【Swift】Mixpanelの使い方

# はじめに
たぶんFirebaseEventsの上位互換です。
Xcode側での設定を載せるのでアカウント側の設定はドキュメントを見てください。

https://developer.mixpanel.com/docs/ios-swift-quickstart

# インストール
① 「File」を選択します
② 「Add Packages...」を選択します
![スクリーンショット 2023-03-12 19.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8e4f8304-b0a2-7777-3ea7-3196ad63a3f9.png)


③ `https://github.com/mixpanel/mixpanel-swift`を検索します
④ 「Dependency Rule」を設定します
⑤ 「Add Package」を選択します
![スクリーンショット 2023-03-12 19.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4616b427-c625-69e8-7a6e-88d5e035983c.png)

⑥ 「Add Package」を選択します
![スクリーンショット 2023-03-12 19.54.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9d734f0b-8721-5931-6512-739693d78b1f.png)

# 初期化
```swift:AppDelegate
import UIKit
import Mixpanel

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
    ) -> Bool {
        // `MIXPANEL_TOKEN`にはアカウントのトークンを入力する
        Mixpanel.initialize(token: "MIXPANEL_TOKEN", trackAutomaticEvents: true)
        return true
    }
}
```

```swift:SampleApp
import SwiftUI

@main
struct SampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

# イベントを送信する
任意の場所に以下のコードをペーストします。
`event`に渡した文字列がイベントを判別するキーになります。
```swift
Mixpanel.mainInstance().track(event: "sample button tapped")
```

# おわり
集計したデータを元にアプリを改善していきたいです。
SwiftUI Listセパレーター線の謎、文字を先にすることで暫定対処！？

![](https://kumonosu.cloudsquare.jp/wordpress/wp-content/uploads/2023/03/list_separator.png)

## コード
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        List {
            Text("aaaaa")
            Image(systemName: "flag.checkered.2.crossed")
            HStack {
                Image(systemName: "flag.checkered.2.crossed")
                Text("bbbbb")
            }
            HStack {
                Text("bbbbb")
                Image(systemName: "flag.checkered.2.crossed")
            }
            Text("ccccc")
            Label("ddddd", systemImage: "gamecontroller")
            Text("eeeee")
            Image("cloudsquare")
            Label("fffff", image: "cloudsquare")
            Text("ggggg")
        }
    }
}
```

## 結果
- ImageのsystemImageのみ：線あり
- HStackでImage＋Text：Imageの下に線なし
- HStackでText＋Image：線あり
- LabelのsystemImage：Imageの下に線なし
- Imageのasset画像のみ：線あり
-  Labelのimage：Imageの下に線なし
![](https://kumonosu.cloudsquare.jp/wordpress/wp-content/uploads/2022/12/i_icon_12279_icon_122791_32.png)
<strong>以前は線が引かれていた。
OS更新により挙動が変わった。仕様？不具合？</strong>
（PostgreSQL・PHP）PDOでboolean型のカラムにINSERTしたときの妙な挙動（※R5.3.14 追記）

PostgreSQLのDBに対しPDOのbindValue()を使って、boolean型のカラムの値が false のレコードをインサートしようとしたらバグった。

せっかくなのでboolean型のカラムをインサートした時の挙動について、場合別にしてまとめてみた。

## 準備
```PHP:PDOインスタンス生成
$pdo = new PDO(
    'pgsql:host=localhost dbname=mydb port=5432',
    'user',
    'pass'
);
```
## query()
クエリに直書きした場合、特に問題なくインサートされた。
```PHP:query() 直書き
$sql = <<<SQL
INSERT INTO boolean_test (bool) VALUES (true);
SQL;
$stmt = $pdo->query($sql); // OK

$sql = <<<SQL
INSERT INTO boolean_test (bool) VALUES (false);
SQL;
$stmt = $pdo->query($sql); // OK
```

変数を埋め込んだ場合、文字列として埋め込まないとインサートしてくれない。
```PHP:query() 変数埋め込み
$bool = true; // NG
$bool = 'true'; // OK
$bool = false; // NG
$bool = 'false'; // OK

$sqlQuery = <<<SQL
INSERT INTO boolean_test (bool) VALUES ({$bool});
SQL;
$stmt = $pdo->query($sqlQuery);
```
## execute()、bindValue、bindParam()

boolean型の false をセットした時だけインサートしてくれなかった。
```PHP:execute()
$bool = true; // OK
$bool = 'true'; // OK
$bool = false; // NG
$bool = 'false'; // OK

$sqlExecute = <<<SQL
INSERT INTO boolean_test (bool) VALUES (:bool);
SQL;
$stmt = $pdo->prepare($sqlExecute);
$stmt->execute([':bool' => $bool]);

```

```PHP:bindValue()
$bool = true; // OK
$bool = 'true'; // OK
$bool = false; // NG
$bool = 'false'; // OK

$sqlExecute = <<<SQL
INSERT INTO boolean_test (bool) VALUES (:bool);
SQL;
$stmt = $pdo->prepare($sqlExecute);
$stmt->bindValue(':bool', $bool);
$stmt->execute();
```

```PHP:bindParam()
$bool = true; // OK
$bool = 'true'; // OK
$bool = false; // NG
$bool = 'false'; // OK

$sqlExecute = <<<SQL
INSERT INTO boolean_test (bool) VALUES (:bool);
SQL;
$stmt = $pdo->prepare($sqlExecute);
$stmt->bindParam(':bool', $bool);
$stmt->execute();
```

## 結論
boolean型のカラムの値について、変数を埋め込んでインサートする場合、変数の値を文字列型に直してしてからじゃないとうまくクエリが実行されないケースがある。

プリペアドステートメントを利用した時に true は実行されて false が実行されないのが謎。

## （追記）PDO::PARAM_BOOLでもいけた
bindValue、bindParam の第三引数にPDO::PARAM_BOOLをセットしたら無事インサートされた

```php:PDO::PARAM_BOOL
$stmt->bindValue(':bool', $bool, PDO::PARAM_BOOL);
```
Node.jsの標準ライブラリのメソッドをJestでモックする方法

先日NodeのテストコードをJestで書いていた際にMathやcrypto等の標準ライブラリのモックでドハマりしたので投稿
StackOverFlowとかを数時間彷徨った結果色々やり方ありそうだったけど、自分の環境だと結局このやり方しか動かなかったので参考までに

# 環境
- Ubuntu20.04(WSL2)
- Node: 18.12.0
- Jest: 29.4.3
- ts-node: 10.9.1
- ts-jest: 29.0.5
- TypeScript: 4.9.5

# 結論
```js
モックしたいメソッド = jest.fn().mockReturnValue(返したい値)
```

# 例
単なる乱数を返すだけの関数ですが、以下のようにモックしてやるとテスト実行時に毎回異なる乱数を返すことがなくなります
TSなのでjest.fnに型引数を与えてますが、当然ながらJSなら無くていいです

```ts:index.ts
const getRandomNum = () => {
  return Math.random()
}

export default getRandomNum
```

```ts:index.spec.ts
import { jest, test, expect } from '@jest/globals'
import getRandomNum from "./index.js"

// この1行でモックしている
Math.random = jest.fn<() => number>().mockReturnValue(0.1111111111111111).
 
test("Math.randomの値がモックされている", () => {
  const result = getRandomNum()
  expect(result).toBe(0.1111111111111111)
})
```
Power Appsで押せと表示されたらボタンを押すというゲームを作ってみました。

押せと表示されたらボタンを押すゲームを作ったので、紹介します。

https://twitter.com/sayaka121413/status/1624968911228895232?s=20

なんとなくゲーム作りたいなーって思って以前あったゲームをモチーフにしました。
# 作成
### Screen1
・ラベルを2つ追加し、「画面に「押せ！」って出たらボタンを押すだけ」「押せ」と記載しておきます。
・ボタンを追加し、Textに「Start」と記載し、OnSelectに以下を記載しておきます。
```
Navigate(Screen2)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404009/246eeaf9-c924-6918-fc61-29f4c9ca38d7.png)

### Screen2
・Screen2のOnVisibleに以下を記載しておきます。
```
UpdateContext({starttime:Blank(), message:"", timestop:true, timing:RandBetween(2000,10000)});Clear(colpress)
```

・切り替えを追加し、OnChangeに以下を記載しておきます。※Button1は押ボタンです。
```
If(Button1.Pressed,Collect(colpress,{ time: Now()}))
```
・ボタンを2つ追加し、「押」「リトライ」と記載しておきます。
・リトライボタンには、OnSelectに以下を記載しておきます。
```
Navigate(Screen1)
```

・押ボタンには、以下をOnSelectに記載しておきます。
```
UpdateContext({pushtime:Now(), timestop:false})
```

・Timerを追加し、画面が表示されたら、開始させたいのでStartに以下を記載しておきます。
```
timestop
```

・ラベルを3つ追加し、以下を記載しておきます。
```ruby:ラベル1
message
```
```ruby:ラベル2
If(
    timestop = false,
    If(
        And(
            !IsEmpty(colpress),
            DateDiff(
                First(
                    Sort(
                        colpress,
                        time
                    )
                ).time,
                starttime,
                TimeUnit.Milliseconds
            ) > 1000
        ),
        "ずるしてない？",
        IsBlank(starttime),
        "早すぎ！",
        starttime >= pushtime,
        "早すぎ！",
        DateDiff(
            starttime,
            pushtime,
            TimeUnit.Milliseconds
        ) < 290,
        "神じゃん！",
        DateDiff(
            starttime,
            pushtime,
            TimeUnit.Milliseconds
        ) < 358,
        "激やばっ！",
        DateDiff(
            starttime,
            pushtime,
            TimeUnit.Milliseconds
        ) < 393,
        "ちょっぱやじゃん",
        DateDiff(
            starttime,
            pushtime,
            TimeUnit.Milliseconds
        ) > 500,
        "おそすぎー",
        "まぁまぁじゃない？"
    )
)
```
```ruby:ラベル3
"スコア:" & 1000 - DateDiff(starttime,pushtime,TimeUnit.Milliseconds)
```

・必要のない切替、TimerのVisibleに「false」と記載しておきます。
・ラベル3のVisibleに以下を記載しておきます。
```
!timestop
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404009/0b94fd08-2218-b4b6-2cf4-e5ccd6b7cc0d.png)

# 次回
Screen2で、なんでこれを使ったのかなどの解説を行います。
異なるサイズ（A4・A3）と角度を持ったPDFをA3サイズのPDFに2アップしよう

# やりたいこと
2つの異なるページサイズ（A3とA4）を持ち、ページの向きも縦横混在するPDFを処理して、A4用紙が2アップされたA3用紙を作成します。

処理対象であるPDFの各ページのサイズと向きによって、処理を変えます。
処理は以下の通りです。

- A4タテの場合：A4サイズで貼り付ける。
- A4ヨコの場合：反時計回りに90度回転し、A4サイズで貼り付ける。
- A3タテの場合：反時計回りに90度回転し、追加する。
- A3ヨコの場合：無処理で追加する。

作成していた基本A4サイズの資料をA3サイズにとりまとめる必要があったので、下記コードを作成しました。

## 苦労した点
A4用紙を回転させつつ、A3用紙に貼り付ける方法が難しかったです。

`.rotateCounterClockwise(90)` で回転させたA4用紙を、そのまま`.mergeTranslatedPage()`でA3用紙に貼り付けられたら簡単だったのですが、回転が反映されませんでした。

最終的には`.mergeRotatedTranslatedPage()`の引数に回転角度と位置を指定することで上手くいきました。

# プログラム

```python:qiita.python
import PyPDF2
from PyPDF2 import PdfFileReader, PdfFileWriter
from pathlib import Path

input_file = "input.pdf"
ouput_file = input_file.replace(".pdf", "_2up.pdf")

# 入力PDFファイルを開く
reader = PdfFileReader(input_file)
# 出力PDFファイルを開く
output_pdf = PdfFileWriter()

# ページサイズを取得し、ページの向きを把握する（A3用紙なら回転させる）。
def organaize_page_rotate(page):
    page_width, page_height = page.mediaBox.getWidth(), page.mediaBox.getHeight()
    rotated_angle = 0
    # A3用紙の場合
    if (page_width > 1000) or  (page_height > 1000):
        page_size = "A3"
        if page_width < page_height:
            page = page.rotateCounterClockwise(90)
            rotated_angle = 90
    # A4用紙の場合
    else:
        page_size = "A4"
        if page_width > page_height:
            rotated_angle = 90
    return page, page_size, rotated_angle

# A3用紙にA4用紙を貼り付ける。左右の位置と、回転の有無で処理を変える。
def rotated_and_add_page(a3_page, page, tx, rotated_angle):
    # 回転が必要ない場合
    if rotated_angle == 0:
        a3_page.mergeTranslatedPage(page, tx=tx, ty=0)
    # 左側で回転が必要な場合
    elif tx == 0:
        a3_page.mergeRotatedTranslatedPage(page, tx=595.32/2, ty=595.32/2, rotation=rotated_angle)
    # 右側で回転が必要な場合
    else:
        a3_page.mergeRotatedTranslatedPage(page, tx=tx, ty=595.32, rotation=rotated_angle)

# 各ページを処理する
old_right_page_num = -1
for page_num in range(reader.getNumPages()):
    # A3用紙の右側へ既に追加していればスキップする
    if page_num == old_right_page_num:
        continue
    page = reader.getPage(page_num)
    page, page_size, rotated_angle = organaize_page_rotate(page)  

    # A3用紙の場合
    if page_size == "A3":
        output_pdf.addPage(page)

    # A4用紙の場合
    else:
        # A3用紙に2アップでページを貼り付ける
        a3_page = PyPDF2.pdf.PageObject.createBlankPage(None, 1190.52, 841.92)
        rotated_and_add_page(a3_page, page, tx=0, rotated_angle=rotated_angle)

        right_page_num = page_num + 1
        if right_page_num < reader.getNumPages():
            print(right_page_num)
            right_page = reader.getPage(right_page_num)
            right_page, page_size, rotated_angle = organaize_page_rotate(right_page)

            # 右側に貼り付けたい次のページがA3用紙の場合は処理をスキップする
            if page_size == "A3":
                pass
            # 右側に貼り付けたい次のページがA4用紙ならそのまま張り付ける
            else:
                rotated_and_add_page(a3_page, right_page, tx=595.32, rotated_angle=rotated_angle)
                old_right_page_num = right_page_num

        output_pdf.addPage(a3_page)

# 出力PDFファイルに保存する
with open(ouput_file, 'wb') as f:
    output_pdf.write(f)

print("Completed")
```