OmniAICreator/Qiita-1.07M huggingface dataset:
双方向コピペ禁止-物理PC⇔クラウドPCのクリップボード禁止

マイクロソフトの渡部です☺

物理PC上でクラウドPCにアクセスする際、クラウドPC上のテキストやファイルを物理PCに持ってこさせたくないニーズがありませんか？

本記事では、物理PCとWindows 365 クラウドPC間の文字やファイルのコピー＆ペーストを**双方向で**禁止する設定方法をご紹介します。

:::note info
片方向はプレビュー中の機能となります。
[新機能](https://learn.microsoft.com/ja-jp/windows-365/enterprise/whats-new)
[片方向クリップボード禁止](https://learn.microsoft.com/ja-jp/azure/virtual-desktop/clipboard-transfer-direction-data-types?tabs=intune)
本記事は**双方向**のやり方を紹介します
:::

# 類似機能
[画面キャプチャ禁止設定](https://learn.microsoft.com/ja-jp/azure/virtual-desktop/screen-capture-protection?context=%2Fwindows-365%2Fcontext%2Fpr-context)
[透かし](https://learn.microsoft.com/ja-jp/azure/virtual-desktop/watermarking)
[RDPデバイスのリダイレクト禁止](https://learn.microsoft.com/ja-jp/windows-365/enterprise/manage-rdp-device-redirections)


# 双方向リダイレクト禁止　設定方法
設定にあたって必要なもの
- Microsoft Intune 管理者の権限

**１．Microsoft Intuneにログインする**
管理者権限があるアカウントで、[Microsoft Intune](https://intune.microsoft.com/)にログインしてください

**２． 構成プロファイルを立ち上げる**
デバイス＞構成＞作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/cca1341a-beaf-2bf9-2c3f-58cb0d056721.png)

新しいポリシー＞
- プラットフォーム:Windows 10以降
- プロファイルの種類: 設定カタログ

＞作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/c5282872-a60c-96c3-e219-0bd989e0fe70.png)

**３． 基本設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/97dbdff5-4779-dcb4-30c7-656de17a8aab.png)

**４．構成設定**
設定の追加＞"Clipboard"で検索＞管理用テンプレート　配下、"デバイスとリソースのリダイレクト"　を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/cd5bed7c-3683-2db5-77e1-aaefd7dffef2.png)

チェックマークを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/6b5937a2-aacb-60de-5fc8-085fc60fef96.png)

管理用テンプレート　を押下し展開、
Do not allow Clipboard redirection　を押下し"Enabled"に
次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/061f14a7-d363-25df-577c-7011b456b253.png)

（スコープタグはスキップ。次へ）

**５．割り当て**
この設定を割り当てたい**クラウドPC**を含めたセキュリティグループを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/8da37816-02c3-e0bc-28c3-61589059f69d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/c467758f-dbd4-447a-95ad-118aed4038bd.png)

次へ

**６．確認および作成**
構成の内容を見直し、よろしければ　作成　を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/16959d83-7dc4-9763-5c02-f84c94c74c9a.png)

設定はこれで完了です。
あとはIntuneからクラウドPCへ、設定が配布されるのを待ちます。

# 設定の配布状況確認
クラウドPCに対して、設定が割り当てられたか確認できます。
デバイス＞構成＞作成したポリシーを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/2719926b-b134-aa35-c2f6-37fccc90ae5f.png)

レポートの表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/4efb86f8-d061-8647-ca4e-1bc204d40373.png)

設定が割り当てられたデバイスの一覧と状態が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/befc51c4-079d-6db3-d7e1-b299821a46b1.png)
Azure VPN Gateway の 「BGP ピアの状態」	の アラートについて

## ◎概要
Azure プロジェクトで、Azure VPN Gateway と Fortigateを使用した 
サイト対サイトのVPN の アラートの選定した際、「BGP ピアの状態」は
一体なにを見ているのかを記載します。

<br>

## ◎VPN Gateway メトリック
Azure VPN Gateway メトリックは下記の画像の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689346/3350567c-82a0-3a59-0133-cb7aecba447a.png)

公式ドキュメントはこちら
https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-howto-setup-alerts-virtual-network-gateway-metric

<br>

アラートしては、単純にVPN の 接続数をカウントして、接続が切れたら
アラート発報するというのが一番ベターなアラートだと思います。

只、ポイント対サイトの VPNであれば、「P2S 接続数」というのがあるので
これを使用すれば問題ないのかと思いますが、サイト対サイトのVPN だと
接続数をカウントするメトリックのアラートはないようです。


今回、Azure VPN Gateway と Fortigate 間のルーティングは、
BGPを使用して動的にルートを学ばせます。

なので、学習したルートの数をカウントして、例えば 5つBGPで学ぶルートがあれば
発報条件を、5つ以下に設定すれば、BGPが切れる、即ちこれはVPNが切れると同義だと
思いますので、これで発報させようかとも考えました。

まぁ、まれですがBGPだけが切れるというのも経験したことはあるので、
BGPが切れる、イコール VPN が切れるとはならないですが、BGPが切れれば
お互いを通るルートなくなり、ルーティング出来なくなる訳ですから、
これでもいいかと思ったのですが、

結論「BGP ピアの状態」の数をカウントするというのが、
なんか良さそうだと思い、これにしました。
>Azure VPN GatewayのログからVPNが切断されたというのを認知して
アラートの発報させるなどのやり方もあるようですが、現状はこれで問題ないので
このメトリックを使用しています。

Azure VPN Gateway と Fortigate だけで、特に間にルータ等は入ってこないので、
Azure VPN Gateway の BGPピアノIPアドレスは、Fortigate の プライベートIP のみに
なります。

なので、BGPが切れる、即ちこれはVPNが切れると同義だと思いますので、
BGPピアの接続状態が、接続中であればVPNが切断されたとしてアラートを
発報するという方法をとっています。

<br>

## ◎BGP ピアの状態
では、BGP ピアの状態は Azure VPN Gateway の どこを見ているかと
いいますと、Azure VPN Gateway のコンソール画面にいき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689346/3bc0c197-ab5c-b6f7-2581-e1164b150aba.png)

下記の「BGPピア」の所の

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689346/75a7dea7-45bb-66ee-e782-5c52ec237807.png)



「状態」という所を見ています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689346/db8363e8-0e1b-793e-4c09-ab4183588cb4.png)

「Connected」であれば接続していて、BGPが切れるなどの事象が起これば
「Connecting」に変わります。

つまり、「Connected」であれば カウントして、「Connecting」であればカウント
しません。

<br>

最後に注意点として、「BGP ピアの状態」	のメトリックの単位ですが、
公式ドキュメントにも、単位は「Count」と記載されていますが、僕の場合
Count では上手くいきませんでした。そこで単位を、合計の「SUM」に変更した所、
想定通りの動きをしてくれました。

Azure サポートに確認してみた所、想定の通りの動きをしなかった際は、
単位を変更してみる事は、策としては間違っていないとの事です。

なので、こちらのメトリックを使用して想定通りの動きをしなかった際は、
単位を変更してみください。
[過去記事]環境構築でよく見かける「curl」ってなんだ！？

## curlってなんだ！？

### ファイルの転送もしくは受信をするコマンドラインツールのこと

- 読み方は「カール」らしい（ずっと「シーユーアールエル」だと思ってた）
- ファイルリソースの特定にURLの構文を用いる事ができる。
- めっちゃ幅広いインターネットプロトコルをサポートしているらしい。
- フリーソフトウェアらしい。
- 例えば弊社のコーポレートサイトのページを取得したいならターミナルで下記の様に実行すれば良い。

```
curl https://google.com
```

- 上記を実行すると構成しているhtmlのコードがターミナル上に出力される。

### 取得した内容をファイルに出力することもできる

- curlコマンドに-oオプションをつけると出力内容をファイルに書き出して取得する事ができる。下記は当該のコマンド例

```
curl -o 書き出すファイル名　書き出したい対象のURL
```

- google.comのhtmlをgoogle.htmlに書き出したいなら下記のようになる。

```
curl -o google.html https://google.com
```

カレントディレクトリにgoogle.htmlが作成され、HTMLが出力されている。

### URL構文で指定したファイルリソースのヘッダのみを取得することもできる（先輩に教えてもらった内容）

- curlコマンドに-Iオプションをつけると指定したファイルリソースのヘッダのみを標準出力に表示することができる。下記は当該コマンドの例

```
curl -I 対象のURL
```

## まとめ

- curlはweb上のファイルリソースをURL形式で指定して取得するコマンドラインツール
- めっちゃいろんなプロトコルに対応している。
- だから環境構築のときにパッケージの取得とかに使われる。
- -oオプションは指定したファイルリソースを標準出力するのではなくファイルとして取得したいとき。
Jetson Nano (Ubuntu 18.04LTS)でUbuntu Proを無理やり使う

## 概要
Jetson Nanoの延命のため、Ubuntu ProのESMを適用することを思いついたが、カスタムされたJetpackのイメージだからなのかアタッチしてサービスを有効化するところでエラーになる。
試行錯誤して無理やり動かす方法を見つけた。(再現性があるかは不明)

まともなやり方ではないので、何か起きても責任取れません。ご了承ください。

## 前提条件
- `sudo pro attach XXXXXXX`でProステータスの紐付けが終わっている
- `sudo pro status`で`esm-apps`等全てが`disabled`になっており、`sudo pro enable XXXX`で有効化できない(エラーが出る)
- モニタ直結・VNC等でGUIデスクトップ環境が使える

## 方法
1. デスクトップ環境で「設定」を開き、「ソフトウェアとアップデート」→「Ubuntu Pro」タブを開く
2. ESM InfraかESM Appsのトグルを「オン」にし、すぐに`sudo apt update`と`sudo apt upgrade`を実行 (無効化されるまでのラグを悪用？してESMアップデートを適用している)
3. 少しするとエラーが出て強制無効化されるので、一度「ソフトウェアとアップデート」を閉じる

この1〜3をトグルをオンにする方を変えたりして何回も繰り返したところ、なぜか普通に有効化できるようになった。(無効化されなくなった)
rosも`sudo pro enable ros`で普通に有効化できた。
途中アップデートタブのアップデートのインストールあたりを有効化したりしたのでその辺も関係しているかもしれない。

![スクリーンショット 2024-03-26 21.06.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115387/8ed834fa-98b8-80e0-175b-e0ca3b8bbcfa.png)
【ブロックプログラミング言語】Trees を作りました

# はじめに

奇抜な言語を作りたいと思っていた私。大学にて改めてコンパイラを学びなおす。
「構文木って美しいよなぁ...」→ 「ん？これを直接落とし込むプログラム言語を作ればいいじゃないか！」

https://x.com/SnowEsamosc/status/1765309061241983396?s=20

そうして Trees 言語がうまれたのであった。

-----------------

[チュートリアル](https://github.com/Snowman-s/Trees/wiki) は GitHub に公開しました。この記事ではそれをさらにまとめたものを説明します。

# 「Trees」は、こんなプログラミング言語です

今回私が作成したブロックプログラミング言語 Trees では、構文木チックにプログラムを記述することが可能です。

例えば、下のプログラムは「3 × 4」...つまり「12」を出力します。

```:3 × 4 を表示するプログラム - 12を表示
        ┌─────┐
        │print│
        └───┬─┘
        ┌───┴─┐
    ┌───┤  *  ├──┐
    │   └─────┘  │
┌───┴─┐      ┌───┴─┐
│  3  │      │  4  │
└─────┘      └─────┘ 
```

次はFizzBuzzのプログラムです。
このプログラムは "12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz" を表示します。

```:FizzBuzz
┌───┐      
│seq├─────────────────────┐
│   ├───────────────┐   ┌─┴───┐
└─┬─┘              ┌┴──┐│print├──┐
┌─┴────┐    ┌──────┤for│└─────┘┌─┴─┐
│defset├─┐ ┌┴─┐ ┌──┤   │       │out│
└─┬────┘ │ │15│ │  └─┬─┘       └───┘
┌─┴───┐┌─┴┐└──┘┌┴──┐┌•──┐  
│"out"││""│    │"i"││set├───┐
└─────┘└──┘    └───┘└─┬─┘  ┌┴─────┐
                    ┌─┴───┐│strcat│
                    │"out"│└┬───┬─┘
                    └─────┘┌┴──┐│  
                           │out││  
                           └───┘│
          ┌─────────────────────┘
          │   ┌───────────────┐   ┌───────────┐   ┌───┐
         ┌┴──┐│              ┌┴──┐│          ┌┴──┐│  ┌┴─────┐
 ┌───────┤if0├┘       ┌──────┤if0├┘   ┌──────┤if0├┘  │to str│
┌┴┐      └┬──┘       ┌┴┐     └┬──┘   ┌┴┐     └┬──┘   └┬─────┘
│%├───┐  ┌┴─────────┐│%├───┐ ┌┴─────┐│%├───┐ ┌┴─────┐┌┴┐
└┬┘  ┌┴─┐│"FizzBuzz"│└┬┘  ┌┴┐│"Fizz"│└┬┘  ┌┴┐│"Buzz"││+├─┐
┌┴┐  │15│└──────────┘┌┴┐  │3│└──────┘┌┴┐  │5│└──────┘└┬┘┌┴┐
│+├─┐└──┘            │+├─┐└─┘        │+├─┐└─┘        ┌┴┐│1│
└┬┘┌┴┐               └┬┘┌┴┐          └┬┘┌┴┐          │i│└─┘
┌┴┐│1│               ┌┴┐│1│          ┌┴┐│1│          └─┘
│i│└─┘               │i│└─┘          │i│└─┘
└─┘                  └─┘             └─┘
```

自作のプロシージャ（ほかの言語で言う関数）を定義し、処理の共通化をはかることもできます。

```: プロシージャ定義 - 6 を表示
┌───┐      
│seq├────────────────────┐
└─┬─┘                   ┌┴────┐
┌─┴─────┐               │print│
│defproc├─────┐         └┬────┘
└┬──────┘    ┌•┐        ┌┴────────┐
┌┴──────────┐│*├─┐      │two times│
│"two times"│└┬┘┌┴─┐    └┬────────┘
└───────────┘┌┴┐│$0│    ┌┴┐
             │2│└──┘    │3│
             └─┘        └─┘

```

# おわりに

無粋ながら Trees 言語は完全にネタとして作ったことを申し添えておきます。

# GitHub

コード

https://github.com/Snowman-s/Trees

チュートリアル

https://github.com/Snowman-s/Trees/wiki
タスクランナーとは何なのか

こんにちは、toraguitarです。
フロントエンジニア(以下、FE)として働いています。
今回は「タスクランナー」についてまとめていきます。

## この記事の目的
* 筆者が 「言葉は知っているけど説明できない」というものをピックアップする
* 調べなくても概要を説明できる、具体例を1~2つ出せるレベルに引き上げる
* 歴史的背景など踏み込んだ説明は省く

## 言葉の意味
タスクランナーとは、開発作業の効率を上げる自動化ツールです。
多岐にわたる作業を簡素化し、開発の生産性を向上させます。

昨今のwebページはhtml, css, JavaScriptなどを利用して表示されますが、実際の開発でそれらを直接書くことはほとんどありません。
以下のようなものを用いて開発を行うことがほとんどです。

* **テンプレートエンジン**(ejs, pugなど)
* **フレームワーク**(Vue.js, Reactなど)
* **CSSプリプロセッサー**(Sassなど)

これらはそのままだとブラウザに表示できないため、html, css, JavaScriptに変換＝**コンパイル**する必要があります。
そのような変換作業を自動化してくれるのが、タスクランナーです。

## どんなタスクランナーがあるのか

### Gulp
最も耳にするタスクランナーのうちの一つですね。
JavaScriptで自動化の処理を書き、非同期的に自動化の処理を走らせることができます。
直感的で自由度が高く、初心者にはこちらの方がハードルが低いという解説が多かったです。

### Grunt
Gulpと比較する文脈でよく登場しました。
Gulpに比べてより細かな債務分担ができる、つまりタスクの線引きがしやすいという特徴があります。
その分自由が聞きにくい、処理が遅いため、Gulpとどっちが良いかはプロジェクトによるようです。

### npm scripts
[Frontend Developer Roadmap 2023版](https://roadmap.sh/frontend)で使用が推奨されているタスクランナーです。
package.jsonの「scripts」箇所に記述することで、シェルスクリプトやaliasコマンドを登録・実行することができます。

```json
{
    "scripts": {
        "say": "echo 'Hello world!!'"
    }
}
```

なお、タスクランナーについて調べていると、関連して**Webpack**がよく登場しました。
Sassのコンパイルができるなど、一部タスクランナーの機能を備えてはいますが、基本的には「**モジュールバンドラー**」と呼ばれるものです。
こちらはJavaScriptなどのファイルを、複数ある状態から一つのファイルにまとめる＝**バンドル**するためのプログラムです。

## タスクランナーの役割
一言で開発効率を上げる、自動化すると言っても、具体的に何ができるのでしょうか。
ツールによっても様々ですが、ここでは2つ機能を紹介します。

### コンパイル
冒頭にも挙げた通り、web開発ではhtmlやcssをそのまま書くことはほとんどありません。フレームワークやテンプレートエンジンを用いて書いたプログラムを、ブラウザで表示できる形に変換します。

### ファイルの圧縮・最適化
JavaScriptのminify化、画像の圧縮など、ファイルの最適化を行います。
ファイルの読み込み速度、ページの表示速度の改善に繋がります。


## まとめ
* タスクランナーとは、開発効率を上げるための自動化ツール
* gulp, Grunt, npm scriptなどが代表的なタスクランナーである
* ファイルのコンパイル、圧縮、最適化を自動で行ってくれる

## 参考記事
* [コーディング効率を変える！おすすめタスクランナー完全ガイド](https://dad-union.com/toolapps/3732)
* [タスクランナーGulp(ガルプ)を使ってみる](https://jps-code.com/gulp)
* [絶対つまずかないGulp 4入門インストールとSassを使うまでの手順](https://ics.media/entry/3290/)
* [現場で使えるGrunt入門 | 第1回 Gruntを試そう - CodeGrid](https://www.codegrid.net/articles/grunt-1/)
* [Gruntとgulpを比較 〜 JSおくのほそ道 #008](https://qiita.com/hosomichi/items/badaee6d0de448ba9770)
* [Node.jsユーザーなら押さえておきたいnpm-scriptsのタスク実行方法まとめ
](https://ics.media/entry/12226/)
* [Frontend Developer Roadmap: What is Frontend Development?](https://roadmap.sh/frontend)
* [処理を自動化できる「タスクランナー」とは](https://www.e-webseisaku.com/column/web/7365/)
ABMと管理対象AppleID

# 管理対象AppleIDについて
https://support.apple.com/ja-jp/guide/apple-business-manager/axm78b477c81/web

https://support.apple.com/ja-jp/guide/deployment/depdc4ba8d82/web

# IdPとの連携

https://learn.microsoft.com/ja-jp/entra/identity/saas-apps/apple-business-manager-provision-tutorial

https://support.apple.com/ja-jp/guide/apple-business-manager/axm8c1cac980/1/web/1

https://support.apple.com/ja-jp/guide/apple-business-manager/axmd88331cd6/1/web/1

https://note.com/krhtj/n/n83b396061fd2

https://www.youtube.com/watch?v=9GrJcClUlB8

# 結論

ABMの場合一括登録はIdPとの同期だけだが、この設定をするとIdPのドメインと同じAppleIDが個人で作れなくなるというのと、すでに作成済みの場合移行を促されるという弊害があり、本当にメールドメインの設計段階から検討していないと現実的に移行が厳しい。
さらに、MFAで使用する電話番号の登録制限は残っているという使い勝手の悪さ。

一方、個人AppleIDみたいに、携帯を解約して電話番号にショートメッセージが受信できなくなるとか、ユーザーにAppleIDのパスワードが変更されて、本人もわかなくなって等、の問題が発生するよりは、パスワードや登録電話番号のリセットが管理者で可能な管理対象AppleIDを使った方が良いとも思う。

Outlookで連絡先をすべて管理するのであれば、そもそも管理対象AppleIDを作らなくてもよいので、その企業の運用の仕方によると思います。
連絡先だけでなく、メモやSafariなどをiCloudと同期しておきたいなら、管理対象AppleIDの選択肢一択ですかね。※MDMの使用は前提での話です

ただ、とにかくアカウントの作成が一件一件すべて手動なので、そこは我慢しなければいけません。
色々中途半端で、Appleもそんなもんかという感想です・・・
更新リクエストの重複登録対策　idempotency(冪等性)

# はじめに
[更新系APIの状態不整合の解決策 リトライ](https://qiita.com/okotaniki/items/a0195aa70494e46f9c5f)の課題として、更新リクエストのリトライで複数のトランザクションを生成させないための設計の肝をメモする。


#### 同一RequestID受信時のidempotency(冪等性)のレスポンス返却
idempotencyの設計思想によるAPIは、同じRequestIDを受信した場合、最初に受信したRequestIDを同じレスポンスを返却する。（下のシーケンスでは、レスポンス値にOKに加えてTransactionID,TimeStampを例として記載）
課題としてサーバBのデータベースの性能を考慮する必要がある。RequestIDの同一チェックに加えて、同一の場合、過去のレスポンス値をデータベース検索するため処理が重くなる。
サーバBにとって性能に課題がある一方、サーバAは実装が容易となる。

#### 正常ケースのシーケンス
```plantuml
サーバA->サーバB : 更新リクエスト1回目(RequestID=001)
note right:処理済み
サーバB-->x サーバA : OK,TransactionID,TimeStamp etc,
note left:状態遷移　初期状態→不明
サーバA-> サーバB : 更新リクエスト2回目(RequestID=001)
note right:RequestIDが001を2回受信したので、新たなデータは生成しない
サーバB-->サーバA:OK,TransactionID,TimeStamp etc,(1回目と同じレスポンス)
note left:状態遷移　不明→処理済み
```
:::note info
よくあるバグ
リトライ時にRequestID=002でリクエストして、サーバBに2件トランザクションが生成されて、件数不整合が発生する。
```plantuml
サーバA->サーバB : 更新リクエスト1回目(RequestID=001)
note right:RequestID001　処理済み
サーバB-->x サーバA : OK
note left:RequestID001　初期状態→不明
サーバA-> サーバB : 更新リクエスト2回目(RequestID=002)**←001にすべき**
note right:RequestID002　処理済み
サーバB-->サーバA:OK
note left:RequestID002　不明→処理済み
```
|トランザクション|サーバAの状態|サーバBの状態|
|---|---|---|
|RequestID001|不明|処理済み|
|RequestID002|処理済み|処理済み|
:::

#### 業務エラー
```plantuml
サーバA->サーバB : 更新リクエスト1回目(RequestID=001)
note right:更新リクエストを業務エラーと判定したので処理なし
サーバB-->x サーバA : NG,業務エラーコード
note left:状態遷移　初期状態→不明
サーバA-> サーバB : 更新リクエスト2回目(RequestID=001)
note right:RequestIDが001を2回受信したので、まったく同じレスポンスを返却
サーバB-->サーバA:NG,業務エラーコード(1回目と同じレスポンス)
note left:状態遷移　不明→業務エラー
```

# 結論
サーバAが設定する一意なパラメータ(ここではRequestIDと定義した)によりサーバBに重複してトランザクションが生成されることを防止できる。

API仕様が、次のようになっているか確認すること
- リトライ時に同一のRequestIDを設定する
- 同一RequestIDに対してidempotencyのレスポンスが返却される

(再掲)課題としてサーバBのデータベースの性能を考慮する必要がある。RequestIDの同一チェックに加えて、同一の場合、過去のレスポンス値をデータベース検索するため処理が重くなる。
第10回 Try English LT! for engineers 発表資料まとめ

# Try English LT! for engineersとは？

エンジニア向けの英語のみのLTイベントを行なっています！
発表テーマはエンジニア向けの内容であれば自由です。
英語でLTをやるとなると、中々ハードルが高く、 参加者が海外の人ばかりだと、なおさら難しく感じると思います。
ちょっと自信はないけど、 英語のLTにチャレンジしてみたいという人にぜひ発表してもらいたいです。
英語が好きなエンジニア同士で交流できるイベント運営ができればと思っています。

第10回イベントページ

https://try-english-lt.connpass.com/event/308327/

## 発表資料
・Nobu 
エンジニアの海外就職 準備編
Preparation for working abroad for engineers

https://docs.google.com/presentation/d/1L1PACSbxG7UUuYL-84wbkMQ6_LLx3UOTN0GmnKv2Vhg/edit?usp=sharing

ワトソンさん
"Do not post credentials on Slack" High School Song

https://speakerdeck.com/wattson496/do-not-post-credentials-on-slack-high-school-song-try-english-lt-10

・kohekoheさん
Terraform user getting started with AWS CDK

https://speakerdeck.com/kohekohe/english-lt-terraform-vs-aws-cdk-kohekohe

・Ugoさん
The Talking Rhythm

https://speakerdeck.com/yugo/the-talking-rhythm

・Yuta Miyamaさん
海外現地就職で6年エンジニアをやって分かった
「英語の力の入れどころ、抜きどころ」

https://docs.google.com/presentation/d/1_nYBeVhYdeUXcZlH2OFbX-Xnf4GBYDU6hyPG3xtrI5k/edit#slide=id.p

・Tamtamさん
"Which should come first, the design of the data model or the domain model?"

https://speakerdeck.com/tamtam0423/which-should-be-designed-first-the-data-model-or-the-domain-model

・Jumpakuさん
cyamli: A YAML-based CLI code generator

https://drive.google.com/file/d/11EMMdoeFo20exqIPYPqNd9bi7CYY5EFU/view
ユニークなレコードの差分をチェックするツールを自作してみた

## はじめに

テキストベースの比較ツールは世の中に多く出回ってるんだけど、テーブルや配列などの構造データを基準にした比較ツールは見当たらなかった。
需要が少ないのか、探し方が悪いのかはわからないけど、自分が使いたいから作ったってだけの話。

発表用にまとめたので、こっちを見たほうがいいかも

https://speakerdeck.com/eag000gle/diff-unique-record-introduction

## ユニークなレコードとは

テーブルの主キーや複合ユニークキーを持っている一意なデータのことです。
例えばdateとnameで一意な組み合わせをもつ構造データのことを指します。

```typescript
{
  date: '2023-12-01',
  name: 'sales',
  value: 100,
}
```

## 業務的な使い所

業務で複雑な計算処理をするWebアプリの開発担当をしています。
入出力データ共に1000以上のデータを含んだ配列を扱っており、テーブルのデータやユーザーの入力値など変数が多く、テストコードのチェックで100%の保証をできるとは思っていません。
実際の生データを使って、コード修正前後に意図しないデータ変更がないか確認するのに使っています。

他には、BigQueryから出力したCSVデータを使った分析をしていて、最新の出力データとの比較なんかにも使えます。

## テキストベースの差分ツールを使ってみる

VSCodeでGit差分を参考に出してみる。

### 単発レコード

1レコードの1項目が変わるぐらいならこれで問題ない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206583/76fe4090-dfd7-fc05-84eb-24044c48ba53.png)

### 複数レコード

単発レコードの分 + レコードの並びが変わると、削除と追加の両方が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206583/321f9439-5d9e-f781-401a-0fd69e121769.png)


## ユニークレコードで差分を出してみる

2023-12-01 sales データはユニークであるため、データ順も関係なく、新旧で比較が可能となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206583/e78fc050-9932-1558-fb38-4bac48c3b108.png)

## npmパッケージで公開

まずパッケージを作ってnpmで公開してみることにした。Web版とパッケージ版の両方を公開することに意義があると考える。

というのも、誰が運営しているかわからないWebサイトに業務データを貼り付けるのに抵抗があって、例えば画像や動画ファイルの変換サイトとかあるけども、極力使いたくないタイプなのだ。
世の中にはChat GPTに社内情報を貼り付けたりする人がいるわけだけど、無料で使えるリソースの対価は何かしら支払っていると考えておいた方がいい。

Webサイトにデータを貼り付ける = バックエンドを通せる ので、気になる人はパッケージ版を使うと安心かもしれない。
とはいえ、公開パッケージも無料で使えるわけで、悪意のある人間が中にはいるかもしれない。そう考えると、今回作ったパッケージも第三者には怪しい野良ツールなんだと思う。

## VercelでWeb版を公開

自分で作ったnpmパッケージをinstallして、Next.jsでWebインターフェースを作成。
最近はVercelでお手軽に公開できるのがかなり便利ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206583/8e5c51d3-9dc7-58bc-9185-4b3e7dddcc25.png)

## アウトプット

READMEに使い方など書いてるので、参考までに。

### パッケージ版
https://github.com/peko-thunder/diff-unique-record

https://www.npmjs.com/package/diff-unique-record

### Web版

https://github.com/peko-thunder/diff-unique-record-web

https://diff-unique-record-web.vercel.app

## 終わりに

というわけで、業務外にチマチマ作ってたツールの紹介でした。
自分が業務で作りたいツールを業務外で作れば、自分の成果物として外部にアウトプットできるのがポイントです。

エンジニアあるあるですが、自分が楽するためのツールを作るのは楽しいんですよね。
とはいえ体を休めるのも仕事なので、程々にしましょう。
【CSS】リセットCSSについて

## はじめに
学習したことを自分用の参考書のようにまとめていきます。

## リセットCSSについて
同じh1タグだとしても、GoogleChromeやSafariなどブラウザごとに表示されるサイズが違ってきます。
その状態でコーディングをしていくと表示が崩れてしまう可能性が出てきます。

なので、まずリセットCSSで表示をリセットしてからコーディングをすることで、どのブラウザでも同じように表示できるようになります。


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>タイトル</title>

  <!-- リセットCSS -->
  <link rel="stylesheet" href="css/reset.css">
  <!-- style.css -->
  <link rel="stylesheet" href="css/style.css">
</head>

<body>
</body>

</html>
```

:::note warn
"reset.css" と "style.css" の順番を逆にしないこと。
逆にしてまうと全てのスタイルがリセットされてなかったことになります笑
:::



## さいごに
いかがだったでしょうか。

他にもいろいろな記事を書いているのでぜひ読んでいただけたら嬉しいです。
【HTML】headタグの中身について

## はじめに
学習したことを自分用の参考書のようにまとめていきます。

## headタグの中身

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <!-- 文字コード -->
    <meta charset="UTF-8">
    <!-- ビューポート -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- タイトルタグ３０文字以内 -->
    <title>タイトル</title>
    <!-- ディスクプション１２０文字から１６０文字 -->
    <meta name="description" content="ページの内容を表す文章">
    
    <!-- OGP -->
    <meta property="og:site_name" content="サイト名">
    <meta property="og:type" content="ページのタイプ"><!--website or article-->
    <meta property="og:url" content="ページのURL">
    <meta property="og:title" content="ページのタイトル">
    <meta property="og:description" content="ページの説明">
    <meta property="og:locale" content="ja_JP">
    <meta property="og:image" content="画像のURL">
    <meta name="twitter:card" content="summary">
    <!--
    <meta name="twitter:site" content="@Twitterユーザー名" />
    <meta property="fb:app_id" content="appIDを入力" />
    -->

    <!-- 検索させない -->
    <meta name="robots" content="noindex,nofollow">

    <!-- ファビコンなど -->

    <!-- CSS、javascript -->
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.css">

    <!-- 不要なコード -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="keywords" content="...">
    <meta name="author" content="...">
</head>

<body>
</body>

</html>
```






## さいごに
いかがだったでしょうか。

他にもいろいろな記事を書いているのでぜひ読んでいただけたら嬉しいです。
WSL に gtest を導入する

## 概要
WSL に GoogleTest(通称 gtest)を導入するための手順書である

## 前提
OS: Windows 10 バージョン 2004 以上 or Windows 11
WSL がインストール済みであること

WSL インストール手順は下記参照

https://qiita.com/semiflat/items/4303a1d8dc20f599aef8


## gtest インストール手順
### ソースコードをダウンロードして展開する
以下のコマンドラインを WSL 上で実行
```
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
tar zxvf release-1.8.0.tar.gz
cd googletest-release-1.8.0/googletest/
```
エラーメッセージが表示されなければ OK

### cmake をインストールする
以下のコマンドラインを WSL 上で実行
```
sudo apt install cmake
```
エラーメッセージが表示されなければ OK

### gtest のソースコードをビルドする
以下のコマンドラインを実行する
```
mkdir build
cd build
cmake ..
sudo make
sudo make install
```
成功した場合、/usr/local/lib に libgtest.a と libgtest_main.a が作成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/59dc9600-89c2-f70f-a2b2-9fcb11796973.png)

#### cmake が失敗する場合
以下のコマンドラインを実行し、gcc と g++ にパスが通っているか確認する
```
gcc --version
g++ --version
```
パスが通っていればバージョン情報が表示される
バージョン情報が表示されない場合は、以下のコマンドラインを実行し gcc または g++ をインストールする
```
sudo apt install gcc
sudo apt install g++
```
インストール後、再度パスが通っているか確認し、通っていれば OK
Spring bootの構築ツール(Spring Initializr)

## Spring Initializr
Spring Bootを使った簡単なウェブアプリケーション、Spring Initializrを使用してプロジェクトを生成し、簡単なRESTfulウェブサービスを作成できる。
https://start.spring.io/

## 構築(Hello World)
### プロジェクトのセットアップ
Spring Initializr(https://start.spring.io/) にアクセスします。
以下の設定を行います：<br>
- Project: Maven Project
- Language: Java
- Spring Boot: 最新バージョンを選択
- Project Metadataを入力（Group, Artifactなど）
- Dependenciesに「Spring Web」を追加
- 「Generate」ボタンをクリックして、プロジェクトを生成し、ダウンロード<br>
![截屏2024-03-26 19.50.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941840/09d5af49-ef71-d77d-cf22-dc5d90438b47.png)

### ビジネスロジックの作成
ダウンロードしたプロジェクトを開き、次のJavaクラスを作成または編集:<br>
```
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello %s!", name);
    }
}
```

### アプリケーションの実行
1. コマンドラインまたはIDEを使用して、プロジェクトのルートディレクトリに移動する。<br>

2. 以下のコマンドを実行して、アプリケーションを起動：<br>
```
./mvnw spring-boot:run

```

3. ブラウザを開き、http://localhost:8080/hello にアクセスして、デフォルトの挨拶が表示される

4. http://localhost:8080/hello?name=YourName  にアクセスして、YourName を自分の名前に置き換えます。パーソナライズされた挨拶が表示される


## 問題対策
以下のエラーメッセージの場合：<br>
```
package org.springframework.web.bind.annotation does not exist
```

まず、pom.xmlをチェックする。dependenciesの中に、以下の内容を確認：
```
    <dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>

	<dependency>
        <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
    </dependency>

```

<br>
そして、以下のコマンドを実行する:<br>

```
mvn clean install
```
以下のメッセージが出ると成功


![截屏2024-03-26 20.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/941840/c5bf48e9-4b1a-0540-854b-70b1ac0a9394.png)
collectionオプション

collection オプションは指定したインスタンス変数の中にある要素の数だけ、部分テンプレートを呼びだすことができる。
collectionを使えば繰り返し表示させたい要素がインスタンス変数に複数入っている場合でも`each`メソッドを使わず`render`で繰り返し表示できる。

## collectionを使う場合
```ruby
<%= render partial: 'hoge', collection: @hoges %>
```
collectionを使用する際は、複数要素が入っているインスタンス変数を、collectionオプションの対象に指定する。部分テンプレート内では、インスタンス変数から取り出した要素を、部分テンプレート名と同じ変数名で扱うことができます。
つまり、_hoge.html.erb内において、@hogesから取り出された1つ1つの要素はhogeとして扱うことができます。

## eachを使う場合
```ruby
<% @hoges.each do |hoge|%>
  <%= render partial: 'hoge', lacals: {hoge: hoge} %>
<% end %>
```
2行目の解説
_hoge.html.erbという部分テンプレートを呼び出し、その部分テンプレート内では、取り出された1つのhogeという要素をhogeという名前で扱う設定をする
「volumeをマウントする」とは

## volumeをマウントする
volumeをマウントするとは、volumeにあるファイルとコンテナにあるファイルを同期(接続)させること。
## volumeとは
Volumeとは、永続化したいデータを保存する場所です。これには、ファイルだけでなく、データベースや設定なども含まれます。
## マウントするとは
ファイルシステム内のある場所を別の場所と同期(接続)すること。
## つまり
つまりDockerで開発を行う際は、Dockerが管理するファイルと、コンテナ内にそれと同様のファイルが2つあると思います。ソースコードが変更された際に直接、開発物に影響するのはコンテナ内のファイルですが、コンテナ内のファイルを書き換えて開発を行うと、万が一コンテナが削除されてしまった際に、そのデータが消えてしまいます。
そのためDockerが管理するファイルとコンテナ内のファイルを(マウント)同期させて、Dockerが管理するファイルにソースコードを書き込み、開発を行います。
マウントさせていることにより、自動的にコンテナ内のファイルも書き換わるため、手動でファイルのコピーなどを行う必要はありません。
それによって安全に開発を行うことができます。
php artisan ui vue --authで追加/変更されるファイル

完全honaki用
悪しからず

```
ターミナル
php artisan ui vue --auth
```
上記を入力したときに追加/変更新されるファイル一覧
▪️追加されるファイル
app/Http/Controllers/HomeController.php
resources/js/components/ExampleComponent.vue
resources/sass/_variables.scss
resources/views/auth/login.blade.php
resources/views/auth/passwords/email.blade.php
resources/views/auth/passwords/reset.blade.php
resources/views/auth/register.blade.php
resources/views/auth/verify.blade.php
resources/views/home.blade.php
resources/views/layouts/app.blade.php
▪️変更されるファイル
package.json
resources/js/app.js
resources/js/bootstrap.js
resources/sass/app.scss
routes/web.php
webpack.mix.js

後から追加で入力するときは、全部のコピーをとっておこう

参考：https://qiita.com/ucan-lab/items/bd0d6f6449602072cb87
[Javascript]??って何？

# 新人殺しの多項式
if文書くのめんどくさいとか、如何にコード量を減らそうという思いで、自分はよく使う多項式。
```typescript:こんなん
let a: boolean;
// 何か処理
const b = a ? 1 : 2; // aがtrueなら1、falseなら2

// 教科書通りに普通に書くなら
let c;
if(a){
  c = 1;
} else {
  c = 2;
}
```
研修上がりの新人とか、本とかで勉強してきた人たちを簡単に絶望の淵に落とすことが出来るであろうこの特殊な書き方。
酷いときには多項式内に多項式がネストするような場合もあったり、条件部分がクソ長くて読む気失せるみたいなときもあるアレ。
```typescript:こんなん
let a: boolean, b: boolean, c: boolean;
// 何か処理
const d = a ? b ? c ? 1 : 2 : 3 : 4;
```
もはやif文で書けよと言いたくなるコレ。

構文としては「条件 ? trueの時に入れるやつ : falseの時に入れるやつ」ってだけなので、
まだ比較的覚えやすいとは思うんだけど。。。

# 更にわけわからんやつ
で、今日ちょっとドツボにはまったヤツがこちら
```typescript:こんなん
let a: string;
// 何か処理
const d = a ?? "??ってなんやねん！";
```

実装わけわからなくなりすぎて「？」２個も付けてしまったんか？と思うようなこの書き方、
「Null 合体演算子」って言うたいそうな名前がついており、

__左辺（上で言う a）が null か undefined だったら、右辺（"??ってなんやねん！"）を（bに）代入する__

という動きをします。

# 何でハマったか？
こいつ、説明にも書きましたが、 __null か undefined__ の時にしか発動しないわけで、
stringの空文字（''）は値がある判定することをしっかり完璧に忘れてて、
__「えっ、全然代入されない…ブラウザの不具合じゃね？」__ と自分のミスを棚に上げて、
天下のChrome様を疑うゲスの極みみたいなことをやってました。

# ちなみに空文字以外には、0も値ある判定になるため、気をつけなはれや！
[詳しい説明はこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing)
usbipd-winでattachしたのにWSL2側で/dev/ttyUSB*が表れない現象の解決方法

## 問題
usbipd-win version 4以降で発生するようになったと思う．
version3ではまったく問題なく使えていたのでカーネルのせいとかではないと思う．
分かんないけど．
一応現状`5.15.146.1-microsoft-standard-WSL2`

WSL2でUSBデバイス（USBシリアルデバイス）を利用するときusbipd-winを使う
powershell
```powershell
usbipd list
usbipd bind --busid #BUSID
usbipd attach -w --busid #BUSID
```

とし，WLS側で
```bash
lsusb
```
とすれば，あらたなデバイスが接続したことが確認できる．

しかしここで，
```bash
ls /dev/ | grep ttyUSB
dmesg | grep tty
```
などすれば`/dev/ttyUSB#`のようなのが見えるはずなのだが，何も表示されたない
`dmesg`の関係ありそうな部分を表示すると
```bash:dmesg
[   49.258522] hv_balloon: Max. dynamic memory size: 16268 MB
[  271.704439] vhci_hcd vhci_hcd.0: pdev(0) rhport(0) sockfd(3)
[  271.706436] vhci_hcd vhci_hcd.0: devid(262146) speed(3) speed_str(high-speed)
[  271.708593] vhci_hcd vhci_hcd.0: Device attached
[  272.056366] usb 1-1: new high-speed USB device number 2 using vhci_hcd
[  272.206412] usb 1-1: SetAddress Request (2) to port 0
[  272.239374] usb 1-1: New USB device found, idVendor=0403, idProduct=6014, bcdDevice= 9.00
[  272.240235] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  272.240812] usb 1-1: Product: Single RS232-HS
[  272.241255] usb 1-1: Manufacturer: FTDI
```
で止まっている．
本当はこの後に`/dev/ttyUSB#`につなぎました～みたいなメッセージがあるはずだがない．
疑わしいのは
`hv_balloon: Max. dynamic memory size: 16268 MB`
これ今回は一番上に表示されてるけど（実際はシステムとかのがもっと上にあるけど，関連していそう打と思っている中での話），一番下で表示されることもある．
だからどうしたと言われると分からないけど，まあ記録として．

この問題はPC自体をリブートすれば私の環境では何度でも再現する．

## 解決方法（Twitterで見かけたbetter版）

https://twitter.com/uchan_nos/status/1765976210973307226

上のリンクの人も全く同じ状況に陥っていたようだが，
彼曰く

```bash
sudo modprobe ftdi_sio
```

とすればよいらしく，試してみたら`usbipd attach/detach`の必要なく確かに解決した．



## 解決方法 (古い版．)

usbipd-winのトラブルシュートやWikiやReadmeに書いてあるやつを試していくかの要素に分けて何回かをテストした結果，おそらく

```bash
sudo service udev restart
sudo udevadm control --reload 
```

あたりが利いてそうな気がする．どっちかというと`sudo service udev restart`のほうか？これをした後に再度powershell側で`detach`して`attach`すると

```bash:dmesg
[  345.907985] vhci_hcd: connection closed
[  345.908140] vhci_hcd: stop threads
[  345.909405] vhci_hcd: release socket
[  345.909815] vhci_hcd: disconnect device
[  345.910282] usb 1-1: USB disconnect, device number 2
[  353.779104] vhci_hcd vhci_hcd.0: pdev(0) rhport(0) sockfd(3)
[  353.780334] vhci_hcd vhci_hcd.0: devid(262146) speed(3) speed_str(high-speed)
[  353.781408] vhci_hcd vhci_hcd.0: Device attached
[  354.136483] usb 1-1: new high-speed USB device number 3 using vhci_hcd
[  354.306396] usb 1-1: SetAddress Request (3) to port 0
[  354.342949] usb 1-1: New USB device found, idVendor=0403, idProduct=6014, bcdDevice= 9.00
[  354.344386] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  354.345911] usb 1-1: Product: Single RS232-HS
[  354.347132] usb 1-1: Manufacturer: FTDI
[  354.414913] usbcore: registered new interface driver ftdi_sio
[  354.417238] usbserial: USB Serial support registered for FTDI USB Serial Device
[  354.418879] ftdi_sio 1-1:1.0: FTDI USB Serial Device converter detected
[  354.420398] usb 1-1: Detected FT232H
[  354.432002] usb 1-1: FTDI USB Serial Device converter now attached to ttyUSB0
```

となり`/dev/ttyUSB0`が表れてくれた．
〇〇.△△の「.」(ドット)ってなに？

プログラミングを学び始めた当初、C#とかJavascriptとかのプログラムを見たときに、
`〇〇.△△`
といったコードが書かれていて、この「ドット」の意味がわかりませんでした。
本記事では、上の文がどういう意味なのかについて書いています。

# 目次

- [〇〇.△△の意味](#〇〇の意味)
- [まとめ](#まとめ)
- [余談](#余談)

# 〇〇.△△の意味

これについて知るためには、「クラス」という概念を知る必要があります。

「クラス」とはなにかというと、「自分の中に値や関数を持ったもの」で、`int`とか`string`みたいな、データ型の「型」に相当するものです。
クラスは、すでに用意されているもの、人が作ったもののほか、自分で好きに作ることもできます。

クラスはそれぞれ、自分の中に変数と関数を持ちます(「メンバ」「プロパティ」「フィールド」とか、いろいろ呼び方はありますが、詳しい使い分けは筆者も分かりません)。

例えば以下のような、`Human`というクラスがあったとします。

```cpp
class Human{
	// 年齢
	int age;

	// 引数に渡したご飯を食べる
	void Eat(food){
		 // なんか処理が書いてある
	}
	
}
```

この`Human`は、「年齢」というint型の変数と、「ご飯を食べる」というvoid型の関数を持ったデータ型です。

あとは`int A = ...`と宣言するのと同じノリで、

```
Human taro = ...;
```

と宣言してあげれば、`Human`型のデータ `taro` を用意できるわけです(この`taro`を「インスタンス」と呼んだりします)。

くどくどクラスについて説明しましたが、ようやく「〇〇.△△」の意味の説明です。
例えばあなたが、「`taro`の年齢を知りたい」と思ったら、

```
int taroAge = taro.age;
```

と書くことで、`taroAge`に`taro`の年齢情報をいれることができます。

一方関数については、

```
taro.Eat(おにぎり);
```

とすれば、`taro`の`Eat`関数に、おにぎりを食べさせた場合の処理をさせることができます。

こんなふうに、「あるクラスのインスタンス `A` の、`a` という変数or関数にアクセスする」ということを表現しているのが、`A.a`という文になります。

# まとめ
`〇〇.△△` = 「〇〇の△△にアクセスします」という意味

アクセスするものが変数ならなにかに代入したりして使えるし、関数ならそれを使うことができる。

# 余談

筆者の個人的なイメージの話になりますが、この`〇〇.△△`という書き方は、ディレクトリ……フォルダとかファイルのパスの書き方によく似ています。

インスタンスの直下にある変数にアクセスしたければ、`A.a`とすればいいですが、そのインスタンスがさらに別のインスタンスを持っている場合はよくあります。

例えばUnityを触っている人は、

```
gameObject.transform.position
```

こういった文を見たことがあると思います。

これなんかはインスタンスの入れ子構造の最たる例で、
「`gameObject`が持っている`transform`が持っている`position`」を取得しています。

これと同様に、PCでなにかのファイルにアクセスしたいとき、ファイルパスは

```
Users\user\デスクトップ\仕事\資料\その他\閲覧禁止\20240326.mp4
```

といったふうに、「フォルダの中のフォルダの中のフォルダの中の……ファイル」と表現できます。

実際寄せているのかもしれませんが、けっこう似てませんか？
MELSEC-Q 分解してみた

# Q00UCPU

![DSC_2707.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/a61eacea-5b71-abfb-aa0e-bc2bd8bb96af.jpeg)

![DSC_2708.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/20c7c609-086b-d8f7-38b4-0e746bc65e08.jpeg)


![DSC_2713.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/f01e64b8-c220-2442-6e1e-ed0c2e2bead0.jpeg)

下のマーキングを見る限り Q00UCPU,Q01UCPU,Q00UJCPU は同一の基板を使用してるように思います。
下記は大きな正方形のICのマーキングですがCPUはV850とカスタムチップかと思います
・NEC D703111BGM-15 V850E/ME2 1251EP426
・三菱 Super MSEH PC09007F
シーケンス専用制御プロセッサの名前は"SuperMSP"のようなのでこれが専用のASICのようです。
MSP=Mitsubishi Sequence Processo:三菱電機技報Vol.74 2000年7月


![DSC_2730.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/697561a3-ed4a-794a-ba3b-040e4ad4558e.jpeg)

# QJ71C24

![DSC_1029.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/809df37d-087b-3e0d-b028-76b54fb8408a.jpeg)
![DSC_1079.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/86cdce1b-e388-35c2-13a7-78a77528b10e.jpeg)

# QJ71C24N
型番にNが付いた改良版です

![DSC_0960.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/f486e8b2-9b64-34c4-426e-0497f3e57659.jpeg)
![DSC_0995.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/04ec7b0b-74ab-3ea4-1f30-c99b7ad564e6.jpeg)

# AJ65SBTB2N-8R

![DSC_2744.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/bfc199b8-c5b3-dab8-b801-ed12b73ecc4c.jpeg)

![DSC_2743.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/4abf3ccd-0876-36df-f668-1c03c2e973c2.jpeg)

![DSC_2738.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/bbc12b26-4229-c2f6-6e96-1638dc2fd63b.jpeg)

![DSC_2737.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/e3300ef1-444a-b975-8d36-8e677ede3f5e.jpeg)

![DSC_2742.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/0e7ad319-b227-1a59-c6d8-0bdb2855161e.jpeg)

![DSC_2733.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/1f7f0c49-251b-c5ad-18ee-2d9811b154c2.jpeg)

![DSC_2734.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/7ba300c8-e26e-7c99-b261-16e5acc66f63.jpeg)

# Q312B

![DSC_2748.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/b6373c83-da5f-ad9d-438a-5b91444409bc.jpeg)
![DSC_2755.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/909c2e64-1dcb-722a-9dec-28f83c7529b0.jpeg)
![DSC_2752.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/1c43ced7-7f86-341d-34fc-e5bb6909806c.jpeg)
Power BIの行レベルセキュリティについて

自分用の覚書です

# 基本的な考え方
- 行レベルセキュリティ(RLS)はPower BI Desktopでセマンティックモデル単位で特定のユーザーのデータ アクセスを制限をできる機能
- おおざっぱな手順はPower BI Desktopでセマンティックモデル(及びレポート作成)の際にロールを作成し、Power BI サービスへ発行後に作成したロールに対してユーザーを割り当て
- ロールに割り当てが可能なグループは以下
    - 配布グループ
    - メールが有効なグループ
    - Microsoft Entra セキュリティ グループ
- RLS では、ワークスペースのビューアーのアクセス許可を持つユーザーのデータ アクセスのみが制限される。 管理者、メンバー、共同作成者には適用されない

参考:[Power BI での行レベルのセキュリティ (RLS)](https://learn.microsoft.com/ja-jp/power-bi/enterprise/service-admin-rls)

# 大ざっぱな設定手順
①Power BI Desktopでセマンティックモデル(及びレポート)を作成する際にロールを作成しPower BIサービスへ発行
②①で発行したワークスペースにて行レベルセキュリティを施したいグループに対してビューア―の権限を付与
③①発行したセマンティックモデル上のロールに対してグループを追加

# Tips
- Power BI Desktop上で各ロール目線でのレポート確認が可能
[Power BI Desktop 内でロールを検証する](https://learn.microsoft.com/ja-jp/power-bi/enterprise/service-admin-rls#validate-the-roles-within-power-bi-desktop)
NFCカードを作る!

カンファレンスに参加した際、Twitterアカウントを交換していただくことがありました🙇
その中で、NFCカードを使って、自分のアカウントに直接遷移させている方がおり、とても便利だと思ったため自分用に作ってみようと思います!:)

"アカウント名を伝える→検索する"この過程が無くなるのは双方にとって、とても有益なことだと思いますー!!

# 1. NFCカードの購入
私は以下を購入しました!
意外と安い😳

https://www.amazon.co.jp/gp/product/B08WRV4NHM/ref=ppx_yo_dt_b_asin_image_o00_s00?ie=UTF8&psc=1

# 2. ステッカーの作成
無地のままだと味気ないので、ステッカーを貼ることにしました☺️
家にはプリンターがないので、ローソンのネットワークプリントを使用して、シールを印刷することにしました。

https://www.lawson.co.jp/lab/tsuushin/art/1443714_4659.html

## 1. レイアウトの作成
ネットワークプリントを使用する場合、画像形式は、jpg, pngです。
今回はL版(89mm * 127mm)を作成することにしました。
NFCカードの大きさは横86mm, 縦54mmなので、それに合わせてレイアウトを作成します!

Adobe Expressを使用してデザインの作成を行いました!
無料で自由に作成ができるので、とても助かります🎨

https://new.express.adobe.com/

完成系はこんな感じになりました!!

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1640998/8111294c-e7d0-a13c-66ff-4abd2dd4f816.png">

## 2. ネットワークプリントを使用してシールを印刷
Line友達登録して送る方法が、仰天するぐらい簡単でした。
むしろローソンを見つける方が難しいぐらいでした。

https://www.lawson.co.jp/lab/tsuushin/art/1443714_4659.html

# 3. NFCカードの設定
これも簡単でしたー!

https://nfctagshop.net/pages/nfc%E3%83%81%E3%83%83%E3%83%97%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E6%96%B9%E6%B3%95nfc-tool%E7%B7%A8

# 4. シールをNFCカードに貼る
あとは、シールを貼るだけで完成ですー!
空気が入るのと、一度貼ったら、剥がすとシワができるので一発Fight覚悟の巻です💪

# まとめ
作るの簡単で、手間も省けるので、とても良い☺️
是非作ってみてくださいー!!
【Go】int型の10進数のリテラル同士のビット演算

## 前置き

最近 [Go 1.22](https://tip.golang.org/doc/go1.22) がリリースされたのでこの機会にリリース内容を理解したいとチャレンジしており、言語の変更の中に「for」ループのバグに対する修正がありました。

詳細は、[Go Wiki: LoopvarExperiment](https://tip.golang.org/wiki/LoopvarExperiment)に記載されています。上から読んでいて、次のようなループの例が登場しました。

```go
    func TestAllEvenBuggy(t *testing.T) {
        testCases := []int{1, 2, 4, 6}
        for _, v := range testCases {
            t.Run("sub", func(t *testing.T) {
                t.Parallel()
                if v&1 != 0 {
                    t.Fatal("odd v", v)
                }
            })
        }
    }
```



その中で `v&1` という記述があり、初めてみた記述だったのでAIのClaudeに聞いてみたところ「ビット演算」を行っているとのことでした。

ビット演算について調べてみると2進数のリテラル同士の例が多く、「10進数のリテラル同士のビット演算をすると返ってくる結果は10進数のリテラルが返ってくるの？」や「10進数のリテラル同士や2進数のリテラル同士をビット演算することはできるの？」など疑問に思った部分について調べてみました。

:::note warn
ビット演算やGoの仕様については私の理解が浅く、的確でない質問や説明になってしまう可能性があります。ご了承ください。
:::

## 要約
- 10進数のリテラル同士のビット演算をすると返ってくる結果は10進数のリテラルが返ってくるの？
  - 実際に試して10進数のリテラルのときは10進数のリテラルが返ってきました
- 10進数のリテラル同士や2進数のリテラル同士をビット演算することはできるの？ 
  - ビット演算子は、整数に適用することができる
    - リテラルの表記方法は関係なく、整数型の値同士であればビット演算をできるようです。

## `v&1` を実行するとどのような結果になる？

登場したコードを簡略化したものです。

`&` の左辺には1,2,4,6が順に渡されます。`&`の右辺は固定で1です。

```go
func main() {
	nums := []int{1, 2, 4, 6}
	for _, v := range nums {
		fmt.Println(v & 1)
	}
}

// 結果
// 1&1 => 1
// 2&1 => 0
// 4&1 => 0
// 6&1 => 0
```

結果は整数の1か0が返ってくるようでした。

`&` は ビット演算でいうところの「論理積」を求めるようです。

イメージ的には次のようなことをやっているみたいです。

```plain
// 1&1 => 1
0001 = 1
0001 = 1
————
0001 = 1

// 2&1 => 0
0010 = 2
0001 = 1
————
0000 = 0

// 4&1 => 0
0100 = 4
0001 = 1
————
0000 = 0

// 6&1 => 0
0110 = 6
0001 = 1
————
0000 = 0
```

## ビット演算について言語仕様だとどのあたりに書いてある？

算術演算子（[Arithmetic operators](https://go.dev/ref/spec#Arithmetic_operators)）の項目に書いてありました。

> Arithmetic operators apply to numeric values and yield a result of the same type as the first operand. The four standard arithmetic operators (+, -, \*, /) apply to integer, floating-point, and complex types; + also applies to strings. The bitwise logical and shift operators apply to integers only.

> 算術演算子は数値に適用され、最初のオペランドと同じ型の結果を返す。四則演算子（+、-、\*、/）は整数型、浮動小数点型、複素数型に適用され、+は文字列にも適用される。ビットごとの論理演算子およびシフト演算子は、整数のみに適用されます。


> &    bitwise AND            integers

## 最後に
こういう小さな疑問も深ぼってみると言語仕様に書いてあってGoは面白いですね。

ちなみに今回のループ例のビット演算では奇数の場合は `1`、偶数の場合は `0`を返すので奇数か偶数かを判定するのに使われているみたいでした。
生成AIは良い、だけど基礎を身に着けるのも大事 ～ 議事録を例に

# コミュニケーションスキルって
生成AIに任せる仕事の典型といえば議事録の作成ですね。
新人なんかはまずは議事録作成から、というくらい基本的な作業です。

面倒くさい？
時間の無駄？
どうせ誰も読まない？

私は議事録を作成することで仕事に必須のスキルが身につくのも事実だと思います。
こういうことをいうと昭和ぽい、、、みたいなことを言われるかもしれないけど。

# 議事録を自分がとることの利点
1. 会議の内容を理解しようと努力する
　
2. 人と自然に会話するようになる
　
3. 書いたことを覚える
　
4. チームの中心人物になれる（かも）
    - 議事録を取っているということは、会議で発言する権利・義務があります。
    「決定事項は××でいいですか？」
    「●日後までに×でいいですね？」
    - マネージャが「前のあの▲ってどうなったっけ？」ときいてきたときにさっと議事録を検索して答えてあげましょう。

# 議事録は会議が終わってから書くんじゃない、会議の前、最中には議事録はできているんだ
## 人は紙があると安心する
どちらかというと中堅の人向けになりますが。

紙でなくても、OneNoteやPowerPointに最低限今日話すことや今日決めたいことといったメインポイントを書いて準備しておいて、お客さんと話すときはそれに沿って話していきます。そのうえで（できれば画面共有しながら）そこに決まったことや出たアイディアを書き足していきます。時間に余裕があれば図や表も書いて整理するといいです。
　
途中途中でお客さんに「こんな感じですよね」とチェックしてもらうのもおすすめです。

そんなことをすると怒られる？
私の経験では、お客さんは「こいつは俺の言うことを理解しているのか」ということを一番気にしています。会話の上に文章でもわかりやすくリアルタイムでまとめてあげたらむしろ歓迎されることが多かったです。

さあ、そうしたら会議が終わった時には大体もう議事録はできています。
あとはフォーマットを少し修正して送るだけです。


# とはいっても新人の場合は
とりあえずメモ魔になりましょう。会議じゃなくても、議事録担当でなくてもメモをとります。

自分用の仕事メモでもいいです。頭の整理ややることリストもいいです。
先輩との会話のメモは議事録をとるための練習です。

これにはChat GPTも使えませんね。

OneNoteは検索もできるのでお勧めです。1日1ページ作ってきます。
目指すのは相手としゃべりながら、会話のスピードを落とさずに自然にメモをとるようになることです。


# 信頼できる人になる
そもそもこんなことを書いた理由は、新人に限らず中堅やマネージャ層でもこんな人を見かけるからです。

- 会議なのにそもそも議事録をとらない
- 会議の決定事項に関心がない
- 前の会議で何を話したのか覚えていない
- 数か月前に決まったことを平気で蒸し返してくる
- 画面共有しているのに、タイピングやマウス操作がやたらと遅い
etc.

今まで仕事をしてきた中でこの人はナァというのは大体議事録どころかメモも取らない人が多かったです。忘れやすく、色々なことが抜け落ちます。

一緒に働くならちゃんと前言ったことを覚えてる人がいいですよね。自戒も込めて。


#### 本音は
YouTubeのショートで「議事録をAIに書かせて時短だ、すごいだろ！」みたいな意識高い系の動画が気に障ったからです。。
iOSのPrivacy対応のトラッキングについて

## 経緯
2024/05/01以降のリリースで必須になるPrivacyManifests対応の中で**Tracking**について理解できなかったため調べました

# ソース
[AppleDeveloper公式](https://developer.apple.com/jp/app-store/user-privacy-and-data-use/#:~:text=%E3%83%93%E3%83%87%E3%82%AA%E3%82%92%E8%A6%8B%E3%82%8B-,%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%81%AE%E8%A8%B1%E5%8F%AF%E3%81%AE%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88,-iOS%C2%A014.5%E3%80%81iPadOS)

# トラッキングする時には
AppTrackingTransparencyを通じてユーザーの許可を取る必要がある
→ 文言は通常通りカスタムできるので、許可をもらいやすい文章にしましょう
　（かと言ってユーザーを騙す、または誤認させるような文章は避けましょう）

# トラッキングとなる条件
公式ドキュメントから抜粋
```
自分のアプリで収集したユーザーやデバイスに関するデータを、
ターゲット広告や広告効果測定を目的として、他社のアプリやWebサイト、
またはオフラインのプロパティから収集されたユーザーやデバイスに関するデータに紐付ける行為を指します。
また、ユーザーやデバイスに関するデータをデータブローカーに共有することもトラッキングに該当します
```

## 観点は次の3つ
- **ターゲット広告や広告効果測定を目的として**
- **データを他社またはオフラインで取得したデータと紐付ける**
    - 解釈： ユーザやデバイスを起点に様々な情報を紐付けること
    - A情報（自社） - デバイス - B情報（他社orオフライン）
- **紐付けはしていないがデバイスやユーザーとそれに紐づいた情報を、データブローカーに共有すること**

# PrivacyManifests
トラッキングに当たる場合は*Privacy Tracking Enable*をYESにして、そのドメインを*Privacy Tracking Domains*に記載しましょう
当たらない場合は*Privacy Tracking Enable*をNOにしておしまい
【Rails 7】DBをテーブル表示

# DBをテーブル表示

## Gemをインストール
```:Gemfile
group :development, :test do
  gem 'hirb'
  gem 'hirb-unicode'
end
```
```terminal:ターミナル
 bundle install
```
## コンソールで適用
```terminal:ターミナル
 rails console
 Hirb.enable
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360425/a3383686-b7df-4b2d-3750-20023975c024.png)
Slackチャンネルでメールを受け取るためにメールアドレスを発行する方法（Slack プロのみ）

## 概要

Slackチャンネルでは直接メールを受け取ることができるらしい。方法はチャンネルでメールを受信する用のメールアドレスを発行するだけだ。大先輩から本方法を教わって試してみたので体験記としてメモ的にまとめる。

## 注意

Slackチャンネルでメールを受け取るためにメールアドレスを発行できるのはSlackプロのみである。

## 方法

1. メールを受信したいSlackチャンネルをSlackアプリで開く。
1. メールを受信したいSlackチャンネルのチャンネル名（画面上部）をクリックする。
1. 「インテグレーション」タブをクリックする。
1. 「このチャンネルにメールを送信する」をクリックする。
1. 「メールアドレスを取得する」のボタンをクリックする。
1. 発行されたメールアドレス宛にメールを送るとSlackで受信する事ができる。

## 参考文献

https://slack.com/intl/ja-jp/help/articles/206819278-Slack-%E3%81%AB%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B
日本社会に外国籍エンジニアの居場所は？スポーツの成功に習って日本のITチームのイメージを刷新しよう

こんにちは、オースティンです。

久しぶりの投稿ですが、技術の話題というより、個人の話を少ししたいと思います。それから、外国籍エンジニア、ホワイトカラー移民としての経験を共有した上、日本社会および企業のコーポレートカルチャーに置ける外国人の立場について一緒に考えたいです。

非常にブログに近い投稿かと思いますが、読んでいただければ嬉しいです。

# 筆者の来日について

僕自身の話ですが、日本に初めて来てからあれこれ10年以上経ちます。初めて来た時は18歳でして、大学2年生だったのです。アメリカの高校を飛級で2年早く卒業してミシガン州立大学に17歳の時に入ったのですが、二十歳になった時は留学先の琉球大学で、お酒が飲めるようになったことを一人で喜んでいた記憶があります:joy: アメリカでは21歳になってからなので、なんとなく得した気分でした。

日本にそもそも来た理由は、アニメが好きだったり、日本文化に親しみがあったわけではなく、単純に母国の兄弟があまり行かない場所に、冒険しにいきたかっただけです。

日本に来てから、「外国人は日本語を上手に喋れないだろう」という既成概念の壁にぶち当たったのですが、挑戦心に溢れた、負けず嫌いの若き筆者は一つのチャレンジとして「完璧にマスターしてやる」ことを決意して、それだけに集中して必死に語学学習に励む時期がありました。所詮、言葉は言葉です。誰でもやろうと思えば喋れるようになるし、訛りだって努力すればなくせるものです。

大学を卒業する時に、次は中国語をやろうと思って一瞬台湾の企業に就職することを考えたのですが、結局は日本に戻って新卒就職をしたのです。

要するに、日本に来たのは、若気の至りで閉鎖的な文化に溶け込むことを最高の挑戦として捉えたからです。若い筆者は、やはり若かったな:joy:。今なら絶対しません。体力が足りんのです。

# なぜ日本に残ったのか

僕が今も日本にいる理由は簡単です：**家族ができて簡単に帰れないからです**。高度人材のプログラマーだとはいえ、円安でチビが二人いると、アメリカに帰るという莫大な費用をカバーするほどの貯金がなかなかできないのです。

アメリカに帰りたいと思います。しかし、若い時とは違って僕一人の思いなんかより現実が鉛の塊を両足に付けて海の中でサメから逃げるのと同じように容赦なく足を引っ張ってくるのです:joy:

# 仲間に入れてもらえないのは疲れます

若い時は、日本の閉鎖的な文化を超えて溶け込むことをチャレンジとして捉えて面白かったのですが、年も食って、子供による慢性的睡眠不足が続くと、そんなチャレンジなんか興味なくなります:joy:。

ずっとガイジンとしているのは、疲れます。もう面白くないです。

半年前に永住権審査も不許可になりました。きっとそのうち許可されるでしょうが単純にその結果でプライドが傷つきましたし、やっぱり帰りたいなと思いました。

また最近も永住者が税金を滞納したら永住権剥奪もありだという法の改正も入るようですが、これは外国籍の移民にとってはとても悲しい改悪です。人生には失敗が付き物です。偶然が重なって更新の時に入管からして好ましくない状況にあったら、更新できないのかと心配するものです。10年後ここにいられるのか、慢性的な不安感は拭えないんです。移住というのは、なかなか神経を削るものだなと今は思います。

# 日本社会に外国籍エンジニアの居場所は？

それで本投稿の本題ですが、筆者が問いたいのは、日本社会に外国籍エンジニアの立場をどうするかということです。

コロナが明けてまたまたホワイトカラーの外国籍人材が入国するようになったのですが、彼女ら彼らは歓迎されますでしょうか？多分歓迎されるでしょう。

ただ、「日本人」には彼ら彼女らが入ることはありますでしょうか？

よく、日本が経済的な競争力を高める議論を聞く時は、「日本」ということと、「日本人」が同一にされています。つまり、日本人＝日本＝日本経済というふうに、全部ゴチャになっているのです。AIの開発にも「国産モデル」というキーワードがあるのですが、「国産」とは何を指しているのでしょうか？日本人が作ったことを指しているのでしょうか？日本人が作ったことと、日本国において多国籍チームが作ったことに、違いはありますか？

日本の今後の国際競争力を本気で高めたいのであれば、戦前から変わらない日本対諸外国の二極構想から脱出しなければなりません。

日本が唯一外国に負けてない分野はなんでしょうか？ちょっと前までは研究と言えましたが今は残念ながら負けています。

負けていないのは、**スポーツ**です。大阪なおみ選手を皮切りに、多国籍のラグビーチームまで、日本のスポーツは日本の戦前以来変わらなかったイメージを変えているのです。牙の生えた、強気のダイバシティで成功しているのです。

日本のIT業界はといえば、負けています。そして、負けているのに、考え方は基本的に変わっていないと感じます。スポーツの成功事例を参考に、日本のIT業界のアイデンティティを刷新してこそ国際的に負けない競争力は手に入るのではないでしょうか？

今受け入れている外国籍のエンジニアにもはっきりと居場所もあって、「日本チーム」の選手として加わってもらおうじゃないですか。競争の対象となるガイジンではなく、同じチームの大切な仲間として、世界に勝ち抜く姿勢を持つのです。

僕ならせっかくいるので日本チームに加担したいのですが、残念ながら日本チームに入っていると感じたことはないです:sweat_smile:

# 日本は世界と肩を並べられる、ただ古きニッポンじゃだめ

そんな思いで、日本のIT業界には勝ち目はあると信じています。自分の同僚に頭もキレて勘もいい仲間がたくさんいます。また、挑戦の心を持っているPDMもいます。追いつけるはずです。

変わらなければならないことはたくさんあるのですが、筆者が声を大きくして訴えたいのは、日本チームのイメチェンです:joy:。もし「国産」は日本国が開発できることを指しているならば、日本国に永住する外国籍エンジニアであろうが、日本で生まれ育った人であろうが関係ないはずです。

日本人だけで作った国産モデルとか、日本が外国人に勝つとか、そういう言葉も概念も捨てて、考え方を変えましょう。仲間の定義も広げましょう。戦前の日本人という束縛に囚われないで未来を切り開いていこう、このへんで止めないとますます陳腐になっていくのです。

# まとめ

無理やりエンジニアの話にこじつけていますが、子供の父親として日本人の定義が僕の一生の間に変わってくれたら嬉しいなと思っています。それが日本の競争力向上の鍵になると思いますし、それによって日本はもっと面白い場所になると思います。今僕が日本にいて感じるのは、日本社会は砂漠に取り残された南国の鳥が水を求めると同じように、変化を求めていることです。ITに限らず、イメチェンをして新しい風が吹いてもいい時期じゃないですか。
Google Ads APIをPythonで叩くときの勘所

# 背景
- Google Ads APIを叩いてRSA広告の実績を取得したいです

# ドキュメント
- 基本これを頑張って見ればいけます

https://developers.google.com/google-ads/api/docs/start?hl=ja

# 認証まわり
これが一番大変です. 
以下の4つの認証情報を集めるということを覚えておいてください.

- developer_token
- client_id
- client_secret
- refresh_token

# login_customer_id
- また広告のアカウントのlogin_customer_idも用意しておく必要があります
- 対象の広告アカウントの管理画面の右上にある `xxx-xxx-xxxx` の数字です

![スクリーンショット 2024-03-26 18.05.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/08339119-15cc-40e0-7aff-e467b629d23e.png)


# developer_token
- MCCアカウントの [API センター] ページからトークンを取得できます
  - MCCアカウント: My Client Centerの略らしい. 広告アカウントのマネージャーアカウントみたいなものだと思います.
- 広告担当の偉い人にお願いして発行してもらいましょう

# client_id, client_secret
- GCPの管理画面から発行できます. GCPの権限がない場合はエンジニアの偉い人にお願いしましょう.
- まずは、OAuth同意画面で、OAuthにGoogle Ads APIのScopeを追加する設定をします
  - アプリは`Internal`で`デスクトップアプリ`にして作っていきます
- その後、"認証情報"のOAuth2.0クライアントIDの画面からクレデンシャルのjsonをダウンロードしてください
  - このjson内にclient_idとclient_secretの値が書いてあります
 
![スクリーンショット 2024-03-26 17.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/b1d581f7-5d2c-58b3-533c-e78676f5a04c.png)

- 以下のページの動画が非常にわかりやすいです

https://developers.google.com/google-ads/api/docs/get-started/oauth-cloud-project?hl=ja

# refresh_token
- `oauth2l`というGoogle OAuth 2.0 を操作するコマンドライン ツール を利用して発行します

```sh
# oauth2lをインストールした後
# credentials.jsonを先ほどダウンロードした認証情報jsonです
oauth2l fetch --credentials credentials.json --scope adwords \
    --output_format refresh_token
```

出力

```
{
  "client_id": "******.apps.googleusercontent.com",
  "client_secret": "******",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "refresh_token": "******",
  "type": "authorized_user"
}
```


https://developers.google.com/google-ads/api/docs/get-started/make-first-call?hl=ja

# google-ads.yamlを用意

https://github.com/googleads/google-ads-python/blob/HEAD/google-ads.yaml

ここからgoogle-ads.yamlをコピーして以下の値を置き換えてください.

- client_id: INSERT_OAUTH2_CLIENT_ID_HERE
- client_secret: INSERT_OAUTH2_CLIENT_SECRET_HERE
- refresh_token: INSERT_REFRESH_TOKEN_HERE
- developer_token: INSERT_DEVELOPER_TOKEN_HERE
- login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE
- (INSERT_USE_PROTO_PLUS_FLAG_HEREはTrueでOK)

# 実装

https://developers.google.com/google-ads/api/docs/get-started/make-first-call?hl=ja#python

```
# google-ads をインストール
python -m pip install google-ads==21.3.0
```

```py
from google.ads.googleads.client import GoogleAdsClient
client = GoogleAdsClient.load_from_storage("./google-ads.yaml")
ga_service = client.get_service("GoogleAdsService")

query = """
SELECT
  campaign.id,
  ad_group.id,
  assset,
  metrics.impressions, 
  metrics.clicks,
  metrics.conversions
FROM ad_group_ad_asset_view
WHERE campaign.id = 'CAMPAIGN_ID'
"""

# Issues a search request using streaming.
# customer_idにはlogin_customer_idと同じものを使ってください
stream = ga_service.search_stream(customer_id="xxxx", query=query)

for batch in stream:
    for row in batch.results:
        print(row)
```