OmniAICreator/Qiita-1.07M huggingface dataset:
UNVTを使ってGeoJSONをPMTilesに変換する

# 取り組みの背景
## 背景1.巷で話題のPMTilesを触ってみる
大規模な地理データをストレージから提供可能な技術「PMTiles」
このPMTilesがGeoJSONから直接生成可能になったとのことで試してみようと思いました。
*今まではMBTilesからしか生成できなかったとのこと。

## 背景2.UNVTを試して、理解する
2つ目の背景として、UNVTを試して理解しようと思いました。

「UNVTとは、国連ベクタータイルツールキット(UNVT)は、Webマッピング用のベクタータイルを作成、ホスト、スタイル設定、最適化するためのオープンソースソフトウェア(OSS)のコレクション」とのこと。

また、OSSコレクションに限らず、Vectorデータの生成からWebでの配信に関してドキュメントも整備されているとのことで、小職は、これらまとめて、Vectorデータの取り扱いのいわゆるベストプラクティスのようなものではないかと理解しております。





*私、個人的には地理データの取り扱いやツール群は、
あまり一般化されていないように感じていたので、かなりありがたいです。
その中に比較的新しいPMTilesに関するライブラリが含まれていることもイケているポイントだと重みます。

# 前提
Dockerがインストールされていること
筆者は下記のコマンドでdockerのインストール状況を確認しました。
`docker -v`
`Docker version 20.10.13, build a224086`

# 手順
## 手順1.unvt/nanbanのDockerイメージをダウンロードし、ターミナルから接続する
下記のコマンドを実行するとDocker環境に接続した状態になるので、
次の手順に移りましょう。
```
docker run -it --rm -v ${Docker環境と連携したいローカル環境のディレクトリパス}:/data unvt/nanban
```
補足: Googleさん曰く、unvt/nanban は、開発者向けの UNVT Dockerfile です。Ubuntu をベースとしており、Docker でユーザーフレンドリーな UNVT 環境を実現します。﻿
とのことです。

## 手順2.変換元になるGeoJSONをDocker環境から参照できるようにする
1.で指定したローカル環境のディレクトリパス配下に変換元のGeoJSONファイルを格納しましょう。
筆者は「Ctrl + t」で別のターミナルを立ち上げ、下記のコマンドを実行しました。
`cp ${格納しているディレクトリの絶対パス}/hoge.geojson $PWD`

## 手順3.GeoJSONのフィルター設定用のymlファイルを作成し、設定を記述する
touchコマンドで任意の名前のymlファイルを作成しましょう。
任意のファイル名ですが、筆者はkata.ymlとしました。
```
touch ${任意のファイル名}.yml
```

作成したymlファイルに設定を記述します。
今回はGeoJSONを表示するための最小のズーム倍率と最大のズーム倍率を記述しました。
ここで、propertiesなども指定することで、
特定のプロパティの値が特定のデータのみをPMTilesに変換できるようになる模様です。

```ruby:kata.yml
${任意のLayer名}:
  source: ${Docker環境上のgeojsonのパス}
  minzoom: 0
  maxzoom: 5
# hogeプロパティが1のデータのみPMTilesの変換対象にする場合
# properties:
#   hoge: 1
```

## 手順4.tippecanoeを利用したPMTilesへの変換
いよいよGeoJSONからPMTilesへの変換処理です。
下記のコマンドを実行ください。
```
kata filter kata.yml | tippecanoe -o ${任意のファイル名}.pmtiles --no-tile-compression --no-feature-limit --no-tile-size-limit
```

実行すると下記の流れで処理が進みます。
kataコマンドでGeoJSONをフィルター
↓
フィルターされたGeoJSONが出力される
↓
出力結果をtippecanoeへ渡す(パイプ)
↓
PMTilesへ変換

# 生成されたPMTilesの確認方法
下記のサイトで、PMTilesの確認が可能です。
ローカルに生成されたファイルをアップロードしてみましょう。

https://protomaps.github.io/PMTiles/

# 分かったこと
・GeoJSONからPMTilesへの直接変換は可能でした。
・複数のGeoJSONファイルをPMTilesに変換する場合は、事前にGeoJSONファイルをマージしておく必要がありますね。
・40MBのGeoJSONを変換するためにも10秒前後の時間がかかったため、より大規模なデータを取り扱う場合は工夫が必要そうですね。
・kataコマンドによるフィルター処理を今回は記述しましたが、こちらスキップしてもいいかもしれないですね。まさにこのフィルターの流れがUNVTの流れを考慮した処理フローと理解していいと思います。

# 宿題
kataコマンドやtippecanoeのオプションなどは、
リファレンスを元に理解を深める必要がありそうです。

# 参考
■参考にさせていただいたQiitaの記事です。多大なる感謝を送らせてください。

https://qiita.com/T-ubu/items/93d84b9d4bf5be608fda

■Dockerコマンド確認用

https://atmarkit.itmedia.co.jp/ait/articles/1702/01/news061.html#:~:text=docker%20run%E3%81%AF%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F,%E5%90%88%E6%88%90%E3%81%97%E3%81%9F%E3%82%82%E3%81%AE%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82

■ターミナルでcpコマンドを使う時にコピー元とコピー先の指定の仕方が分からなくなった時用

https://discussionsjapan.apple.com/docs/DOC-1061

■UNVTのアプローチも参考になりました

https://github.com/unvt/nanban

■UNVTについてもっと詳しく

https://qiita.com/T-ubu/items/3f1a431fdd1e39d07ade
SalesforceのOauth認証がinvalid_client_id","error_description":"client identifier invalidで失敗したときにやったこと

## この記事について
SalesForceのAPIを叩く前にOauth2にてトークンを取得しようとしていた時に躓いたポイントをまとめています。

## 起きていた現象

GoogleAppsScriptを用いて以下のコードでSalesForceのOauth2を叩いて、アクセストークンを取得しようとしていたのですが、invalid_client_id","error_description":"client identifier invalidというエラーがでてきて取得ができませんでした。

```code.js
function authorization() {
    var res = UrlFetchApp.fetch(
      "https://login.salesforce.com/services/oauth2/token", 
      {
        "method" : "POST",
        "payload" : {
          "grant_type": "password",
          "client_id": "SalesForceのコンシューマ鍵", //コンシューマ鍵
          "client_secret": "SalesForceのコンシューマの秘密", //コンシューマの秘密
          "username": "ユーザーネーム", //ユーザ名
          "password": "パスワード" //パスワード
      },
      "contentType": "application/x-www-form-urlencoded",
      "muteHttpExceptions": true
    });
    if (res.getResponseCode() == 200) {
      var prop = PropertiesService.getScriptProperties();
      prop.setProperty("session_info", res.getContentText());
      console.log("接続成功");
    } else{
      console.log(res.getContentText());
      console.log("接続失敗");
      }
}
```
resという変数に返ってくるのはエラーレコードだけでした。

## 対応したこと
結論、エラーが出た次の日に認証を試してみたら接続できました。そもそも接続用のアプリケーションが有効化されるのに時間がかかるようですね。他にもいろいろと対応したことがあったので書き記します。

### ユーザー名パスワードフローを許可のトグルをONにした

以下のキャプチャのようにOauth設定のユーザー名とパスワードフローを許可のトグルをＯＮにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/f14e3d67-85e2-696f-557a-d3428cf6f4e2.png)

### 作成したアプリケーションへのアクセスを許可した

プロファイル設定から接続アプリケーションへのアクセスというチェックボックスがあります。今回作ったのはGASAPIという接続アプリケーションを作っていたので、これのアクセスができるようにチェックボックスをTRUEにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/67559081-b72a-708c-4419-1bd62d61807e.png)

### 接続用アプリケーションのOauthポリシーを変更した

IP制限の緩和というオプションをIP制限の緩和に設定し、許可されているユーザーというオプションをすべてのユーザーは自己承認可能に変更しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/684c2a44-5d49-0300-f8d0-10f527799df9.png)


## 何が理由でできたか

上記の対応を行ったとしてもしばらくアクセストークンを取得することができず、一晩寝て、次の日にトライしたらアクセストークンの取得に成功しました。つまり、結局いろいろ設定をいじってみたのですが、たぶん有効化されるまでに時間がかかるだけなのかなと思います。同じく躓いた人に参考になればと思います。
富岳のPyTorch-1.13.0でSwallow-7b-instruct-hfをムリヤリ動かすには

スーパーコンピュータ「富岳」のspack0.19版python3.10で、[tokenizers](https://huggingface.co/docs/tokenizers)が動かない理由は、rustの[スレッド周り](https://github.com/rust-lang/rust/blob/1.75.0/library/std/src/sys/unix/thread.rs#L102)にある。これを[ムリヤリ回避する](https://qiita.com/KoichiYasuoka/items/545e6eefcd7a41737eec)には、tokenizersにスレッドを使わせないよう`TOKENIZERS_PARALLELISM=false`すれば、何とか[transformers](https://huggingface.co/docs/transformers)が動く。[Swallow-7b-instruct-hf](https://huggingface.co/tokyotech-llm/Swallow-7b-instruct-hf)に「[パソコンのキーボードは，なぜABC順・五十音順ではないのですか](https://kotobaken.jp/qa/yokuaru/qa-35/)」と尋ねてみよう。

```
#! /bin/bash
#PJM -L rscgrp=small
#PJM -L elapse=1:00:00
#PJM -L node=1
#PJM -j
#PJM -S

. /vol0004/apps/oss/spack/share/spack/setup-env.sh
spack load py-torch@1.13.0/glqavnh
G=`id | sed 's/^.*gid=[0-9]*(\([^)]*\)).*$/\1/'`
set `ls -d /vol*/$G /vol*/data/$G` $HOME
export PYTHONUSERBASE=$1/Swallow
export PATH=$PYTHONUSERBASE/bin:$PATH
export HF_HOME=$PYTHONUSERBASE
export TMPDIR=$PYTHONUSERBASE/tmp
mkdir -p $TMPDIR
pip3 install -U transformers accelerate sentencepiece tqdm typing_extensions --user

P=$TMPDIR/swallow.$PJM_JOBID.$$.py
cat << 'EOF' > $P
from transformers import LlamaForCausalLM,LlamaTokenizer,TextGenerationPipeline
mdl=LlamaForCausalLM.from_pretrained("tokyotech-llm/Swallow-7b-instruct-hf",low_cpu_mem_usage=True)
tkz=LlamaTokenizer.from_pretrained("tokyotech-llm/Swallow-7b-instruct-hf")
tgn=TextGenerationPipeline(model=mdl,tokenizer=tkz,max_new_tokens=128)
nlp=lambda txt:tgn(f"以下に、あるタスクを説明する指示があります。リクエストを適切に完了するための回答を記述してください。\n\n### 指示:{txt}\n\n### 応答:",do_sample=True)[0]["generated_text"]
print(nlp("パソコンのキーボードは，なぜABC順・五十音順ではないのですか"))
EOF
env TOKENIZERS_PARALLELISM=false python3 $P
```

富岳のログインノードから`pjsub`してみたところ、ジョブ待ち・インストール・ダウンロード等も含め、30分ほどで以下の結果が得られた。

> 以下に、あるタスクを説明する指示があります。リクエストを適切に完了するための回答を記述してください。
>
> \### 指示:パソコンのキーボードは，なぜABC順・五十音順ではないのですか
>
> \### 応答:キーボードの配列は、使用頻度の高いキーを中心に、英語圏の人にとって効率的に入力できるように設計されています。アルファベット順に並んでいないのは、キーボードには多くの文字があり、アルファベット順に並べると、キーボードのスペースが不足するからです。

[12月22日の記事](https://qiita.com/KoichiYasuoka/items/553038ec96e49a0b6663)とは微妙に異なる結果だが、とりあえず7bモデルなら、富岳1ノードで十分ということだ。さて、13bモデルや70bモデルも、この手法で動かせるのかな。
【Linux】基本的なコマンド

# Linuxの基本的なコマンドまとめ

### ディレクトリの移動 cd

```
$ cd [ディレクトリ名]
```
#### 補足

|ディレクトリ名|書き方|意味|
|---|:-:|---|
|カレントディレクトリ|.|現在いるディレクトリ| 
|親ディレクトリ|..|カレントディレクトリの一つ上の階層のディレクトリ|
|ホームディレクトリ|/home/ユーザー名|ユーザー個人のディレクトリ|
|ルートディレクトリ|/|一番上のディレクトリ|

※ `/home` はホームディレクトリではない

### カレントディレクトリの表示 pwd
```
$ pwd
```

### ディレクトリの中身を表示 ls
```
$ ls [オプション名] [ディレクトリ名/ファイル名]
```

ディレクトリ名やファイル名はワイルドカードで指定することも可能
`*` 任意の文字列
`?` 任意の一文字

#### オプション
- ファイルの詳細を表示する 
```
$ ls -l
```
- 隠しファイルも含めたすべてのファイルを表示
```
$ ls -a
```
- ファイル種別を表示する
```
$ ls -F
```
|表示|ファイル種別|
|:-:|---|
|/|ディレクトリ|
|@|シンボリックリンク|
|*|実行可能ファイル|
|記号なし|通常ファイル|

### ディレクトリの作成 mkdir
```
$ mkdir [オプション] 作成するファイル名
```

#### オプション
- 深いディレクトリを一度に作成する
```
$ mkdir -p ディレクトリ名1/ディレクトリ名2/ディレクトリ名3
```

### 空のディレクトリの削除 rmdir
```
$ rmdir 削除したいディレクトリ名
```

### ファイルの中身を表示 cat
```
$ cat [オプション] [ファイル名]
```

#### オプション
- 行番号を表示する
```
$ cat -n [ファイル名]
```

### ファイルの中身をスクロールして閲覧 less
```
$ less ファイル名
```




### ファイルの最後10行を表示 tail
```
$ tail [オプション] ファイル名
```
#### オプション
- 最後の指定行数分を表示
```
$ tail -n 数字 ファイル名
```

### ファイルの作成 touch
```
$ touch 新規ファイル名
```
※既存のファイル名を指定すると実行されない

### ファイルの削除 rm
```
$ rm [オプション] 削除するファイル名
```
#### オプション
- ディレクトリの中身もまとめて削除
```
$ rm -r 削除するファイル名
```
- 削除するときの警告文非表示
```
$ rm -f 削除するファイル名
```
- 削除前に確認する
```
$ rm -i 削除するファイル名
```

### ファイルの移動、ファイル名の変更 mv
```
$ mv [オプション] 移動元 移動先
```
※移動先がファイルの場合はファイル名が変更され、ディレクトリの場合はディレクトリ内に移動する
```
#### オプション
- 上書き前に確認する
```
$ mv -i 移動元 移動先
```

### ファイルやディレクトリのコピー cp
```
cp [オプション] コピー元 コピー先
```
```
#### オプション
- 上書き前に確認する
```
$ cp -i 移動元 移動先
```
- ディレクトリをコピー
```
$ cp -r 移動元 移動先
```

### ハードリンクを張る ln
```
$ ln [オプション] リンク元ファイル名 リンク名
```
#### オプション
- シンボリックリンクを張る
```
$ ln -s リンク元ファイル名 リンク名
```

### ファイルの検索 find
```
$ find 検索開始ディレクトリ 検索条件 アクション
```
検索開始ディレクトリを起点に、検索条件と一致するファイルを検索する
検索したファイルに対し、アクションを実行する

### 検索条件
- ファイル名で検索（ファイル名を大文字小文字で区別）
```
$ find 検索開始ディレクトリ -name 検索したいファイル名 アクション
```
- ファイル名で検索（ファイル名を大文字小文字で区別しない）
```
$ find 検索開始ディレクトリ -iname 検索したいファイル名 アクション
```

※ファイル名で検索するとき、ワイルドカードの使用も可能
ワイルドカードで指定するときは、検索するファイル名をクォーテーションで囲む必要がある

- ファイル種別で検索
```
$ find 検索開始ディレクトリ -type ファイル種別 アクション
```

### ファイルやディレクトリのパーミッションを設定
```
$ chmod [u/g/o/a] [+/-/=] [r/w/x] ファイル名
```
- [ u / g / o / a ]

|書き方|対象|
|:-:|---|
|u|オーナー|
|g|グループ（ファイルの所有グループ）|
|o|その他のユーザー|
|a|すべてのユーザー|

- [ + / - / = ]

|書き方|対象|
|:-:|---|
|+|権限の追加|
|-|権限の削除|
|=|記載の権限|

- [ r / w / x ]

|書き方|対象|
|:-:|---|
|r|読み取り|
|w|書き込み|
|x|実行|

### ファイルのオーナーやグループを変更 chown
```
$ chown [オプション] ユーザー名 ファイル名
```
ユーザー名には、オーナーのユーザー名やユーザーID、
グループのグループ名やグループIDを指定することができる

### 実行中のプロセスを表示 ps
```
$ ps [オプション]
```
#### オプション
- 全ユーザーのプロセスを詳細情報と合わせて表示
```
$ ps aux
```

### プロセスやジョブを終了させる
```
$ kill [オプション] %ジョブID
$ kill [オプション] プロセスID
```
#### オプション
- 強制終了
```
$ kill -SIGKILL ID
$ kill -9 ID
```
（超初心者）LINE「赤ペン先生」作りたい！

## ご挨拶
はじめまして
食品スーパー事業の企業内で食品工場に従事する会社員です。複数の工場からの報告書をまとめ上司に報告する業務の頻度が多いのですが自分も含めて誤字脱字　意味の分からない文書が多くて悩むことが多いのです。
## こんなことがしたい
目の前の報告書の文章を校正する「**赤ペン先生が欲しい**」と考えています。
そこでLINE Botを使って瞬時に校正出来ないか？と思いつきトライしてみました。

![スマホ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/f56728a7-df4f-3abd-89a9-6c883ff2cb2e.png)




### 使用したツール
<details><summary>1.Make</summary>
 タスクやワークフローからアプリやシステムまで、あらゆるものをビジュアルプラットホーム上で作成できるツール
</details>
<details><summary>2.LINE</summary>
　LINE Botを活用して自動で返答する仕組みを活用
</details>
<details><summary>3.Google Cloud Vision</summary>
 画像のocr機能を使いテキスト化　
</details>
<details><summary>4.OpenAI(ChatGPT)</summary>
 文章校正を検索するとChatGPTが出てきました。本当にできるかな？
</details>

### スマホで文字起し


https://cloud.google.com/vision/docs?hl=ja

### 文字校正するには　
調べてみると　OpenAI(ChatGPT)　ができるみたい

https://www.tactsystem.co.jp/blog/catalog_32/

だけど・・・使い方がよくわからない
とりあえず繋げてみたが・・・

### Makeの全体ショット
![スクリーンショット (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/f5013415-3cae-fe75-ed22-c6d95329f59a.png)


### 試してみた
https://twitter.com/6IfGib4SMp86140/status/1746061752180293862




### 結果(未完成）

文書の中の「【終繕費】」と誤ったところを指摘してほしかったのですがそのまま反映しています。

写真のテキスト化まではできましたが校正をする機能がわかりません
つなげ方やAPIの使い方も理解していないからだと思います。
文書校正の目的を果たせるように調べていきます。


## 今後の参考になる記事
　記事を参考に試してみたい。
 　自動で議事録を作成できるなんてすごく助かる。やってみたい。

## LINEに文字起こし機能があった

https://guide.line.me/ja/services/scantext.html


## スマホで文字起こし、議事録自動作成
https://note.com/rencontre_1/n/ndbc8188ec939
Prisma

Prismaは、Node.jsとTypeScriptのための次世代のORM（オブジェクトリレーショナルマッピング）ツールです。Prismaを使用すると、データベースのスキーマを定義し、データベース操作をより簡単に行うことができます。以下に、Prismaの基本的な使い方について説明します。

Prismaのセットアップ

1.プロジェクトへのPrismaのインストール:
```
npm install @prisma/cli @prisma/client
```
2.Prismaスキーマファイルの初期化:
```
npx prisma init
```
これにより、prismaディレクトリと.envファイルがプロジェクト内に作成されます。

3.データベーススキーマの設定:
prisma/schema.prismaファイルを編集して、モデル（データベースのテーブルに相当）を定義します。
```
model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
}
```

4.データベースへの接続:
.envファイルにデータベース接続情報を設定します。
```
DATABASE_URL="postgresql://username:password@localhost:3306/mydb"
```

5.データベースのマイグレーション:
モデルの変更をデータベースに適用します。
```
npx prisma migrate dev --name init
```

データベース操作
Prisma Clientを使用して、データベースのCRUD（作成、読み取り、更新、削除）操作を行います。

1.データの作成:
```
const prisma = new PrismaClient();

async function createUser() {
  const user = await prisma.user.create({
    data: {
      name: 'Alice',
      email: 'alice@example.com',
    },
  });
  return user;
}
```

2.データの読み取り:
```
async function getUsers() {
  const users = await prisma.user.findMany();
  return users;
}
```

3.データの更新:
```
async function updateUser(userId, newEmail) {
  const user = await prisma.user.update({
    where: { id: userId },
    data: { email: newEmail },
  });
  return user;
}
```

4.データの削除:
```
async function deleteUser(userId) {
  const user = await prisma.user.delete({
    where: { id: userId },
  });
  return user;
}
```
これらの基本操作を通じて、Prisma Clientを使用してデータベースを操作できます。PrismaはTypeScriptとの互換性も高く、強力な型安全性と自動補完機能を提供します。

公式ドキュメント（Prisma Docs)
https://www.prisma.io/docs
NetworkX入門(5)

# ノードを増やす
これまでの2個のノードの場合：
```Python
G = nx.DiGraph()
G.add_node(1)
G.add_edge(1, 2)
```

ノードを増やすのに、add_nodeを使っても良いのだが、そうすると離れ小島ができてしまう。結局、add_nodeとadd_edgeを２つ呼ぶことになる。
その点、add_edgeを使うと、１回でノードとエッジを増やしてくれる。

今回は、add_edgeのリスト版の **add_edges_from** を使った。引数はエッジのリストである。

```Python
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3), (1, 4), (2, 4)])

nx.draw_networkx(G, node_color='lightblue', edge_color='dimgray')
plt.savefig('file05_.png')
```

![file05_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78475/ad4fca0e-3fdc-2104-d3ce-1ed2e9c6dedc.png)
apacheにmod_perlを導入する方法

# はじめに
アプリケーション導入とかに必要なmod_perlをapacheに導入したい人向けの記事です。
apacheのインストール方法は割愛してます。
導入のための必要最低限の事項しか書いてませんので、ご了承ください。

# 実施環境
 **Rocky Linux 8.5(Red hat系ならおそらく転用可能)**
※外に出られる環境であることが前提です

 # 方法
1. yumもしくはdnfコマンドでインストール

```
# yum install mod_perl
もしくは
# dnf install mod_perl
```

2./etc/httpd/conf/httpd.confに以下を追加

```
LoadModule perl_module modules/mod_perl.so
```

3.apacheの再起動

```
systemctl restart httpd
```

終了です。外に出られる環境なら簡単ですね。
あとは必要に応じて、設定ファイルに設定を追加していってください。
ソースインストールする方法もありますが、それはまたの機会に解説できればと(未検証)…
モーメント荷重が作用するはり 第6章 はりのたわみと不静定はり 基本例題6.30 P180「材料力学演習(20221021)」をsympyでやってみたい。

・モーメント荷重が作用するはり
 
 # オリジナル
[基本例題6.30 p180](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=185)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
```python
# ver0.1
# 基本例題6.30 P180
from sympy import *

var('l,EIz,a,b,vA,x,z',real=True)
θA = Symbol('θA')
RA  = Symbol('RA')
RB  = Symbol('RB')
MA  = Symbol('MA')
MB  = Symbol('MB')
MC  = Symbol('MC')
repxl={x:l}
repxz={x:z}
repx0={x:0}
replab={l:a+b}
repabl={a+b:l}
repθA0={θA:0}
repvA0={vA:0}
zax=(z,a,x)
z0x=(z,0,x)
MAC=MA+RA*x                                                      ;print("# MAC   =",MAC)
MCB=MA+RA*x-MC                                                   ;print("# MCB   =",MCB)
# 
θCB=θA-1/EIz*integrate(  MA        .subs(repxz),z0x)           \
      -1/EIz*integrate( (RA*x)     .subs(repxz),z0x)           \
      -1/EIz*integrate( -MC        .subs(repxz),zax).factor()    ;print("# θCB  =",θCB)
vCB=vA-      integrate( -θA        .subs(repxz),z0x)           \
      -1/EIz*integrate( (MA*x)     .subs(repxz),z0x)           \
      -1/EIz*integrate( (RA*x**2/2).subs(repxz),z0x)           \
      -1/EIz*integrate( -MC*(x-a)  .subs(repxz),zax).factor()    ;print("# vCB  =",vCB);print()
θCB=θCB.subs(repθA0)
vCB=vCB.subs(repθA0).subs(repvA0)
# 
sol=solve([θCB.subs(repxl),vCB.subs(repxl)],[RA,MA])                      #;print("# sol  =",sol)
RA_ans =sol[RA].factor();RA_ans=numer(RA_ans).subs(replab) / denom(RA_ans)  ;print("# RA  =",RA_ans)
MA_ans =sol[MA].factor();MA_ans=numer(MA_ans).subs(replab) / denom(MA_ans)  ;print("# MA  =",MA_ans)
RB_ans =-RA_ans                                                             ;print("# RB  =",RB_ans)
MB_ans=(MA_ans+RA_ans*x-MC).subs( repxl ).factor()                         #;print("# MB  =",MB_ans)
MB_ans= numer(MB_ans).subs(replab).factor() / denom(MB_ans)                 ;print("# MB  =",MB_ans)
# MAC   = MA + RA*x
# MCB   = MA - MC + RA*x
# θCB  = θA - MA*x/EIz + MC*(-a + x)/EIz - RA*x**2/(2*EIz)
# vCB  = vA + x*θA - MA*x**2/(2*EIz) + MC*(-a + x)**2/(2*EIz) - RA*x**3/(6*EIz)

# RA  = 6*MC*a*b/l**3
# MA  = -MC*b*(2*a - b)/l**2
# RB  = -6*MC*a*b/l**3
# MB  = -MC*a*(a - 2*b)/l**2
```

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p89~~
　
~~＞単純支持ばり 7)~~
~~＞構造力学公式集 p136~~
iPhone純正ミュージックアプリにパソコンから転送している人はApple Musicにお試しでも加入しない方が良い

少数であるがそういう風にしている人はいるだろう。
ではなぜやめた方が良いのか。
ミュージックアプリを開くとたまにApple Musicの無料体験のお誘いが来ることがある。
私はパソコンから音楽ファイルを転送する方法で音楽を聴いているが、無料につられて申し込んだことがあった。

すると、自分の端末にあるアルバムが、Apple Musicのラインナップにも存在すると、Apple Music側のデータに上書きされる。曲名やジャケットなど。
実際あったのが、苦労して探して見つけたマイナーなアルバムのジャケットの一番高品質なものを設定していたのに、Apple Musicの圧縮されたガビガビ画質のお粗末な物に置き換えられてしまったり、限定版のジャケットが通常版の物になっていたりした。

というように、Apple Musicのデータを優先されるので、自分で転送している人はApple Musicはお勧めしない。（例え無料体験でも）
gasをつかってspreadsheetでセルをコピーするときの形式まとめ


E36の内容をR5にコピーする場合。この場合は、値のみコピー。
~~~java:
//csheet は、操作するシート
csheet.getRange('E36').copyTo(csheet.getRange('R5'),SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
~~~

CopyPasteTypeの種類 ([GoogleWorkspaceのリファレンス](https://developers.google.com/apps-script/reference/spreadsheet/copy-paste-type?hl=ja))

|プロパティ|種類|貼り付けるもの|
|:---------|:-----------|:------|
|PASTE_NORMAL|Enum|値、数式、書式、結合|
|PASTE_NO_BORDERS|Enum|値、数式、書式、結合(枠線なし)|
|PASTE_FORMAT|Enum|書式のみ|
|PASTE_FORMULA|Enum|数式のみ|
|PASTE_DATA_VALIDATION|Enum|データ検証のみ|
|PASTE_VALUES|Enum|値のみ|
|PASTE_CONDITIONAL_FORMATTING|Enum|色ルールのみ|
|PASTE_COLUMN_WIDTHS|Enum|列幅のみ|
Galaxy Z Fold5でProxy設定が解除されなくて困った話

## TL;DR
[Proxyman](https://proxyman.io/) 使って通信デバッグしてたら、設定からProxy解除しても内部的にProxy外れてない ということがありました。
端末固有な問題な気がしますが、内容を記事にします。

（結論: `adb shell settings` でプロキシ外した。）

# **Galaxy Z Fold5でのプロキシ設定解除問題の解決法**
プロキシを使用する際は手順に注意が必要です。Samsung Galaxy Z Fold5でプロキシマン（[Proxyman](https://proxyman.io/)）を使用されたところ、後でプロキシ設定が解除できなくなるという事態が起きました。
### 発生した事象
[Proxymanのトラブルシューティング](https://docs.proxyman.io/debug-devices/android-device#2.-troubleshooting)に記載されている手順に従って設定した後、設定からネットワークへと進み、プロキシ設定を解除しました。しかし、設定が解除されたにも関わらず、すべてのアプリがプロキシ経由で通信しようとしてエラーになってしまうという問題が発生しました。
### トラブルシューティング
問題を解決するため、Android端末の設定でプロキシが残っていないかを調査しました。以下のADBコマンドを使用して、プロキシ設定を確認してみます。
```shell
# Androidのシステム設定を確認
adb shell settings list global
# セキュア設定を確認
adb shell settings list system
# グローバル設定を確認
adb shell settings list secure
```
その結果、以下のようなプロキシ設定が見つかりました。
```kotlin
global_http_proxy_host="IP"
global_http_proxy_port="port"
http_proxy="ip:port"
```
設定を削除するには以下のコマンドを使用します。
```kotlin
adb shell settings delete global http_proxy
```
その後、端末を再起動し、問題が解決しました。
### 結論
Galaxy Z Fold5で再度プロキシ設定をしても同じ問題が再発しなかったため、原因ははっきりしませんでした。同様の方法でGoogle Pixel Pro 7を使用した際には問題は起こっていません。なお、どのような設定も自己責任で行う必要があることはご理解ください。
お家サーバー その10

# 概要
お家サーバーやってみる。
ハッカソンなので、wordpressにthree.js載せてみた。

# 写真

![スクリーンショット 2024-01-13 153616.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dd16d0e2-2bde-c60f-7179-7532f222dd60.png)

# 手順
- 新規投稿クリック。
- カスタムHTMLブロックを追加。


# サンプルコード

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/three@0.124.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.124.0/examples/js/controls/DragControls"></script>
<script src="https://unpkg.com/three@0.124.0/examples/js/controls/OrbitControls.js"></script>
<div id="koko"></div>
<script>
let scene, 
    camera, 
    light,
    renderer;
renderer = new THREE.WebGLRenderer({ 
	  antialias: true 
});
renderer.setSize(400, 400);
var conk = document.getElementById('koko');
conk.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.background = new THREE.Color(0xbfd1e5);
camera = new THREE.PerspectiveCamera(45, 400 / 400, 1, 1000);
camera.position.set(0, 0, 200);
scene.add(camera);
light = new THREE.AmbientLight(0xFFFFFF);
scene.add(light);
const size = 70;
const geometry = new THREE.BoxGeometry(size, size, size);
const material = new THREE.MeshNormalMaterial()
const box = new THREE.Mesh(geometry, material);
scene.add(box);
renderer.render(scene, camera);
var raycaster = new THREE.Raycaster();
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.update();
renderer.domElement.addEventListener('click', function(e) {
  var raymouse = new THREE.Vector2();
	raymouse.x = (e.offsetX / 400) * 2 - 1;
	raymouse.y = -(e.offsetY / 400) * 2 + 1;
	raycaster.setFromCamera(raymouse, camera);
	var intersects = raycaster.intersectObjects(scene.children);
	if (intersects.length > 0)
	{
		const material0 = new THREE.LineBasicMaterial({ 
  	  color: 0xff0000 
    })
    const points = new Array()
    points.push(intersects[0].point)
    points.push(new THREE.Vector3(50, -50, 40))
    const geometry0 = new THREE.BufferGeometry().setFromPoints(points)
    const line = new THREE.Line(geometry0, material0)
    scene.add(line)
    renderer.render(scene, camera);
    }
})
function tick() {
	requestAnimationFrame(tick);
	//box.rotation.x += 0.03;
	//box.rotation.y -= 0.02;
	renderer.render(scene, camera);
	controls.update();
}
tick();
</script>
```

以上。
Experience Cloud をブログとして使用する


+ [Use Experience Cloud as Blog](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000C37zESAR)


www.learn experiencecloud.comでは、OOTB コンポーネントとカスタム コンポーネントを CMS とナレッジと組み合わせて使用​​し、ブログ機能を実現しています。したがって、少しカスタマイズする場合でも、高度なカスタマイズが必要な場合でも、Experience Cloud は間違いなくブログサイトに使用できます。

私たちのサイトでは、ナレッジ記事と CMS ニュース レコードを組み合わせて使用​​しています。

プラットフォームに関して言えば、いくつか言いたいことがあります。

1. このシナリオにおける wordpress と Experience Cloud の最大の考慮事項の 1 つは、wordpress サイトのサーバー側のメンテナンスです。ホスティング、SQL DB、負荷分散などが必要になりますが、Experience Cloud OOTB ではそれらのほぼすべてを実現できます。

2. 構築の観点から見ると、明らかにブログタイプのサイトとしては、WordPress は歴史的にトッププラットフォームの 1 つです。それがその存在の主な目的であるとさえ言えるでしょう。そのため、ブログプラットフォームとして公開するのが簡単で、Experience Cloud よりも無料のプラグインがたくさんあります。

したがって、特にブログプラットフォームの場合は、WordPress が主な機能であるため、WordPress が有力なケースとなります。Experience Cloud を使用すると、「クラウド」機能を使用する必要のないメンテナンスが大きな価値を生みます。単なるブログサイトからサイトを拡張し、ビジネスプロセスや CRM オブジェクトに基づくいくつかの機能を追加して、Experience Cloud から多くの価値を得ることができます。


あなたの場合、ただ楽しむためにやっているのであれば、Experience Cloud 上にブログ サイトを構築するのは楽しい挑戦かもしれません :) 

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

他にも、CMS やエクスペリエンス ビルダーのコンテンツを使用してブログを構築した顧客がいます。コンテンツでは、手動収集と動的収集 (タグ付けあり) も提供します。こちらは、あなたにぴったりのフォローブログですhttps://developer.salesforce.com/blogs/2019/11/deliver-Beautiful-and-contextualized-digital- experiences-with-salesforce- cms.html 。最後に、これを構築する際に、これをサポートするために cms がさらに改善できることについてフィードバックをいただければ幸いです... ご自宅の完成おめでとうございます。構築の過程を文書化するというアイデアがとても気に入っています。
Github Pages で BrowserRouter が正常に処理されない

個人で、`React`アプリを作成し、`Github Pages`で公開したのですが、`BrowserRouter`を使用した複数ページの表示がうまく動作しない問題にハマったので、解決方法を記載します。

因みに、学習結果としてのソースコード、公開しているページのリンクは以下なので、興味があれば閲覧ください！

##### ソースコード

https://github.com/NagaJun1/sample_react_ts

##### 公開ページ

https://nagajun1.github.io/sample_react_ts/

## 環境
- windows11
- `react-router-dom` バージョン: `6.21.1`
　※バージョン`5.x.x`を使用した際、実装方法が異なります。
- `gh-pages` バージョン: `6.1.1`
　※`package.json`に手を加えて、`npm run deploy`の実行で、`gh-pages`ブランチに変更内容が直接プッシュされるような状態になっています。

## 原因
先に原因を記載しておくと、`Github Pages`で`react-router-dom`を使用したページ遷移を行った際、正しく遷移・処理が行えず、`404.html`へ遷移してしまうというのが原因でした。
解決方法として、`404.html`の読み込み時に`index.html`と同じ内容を読み込ませることで解決できました。
具体的な方法は、以下に記載します。

## `package.json`の修正
`scripts`の`build`の記載を、以下の様に修正します。
修正により、`build`時に`index.html`を`404.html`へコピーする処理が走ります。
※ `cp` コマンドでコピーを行っているため、`git bash`が使えることが前提となります。

```package.json
{
  "scripts": {
    "build": "react-scripts build && cp build/index.html build/404.html",

.... // 以下は、deploy 時に、gh-pagesブランチへプッシュするための設定
    "deploy": "gh-pages -d build",
```

## その他
そもそも、初期ページが表示できないという場合は、`BrowserRouter`に`basename={process.env.PUBLIC_URL}`を記載するか、各ページのパスに対して、自身のリポジトリ名を追加する様な修正が必要です。

```App.tsx
const App = () => {
  // 各ページのパス設定
  return <BrowserRouter basename={process.env.PUBLIC_URL}>
    <Routes>
      <Route path='/' element={<Home />} />
      <Route path='/author' element={<Author />} />
      <Route path='/report' element={<Reports />} />
    </Routes>
  </BrowserRouter>;
};
```

各ページのパスを修正するなら、以下
※ 私が作ったサンプルだと、`sample_react_ts`がリポジトリ名となります。

```App.tsx
const APP_NAME: String = "sample_react_ts"; // これが、リポジトリ名

const App = () => {
  // 各ページのパス設定
  return <BrowserRouter>
    <Routes>
      <Route path={APP_NAME + '/'} element={<Home />} />
      <Route path={APP_NAME + '/author'} element={<Author />} />
      <Route path={APP_NAME + '/report'} element={<Reports />} />
    </Routes>
  </BrowserRouter>;
};
```
AWS SOA 取得に向けて覚えておいた方がいいこと

AWS SOA 取得に向けて勉強している中で、個人的に覚えておいた方がいいと思ったことを備忘録として残しておきます。

# EC2 の購入オプション
Savings Plan は１時間あたりに支払う利用金額をコミットする
リザーブドインスタンスはインスタンススペックをコミットする
## Savings Plan
### EC2 Instance Savings Plan
同じリージョン内の特定のインスタンスファミリーに適用される割引プラン
### Compute Savings Plan
インスタンスファミリーやリージョンに依存せず適用される割引
FargateとLambdaにも適用可能
## リザーブドインスタンス
### スタンダード
リージョンとインスタンスファミリーが固定
### コンバーティブル
作成時の価格と同等以上であればインスタンスファミリー・タイプ、OS の変更が可能

### 参考
- [【徹底解説】AWSコスト削減、Savings Plansとは（第1回）](https://www.sunnycloud.jp/column/20220427-01/)

# Elastic Beanstalk のデプロポリシー
## All at once
- 一気にデプロイする
- 既存インスタンスへのデプロイ
- ダウンタイムが発生する
## Rolling
- バッチサイズ(50%など)を決めてデプロイする
- 既存インスタンスへのデプロイ
- ダウンタイムは発生しない
- 一時的にキャパシティが減り、新旧のアプリケーションが混在する
## Rolling with additional batch
- キャパシティを維持するために一時的に新規インスタンスを起動してデプロイし、完了したら新規インスタンスは削除する
- 既存インスタンスへのデプロイ
- ダウンタイムは発生しない
- 一時的に新旧のアプリケーションが混在する
## Immutable
- 新規インスタンスへのデプロイ
- ダウンタイムは発生しない
- 一時的に新旧アプリケーションが混在する
## Traffic splitting
- 新規インスタンスへのデプロイ
- 一定期間新規インスタンスにも振り分けて問題がなければ全て新規インスタンスに切り替える
- 一時的に新旧アプリケーションが混在する
### 参考
- [【AWS初心者向け・図解】AWS Elastic Beanstalkのデプロイポリシーを現役エンジニアがわかりやすく解説](https://o2mamiblog.com/aws-elastic-beanstalk-deploypolicy-beginner/)

# CloudFront と Global Accelerator の違い
## CloudFront
- 低遅延のコンテンツ配信のサービス
- キャッシュする
- HTTP/HTTPS トラフィックに特化
## Global Accelerator
- アプリの高可用性とパフォーマンス向上、世界中からのアクセスを高速化
- キャッシュせずにオリジンに毎回アクセスする
- ネットワーク層で動作
### 参考
- [CloudFrontとGlobal Acceleratorの違い](https://qiita.com/kimuni-i/items/cefef8f5768a788e667e)
- [Global AcceleratorとCloudFrontの違いが見えてきたら解るCloudFrontの活用方法](https://tech.nri-net.com/entry/global_accelerator_cloudfront)

# EC2 がデフォルトで CloudWatch に送信するメトリクス
  - CPU 使用率
    - PID(プロセス ID)など詳細な情報はエージェントが必要
  - ディスク I/O の読み取り・書き込み
  - NW 情報量（送受信）
  - インスタンス・システム状態
**ディスク使用率やメモリ使用率は CloudWatch エージェントをインストールして取得する**

### 参考
- [CloudWatchでEC2を監視する方法やメトリクスを詳しく解説](https://www.site24x7.jp/blog/cloudwatch-ec2-monitoring/)

# ECS のネットワークモード
## host モード
- ホストの ENI を使ってコンテナが通信を行う
- ホストのポートとコンテナのポートが 1 対 1 になるので同じポートで複数コンテナ起動できないため負荷分散ができない、非推奨
## bridge モード
- ENI とコンテナの間に Bridge を挟むのでホストとコンテナを別ポートで接続して同じポートで複数コンテナを起動できる
- ENI とコンテナは 1 対 N の関係なので SecurityGroup の設定と通信帯域も共有になる
## awsvpc モード
- ホスト EC2 の ENI とは別に、コンテナごとに ENI が生成されるのでコンテナごとにセキュリティ設定ができる
- EC2 の種類によって作成できる ENI の数に上限があるのが欠点

### 参考
- [ECSのネットワークモードを調べてみた](https://zenn.dev/fdnsy/articles/43b7f4d745ed1f)

# Route53 のルーティングポリシー
## 位置情報ルーティングポリシー
- クライアントの位置情報に基づいてルーティングする
- クライアントの国によって言語を変えたい場合などに使用する
## 地理的近接性ルーティングポリソー
- クライアントとリソースの位置情報補に基づいて、クライアントと地理的に近いリソースにルーティングする
- レイテンシを小さくさせる場合に使用する

### 参考
- [Route53の位置情報ルーティングポリシーと地理的近接性ルーティングポリシーの違い](https://qiita.com/kosments/items/b25e893d5d4e47a86216)
webサービスを公開して、2週間たった結果www (ランニングコストとかも公開!)

# webサービスの概要と仮説
2週間って言ったけど、厳密には15日です。たしか、12/29にリリースして、今1/13
[infolink.dev](https://infolink.dev/)
間違いを指摘できる記事投稿サイトって感じです。
詳しくは、これを読んでください。
[webサービス作って公開してみた！](https://qiita.com/infolink/items/90d8ed969d82d9ae3729)

なんか、ネットの記事って信用できないじゃないですか。信用したらバカみたいな風潮もあるし。もちろん、色んなサイトをみたら正しい情報を知れると思うけど、実際はめんどくさくてしない。
というか、そもそも信用に頼りたくないなぁって思う。
なので、需要あるかなぁと思ってたけど...
(infolinkでは、ページビューとか通知とかであるから、それを根拠にできる。)
# 結果
ユーザーは俺だけｗｗ
悲しい😢

# 公開後、改善したこと
- Markdownを貼り付けられるようにした

これで、infolinkにも一応投稿しとくか。とか、過去のを投稿してくれるかなと思ったけど無理でした。

# ランニングコスト
- cloudflare images 5ドル(画像保存)+1ドル(配信) 今のところ、結構オーバースペック
- aws 無料枠を使って13日現在で、0.5ドルぐらいだから1ドルぐらい？まあ、誤差
- mailgun 5000円ぐらい。高すぎるから、mailchimpに乗り換える(mailchimpは8ドルぐらい)。

追記　mailchimpには乗り換えませんでした。送るアドレスのメール認証が必要っぽくて、受信できないので無理でした。 なんか、APIをつかって簡単に送るみたいなシンプルなのがあんまりないんですよね。キャンペーン用のメールみたいなのとかに特化したのが多い気がする。テンプレート作れたり。

amazon sesの無料枠使えば、もっと安くすむけど審査に落ちた笑
awsの構成はelastic beanstalk(elb + ec2 + rds)

これなら、全然維持していける。無料枠があるまでは。

一応、1月の終わりにawsの請求を追記します。追記　5.7ドルでした
![スクリーンショット 2024-02-03 131222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664211/503dc3da-9f48-d8df-8803-04e9c741a3b0.png)



# これから
維持はしていくつもりです。自分の投稿用と、まだいけると思ってるからです！

正直、なんで人気ないのか疑問なんですよね。情報収集するときに、間違ってるか確認するの面倒じゃないですか。プログラミング関連で調べてるときも、これ間違ってたらやばいなって思うときがあって、結構調べたりしたし。

あと、将来的にchatgpt的なのに、データを活用したらめっちゃ便利なんじゃないかなって思ってます。

なんで使わないのか、ぜひコメントで教えてください！本当に！リリースしてから、反応なさ過ぎてやる気なくなってきてます(´；ω；`)　ダメだしでいいのでぜひ！

# おまけ　宣伝した結果

Qiita [webサービス公開してみた！](https://qiita.com/infolink/items/90d8ed969d82d9ae3729) 250pv
qiitaは自分でpv確認したりしてるので、それもカウントされてるかも。

Zenn
![](https://storage.googleapis.com/zenn-user-upload/14c2cb87015f-20240113.png)

よくよく考えると、400回ぐらい見られてるのか。それで、いいね1 ユーザー0ってどうなんですかね。
zennは2だけど、自分で一回押したので実質1です。

Product hunt
予約せずにlaunchしたのもあって、ほぼupvoteされてないです。ランキングに乗るためにも、予約して一日のはじめから投稿したほうがいい。(太平洋時間で2時だったので、まあいいかとおもって投稿してしまった。)
![](https://storage.googleapis.com/zenn-user-upload/e6ded58bd4a7-20240113.png)

[product hunt ページ](https://www.producthunt.com/posts/infolink-dev)


# おまけ　買収提案を送ってみた

売るつもりはそこまでなかったけど、このサービスって価値ないのかなぁって思ってたのと人気がない理由が、僕の技術レベルかなと思って、売ったほうがいいかと思い送ってみた。

ジェフベゾスはメールアドレスを公開していて、ほとんど見てるらしい。

[jeff@amazon.com]()

Would you like to buy my website? Infolink.dev

Description is on the Home page. https://infolink.dev/

Although the number of users is small(me only), I think there is a lot of potential.
For example, we could have something like a mistake-free chatgpt.
who am i ?. verify go to My twitter account @infolink_12_22 dm
 
Released 12/29

みたいなメールを送ってみたけど、返信なし。つまり、拒否か見てない。

ほかの企業
![](https://storage.googleapis.com/zenn-user-upload/7a616e4e56df-20240113.png)

DMが送れて、有名な企業に送ってみた。返信は来なかった笑

GoogleはDMできなかったので、リプライにしました。
もちろん、返ってこなかったです(´；ω；`)
Homebrew コマンドメモ

# インストール前の確認
```s
$ brew list
==> Formulae
autoconf		lua			pycparser
awscli			m4			python-setuptools
ca-certificates		mpdecimal		python@3.11
cffi			nmap			readline
docutils		node-build		six
gettext			nodenv			sqlite
git			oniguruma		tfenv
grep			openssl@3		xz
jq			pcre			yarn
liblinear		pcre2
libssh2			pkg-config
```
```s
$ brew list | grep git
git
```

# インストール
```s
$ brew install <対象>
```

# 困ったら
ココミル
https://qiita.com/fuqda/items/db8aff0ba4068aea2cc6
macOS Unity + VSCodeで Failed at 'command: "dotnet" restore が出て補完できない問題への対処

VSCodeでUnityアプリ開発中、ある時急に
```
Failed at 'command: "dotnet" restore
```
というメッセージが出現し補完が一切効かなくなってしまったので、その対処について書く

# 前提
* 最新のUnity拡張機能を使用していること
* 最新の`"com.unity.ide.visualstudio"`Unityパッケージを導入していること
(`"com.unity.ide.vscode"`ではないことに注意)
* Unity > Preference > External Tools > Regenerate Project filesしてあること


# 結論
1. **`sudo rm -rf /usr/local/share/dotnet`を実行する**
1. **[.NET SDK](https://dotnet.microsoft.com/ja-jp/download/dotnet)をインストールする**
    * Unity2021.3の場合は[.NET SDK 6](https://dotnet.microsoft.com/ja-jp/download/dotnet/6.0)
    * Unity2022.3の場合は[.NET SDK 7](https://dotnet.microsoft.com/ja-jp/download/dotnet/7.0)
1. **PCを再起動する**

で解決した。
どうやら何かの拍子でDOTNET_ROOT環境変数が外れてしまったが、上記手順によってる再生するよう。
SQLServerをdocker-composeで使いたい！

# 概要

Dockerのコマンドを覚えるのが面倒くさい...
docker-composeにしようという事で手順をまとめました。

# 動作環境

* Windows11
* Docker Desktop for Windows
  <https://docs.docker.jp/docker-for-windows/install.html>

# フォルダ構成

```
rootdir
    |- docker-compose.yml
    |- sqlserver.env
```

## docker-compose

```docker-compose.yml
version: "3.8"
services: 
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: sqlserver2022
    hostname: sqlserver2022
    ports:
      - 1433:1433
    volumes:
      - ./mssql/data:/var/opt/mssql/data
      - ./mssql/log:/var/opt/mssql/log
      - ./mssql/secrets:/var/opt/mssql/sec
    env_file: 
      - sqlserver.env
```

## 設定ファイル

```sqlserver.env
# 使用許諾契約書の同意
ACCEPT_EULA=Y
# タイムゾーンの設定
TZ=Asia/Tokyo
# 照合順序
MSSQL_COLLATION=Japanese_CI_AS
# 言語
MSSQL_LCID=1041
# SQLServerAgent
MSSQL_AGENT_ENABLED=true

# SAのパスワード　※変更してください
MSSQL_SA_PASSWORD=sqlpass123!
```

# 使い方

1. sqlserver.envのパスワードを変更してください。
2. コマンドを叩いてSQLServerを起動します。
   ```bash
   docker-compose up -d
   ```
3. SQLServerが立ち上がるまで少し待ってから、sa/先程変更したパスワードで接続してください。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239480/12605368-9b5b-e119-20b8-ce91d4b6b435.png)
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239480/1254db89-2197-7656-5f0f-1c825698bba3.png)

# 補足

頻繁に使われる方は、docker-compose.ymlにrestart: alwaysを入れておくと楽です。

# 関連URL

* Docker Hub
  <https://hub.docker.com/_/microsoft-mssql-server/>
* Docker Desktop for Windows
  <https://docs.docker.jp/docker-for-windows/install.html>
何もしていないのにマウスカーソル砂時計が頻繁に繰り返し表示される

同じ問題を抱えている方がいるかと思い投稿しました。
内容的には負荷の原因となっているアプリの特定です。
私の場合は、某ウイルススキャンソフトがログを頻繁にディスクに書き込むことによりSystemプロセス（Windows Kernel）やディスクIOが高くなり事象が発生していることが分かり、アンインストールしたところ、すっきり解決しました。
以降が解決までのプロセスです。調査中に記録を取っていないし、再度インストールもしたくないので画像説明とかないです。フルテキストです。

１．まずはタスクマネージャのプロセスタブでCPU使用率が高いプロセスを見つけます。
　　私の場合は、Systemプロセスが非常に高負荷な状態になってました（何もしていないのに）。次に某ウイルススキャンソフトでした。
２．タスクマネージャから某ウイルススキャンの停止を試みましたが拒否されました。
３．某ウイルススキャンソフトの機能でリアルタイムスキャンやその他をすべて一時停止しました。しかし、状況変わらず。
４．CPU割り込みかと思い、ネットワーク、キーボード、マウス等をすべて切断しました。しかし、状況変わらず。
５．Windows Updateが原因かと思い、最近のアップデートをアンインストールしました。しかし、状況変わらず。
６．IO関連と思い、タスクマネージャのパフォーマンスタブからのリソースモニタを開いたところ、ディスクIO負荷が高いことが分かりました。ディスクの活動にあるファイルパスを見るとアクセスが高いのが某ウイルススキャンのログ出力でした。
７．なので某ウイルススキャンをアンインストールしました。これで解決。

ウイルススキャンの機能を停止してもログを吐き続けるのはどうかと思います。
そもそも、PCの使用を妨げるような負荷が発生するウイルススキャンソフトは本末転倒だと思います。ウイルスかよ。と思いました。しかもお金払ったのに。

一応言っておくのですが、この記事はウイルススキャンソフトを非難するものでは決してありません。ウイルススキャンソフトがすべてダメとは思わないでください。すばらしい製品はあります。
セキュリティは３原則があって、「秘匿性」「機密性」「可用性」です。
PCの可用性を損なうなら、セキュリティ製品として問題があります。
たとえば最強のネットワークセキュリティ（とは呼べないですが防御策）は、ネットワークから切断することです（LAN抜いたり、WiFiをOFFにしたり）。しかし可用性は著しく損なわれます。
某ウイルススキャンソフト会社も、その事を意識した上で製品開発及び改善をしてもらいたいですね。スキャンにより多少負荷が上がるのはしかたない事ですが、使用に支障をきたすようではダメです。ようするにセキュリティはバランスが一番大事と私は思います。
バージョン確認形コマンドのメモ

# Terraform
```s
$ terraform version
Terraform v1.6.1
on darwin_arm64

Your version of Terraform is out of date! The latest version
is 1.6.6. You can update by downloading from https://www.terraform.io/downloads.html
```

# tfenv
```s
$ tfenv
tfenv 3.0.0
Usage: tfenv <command> [<options>]

Commands:
   install       Install a specific version of Terraform
   use           Switch a version to use
   uninstall     Uninstall a specific version of Terraform
   list          List all installed versions
   list-remote   List all installable versions
   version-name  Print current version
   init          Update environment to use tfenv correctly.
   pin           Write the current active version to ./.terraform-version
```
```s
$ tfenv list
* 1.6.1 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
```
【Excel】Yahoo!ジオコーダAPIを使って住所から緯度・経度を取得する

## 目的
CSVファイルで持っている住所一覧データに対して、それぞれの緯度・経度を取得したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781596/a2cfbd96-2d03-7706-b24f-d1d1d1d6df68.png)


## 背景
Tableauでのマップ形式の可視化には、緯度・経度が必要だが、
使いたいデータソースには「住所」情報のみしかなかった。
データ量は10万件以下程度。

## 使ったもの
- Excel 2021
    - [ENCODEURL関数](https://support.microsoft.com/ja-jp/office/encodeurl-%E9%96%A2%E6%95%B0-07c7fb90-7c60-4bff-8687-fac50fe33d0e)
    - [WEBSERVICE関数](https://support.microsoft.com/ja-jp/office/webservice-%E9%96%A2%E6%95%B0-0546a35a-ecc6-4739-aed7-c0b7ce1562c4)
    - [FILTERXML関数](https://support.microsoft.com/ja-jp/office/filterxml-%E9%96%A2%E6%95%B0-4df72efc-11ec-4951-86f5-c1374812f5b7)
- Yahoo!ジオコーダAPI（無料）
https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html

<details><summary>試せてないけど他候補
</summary>


-Google Maps Platform Geocoding API（有料）
https://developers.google.com/maps/documentation/geocoding?hl=ja

-シンプル ジオコーディング 実験（無料）
https://geocode.csis.u-tokyo.ac.jp/home/simple-geocoding/

</details>


## 手順
### Yahoo!ジオコーダAPIの利用準備　アプリケーションの登録
こちらの手順に沿って登録。※Yahoo!JAPAN IDが必要。
https://developer.yahoo.co.jp/start/

ガイドライン
https://developer.yahoo.co.jp/guideline/

Client IDを取得できれば準備OK。

### Excel上でカラム追加していき緯度・経度を取得

:::note info
Yahoo!ジオコーダAPIのサイトより、作りたいURLは下記
```
https://map.yahooapis.jp/geocode/V1/geoCoder?appid=<取得したClient ID>&query=<UTF-8でエンコード化された住所>
```
:::

元データ住所に対して、下記の流れで取得。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781596/5fc17ce1-05a2-613b-8266-610fa5a3afc7.png)


①ENCODE
　住所をUTF-8形式にエンコードする（URLに埋め込むために必要）
```
=ENCODEURL([@住所])
```

②URL
　URL生成
```
="https://map.yahooapis.jp/geocode/V1/geoCoder?appid="<取得したClient ID>&"&query="&[@ENCODE]
```

③XML
　リクエスト実行してXML形式のレスポンスを取得
```
=WEBSERVICE([@URL])
```

④緯度経度抽出
　XMLから緯度・経度情報のみ抽出
```
=INDEX(FILTERXML([@XML],"//Coordinates"),1)
```
レスポンスフィールドのドキュメントより、Coordinatesが座標情報なので、
その要素のみをFILTERXML関数で取得。
FILTERXML関数 参考：https://www.helpaso.net/archives/2359/

:::note warn
今回の住所は～丁目までで番地情報がないので、
そのままだとレスポンスが「スピル形式」というもので1セルに複数入ってくる。
Ex. 東京都中央区日本橋本町4丁目、4丁目8、4丁目4・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781596/5dec595d-6105-23dc-e7e5-d470fbb80263.png)

これだと困るので先頭のもののみ取得するためにINDEX関数で1つめを取得。
※FILTERXML関数で要素指定できそうなものではと思ったもののうまくいかず断念。方法あるかも？
:::

⑤経度、緯度
　抽出したカラムから、カンマで分割して取得（区切り位置で切ってしまった）

:::note warn
 サンプルで調べたところ④で返ってくる並びは
 **[経度,緯度]**
:::


## まとめ
スピル形式に初めて出会ったところで若干面食らった。
Excelの関数、ほんとに色々ある。

:sheep:
Cloud Shellが垢Banされました

## 0. 起こったこと

Cloud Shellが垢Banされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662726/0a77269d-2545-9528-e178-40d8a4c347d4.png)




## 1. ワークログ

週次バッチ化にGoogle Cloudを用いて開発を進めていましたが、Cloud Shellが無効になっていました。これまで行ったことといえば、Cloud Storageのバケット作成やinstanceの作成、SSH接続くらいです。やましいことはしていないはずです……多分(笑)



Cloud Shellの画面の「こちら」のリンクから再審査を請求してみることにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662726/44cbee39-591c-d4ff-9503-1474810e8128.png)



「カスタマーケア サービスを表示」や「ベーシックサポートを選択する」をクリックすると、料金が発生するようなので、「お困りの場合」から再審査を申し込むことにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662726/97b449ad-2289-c283-7275-dbd068784232.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662726/7010b819-3a78-5527-43cf-c56030a639a0.png)




ページを進んでいき、最後の画面「詳細な説明」まで入力を進めました。しかし、送信ボタンが見当たりません。水色の欄を見ると権限がないとのこと。権限とはどういうことか調べてみたら、サポートを受けるためには、やはり課金しなければならないようです。

https://cloud.google.com/support/docs?_ga=2.223605977.-37731933.1699778603&hl=ja 

アカウントを変え、Google Cloudの閲覧履歴を削除することでshellが使えるようになりました。
aws クレデンシャル関連のメモ

# 情報がある場所

```s
$ cat /Users/<UserName>/.aws/credentials
[master]
aws_access_key_id = aa
aws_secret_access_key = aa
[terraform]
aws_access_key_id = bb
aws_secret_access_key = bb
```

```s
$ cat /Users/<UserName>/.aws/config
[profile aaa-sso]
sso_session = aws_cli
sso_account_id = aaa
sso_role_name = AWSAdministratorAccess
region = ap-northeast-1

[sso-session aws_cli]
sso_start_url = https://d-aaa.awsapps.com/start
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access

[profile aaa]
source_profile = master
mfa_serial = arn:aws:iam::aaa:mfa/mfa_aaa
role_arn = arn:aws:iam::aaa:role/aaa
region = ap-northeast-1
[profile terraform]
region = ap-northeast-1
output = json
```

# 新規でクレデンシャル情報を増やす場合
1. IAMユーザー作成する
1. アクセスキーを作成する
1. CLIで登録する
    ```s
    $ aws configure --profile <新しく作成する名前>
    AWS Access Key ID [None]: ccc
    AWS Secret Access Key [None]: ccc
    Default region name [None]: ap-northeast-1
    Default output format [None]: json
    ```
Deploy Source to Org failed to run

+ [LWC エラーの対処方法](https://qiita.com/Keiji_otsubo/items/480135e98f6b0144ee63)
+ [LWC エラーの対処方法2](https://qiita.com/Keiji_otsubo/items/54983dba4eb802686a12)
+ [SFDX: Authorize Errorのまとめ](https://qiita.com/Keiji_otsubo/items/3d6fe7dff0e537ea72c2)

# Deploy Source to Org failed to run

+ ["SFDX: Deploy Source to Org failed to run" How did you resolve this issue?](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000KhDpE)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ad5aef0b-dcef-9b8d-8b93-19000b73809c.png)


+ [i am facing trouble while deploying to org :" SFDX: Deploy Source to Org failed to run"](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PwcXwSAJ)

:::note
try to create a new project and re-authenticate the org 
Please check, 

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000FuzAgSAJ 
:::

+ [Need Help with Apex Class Deployment from VS Code to Authorized Org](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UvQFsSAN)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7358dd4c-cf21-1427-a109-1492fe0f17c6.png)

:::note
Please visit below link and follow the steps to setup correctly.

https://www.apexhours.com/how-to-setup-visual-studio-code-for-salesforce/


Also, I hope you have added the Salesforce extension in your vs code instance.


また、vs code インスタンスに Salesforce 拡張機能を追加していることを願っています。
:::

# Unable to build Lightning Component source for markup://c:contactList: Invalid suffix: json.

+ [i am getting this error : " Deploy Source to Org failed to run "while deploying](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PvRXU)
+ [i am facing trouble while deploying to org :" SFDX: Deploy Source to Org failed to run"](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PwcXwSAJ)

:::note
try to create a new project and re-authenticate the org 
Please check, 

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000FuzAgSAJ 
:::
cloudfrontとalb間で443通信をしたい時の注意点

## やりたかったこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/43f3be1d-3433-5159-fb4e-c47d026e9609.png)
cloudfrontからalb間の通信をHTTPS通信にしたい。
しかし502エラーになってしまった。

## 原因
cloudfrontのオリジンドメインにalbのデフォルトのDNS名を入力していたが、証明書(*.example.com)と紐づいておらずHTTPS通信が出来なくて502エラーが返ってきてしまった。

## 解決方法
前提：
test.exampe.comでcloudfrontにアクセスしたい。
ドメイン名「example.com」はRoute53で取得している。
ACMは「*.example.com」で取得している


１，ホストゾーンレコードにAレコードでtest.exampe.comとcloudfrontディストリビューションドメイン名を設定する。（外部DNSの場合はCNAME）
２，Aレコードでalb.example.comとalbのデフォルトDNS名を設定する。（外部DNSの場合はCNAME）
３，ACMで*.example.comの証明書を取得して、cloudfrontとalbリスナーに証明書を入れる。
４，cloudfrontのオリジンドメイン名を「alb.example.com」に設定する。

## まとめ
cloudfrontとalb間の名前解決について考慮する必要があることを学んだ。ドメインを外部で取得しているとより煩雑になるため理解しにくい。
Macの.movからgifを作成する簡易GUIツールつくりました！Python



### 0.完成例
![gamen_test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/7fff7f19-8b58-c039-c1b0-b08860594d39.gif)
#### ※pythonのインストールが必須です

### 0.5.Pythonで使う外部ライブラリの「ffmpeg」のインストール！
##### -1.「homebrew」のインストール
外部ライブラリをインストールするためのツールです。
```ターミナル
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
##### -2.「ffmpeg」のインストール
```ターミナル
brew install ffmpeg
```

### 1.デスクトップ等に[convertToGif.py]を作成し下記を記述する！

convertToGif.py
```python
import tkinter as tk
from tkinter import filedialog
import subprocess
import os

def convert_mov_to_gif(input_path):
    # 入力ファイル名から拡張子を取り除いた名前を生成
    input_filename = os.path.splitext(os.path.basename(input_path))[0]
    # .gifファイル名を生成
    output_file = f"{input_filename}.gif"

    # ffmpegコマンドを実行して.movを.gifに変換
    cmd = ["/usr/local/bin/ffmpeg", "-i", input_path, "-r", "24", output_file]
    try:
        subprocess.run(cmd, check=True)
        result_label.config(text=f"{input_filename}.mov を {output_file} に変換しました。", fg="green")
        
        # 変換が完了したらウィンドウを1秒後に閉じる
        root.after(1000, close_window)
    except subprocess.CalledProcessError as e:
        result_label.config(text=f"ffmpegコマンドの実行中にエラーが発生しました: {e}", fg="red")
    except Exception as e:
        result_label.config(text=f"エラーが発生しました: {e}", fg="red")

def browse_file():
    file_path = filedialog.askopenfilename(filetypes=[("MOV ファイル", "*.mov")])
    if file_path:
        convert_mov_to_gif(file_path)

def close_window():
    root.destroy()

# Tkinterウィンドウを作成
root = tk.Tk()
root.title("MOV to GIF Converter")

# ファイル選択ボタン
browse_button = tk.Button(root, text="MOVファイルを選択", command=browse_file)
browse_button.pack(pady=20)

# 結果表示ラベル
result_label = tk.Label(root, text="", fg="black")
result_label.pack()

# ウィンドウを表示
root.mainloop()



```

### 2.完成！
ダブルクリックしてmovファイルを選択したらgifができる！


### ※ダブルクリックでうまく起動しない時
##### -1.作ったpyファイルを右クリック>情報をみるを選択
![スクリーンショット 2024-01-13 13.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/b0d4eee1-5f52-fa19-e2c4-e1da07d87d99.png)

##### -2.このアプリケーションで開くに「Python Launcher.app」を選択
![スクリーンショット 2024-01-13 13.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/5fce94c8-1558-08f9-6611-919f2d228a19.png)

これでいけると思います。
【Android】非推奨なgetParcelableの修正方法

# はじめに
getParcelableが非推奨になったのは１年以上前だと思いますが、Navigationを使わない画面遷移で実装していると、比較的頻繁に使いたくなる機能ではありますよね。
今回は非推奨になったgetParcelableに変わる便利なBundleCompatをご紹介したいと思います。

# 非推奨解消方法
まず、こんな感じで呼んでいたものが非推奨になっています。

```main.kt
requireArguments().getParcelable("key")
```

上記の関数定義を確認してみると、下記のように記載されています。

```
Deprecated
Use the type-safer getParcelable(String, Class) starting from Android Build.VERSION_CODES.TIRAMISU.
```

つまりgetParcelableを呼ぶのであれば、クラスを指定しろということなのですが、問題はTIRAMISU以上だということです。
上記説明をそのまま鵜呑みにすると以下のような実装になるかと思います。

```main.kt
val data = if (VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  requireArguments().getParcelable("key", Data::class.java)
} else {
  requireArguments().getParcelable("key")
}
```

確かに上記実装で解決できますが、使用頻度の多いgetParcelableで上記のような分岐は考えたくありません。
そこで便利なのがBundleCompatになります。

BundleCompatを使用すると、以下のように実装が可能です。

```main.kt
BundleCompat.getParcelable(requireArguments(), "key", Data::class.java)
```
以上です、非常にシンプルに実装できて良いですね。
BundleCompatには上記以外にも以下のように定義されているので、Arrayなどのケースにも対応可能です。

```BundleCompat.kt
BundleCompat.getParcelableArray(Bundle, String, Class<? extends Parcelable>): Parcelable[] 
BundleCompat.getParcelableArrayList(Bundle, String, Class<? extends T> clazz): ArrayList<T>
BundleCompat.getSparseParcelableArray(Bundle, String, Class<? extends T>): SparseArray<T>
```

また、Intentに対応したIntentCompatというのもあります。
```IntentCompat.kt
IntentCompat.getParcelableExtra(Intent, String, Class<T>)
IntentCompat.getParcelableArrayExtra(Intent, String, Class<? extends Parcelable>): Parcelable[]
IntentCompat.getParcelableArrayListExtra(Intent, String, Class<? extends T>): ArrayList<T>
```
対象画面がActivityの場合にも同様に実装が可能なので、非常に便利ですね。
ご説明した上記機能はcore-ktxの1.10.0に含まれているので、お困りの方は是非導入を検討してもらえればと思います。

```
androidx.core:core-ktx:1.10.0
```

# さいごに
Webを進めていますが、フッとkotlinで実装したらどうなるかという疑問を持ってしまいました、、、
方向転換してkotlinをベースに対応できる方法を模索してみようと思います。
boto3でAWS Batchジョブ定義の最新リビジョンを取得するときにハマった

# はじめに
Lambda経由でBatchを実行しようとしたら古いリビジョンのジョブ定義が呼ばれてしまった。
困ったのは**同条件でも最新リビジョンが取れてしまうことがあった**という点。
同じコードを実行しているのに挙動が変わるので、原因がコードにあるのか、それとも他にあるのか、という段階から当たりをつけていくことになり、迷走しました。

# 目次
1. [原因](#原因)
1. [コード](#コード)
1. [解決方法](#解決方法)
1. [最大100件の制限を忘れない](#最大100件の制限を忘れない)


<a id="#"原因"></a>
# 原因

原因はコードにありました。
```python
client.describe_job_definitions()
```
このdescribe_job_definitions()は
アカウントの同一リージョンに存在するすべてのジョブ定義から最大 100 件のジョブ定義のみを取得するメソッドでした。
一方アカウントに存在するジョブは200件を超えていました。
同じコードでも最新リビジョンが取れてしまうことがあったのは最大100件の中に対象のジョブ定義が含まれていたからでした。

<a id="#コード"></a>
# コード
```python
def get_newest_revision():
　　job_definition_name = 'qiita'
    client = boto3.client("batch")
    job_definitions = client.describe_job_definitions()['jobDefinitions']
    
    revision_n = 1
    for job in job_definitions:
        if job["jobDefinitionName"] == job_definition_name:
            if job["revision"] > revision_num:
                revision_n = job["revision"]

    return revision_n
    
```

<a id="#boto3のエラーハンドリング"></a>
# 解決方法
`get_newest_revision()`を使わないで、ジョブの実行を行う。
現在、`submit_job()`はデフォルトで最新リビジョンを参照するようになっています。
一応`jobDefinition=definition-name:revision`として古いリビジョンを指定することもできるようです。

```python
client.submit_job(
                jobName=job_name,
                jobQueue=job_queue,
                jobDefinition=job_definition
            )
```

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/batch/client/submit_job.html



<a id="#最大100件の制限を忘れない"></a>
# 最大100件の制限を忘れない
`describe_job_definitions()`に限らず、boto3のメソッドには一回のリクエストで取得できるオブジェクトの数が制限されるメソッドが多く存在します。(S3の`list_objects_v2`等)
実装する際は注意しようと思う。