OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】初めてBashスクリプトを使ったけど便利だった

# はじめに

最近、長らく挫折していた競プロに再入門したのですが、過去問を解く度にファイル作成するのが面倒に感じていました。

そこで***Bashスクリプト***を使えば、ターミナルにてそのファイルを実行するだけで、競プロ用のファイルを作成することが出来、便利だったので共有します。


# 実際にBashスクリプトを作成

まずターミナルにて、以下を実行してBashスクリプトを記述するファイルを作成します。

```bash
touch create_file.sh
```


そして以下を行い、作成されたファイルに実行権限を与えます。

```
chmod +x create_file.sh
```

例として、作成されたファイルを以下のように編集します。

```sh
#!/bin/bash

# ディレクトリ名を入力として受け取る
echo "ディレクトリ名を入力"
read dirname

# このスクリプトファイルが存在するディレクトリを取得
script_dir="$(cd "$(dirname "$0")" && pwd)"

# ディレクトリ作成先
full_dir="${script_dir}/abc/${dirname}"

# ディレクトリが存在しなければ作成
if [ ! -d "$full_dir" ]; then
    mkdir -p "$full_dir"
    echo "ディレクトリが作成された: $full_dir"
else
    echo "同じディレクトリが既に存在: $full_dir"
fi

# ディレクトリ内に新しいファイルを作成
touch "${full_dir}/a.cpp"
touch "${full_dir}/b.cpp"
touch "${full_dir}/c.cpp"
touch "${full_dir}/d.cpp"
echo "実行完了"
```

ファイルの実行内容に関しては、コメントに書いてある通りですが、ディレクトリ名を受け取ってその中に決まったファイルを作成するものになっています。


ファイル名や、作成するディレクトリ先も、少しスクリプトを編集すれば変えることが出来ます。

またテンプレートファイルがある場合は、***Bashスクリプト***と***テンプレートファイル***を***同じディレクトリ***に配置し、Bashスクリプトの最後のファイル作成という部分を

```sh
cp "${script_dir}/template.cpp" "${full_dir}/a.cpp"
```

のように変更すると、テンプレートファイルの内容をコピーする形で各ファイルが作成されます。

作成したBashスクリプトを実行するには以下をターミナルに打ち込むだけです。

```bash
 ./create_file.sh   
```

これでファイルを手作業で作成するより、かなり面倒が減りました！


# 終わりに

本記事には関係ないんですけど、ターミナルって矢印上下キーで過去に実行したコマンドを入力できるんですね。それも便利でびっくりしました。

記事が参考になれば嬉しいです！

# 宣伝

***Konwalk(コンウォーク)*** という ***「歩く時間に英単語を覚える」*** をコンセプトにしたWeb英単語帳を運営しています！

https://konwalk.jp

ぜひ興味を少しでも持っていただいた方は見てやってください🙇
【Swift】じゃんけんの対話プログラム

# じゃんけんの対話プログラム

コードの基本的なスキルだけで、じゃんけんゲームを実装する。

### 動作環境

- iPadアプリ「Swift Playgrounds」
- 対話ブック


## じゃんけんのロジック

```swift
// じゃんけんの仕組み
let hands = ["✊", "✌️", "🖐️"]
let randomNumber = Int.random(in: 0...2)
let enemyHand = hands[randomNumber]

// 勝敗を判定する
show("じゃんけん...")
pauseUntilTapped(message: "ぽん！")
show("コンピュータは\(enemyHand)を出しました。")
```

### コードで勝負する

```swift
// じゃんけんの仕組み
let hands = ["✊", "✌️", "🖐️"]
let randomNumber = Int.random(in: 0...2)
let enemyHand = hands[randomNumber]

show("じゃんけん...")
let yourHand = askForChoice("何を出す？", strings: hands)

// 勝敗を判定する
pauseUntilTapped(message: "勝負する！")
show("コンピュータは\(enemyHand)を出しました。")

if yourHand == "✊" {
    if enemyHand == "✌️" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "✊" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 

if yourHand == "✌️" {
    if enemyHand == "🖐️" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "✌️" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 

if yourHand == "🖐️" {
    if enemyHand == "✊" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "🖐️" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 
```

## 相手を選ぶ

```swift
// 相手を選択する
show("相手を選んでください")
let enemies = ["🤖", "👻", "🧚", "😈"]
let enemy = askForChoice(strings: enemies)

if enemy == "🤖" {
    show("じゃんけんモードを開始しマス。")
} else if enemy == "👻" {
    show("おばけだぞ〜")
} else if enemy == "🧚" {
    show("じゃんけんしましょ♪")
} else {
    show("負けないぞ！")
}

// じゃんけんの仕組み
let hands = ["✊", "✌️", "🖐️"]
let randomNumber = Int.random(in: 0...2)
let enemyHand = hands[randomNumber]

show("じゃんけん...")
let yourHand = askForChoice("何を出す？", strings: hands)

// 勝敗を判定する
pauseUntilTapped(message: "勝負する！")
show("\(enemy)は\(enemyHand)です。")

if yourHand == "✊" {
    if enemyHand == "✌️" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "✊" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 

if yourHand == "✌️" {
    if enemyHand == "🖐️" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "✌️" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 

if yourHand == "🖐️" {
    if enemyHand == "✊" {
        show("すごい！あなたの勝ち☀️")
    } else if enemyHand == "🖐️" {
        show("うーん、引き分け☁️")
    } else {
        show("残念、あなたの負け🌧️")
    }  
} 
```
【Sourcetree】差分ファイルを抽出する（Windows）

自分用のメモ。
Sourcetreeのカスタム操作で指定した差分をzipで抽出する方法。


# 1. Gitをインストールする

コマンドプロンプトでGitがインストールされているかを確認する。

    git --version

インストールされていなければ、Gitをインストールする。
https://git-scm.com/

# 2. batファイルを作る

テキストエディタで以下のbatファイルを作る。

git_sabun_chushutu.bat

    if "%2" equ "" (
      set param1=HEAD
      set param2=%1
    ) else (
      set param1=%1
      set param2=%2
    )
    
    setlocal enabledelayedexpansion
    set RET_DIR=
    for /F "usebackq" %%i in (`git diff --name-only --diff-filter=ACMR %PARAM2% %PARAM1%`) do (
      set RET_DIR=!RET_DIR! "%%i"
    )
    set time=%time: =0%
    set TODAY=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%
    
    git archive --format=zip --prefix=archive/ %PARAM1% %RET_DIR% -o archive_%TODAY%.zip


# 3. Sourcetreeのカスタム操作に登録する

1. Sourcetreeのメニューバーから「ツール」>「オプション」>「カスタム操作」>「追加」
1. カスタム操作を編集ウィンドウで、下記の内容で登録する

【メニュー表示名】好きな名前（「指定の差分をZIPにする」など
【実行するスクリプト】上記で作ったbatファイル
【パラメータ】$SHA


# 4. カスタム操作で差分抽出する

1. Sourcetreeの画面で、差分を取りたい２つのコミットを選択する
（1つ目を左クリックし、Ctrl押しながら２つ目を左クリック）
1. 右クリックを押して、「カスタム操作」>「指定の差分をZIPにする」（上記で自分がつけた名前）を選ぶ

差分がZIPに書き出される。
ITパスポート システム監査

・システム監査
情報システムを、独立した第三者が調査し改善案を助言すること

システム管理基準
企業が情報システムを管理するうえで実施すべき事項などをまとめたもの

システム監査基準
システム監査人の行動規範などをまとめたもの

・予備調査
アンケート調査などを行い、本監査に先立って監査対象の実施を把握すること

・本調査
ヒアリングや現地調査などを行い、監査対象の実態を詳細に調査して、監査証拠を入手し、監査調書を作成すること

・監査報告書の提出

・フォローアップ
システム監査人が適切に指摘事業の改善が実施されているかを確認し助言すること
【AWS】CloudFront FunctionsでIPアドレス範囲指定のアクセス制限

### はじめに

S3に配置したhtmlファイルにCloudFront経由でアクセスします。
よりセキュアにするため、アクセス制限をかけます。
特に、CloudFrontへのIPアドレス制限について、CloudFront Functionsを利用してIPアドレス範囲指定でアクセス制限をする記事が見つからなかったので投稿します。

### やること
構成としては以下となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/43192cd2-7b87-8ab3-676d-41a03b13337c.png)

それぞれの説明です。

* S3のアクセスは「パブリックアクセスをブロック」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/92ea3c3e-5a10-c2d9-e935-4c88ca58622e.png)


* S3のバケットポリシーには「CloudFront経由のみアクセス許可」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/98be37e3-2afd-b704-3f31-817d5c187c34.png)

* CloudFrontで「IPアドレス制限」（構成の図の<font color="Red">赤線</font>の箇所です。）

ここで、**CloudFront Functions**を利用します。
利用方法は以下が参考になります！

https://dev.classmethod.jp/articles/cloudfront-functions-ip-control/

しかしながら、IPアドレスのリストを指定するのは良いですが、
「X.X.X.X/16」など**CIDRブロックで指定したい**場合はどうしましょう？

全てのIPアドレスを記述するのは現実的ではないでよすね。
そこで、**正規表現**を利用します。

```cloudfront-js-2.0
function handler(event) {
    var request = event.request;
    var clientIP = event.viewer.ip;
    
    // アクセス許可するIPアドレス範囲を設定
    var pattern = new RegExp('1.2.\\d{1,3}.\\d{1,3}')
    
    // クライアントIPが、アクセス許可するIPアドレス範囲にマッチすればtrueを返す
    var isPermittedIp = clientIP.match(pattern);

    if (isPermittedIp) {
        // trueの場合はオリジン側へリクエストを渡す
        return request;
    } else {
        var response = {
            statusCode: 403,
            statusDescription: 'Forbidden',
        }

        // falseの場合はViewer に対してレスポンスを返す
        return response;
    }
}
```
上記コードの
`var pattern = new RegExp('1.2.\\d{1,3}.\\d{1,3}')`　で正規表現を利用しています。
`var isPermittedIp = clientIP.match(pattern)`　で判定しています。　

### IPアドレス範囲指定のアクセス制限動作確認

テストしてみます。
CloudFront Functionsのテストタブでテスト実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/f8239b07-3c46-f041-6262-de23183653a2.png)

「IPアドレス」に「1.2.3.4」を入力し、
「関数をテスト」ボタンをクリックすると・・・ :o: ステータス「成功」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/42a29167-5890-ca9c-dfdc-a14405921a95.png)

「IPアドレス」に「1.**3**.3.4」を入力し、
「関数をテスト」ボタンをクリックすると・・・ :x: ステータス「403 Forbiden」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288944/411365de-717e-e851-e365-b93a0928db09.png)

意図した通りに動作してますね:thumbsup:

### さいごに
* CloudFront Functionsがあったなんて！（便利だな。）
* CloudFront Functionsは書き方に制限があるようですが、JavaScriptとして他にも表現できそうですね。
【ChatGPT＋DALL-E3】Select機能で人数をきちんと。


　どうも、カーブミラーです。

　今回は、Select機能で人数をきちんとしよう、という話です。複数人を指定すると、余計な人間が出てきたり足りなかったりします。それをSelect機能で直します。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　まずは、ニュース。

　Adobeの画像生成AIである
　　Fireflyのバージョンが
　　　2から3になりました。
[Adobe Fireflyサイト](https://firefly.adobe.com/#)

　ちょっと触りましたが、
　　プロンプトの入力形式は
　　　旧Bing ImageCreatorと同じ。

　そことは別に
　　アスペクト比やスタイルなどを
　　　個別にポチポチ指定できます。

　無料なので
　　誰でも使えますよ👍
***
　さて、
　　本題です。

　昨日（2024/04/24）の記事
[【ChatGPT＋DALL-E3】Select機能で文字列をきちんと（試行錯誤）](https://qiita.com/kabumira/items/d9cc1f351970d981db86)
　　では、文字列の修正を
　　　行ないました。

　今日は、
　　複数人の人物を修正します。

　複数人を指定すると、
　　余計な人間が出てきたり
　　　足りなかったりします。

　きちんと
　　指定人数に
　　　なってくれないことが
　　　　ほとんどですよね。

　プロンプトを見ても
　　人数に間違いはありません。

　ということは
　　DALL-E3の問題である
　　　ということですね。

　しかし、
　　これまでは
　　　修正する手立てが
　　　　ありませんでした。

　これからは
　　Select機能で
　　　修正できます。
***
　まずは、
　　元画像とプロンプトを。
***
![1714012653224.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/dcfe10b2-d2d5-45fc-de97-4a268fc48837.jpeg)
A conference room with a rectangular table hosting six diverse men in a discussion. 1. An energetic, talkative man entertaining the group, leading the discussion. 2. A quiet, contemplative man listening intently. 3. A sporty man in casual sportswear, looking competitive. 4. An artistic man in stylish, unique clothing, possibly sketching or discussing art. 5. An intellectual man with glasses, holding a book. 6. A foreign exchange student sharing his culture, engaging with others. The room has a professional yet relaxed atmosphere, with papers and laptops visible.
***
　プロンプトをごらんのとおり、
　　六人の男性のペルソナを
　　　指定しています。

　これは六人だけを
　　描くようにして欲しかったので。

　ところが
　　六名以上、しかも大人数。

　そこで
　　Select機能で
　　　全員を塗りつぶして
　　　　“書き直して”と送信します。

　出来上がったのがこちら。
![1714012668252.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/45f3090a-5923-0c2c-c87c-6a32794e7775.jpeg)

　たまに
　　失敗しますが、
　　　その画像に対して、
　　　　同じことをします。

　上記プロンプトで
　　２セッションで行ない、
　　　確認しました。
　　　　ですから、
　　　　　一度でダメでも
　　　　　　何度か実行してください。

　**注意としては
　　人間の全身を
　　　塗りつぶすこと**です。

　上半身だけを塗りつぶして
　　生成された画像に変化は
　　　見られませんでした。
***
　文字列と人間の修正から
　　考えられるのは、
　　　以下のとおり。

　プロンプトに書かれた事柄を
　　ChatGPTは忠実に
　　　DALL-E3に渡した。

　だが、
　　DALL-E3は
　　　余計なことを行なった。
　　　　（DALL-E3に自覚なし）

　そこで
　　Select機能で
　　　塗りつぶして、
　　　　何を修正するのかに
　　　　　集中される。

　そこだけに集中するので
　　書き直しが楽。

　こんなところ？

　まぁ、
　　理屈は理屈としておきましょう😅

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
cssのセレクタメモ

# はじめに

# 書き方
cssのセレクタ

html
```html
<p style="color: red;">test</p>
```

【要素セレクタ】
```html
<p>node</p>
```

```css
style.css
p {
	color: red;
}
```

pタグにstyleを当てる


【クラスセレクタ】

```html
<p class="text-yello">node</p>
```

```css
style.css
.text-yellow {
	color: yellow;
}
```

クラスをチェーンして設定

```html
<p class="large text">Large Text</p>
```

```css
.large.text {
    color: aqua;
    font-size: 25px;
}
```

要素とクラスをチェーンして設定

```html
<p class="small text">Samall Text</p>
```

```css
p.small.text {
    color: red;
    font-size: 10px;
}
```

【IDセレクタ】

```html
 <p id="danger">Danger</p>
```

```css
#danger {
    color: orange;
}
```

id セレクタは他の id セレクタと結合することはできない

【属性セレクタ】
指定された属性がタグ内にあると指定することもできる

```html
<h4 class="example">test1</h4>
<h4>test2</h4>
<h4 class="example2">test3</h4>
```

```css
h4[class] {
    color: brown;
}
```

属性をチェーンすることも可能

```html
<p class="lorem">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Iure voluptatum, rem modi nobis velit quasi ad hic, veniam ab quos deserunt facere tempore iste ullam labore saepe, reprehenderit beatae temporibus!<a href="https://google.com" title="Link">Link</a></p>
```

```css
a[href][title] {
    font-size: 30px;
}
```

【全称セレクタ】

```html
<h1>Title</h1>
<h2>Sub Title</h2>
<p>Lorem</p>
```

```css
* {
    color: blue;
}
```

【子孫セレクタ】

```html
<h2><strong>Sub Title</strong></h2>
```

```css
h2 strong{
    backgound-color: yellow;
}
```

【擬似クラス】
HTML要素の特定の状態や位置に基づいてスタイルを適用するための仕組みです。これらのクラスは通常、要素が特定の状態にあるときにのみ適用される

```html
<a href="https://google.com">Google</a>
```

```css
a:hover {
    color: yellow;
}
```

【擬似要素】
擬似要素では選択された要素の特定の箇所にレイアウトを適用することができる

```html
<h2>Description</h2>
```

```css
h2::before {
    content: "Title : ";
    color: gray;
}
```
Workato：Google WorkspaceやOffice Onlineに頼らずに、Excel（xls, xlsx）ファイルを処理するには

# はじめに
Workatoで、Excel(xls, xlsx)ファイルを処理したい場合は、Google SheetsコネクタやExcelコネクタを利用すると簡単に扱うことが出来ます。

これらのコネクタの利用にあたっての前提として、Google Sheetsコネクタの場合はGoogle Workspace、Excelコネクタの場合はMicrosoft 365、それぞれの契約が必要となります。

しかし、それらのサービスを契約していない場合や、（Workato以外の）クラウドサービスに渡したくないファイルを処理したい場合は、次の手順にて、Google WorkspaceやMicrosoft 365などのクラウドサービスを利用せずにExcelファイルをWorkato上で処理することが可能となります。

# 手順

## 過去に紹介した内容
クラウドサービスに頼らずxlsx形式のファイルをWorkato上で処理する方法として、2021年に以下の記事を公開しています。

https://qiita.com/tabimoba/items/3c91d793c23c10324bc3

今後においては、この方法ではなく、後述するPythonコネクタによる方法で対応されることをお勧めします。

この記事による方法は、Workatoの標準機能だけでノーコードでxlsxファイルを処理することが可能ですが、その反面、処理は複雑かつ実行時のタスク数も多めになります。

※タスク数の増加はWorkatoの運用コストの増加につながるため、いかに少ないタスク数で効率よく処理をまとめることが、Workatoを運用する上でのポイントの1つになります。

## Pythonコネクタによる方法

以前は上記の手順を含め、限られた選択肢しかありませんでしたが、Pythonコネクタの登場により、現在ではローコードでありながらも、よりシンプルな方法でExcelファイルが処理できるようになっています。

また、Workato上のCommunity Libraryにて、Pythonコネクタを利用してExcelファイルを処理するCommunity Recipe（以下）が公開されています。レシピの実装にあたっては、こちらのレシピを参考に実装を進めていくと良いでしょう。


### USDC（米国データセンター利用の方はこちら）

https://app.workato.com/recipes/4795692-w_advanced_transformations_ph-python-excel-to-csv?community=us

### USDC（日本データセンター利用の方はこちら）

https://app.jp.workato.com/recipes/4795692-w_advanced_transformations_ph-python-excel-to-csv?community=us

### Community Recipeの解説

このCommunity Recipeでは、Step4にExcel(xls, xlsx)からCSVへ変換する処理が実装されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/208122ff-2042-da26-d20b-b6727400dde5.png)

Step 4はPythonコネクタで実装されており、コードは次のようになっています。


```python
import pandas as pd
import base64
import io

def main(input):
  file_content = input['file_content']
  sheet_name = input['sheet_name']
  message_bytes = base64.b64decode(file_content)
  
  #Excel File to memory - io — Core tools for working with streams
  toread = io.BytesIO(message_bytes)
  
  #Read the Sheet
  read_file = pd.read_excel(toread, sheet_name=sheet_name)
  
  #convert csv
  csv = read_file.to_csv(path_or_buf=None,index=False, header=True)
  return {'csv': csv}
```

変換処理はPandas（データ解析ライブラリ）の機能を利用して実現されています。Pandasの [read_excel](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html) メソッドにExcelファイルを読ませる際、通常はファイルを指定しますが、WorkatoではIOライブラリの [BytesIO](https://docs.python.org/ja/3/library/io.html) メソッド（オンメモリストリーム）で対応します。

なお、WorkatoではPython3.9以降に含まれる標準ライブラリと、Pandasを含めいくつかのライブラリに対応しています。

- bcrypt
- lxml
- msoffcrypto
- NumPy
- openpyxl
- pandas
- Pytz
- requests
- xlrd

また、今回紹介したCommunity LibraryではPandasを用いてExcelファイルを処理していましたが、openpyxlやxlrdでも同様に対応が可能ですし、openpyxlやxlrdはExcelファイルの読み込みだけでなく、Excelファイルの生成にも対応しています。用途に応じて最適なライブラリを選択いただくと良いと思います。
ログデータに関して

## はじめに
ゲームに限った話ではありませんが、ことソーシャルゲームにおいてログデータは必要不可欠な役割を果たしています。
主に運用の段階で利用されるものですが、開発段階でもログデータは重要なデータとなります。

## ログデータの種類
ログデータには、大雑把ではありますが以下のような種類が存在します。
* アウトゲームのプレイヤーアクションログ
アウトゲームにおいてどのような画面遷移を行ったかなど
* インゲームのプレイヤーアクションログ
例えばRPGの戦闘だったら使用したスキルやその順番など
* 課金ログ
ユーザがいつどの程度課金を行ったかなど
* システムログ
        APIサーバやDBサーバなどが出力するログ

## ログデータの活用
上記ログデータを収集することでどういった事ができるでしょうか。

1. プレイヤー行動の理解
プレイヤーのアクションログを追跡することでゲーム内でどのような行動を取っているか把握することができます。
これによってどの機能を利用し、どのコンテンツに興味を示しているかなどを分析することで、ゲーム体験を向上させるための改善点を見つけることに役立ちます。

2. ゲームバランスの改善
プレイヤー行動の理解からゲーム内で特定の武器やキャラクターが過剰に強力に、または弱すぎていないかなどの情報を得ることができます。
これらのバランスを調整することでプレイヤーに公平なプレイ環境を与えることができます。

3. 効果的な施策の実施
ユーザ行動の傾向によって、特定のセグメントにおいてどのような施策が成功したのかを理解するのに役立ちます。
またこれから実施する施策の指針とすることもできます。

4. 問題の検知と対応
ゲームの運用中に限らず開発中でもシステムの問題の検知を早期に発見するのに有用です。
例えば開発段階のシステムでSQLクエリのログデータを出力していたところ、単純なAPIにも関わらず大量のクエリが流れている事がありました。
こういったことは開発時は処理データも少なく気にならない点ではありますが、扱うデータ量が増えた際にパフォーマンスの問題に直結します。
今回の場合は繰り返し処理内でクエリを発行していたことが問題であったため、繰り返し処理前に必要なデータを取得したり、更新時はbulk処理でまとめて更新を行うように修正を行いました。

## ログデータ収集の例
ここでは主にアウトゲームでのデータ収集について記述します。
例えばアイテムを取得した場合**いつ・なにを・どのくらい**などをイベントのトラッキングを利用してログを生成します。
こういったログは主にDBへ保存されますがこの際に気をつけておきたいのはトランザクションです。
アイテムの取得、ログの出力、どちらかが失敗した場合ログデータは意味をなさなくなるため必ず**同トランザクション内で行う必要**があります。

## ログデータの保管
ログの性質上データは常に増え続けるためDBやサーバの容量の圧迫は避けられません。
この場合、いつどこまでのログデータを保存するか事前に設計しておく必要があると考えます。
ある程度の期間までのデータはすぐに取り出せたほうがよいため、現在のプロジェクトでは直近の期間のものはDB内、それを過ぎたらダンプしてS3などに保管ということを行っています。

## おわりに
ざっくりではありますがログデータについてまとめさせていただきました。
上でも述べたようにログデータは様々な用途で使われるため、適切にデータの収集・保管について早い段階から設計に組み込んでおくことが重要です。


## 一緒に働く仲間を募集しています！
株式会社OGIXでは一緒に働いてくれる仲間を募集しています！
エンタメ制作集団としてゲームのみならず、未来を見据えたエンタメコンテンツの開発を行っています。

事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/company_6473754/about
▼代表インタビュー
https://www.wantedly.com/companies/company_6473754/post_articles/443064
▼東京オフィスの応募はこちら
https://www.wantedly.com/projects/1468324
▼新潟オフィスの応募はこちら
https://www.wantedly.com/projects/1468155
標準の画面のまとめ

[UI関係のトラブルに戻る](https://qiita.com/Keiji_otsubo/items/cc344223cfa02db6bed7)



+ [項目コンポーネントのロストフォーカスを取得する方法について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ajTaS)

できないですね。

+ [標準画面をcssの上書きでハックする](https://qiita.com/Keiji_otsubo/items/195dacaeb7bd4760fbf4)
+ [Auraコンポーネントを使って標準画面を上書きする？](https://qiita.com/Keiji_otsubo/items/f40127466421a93da04f)
+ [標準画面で正常に保存されてから別の画面を起動させたい](https://qiita.com/Keiji_otsubo/items/2e1a0cffad43dc4eeccb)
+ [スクリーンフローで更新したレコードに戻る](https://qiita.com/Keiji_otsubo/items/87195dcc9976cb0cc59d)
+ [クイックアクションを使用して項目セットを標準 Lightning コンポーネントとして使用できるようにします](https://qiita.com/Keiji_otsubo/items/67ba593cb78ca7c173c3)
+ [レコードトリガーフローでは画面を起動できない](https://qiita.com/Keiji_otsubo/items/cc3464369dc96255c32b)
+ [親子の参照関係の画面のリフレッシュ](https://qiita.com/Keiji_otsubo/items/b9084f9d171bcd6d3bda)


# 解答例

+ [フィールド レベルのセキュリティを設定しても、一部のプロファイルでは期待どおりにフィールドを表示または編集できません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmQTe)

:::note
ユーザーが使用しているページ レイアウトでこれらのフィールドが使用可能かどうかを確認します。また、Lightning レコード ページの動的フィルターも確認します。

Check whether these fields are available on the page layout the user is on. Also check for dynamic filters in lightning record pages.
:::

# 密度設定

+ [オブジェクトのレコードを追加する画面の項目の幅について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000J8iho)

:::note
この設定を試してみるのもいいかもしれません

カンファタブル

広々としたビューが必要なユーザー向け。表示ラベルは項目の上部に表示され、項目間やカード間のスペースが広くなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1d17b5a3-c63e-7abd-a3a1-0646058a49bf.png)
:::


# 時間の入力

+ [Lightningでの「日付/時間」項目、「時間」項目の入力操作について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000WCW3)

タブキーを使う
GASでメンション付きの通知をするための準備で四苦八苦した

仕事が忙しくなってここんとこ毎日やってたPaizaの勉強がどんどんできなくなってきていた。
まあ忙しいということはありがたいことだ。
さて、そんな毎日でぶつかった問題について。

さて、メンション付きの通知をするためにはGoogleChatで調べなければならないものがある。
UserIdだ。

https://qiita.com/takatama/items/9029ceef857516363c32

私は上記の2つ目のやり方、「ブラウザーの開発者コンソールでスクリプトを実行する」方法でやってみた。
まあやっていることを簡単に言うと、Divのクラスがdata-member-idであるものを抜き出してコンソールに表示させるってだけだ。
ただし、コピペしてもセキュリティ上の問題で貼り付けられないので直接ベタ打ちしてやるしかない。

しかし、抜き出せないメンバーもいた。それは管理者とか普通のメンバーではない人たちだが、これはもう普通にGoogleChatのメンバー一覧でその人の名前をクリックして、data-member-idを調べればOKである。

ちなみにこのUserIdはメールアドレスではないので注意。
色々調べてると、時々メールアドレス？と思わせる文章に出会ったりするので。
そうではなく特定の羅列した文字です。

メッセージで、たとえば
「@Atsulabo 通知です！記事を書くの忘れてない？」と通知したいとすると、

```javascript
//JSではなくGASで記述
// ...は上記で調べた数値で置き換える
//以下は良い例
user_ID = '<users/...>';
let Message = user_ID + " 通知です！記事を書くの忘れてない？";
//以下は送信メソッド（略）

//以下は悪い例
//IDの部分以外を文章に入れようとしてこう書きたくなるが、エラーになってしまう
user_ID = '...';
let Message = ”\<users\/” + user_ID + "\> 通知です！記事を書くの忘れてない？";
```
と、こうなる。
どうも、上記のように<users/...>は完全につなげた状態で引用しないとだめらしい。
スプシつかうなら、セルに\<users/...>とかいといて、それを引用して使うという方法もある。
以上。
Lidar備忘録(iPhone Pro / iPad Pro)

# はじめに

所持しているiPad ProにLidar機能がついていることに、今更気づいた。
浅く調査したのでメモを残しておく。

# Lidarとは
Lidar:Light Detection and Rangingの略。光学技術。光の発射と反射から距離を測定する。
Lidarスキャナ:Lidarを実装・利用するための物理的装置。

Lidarそのものは1960年代から存在する。
Appleが2020年以降発売のiPhone ProとiPad ProにLidarスキャナを搭載したため、一般ユーザーが使いやすい技術となった。

# できること
端末操作者が移動せずとも、端末から比較的高精度な距離情報を得られる。
空間や物体をマッピングして3Dデータを作成できる。

# 苦手、弱点
透明な物体
光の反射が強い物体
動く物体
大きすぎる物体、小さすぎる物体（iPhone/iPadが民生品ゆえの性能限界）

# Appleストア公開アプリ
「Scaniverse」アプリ：こんなことができるのかというのが大体わかる。無料。
「計測」アプリ：Apple純正の現実距離測定アプリ。Lidarを使うことでLidar非搭載機よりも精度が高いらしい。

# ソース

下記サンプルソースをgit cloneすることでXcodeから簡単に実行することができた。
感謝。

https://qiita.com/TokyoYoshida/items/3b1c633dd9adc244aff9

https://github.com/TokyoYoshida/ExampleOfiOSLiDAR?tab=readme-ov-file#exampleofioslidar


# 参考リンク

https://www.blickfeld.com/ja/blog/the-beginnings-of-lidar/

https://tech.aptpod.co.jp/entry/2020/12/22/100000

https://note.com/iwamah1/n/n48a549845ae3

https://note.com/iwamah1/n/n1419056b7445


# 筆者の所感
3Dデータ、土木、不動産、大型動産などを扱う職業の人には便利なツールだと思う。
筆者の職業領域には現状では使い道が思いつかない。
ストア公開済みアプリを面白く使わせてもらうことにする。
esbuildのバイナリと互換性がないことで生じるエラー

# 経緯

私の場合は、以下のコマンドを押下した際にエラーが生じた。
```terminal
monaca upload
```
開発環境構築時やビルド時にも生じる現象らしい。


# エラーログ

```terminal

Specifically the "@esbuild/darwin-x64" package is present but this platform
needs the "@esbuild/darwin-x64" package instead. People often get into this
situation by installing esbuild on Windows or macOS and copying "node_modules"
into a Docker image that runs Linux, or by copying "node_modules" between
Windows and WSL environments.

If you are installing with npm, you can try not copying the "node_modules"
directory when you copy the files over, and running "npm ci" or "npm install"
on the destination platform after the copy. Or you could consider using yarn
instead of npm which has built-in support for installing a package on multiple
platforms simultaneously.

If you are installing with yarn, you can try listing both this platform and the
other platform in your ".yarnrc.yml" file using the "supportedArchitectures"
feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures
Keep in mind that this means multiple copies of esbuild will be present.

Another alternative is to use the "esbuild-wasm" package instead, which works
the same way on all platforms. But it comes with a heavy performance cost and
can sometimes be 10x slower than the "esbuild" package, so you may also not
want to do that.

```

# 解決方法

node_moduleを一回削除し、再度インストールすることで解決。

```terminal
rm -rf node_modules
npm install
```
Set Up Provider Search Challenge Mapping Step



+ [Stuck completing the Set Up Provider Search Challenge Mapping Step](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BtFVjSAN)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c42a6345-04a7-8506-9df7-98ee03924b6b.png)


+ [Why am I not able to proceed in Health Cloud Provider Search and Cards - Set Up Provider Search?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ajZdY)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/85ec1826-c819-c479-be9c-7db908ba9c00.png)

+ [Trailhead: Set Up Provider Search - Unable to map fields](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000HDW1ZSAX)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/eb2f2611-a581-79f0-7a86-007cddf98c0c.png)

:::note
I was able to figure this out with the help of some colleagues. . . Turns out both the Source field and Target fields in this config require API names. Need to map what you configured for your Health Provider field API name to Source field (where data will pull from and search on) and use the Care Provider Search config API name for the Target field settings (where the user will search).

私は何人かの同僚の助けを借りてこれを理解することができました。 。 。この設定のソース フィールドとターゲット フィールドの両方に API 名が必要であることがわかりました。医療提供者フィールド API 名に設定した内容をソース フィールド (データの取得元および検索先) にマッピングし、医療提供者検索構成 API 名をターゲット フィールド設定 (ユーザーが検索する場所) に使用する必要があります。
:::
BigQueryで 最新の値 などを集計する場合に ARRAY_AGG と MAX_BY (と ROW_NUMBER)で 計算効率は違うのか？

# はじめに

先日まで知らなかったのですが、BigQueryに `MIN_BY` や `MAX_BY` という集約関数が2023年の８月頃に追加されたようです。([→Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#max_by))
これは例えば、「人口の最も大きな都市名」みたいなのを集計したいときに `MAX_BY(city_name, population)` というように書けるすぐれモノで、今までちょっと面倒な書き方をしないといけなかったのですが、かなり直感的に書けるようになったと言えます。

計算コストの点でも有利である、というような話を聞いたので、簡単に検証してみたので共有します。

# ROW_NUMBER(), ARRAY_AGG(), MAX_BY() の計算コストの比較
今までは ROW_NUMBER や ARRAY_AGG を使った方法があったと思うので、それらと比較してみます。

## case1
サンプルとして、「user_id別の key-value の更新ログ」を表す `data` というテーブルに対して、
`(user_id, key)` 毎に 最新の `value` を取得するというケースを用います。
※ 更新時刻は `event_time` という列です。

それぞれのQueryは以下のような感じになります。

**ROW_NUMBER方式**
```SQL
SELECT
  user_id,
  key,
  value as latest_value
FROM data
QUALIFY ROW_NUMBER() OVER (PARTITION BY user_id, key ORDER BY event_time DESC) = 1
```

**ARRAY_AGG方式**
```SQL
SELECT
  user_id,
  key,
  ARRAY_AGG(value ORDER BY event_time DESC LIMIT 1)[OFFSET(0)] as latest_value
FROM data
GROUP BY 1, 2
```

**MAX_BY方式**
```SQL
SELECT
  user_id,
  key,
  MAX_BY(value, event_time) as latest_value
FROM data
GROUP BY 1, 2
```

結果は以下の通りになりました。

|  | 実行時間 | 課金されるバイト数 | スロット（ミリ秒） |
| :---: | ---: | ---: | ---: |
| ROW_NUMBER(1回目) | 46秒 | 33.74 GB | 2,824,981 |
| ROW_NUMBER(2回目) | 50秒 | 33.74 GB | 2,679,523 |
| ROW_NUMBER(3回目) | 49秒 | 33.74 GB | 2,961,964 |
| ARRAY_AGG (1回目) | 49秒 | 33.74 GB | 2,981,721 |
| ARRAY_AGG (2回目) | 60秒 | 33.74 GB | 3,166,819 |
| ARRAY_AGG (3回目) | 55秒 | 33.74 GB | 3,808,180 |
| MAX_BY(1回目) | 48秒 | 33.74 GB | 2,955,808 |
| MAX_BY(2回目) | 48秒 | 33.74 GB | 2,877,443 |
| MAX_BY(3回目) | 46秒 | 33.74 GB | 2,851,954 |

注目すべきは スロット（ミリ秒）の部分かなと思います。バイト数などは参考程度に残しておきました。
しかしあれ、おかしいな。大差ない..。

よくよく考えると、ちょっとデータの期間が短かったので user_id, key 毎の更新数が少なかったので差が出なかったのかもしれません。 
ちょっと違うケースでもう一度試してみます。

## case2

今度は `user_id` 毎に (任意のKeyの)最新の value` を取得するというケースを用います。
※ あまり意味は無いですが、単なる検証なのでOKとします。
これで 集約対象となる値の数が増えるので差が出やすくなることを期待します。

それぞれのQueryは以下のような感じになります。

**ROW_NUMBER方式**
```SQL
SELECT
  user_id,
  value as latest_value
FROM data
QUALIFY ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY event_time DESC) = 1
```

**ARRAY_AGG方式**
```SQL
SELECT
  user_id,
  ARRAY_AGG(value ORDER BY event_time DESC LIMIT 1)[OFFSET(0)] as latest_value
FROM data
GROUP BY 1
```

**MAX_BY方式**
```SQL
SELECT
  user_id,
  MAX_BY(value, event_time) as latest_value
FROM data
GROUP BY 1
```

結果は以下の通りになりました。

|  | 実行時間 | 課金されるバイト数 | スロット（ミリ秒） |
| :---: | ---: | ---: | ---: |
| ROW_NUMBER(1回目) | 26秒 | 21.11 GB | 1,613,476 |
| ROW_NUMBER(2回目) | 28秒 | 21.11 GB | 1,465,383 |
| ARRAY_AGG (1回目) | 21秒 | 21.11 GB | 1,040,092 |
| ARRAY_AGG (2回目) | 22秒 | 21.11 GB | 1,029,843 |
| MAX_BY(1回目) | 18秒 | 21.11 GB | **755,268** |
| MAX_BY(2回目) | 16秒 | 21.11 GB | **626,505** |

スロット（ミリ秒）は、予想と期待通り ROW_NUMBER > ARRAY_AGG > MAX_BY という傾向が見て取れます。

# さいごに

記述の簡潔さもパフォーマンスも MAX_BY, MIN_BY が優秀そうです。

ARRAY_AGG 方式のメリットはまだ少しあって、 `ORDER BY event_time, another_value` と順序を複数指定したいときは良い...とは思いますが、だいたいの場合は MAX_BY等を使っていくのが良さそうです。
ちょっとニッチな学習サイト【初学者向け】

# はじめに

「初学者が知らないかもしれない」オススメの学習サイトを紹介します。

# Progate

https://prog-8.com/courses

いきなり有名どころですが、Progateは外せません。
幅広い言語を、基礎の基礎から学ぶことができます。
ポップなUIで楽しく、テンポ良く進めることができるのが楽しいです。

有料ですが、月1490円（年払いなら月当たり990円）はたいていの入門書より安いです。

[有料会員プラン | プログラミングの入門なら基礎から学べるProgate\[プロゲート\]](https://prog-8.com/plans/for_users?ref=plansNotice_%2Fplans%2Fnotice)

初心者にオススメとされていますが、私自身は息抜き&基礎力チェックでも使っていました。
# SQLab

https://sqlab.net/

SQLラボと読みます。SQLの問題集です。
SQLって触れる機会が少ないんですよね。そこにベストマッチのアプリです。
無料です。

https://qiita.com/take_paolo/items/6b69767d8efbd013bf64

# current-user

https://current-user.vercel.app/

RailsのActiveRecordという概念について、問題を解きながら感覚を掴むことができます。

https://qiita.com/k-sukesakuma/items/b33031a28f7c36741342

RUNTEQの先輩のアプリです。ありがてえ・・・
ニッチなアプリですが、Rails学習者にぜひオススメです。
無料です。

# Regex Hunting

https://www.regex-hunting.com/

regex・・・「正規表現」というものはご存知でしょうか？

例えば「文字列がメールアドレスかどうかを判別する」時に使用します。

```
^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$
```
（↑これでメールアドレスを判別できる）

この「正規表現」、やはり触れる機会が少ないです。
このアプリで基礎から感覚を掴んで、機械の気持ちがわかるようになりましょう。
（正規表現のコツは「機械の気持ちを理解すること」のようです。）

こちらもRUNTEQの先輩のアプリです。ありがてえ・・・

https://qiita.com/yukiHaga/items/8ef2051036e126eb00c6

正規表現をもっと知りたい方はこちら

https://qiita.com/jnchito/items/893c887fbf19e17d3ff9


# VIMATE

https://vimate.jp/lessons

エンジニアなら知らない人はいないエディタ
「Vim」のコマンド問題集です。無料です。

最初は全くわかりませんが、やってるうちに覚えます。

VIMATE・・・Vim + mate（仲間）という命名がシンプルながら素敵です。
かわいらしいキャラクターのデザインもすごい。

<br>

個人的には`hjkl`で移動する脱出ゲームが好きです。
最高タイムは11秒だったと記憶しています。対戦よろしくお願いします。

https://vimate.jp/lessons/vimmer-01

※WindowsとM3 Macbook Airでは移動速度が違いました。キーボードの違いでしょうか。
Windowsのほうが圧倒的に早かったです。


# Codewars

https://www.codewars.com

他のユーザーが投稿した、プログラミング・アルゴリズムの問題を解くことができます。

- 他のユーザーの回答を見ることができ、非常に学びになる。
- 58のプログラミング言語に対応

という特徴があります。

英語なためハードルは高いですが、オススメのサイトです。

# おわりに

以上、ちょっとニッチな需要に答える学習サイトでした。

次は何を書こうかしら・・・
IBMCloud OpenShift Container Registry保存先ストレージの変更

## 内容サマリ
Red Hat OpenShift on IBM Cloudを購入（オーダ）する時に、コンテナイメージの保存先としてICOSストレージを指定する必要がある。本記事では、コンテナイメージの保存先を変更する必要が発生した場合の変更手順について記載する。

:::note warn
本記事は、OpenShiftのイメージレジストリをデフォルトのUnmanagedモードを前提としています
:::

:::note info
IBMCloudのドキュメントは下記に記載がある
<font color="gray">※本記事作成時点では、保存先の変更方法については記載がない</font>
[イメージ・レジストリーのセットアップ](https://cloud.ibm.com/docs/openshift?topic=openshift-registry&locale=ja#openshift_registry_options)
:::

製品オーダ時の下記赤枠の部分が必要になった時の話です。
![Pasted_Image_2024_04_24__22_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/e84cb393-5712-a623-901e-bae8eb685838.png)
 
## 現在の設定を確認
現在どのバケットが内部レジストリーとして設定されているか確認

OpenShift 上でイメージレジストリーに関する設定を詳細に表示
```
oc describe configs.imageregistry.operator.openshift.io cluster
```
このコマンドを実行すると、現在の設定が表示される。ここで、"Storage"セクションに注目して、現在設定されている"s3"ブロックの"bucket"フィールド名を確認します。

```yaml:
Spec:
  Storage:
    Management State:  Unmanaged
    s3:
      Bucket:           icos-test1827130
      Region:           jp-tok-standard
      Region Endpoint:  https://s3.direct.jp-tok.cloud-object-storage.appdomain.cloud
```
Bucketの部分がICOSのバケット名となっている

## 設定の編集
次に、設定を編集するために、以下のコマンドを使用して設定ファイルを開き、編集する
テキストエディタが開かれ、設定ファイルを直接編集する
```
oc edit configs.imageregistry.operator.openshift.io cluster
```
エディタが開いたら、"storage"セクションを探し、"s3"ブロック内の"bucket"フィールドを見つけ、その値を新しいバケット名に変更する。
```
storage:
  s3:
    bucket: <new-bucket-name>
```
編集が完了したら、ファイルを保存してエディタを閉じる。OpenShiftは自動的に変更を検出して設定を更新し、必要な再起動やリソースの再配置を行う。

## 変更内容の確認
イメージレジストリの設定を詳細に表示する
先ほど設定したbucketが反映されていることを確認する
```
oc describe configs.imageregistry.operator.openshift.io cluster
```

## システムへの影響について
:::note warn
イメージレジストリの再起動
設定の変更を適用するためにレジストリが再起動されることがあり、イメージのプルやプッシュが一時的に影響を受ける可能性があるので注意
:::
カメラモジュールとレンズの組合せの選び方がわかる記事

# カメラモジュールとレンズの組合せの選び方がわかる記事

- 組込みの分野で使われるM12マウントには、豊富なカメラモジュールとレンズが提供されている。
- その組合せをどう考えたらよいのかがわかる記事があった。
- カメラモジュールのイメージセンサ
  - イメージセンサの品番
  - イメージセンサの大きさ
  - イメージセンサの解像度
  - カメラモジュールのコネクタ: 例MIPI
  - フレームレート
- レンズの特性
  - イメージサークルの大きさ
  - 視野角
  - 焦点距離 


## 「インターフェース」2024年5月号
[デュアルカメラ製作を通してVR撮影ツールとしての実力を見てみる 実験④…VR動画撮影](https://interface.cqpub.co.jp/wp-content/uploads/if2405_079.pdf)

このような方法で組合せの検討ができる。
ほかに検討することとしたら、こういったものがあるだろうか。
- ピントを合わせた後の画像の鮮明さ
- 低照度環境でのノイズの評価
- 対象物の距離ごとの画像上の大きさ
    - その対象物が何ｍ先まで検出できるかどうか
- 照度が極端に変化する状況での画像の品質 

この記事を読めば、あなたもカメラモジュールの選択・レンズの選択ができるようになるはずだ。
STM32C011J4M7のI2Cを使い、AQM0802A液晶で文字表示(簡易版)


x 原因は、わからないが液晶がちらつく場合は、ウェートを調整してね!!

目的
I2C液晶のテスト

![o_coq060.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/eb985364-4852-4071-e5b1-6a2a90aaea6c.jpeg)


![o_coq061.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fbdd26e0-2215-224a-3b51-f6c14acd428d.jpeg)

![o_coq062.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2634a3e3-b9af-9b2e-adb7-6d3a45e09c4d.jpeg)

![o_coq063.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/20653b88-9dac-e058-0a98-6a58801a2547.jpeg)



結果

![o_coq064.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5877778c-9d70-8d04-4ff3-f7ccaa455960.jpeg)


プログラム

```c++


//AQM0802A_DEMO1

#include <Wire.h> //I2C library

//i2cバッファー
char data_read[4];

//初期レジスター
char INIT_com[] = {
  0x0, 0x38, //1
  0x0, 0x39, //2
  0x0, 0x4,  //3
  0x0, 0x14, //4
  0x0, 0x70, //5
  0x0, 0x56, //6
  0x0, 0x6C, //7
  0x0, 0x38, //8
  0x0, 0xC   //9
};

//画面のクリアレジスター
char INIT_cls[] = {0x0, 0x1};


//i2c書き込みルーチン
void i2c_lcd_w(char *buff1) {
  Wire.beginTransmission(0x3E);
  Wire.write(buff1[0]);
  Wire.write(buff1[1]);
  Wire.endTransmission();
  delay(2);
}//i2c_lcd_w


void ns_putc(char ch)
{

  data_read[0] = '@';
  data_read[1] = ch;

  //I2Cに送信
  i2c_lcd_w(data_read);

}//ns_putc


void ns_puts(const char *str1)
{

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    ns_putc(*str1 ++);

  }//while

}//ns_puts


//カーソルの移動
void setCursor(int col, int rows)
{

  data_read[0] = 0x0;
  data_read[1] = 0x80 +  (rows * 0x40) + col ; //カーソルを移動

  //I2Cに送信
  i2c_lcd_w(data_read);

}//setCursor


//初期化関数
void setup()
{

  //I2Cのポートの変更
  Wire.setSDA(19); //PA10
  Wire.setSCL(18); //PA9

  //I2Cの初期化
  Wire.begin();

  //液晶の初期化
  for (int ii = 0; ii < 9; ii++) {
    i2c_lcd_w(&INIT_com[ii << 1]);  // ii << 1 = ii * 2
  }//for

  //画面のクリア
  i2c_lcd_w(INIT_cls);

  //表示
  setCursor(0, 0); ns_puts("HELLO");
  setCursor(0, 1); ns_puts("WORLD");

}//setup


//メインループ
void loop()
{}//loop


```
KPTでチームの改善を促進！チームKPTふりかえりの個人ふりかえり

# はじめに
今年から、リビン・テクノロジーズの開発部はFindy Team+ を導入しました。 そして、最近Findy Team+ に 「チームふりかえりβ」機能が追加され、現在チームはこの機能を使って、KPTふりかえりを行っています。
Qiita×Findy記事投稿キャンペーンに合わせて、「チームふりかえりβ」を利用したチームのKPTふりかえりに対して、個人ふりかえりをしてみたいと思います。

:::note warn
Findy Team+ とチームふりかえりβの詳細は、[ファインディ株式会社(Findy Inc)](https://findy.co.jp/)でご確認ください。
:::

# KPTとは
KPTは「Keep」（続けるべきこと）、「Problem」（問題点）、「Try」（改善策）の三つの要素から成るふりかえり手法です。これにより、チームでのコミュニケーションが活発になり、継続的な改善が行えるようになります。

# KPTふりかえり

## Keep:
- **毎週のふりかえりができて良かった。**

## Try: 
毎週のKPTふりかえりを日常的な習慣にすることを目指す。常にふりかえりすることによって、継続的に個人、チームの「取り組み」がよくなる

## Problem:
- **自分のKeepとProblemが、チケットの完了した事項や発生した不具合に関する話題に偏りがちである**

## Try: 
KPTの基本を見直し、以下のリソースを参考にしました：
  - [ふりかえりメソッド「KPT」の基本とはじめ方 – Social Change!](https://kuranuki.sonicgarden.jp/archives/27399)
      推しポイント：KPTの定義、基本的な進め方を再確認できる！
  - [【徹底解説】正しい「KPT」が仕事の成果を生み出す！進め方のコツ、現場の事例を紹介 | SELECK [セレック]](https://seleck.cc/kpt)
      推しポイント：「フィットネス」のテーマの例でKPTのあるべき姿がよくわかる！
### 基本を見直して、これから心がけたいKeep/Problemの考え方
- Keep = 仕事のプロセス中に『取り組み』が良かったことを記述する
- Problem = 仕事のプロセス中に、『取り組み』が良くなかった、または、『取り組み』がなくて、大変だったことを記述する

# 最後に
KPTは、仕事だけでなく、私生活にも応用可能なフレームワークです。チームだけではなく、自分自身のふりかえりにもうまく活用して、継続的に改善していきたいと思います！
[MUI X Data Grid v6] で画像をセルに埋め込む / フィルタ後のデータにも適用する

# 画像をセルに埋め込む

https://v6.mui.com/x/react-data-grid/

https://v6.mui.com/x/react-data-grid/export/#excel-export

> Excel export
> This feature relies on [exceljs][1]. The Excel export allows translating columns' type and tree structure of a DataGrid to an Excel file.

> Customizing the document
You can customize the document using two callback functions:
> exceljsPreProcess called before adding the rows' dataset.
exceljsPostProcess called after the dataset has been exported to the document.
Both functions receive **{ workbook, worksheet }** as input. They are exceljs objects and allow you to directly manipulate the Excel file.




## exceljsPostProcess

`GridToolbarExport`に`exceljsPostProcess`を渡してエクセルの出力を`exceljs`を使って制御する。


1. まず`workbook`に`addImage`で画像を追加する
1. 次に`worksheet`の`addImage`でセルに画像を埋め込む

```tsx:CustomToolbar.tsx
const rows = ... // data gridで表示しているデータ

<GridToolbarExport
excelOptions={{
  fileName: "export-filename",
  exceljsPreProcess: ({ workbook, worksheet }: ExcelJsProcessProps) => {

    rows.forEach((row, index) => {
      const base64 = ...

      const imageId = workbook.addImage({
        base64, // https://github.com/exceljs/exceljs?tab=readme-ov-file#add-image-to-workbook
        extension: "jpeg",
      })
    
      worksheet.addImage(
        imageId,
        `A${index + 1}:A${index + 1}`
      )
    })
  },
}}

```

https://github.com/exceljs/exceljs?tab=readme-ov-file#add-image-to-workbook

## フィルタ後のデータにも適用する

例えばData Gridに10行あったとして、フィルタの使用で3行に絞り込んでいる状態からexcelを出力しようとしたとする。この場合、Data Gridでフィルタ後の表示されている行だけで画像の埋め込みを行わなければいけない。
が、`exceljsPreProcess`では絞り込み後のデータは受け取れないので自分でなんとかするしか無い。

```tsx:ListPage.tsx
<DataGridPremium
  onStateChange={(params) => {
    const ids = Object.entries(params.filter.filteredRowsLookup)
      .filter(([_, shown]) => shown)
      .map(([id, _]) => id)

    sessionStorage.setItem("excel.export.ids", JSON.stringify(ids))
  }}
/>
```

まずはこのようにして`sessionStorage`に表示されている行のIDを一時保存しておく。

```tsx:CustomToolbar.tsx
const ids = JSON.parse(sessionStorage.getItem("excel.export.ids"))
const rows = ... // data gridで表示しているデータ
const filteredRows = rows.filter((row) => ids.includes(row.id.toString()))

// 以下は同じ
```

ポイントはDataGridPremiumの`onStateChange`で`sessionStorage`を使う所。

- `React.useState`に入れようとすると無限にre-renderを繰り返してエラーになる
- `React.useRef`だとうまくToolbarコンポーネントに渡せない

`sessionStorage`ならブラウザを閉じれば消えるし、re-renderなどの副作用もない。

[1]: https://github.com/exceljs/exceljs?tab=readme-ov-file#add-image-to-workbook
Viva InsightsでCopilot for M365の利用状況が取得できるようになっている件

Viva Insights(旧Work Place Analytics)でCopilot for M365の利用データが取得できるようになっていました。
Copilotの利用状況についてはViva InsightsのダッシュボードやM365管理センター側で出力することができますが、それよりも詳細データを取得することができます。より利用実態やユーザーの使い方分析をする場合はVivaでデータをみたほうがよいかもしれません。

**Viva Insightsのダッシュボード**

https://techcommunity.microsoft.com/t5/viva-insights-blog/microsoft-copilot-dashboard-now-generally-available/ba-p/4097742

**M365管理センター側での出力**

https://learn.microsoft.com/ja-jp/microsoft-365/admin/activity-reports/microsoft-365-copilot-usage?view=o365-worldwide


## 対象クエリ
個人のクエリのみ対象。組織間等分析する場合は、個人クエリから別途自分で集計する必要がありそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/0f6a4910-b72f-9119-aaa5-fa2b416497e6.png)

## メトリックの選択方法

いつもはメトリック（指標）をひとつずつ選択する必要があるのですが、Copilotの利用状況についてはこちらにチェックボックスを入れると一括で選択されます（現時点では個別に選択することは不可）。急に雑な仕様…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/33336f77-955e-8251-7d28-cffadf58d5aa.png)

## メトリックについて

### 通常のメトリック

通常のメトリックについては以下のドキュメントにまとまっていますが、Copilot関連についてはまだ整備されていないのか記載がありません。（これから転記されるのかな？）

https://learn.microsoft.com/ja-jp/viva/insights/advanced/reference/metrics

### Copilot関連のメトリック

Insightsの分析ページには以下のメトリックの説明がありましたが、
他にもCopilotライセンスの有効日、Office製品ごとのCopilotアクティブ日等が含まれます。

* Copilot が要約した会議
Copilot によって要約された会議の数。
* Copilot が要約した会議時間
Copilot によって要約された会議の時間数。
* Copilot によって作成された会議の要約
ユーザーが Copilot を使用して会議を要約した回数。
* Copilot によって作成されたチャットの会話の要約
ユーザーが Copilot を使用して Teams のチャットやチャネルの会話を要約した回数。
* Copilot を使用して作成されたチャット メッセージの下書き
Copilot を使用して Teams で作成されたチャットとチャネル メッセージの下書きの数。
* Copilot によって要約されたチャットの会話
Copilot によって要約されたチャットやチャネルの会話の数。
* Copilot を使用して送信されたメール
Copilot を使用して下書きを生成して挿入した後に送信されたメールの数。
* Copilot によって作成されたメールのスレッドの要約
ユーザーが Copilot を使用してメールの会話を要約した回数。
* Copilot を使用して実行されたメールのコーチング アクション
ユーザーが Copilot in Outlook によるコーチングを使用してメールの下書きに関するフィードバックを生成した回数。
* Copilot によって作成されたメールの下書き
ユーザーが Copilot を使用して生成したメールの下書きの数。
* Copilot によって作成された文書の要約
ユーザーが Copilot を使用して Word 文書を要約した回数。
* Copilot によって作成されたドキュメントの下書き
ユーザーが Copilot で Word 文書の下書きを作成した回数。
* Copilot を使用して実行されたテキストの書き換えアクション
ユーザーが Copilot を使用して Word 文書のテキストを変更した回数。
* Copilot によって作成されたプレゼンテーションの要約
ユーザーが Copilot を使用して PowerPoint プレゼンテーションを要約した回数。
* Copilot によって作成されたプレゼンテーション
ユーザーが Copilot を使用して PowerPoint プレゼンテーションを作成した回数。
* Copilot を使用して実行された Excel 分析アクション
ユーザーが Copilot を使用してデータを分析し、Excel で分析情報をグラフ、ピボットテーブル オブジェクト、サマリー、傾向、または外れ値として表示した回数。
* Copilot によって作成された Excel の数式
ユーザーが Copilot を使用して Excel データに基づく数式を含む新しい列を生成した回数。
* Copilot を使用して実行された Excel の書式設定アクション
ユーザーが Copilot を使用して Excel で表を強調表示、並べ替え、フィルター処理した回数。
* 送信された Copilot チャット クエリ
グラフを使用したチャット (旧称 Microsoft 365 Chat) を使用して Copilot のユーザーによって送信されたクエリの数。
mswについて

## MSWの基本
Mock Service Worker（MSW）は、サービスワーカーを利用してネットワークリクエストを捕捉し、カスタマイズされたレスポンスを返すことでAPIのモックを簡単に作成できるJavaScriptのライブラリです。これにより、実際のバックエンドサービスが完成する前でも、フロントエンドの開発を進めることができます。

## サービスワーカーとは
サービスワーカーは、Webページとは独立してバックグラウンドで動作するスクリプトで、Webブラウザが提供する技術の一つです。サービスワーカーは、プロキシサーバーのように動作し、ネットワークリクエストをインターセプトして処理することができます。これにより、オフラインでのページアクセスの向上、バックグラウンドデータ同期、プッシュ通知の送信、ネットワークリクエストのキャッシュ管理など、多岐にわたる機能を実現することが可能です。

## MSWの設定方法
まず、npmやyarnを使ってMSWをプロジェクトにインストールします。

```bash
$ npm install msw --save-dev
$ npx msw init public --save
```

## APIのモッキング
モックを設定する際は、handlers配列にAPIエンドポイントごとに定義します。これにより、異なるAPIリクエストに対して具体的なレスポンスを模擬できます。

```src/mocks/handlers.ts
import { rest } from 'msw'

export const handlers = [
  rest.get('/users', (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json([{ id: 1, name: 'John Doe' }])
    )
  }),
  // 他のAPIエンドポイントに対するモックをここに追加
]
```
## ハンドラーを呼び出す処理
```src/mocks/browser.ts
import { setupWorker } from 'msw'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)
```

## workerを起動させる処理
```src/index.tsx
if (process.env.NODE_ENV === "development") {
  const { worker } = require("./mocks/browser");
  worker.start();
}
```

## 使用シーン
- フロントエンドの動き＆デザインを確認すること
- jestでAPIを呼ぶ部分のテスト
- seleniumなどでBEを使わずブラウザを通したテスト

## 便利だと感じること
- バックエンドの開発を待たずにフロントエンドの開発ができること
- バックエンドとフロントエンドでリポジトリを完全に分けても開発が可能
- handlerを少しいじるだけでレスポンスのステータス&中身を変えることができるため異常系の確認が楽
- レスポンスが返ってくるまでの時間を調整できる

## 使ってみて反省点
- 突き詰めすぎるとBEの再開発になってしまう
    - リクエストに応じてresponseを変えることができるが完璧にしようとしてmock実装に時間をかけてしまった

## 解決できていない課題
- 更新&refetchするパターンの実装の時に値を変えるにはどうすればよいか
USDを学習する 01 : ビルド

## はじめに
最近，USDというフレームワークの存在を知り，その可能性に将来性を感じています。[](最近，USDというフレームワークの存在を知りました。解析モデルの異なる複数のシミュレーションコードでデータを共有しようというときに，USDで管理するとスマートに実現できそうです。)本記事では特に，**Python プログラムによる USD データファイルの作成** に焦点を当てて書いていきます。

## ビルド
まずは，OpenUSD のビルドから ... ですが，その前に開発環境を整理しておきます。OS は Fedora Linux を使用しています。ビルドに必要な次のもの

- GCC (13.2.1)
- CMake (3.27.7)
- Python (3.11.9)

は事前にインストールされています。
この他に，追加ライブラリ libXt-devel をインストールしておきます。また、PySide6 と PyOpenGL も利用できるようにしておきます。

```shell
sudo dnf install libXt-devel
```

```shell
pip install PySide6 PyOpenGL
```

OpenUSD のソースコードをダウンロードします。私が取得したものはバージョン 24.05 でした。

```shell
git clone https://github.com/PixarAnimationStudios/OpenUSD
```

いよいよビルドです。オプション -j は並列ジョブ数を表します。システムに負荷が掛かりすぎないように 1 を指定しました。

```shell
python OpenUSD/build_scripts/build_usd.py /opt/usd -j 1
```

「Success!」と表示されたらインストール完了です。

```
Success! To use USD, please ensure that you have:

    The following in your PYTHONPATH environment variable:
    /opt/usd/lib/python

    The following in your PATH environment variable:
    /opt/usd/bin
```

:::note
公式ドキュメントに案内されている Boost, IntelTBB, OpenSubdiv については，Python スクリプトによってビルドを行う限りは自動で取得してくれるようです。取得したものはインストールに指定したディレクトリの src/ 以下に置かれています。 
:::

## 環境変数の設定

私はソフトウェア毎の環境設定に Environment Modules（module コマンド）を使用しているので，以下の設定を追加します。

```text:/usr/share/modulefiles/usd/24.5
#%Module1.0

set USD_ROOT /opt/usd

prepend-path PYTHONPATH $USD_ROOT/lib/python
prepend-path PATH $USD_ROOT/bin

```

## 起動テスト

```
module load usd
usdview /opt/usd/share/usd/tutorials/convertingLayerFormats/Sphere.usda
```

無事にインストールできたようです。

![Usdview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659949/37a1d0fe-1711-c9c2-738f-35f7b30875d4.png)

:::note
Wayland を使用する環境では usdview の起動時に「HgiGL minimum OpenGL requirements not met.」というエラーが出ます。~~シェルに環境変数 QT_QPA_PLATFORM=xcb を指定してエラーを回避しました~~（追記： QT_QPA_PLATFORM=xcb を指定してもエラーを回避できなくなってしまったので，代わりに LIBGL_ALWAYS_SOFTWARE=1 を指定するようにしました）。
:::

## 参考

https://github.com/PixarAnimationStudios/OpenUSD/blob/release/README.md/
QRコード

```php
use ZipArchive;
use Illuminate\Support\Facades\Storage;

public function createAndDownloadZip()
{
    // ZipArchiveを作成してzipファイルを開きます
    $zip = new ZipArchive;
    $zipFileName = 'archive.zip';
    $zipFilePath = storage_path('app/work/' . $zipFileName);

    if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
        // QRコードのデータ
        $qrCodeData = 'https://example.com';

        // QRコードをjpgファイルとして作成して直接zipに追加します
        $qrCodeFileName = 'qrcode.jpg';
        $qrCodeFileContents = QrCode::format('jpg')->size(200)->generate($qrCodeData);
        $zip->addFromString($qrCodeFileName, $qrCodeFileContents);

        // アーカイブを閉じます
        $zip->close();

        // レスポンスとしてzipファイルをダウンロードします
        return response()->download($zipFilePath)->deleteFileAfterSend(true);
    } else {
        // アーカイブを作成できない場合の処理
        return response('アーカイブを作成できませんでした', 500);
    }
}
```
技術書の読書術を読んだ感想とメモ

初めまして。Shaulaといいます。
4月から東京の大手IT企業で働き始めました。
私自身のプロフィールはまた後日書くとして、今日は「技術書の読書術」という本を読んだ感想を述べます。

# この本を選んだ理由
エンジニアとして活躍するためには、多くの技術を身につける必要がある。そのための方法として、やはり読書は避けて通れないと思いました。私自身読書自体は嫌いではないものの、なかなか継続できない性格なので、この本で何かきっかけが得られないかと思って読んでみました。
# メモ
## ①選び方
この章ではどのように自分に合った本を選べば良いか、ということが書いてありました。と言いつつ、私が特に印象深かったのは以下の２つ。

・新刊情報を通知で自動で取得できるようにしよう！
・くじ引き読書法

新刊を自動で通知してくれるサービスがあることを、全く知りませんでした。技術は発展が目覚ましいですからね。すぐにhontoというサービスに登録してみました。
また、読書を習慣化できていない自分にとって、くじ引き読書法という手段は非常に楽しそうだと感じました。全くしらない分野の本棚の前に立って、目を瞑って本を選ぶ。とても楽しそうです。また、何か考えが詰まっている時に、全く新しいジャンルの本に挑戦することで、新しいアイデアが出てくることもあると書いてありました。
## ②読み方
続いて読み方。自分が一番気になっていた項目です。

### 「『3』の発想」
技術書は、同じレベルで3冊ほど読んでみるといい。過去の自分は、1冊読んでそれで理解できなければ向いてないんだろうな…と挫折することが多かったです。そうではなく、入門書なら入門書レベルで3冊ほど読み比べることで、何が大切か、ある本では理解できなかった項目が別の本では理解できるようになることがある。読書を継続するために大切だと感じました。

### 「同じ本を何度も読む」
人間1度で全てを理解するのは難しい。ましてや分厚い技術書なら尚更です。3回読んで定着させる方法が書いてありました。
1回目：流し読みでOK。具体的には、各章や項のタイトル＋最初の数行を読む。それで何が書いてあるか大体わかりそうなら今の自分に合っていると判断
2回目：手を動かしながら読む。プログラムはコピペではなく自分で書く
3回目：メモをとりながら。2回目で詰まったところ、重要な箇所など

### 「読書の管理」
何事でも、自分が頑張ったことを振り返る時に可視化していることは大切です。読書管理について書いてありました。Notionを使っているので、テンプレを引っ張ってきてカスタマイズして使ってみようかなと思います。

### 読み飛ばしテクニック
本の要旨の８０％は、全体の２０％に含まれているんだとか。読書をするときは、その20％を見極めることが重要です。そのためにも、読み飛ばしをすることは非常に有効的です。例えば、順接（だから、このように等）の後には結論がくることが多い＝著者が言いたいこと＝重要箇所と判断して、しっかり読んでみるとか。

### 自分のレベルに合っているか判断する基準
・流し読みで本の概要が掴めるか否か
・新しい発見が数ページに１つあるくらい（毎ページ発見していては、自分の脳の処理が追いつかない）

### 付箋の活用方法
重要だと思ったらとりあえず付箋を貼る。というのも、これまでは私は本を読みつつメモをNotionにとる、みたいなことをやっていましたが、気づいたらメモを取ることが目的化していて、途中で疲れる、なんてことがよくあるんですよね。付箋ならサッと貼るだけなので、お手軽。これは実践したいですね。

## 情報発信＆共有
### アウトプットは最大の成長！
アウトプットをするメリットは、
・頭の整理ができること
・間違いに気づけること
・好循環を形成できること
です。好循環とは、

本を読む→とりあえずアウトプット→フィードバックをもらう→もうちょっと勉強
本を読む→わからないことが多い→でもとりあえずアウトプット→インプットが足りない

という2つのループ。わからないけどアウトプット、アリだなと思いました。そうすることで、何を理解できていないか俯瞰的にみることができそうです。読んだらとりあえずQiitaに書いてみます。

# まとめ
超雑に書いてきましたが、インプット→アウトプットの好循環、読書を習慣づけするために、これからもQiitaに書くことを継続します。文章力、もっと身につけたいな…

# 書籍情報
タイトル：「技術書」の読書術

著者：IPUSIRON、増井敏克

出版社：株式会社翔泳社

発行年月：2022年11月

ページ数：269ページ
https://www.shoeisha.co.jp/book/detail/9784798171548
[GAS]ダイアログボックスに整数を入力し、偶数か奇数かを判断

GAS勉強の備忘録としアウトプットしていきます。
↓本日のコード
# ユーザーからの数値入力と条件分岐
GASで数値を入力させ、その数値が偶数か奇数かを判定するスクリプトです。

```
function checkEvenOdd() {
  let ui = SpreadsheetApp.getUi();
  let userInput = ui.prompt("数値を入力してください").getResponseText();
  let number = parseInt(userInput);
  if (!isNaN(number)) {
    if (number % 2 === 0) {
      Browser.msgBox(number + "は偶数です");
    } else {
      Browser.msgBox(number + "は奇数です");
    }
  } else {
    Browser.msgBox("数値を入力してください");
  }
  
}
```

## ■アウトプット
`SpreadsheetApp.getUi()` 
スプレッドシート上にダイアログボックスやユーザーの入力を取得

`prompt("数値を入力してください")`
ユーザーが入力するダイアログボックスを表示

`getResponseText()` 
ダイアログボックスでユーザーが入力したテキストを取得する

`parseInt()` 
文字列を整数に変換する関数

`isNaN()`
「is Not a Number（数値ではない）」の略
与えられた値が数値でない場合にtrueを返す関数
cscの作法 その499

# 概要
cscの作法、調べてみた。
bit数判定を、見つけたので、コンパイルしてみた。

# 参考にしたページ

https://qiita.com/radian-jp/items/72ae751e55ab5373d00a


# サンプルコード

```

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class ExcelUtility {
	[DllImport("kernel32.dll")]
	private static extern bool IsWow64Process(IntPtr hProcess, out bool Wow64Process);
	public static bool IsExcel32Bit() {
		bool result;
		dynamic app = null;
		try
		{
			var appType = Type.GetTypeFromProgID("Excel.Application");
			if (appType == null)
			{
				return false;
			}
			if (!Environment.Is64BitOperatingSystem)
			{
				return true;
			}
			app = Activator.CreateInstance(appType);
			var procs = Process.GetProcessesByName("EXCEL");
			if (procs.Length == 0)
			{
				return false;
			}
			bool bWow64;
			if (!IsWow64Process(procs[0].Handle, out bWow64))
			{
				return false;
			}
			result = bWow64;
		}
		catch (COMException)
		{
			return false;
		}
		finally
		{
			if (app != null)
			{
				app.Quit();
				Marshal.ReleaseComObject(app);
				app = null;
				GC.Collect();
				GC.WaitForPendingFinalizers();
				GC.Collect();
			}
		}
		return result;
	}
}
namespace app
{
	class test0 {
		static void Main() {
			if (System.Environment.Is64BitOperatingSystem)
			{
				Console.WriteLine("64ビットOSです。");
			}
			if (IntPtr.Size == 4)
			{
				Console.WriteLine("32ビットで動作しています");
			}
			else if (IntPtr.Size == 8)
			{
				Console.WriteLine("64ビットで動作しています");
			}
			if (ExcelUtility.IsExcel32Bit())
			{
				Console.WriteLine("ok Excel is 64bit");
			}
			else
			{
				Console.WriteLine("ng Excel is 32bit");
			}
		}
	}
}




```

# 実行結果

```
c>ex6
64ビットOSです。
64ビットで動作しています
ok Excel is 64bit

```


以上。