OmniAICreator/Qiita-1.07M huggingface dataset:
LibreOfficeのコマンドラインと字幕ファイルの翻訳と変換

使用OS: Linux Minto 21.1
使用ソフト LibreOffice

米英テレビの番組が好きなので字幕を翻訳できないか考えてみる。最初はAoutkeyで考えて、手間がかかりそうとあきらめる。つぎはPandocはどだろうと思ったがMarkdownいいがSrtになるとOptionが多すぎで同じようにあきらめる。一番かんたんなLibreOfficeのコマンドラインに落ちつく。

### 3つの処理が必要です。
次の命令がメインなります。コンソールとブラウザーを使います。
```
soffice --headless --convert-to
```
## 流れ 
1\. srtファイルをdocxファイルに変換する。
```
soffice  --headless --convert-to docx *.srt
```
2\. docxファイルを翻訳する。
```
Google翻訳
https://translate.google.com/?source=gtx&sl=en&tl=ja&op=docs
```
3\. docxファイルをsrtファイルに変換する。
```
soffice --headless --convert-to "srt:Text (encoded):UTF8" *.docx 
```
ここで出来たSrtを動画へはめ込みます。

以上
参考サイト

https://opensource.com/article/21/3/libreoffice-command-line
Amazon ECS 予測不能な負荷急増に対するアプリケーションの耐障害性を向上

# 背景

Amazon ECS において予測不能な負荷急増は、突然のアクセス増加やシステムの変更などが原因で発生する可能性があります。これはアプリケーションのパフォーマンスを低下させ、サービスの中断を引き起こす可能性があります。

Amazon ECSの旧システムでは、タスクがヘルスチェックに失敗するとすぐに終了され、新しいタスクが開始されます。しかし、これはサービスの中断時間を引き起こす可能性がありました。

```mermaid
sequenceDiagram
    participant User
    participant ECS
    participant Unhealthy Task

    User->>ECS: Starts Application
    ECS->>Unhealthy Task: Runs health check
    Unhealthy Task-->>ECS: Fails health check
    ECS->>Unhealthy Task: Terminates unhealthy task

```

この図は、ユーザーがアプリケーションを開始し、ECSが不健康なタスクのヘルスチェックを実行し、不健康なタスクがヘルスチェックに失敗するとすぐに終了することを示しています。

この背景に対し、Amazon ECSはタスクのスケジューリング方法を改善し、アプリケーションの耐障害性を向上させる必要がありました。

# 課題

旧システムでは、負荷急増時にタスクが不健康になると、新しいタスクが開始されるまでの間にサービスが一時的に中断する可能性がありました。このサービスの中断は、ユーザーに対してエラーや遅延を引き起こす可能性があり、アプリケーションの可用性とユーザー体験に悪影響を与える恐れがありました。

また、オートスケーリングは新しいタスクを追加することができますが、アプリケーションのコードや設定に問題がある場合、新しいタスクもすぐに不健康になる可能性がありました。このようなシナリオでは、オートスケーリングだけではアプリケーションの耐障害性を十分に向上させることは困難でした。

# 解決

上記のような課題に対して 2023年10月23日 に新機能が発表されました。

https://aws.amazon.com/jp/about-aws/whats-new/2023/10/amazon-ecs-applications-resiliency-unpredictable-load-spikes/

Amazon ECSはタスクスケジューリングを改善し、不健康なタスクがある場合、そのタスクを終了する前に新しい健康なタスクを開始するようにしました。これにより、サービスの連続性が保たれ、アプリケーションの可用性が向上します。

```mermaid
sequenceDiagram
    participant User
    participant ECS
    participant Unhealthy Task
    participant Healthy Task

    User->>ECS: Starts Application
    ECS->>Unhealthy Task: Runs health check
    Unhealthy Task-->>ECS: Fails health check
    ECS->>Healthy Task: Starts a replacement task
    Healthy Task-->>ECS: Passes health check
    ECS->>Unhealthy Task: Terminates unhealthy task

```

この図では、新しい健康なタスクが開始されてから古い不健康なタスクが終了されるプロセスを示しています。これにより、サービスの中断を最小限に抑えることができます。

# 解説

新しい改善において、ユーザーは`maximumPercent`パラメータを設定することで、同時に開始できるタスクの代替の最大数を制御できます。デフォルトでは200％に設定されており、これによりユーザーはアプリケーションの需要に応じてタスクのスケジューリングを柔軟に調整できます。

また、ヘルスチェックとロードバランサのチェックを定義することで、Amazon ECSスケジューラに不健康なタスクを終了し、新しいタスクで置き換えるタイミングを知らせることができます。これにより、負荷の変動に柔軟に対応し、アプリケーションの耐障害性をさらに向上させることが可能となります。

# 一言
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html

上記URLには maximumPercent のデフォルトは 100% と書いてあるが、 以下のアナウンスではデフォルトが 200% になったと書かれてますね。（そもそも日本語ドキュメントは古いのでそちらを見ないようにw）

https://aws.amazon.com/jp/about-aws/whats-new/2023/10/amazon-ecs-applications-resiliency-unpredictable-load-spikes/ 

どちらが正しいのか念のため確認してみた。

```
aws ecs describe-services \
--cluster {cluster} \
--services {service} \
| jq '.services[0].deploymentConfiguration.maximumPercent'
200
```

おー！
もう 200% になってる！

:::note info
AWSさん、流石です。
:::
ナチュラルキーでの直接Detailアクセス

ScaffoldするとId（サロゲートキー）をInput ParameterとしたDetail Screenが作成されますが、ナチュラルキーでそのDetailを表示するURLを作成して、他のシステムから直接Detailアクセスできるようにする方法を紹介します。

ScaffoldしたアプリでDetailにアクセスするとこのようなURLになっています。
https\://personal-12345678.outsystemscloud.com/AppleDevice/AppleCPUDetail?AppleCPUId=3

最後の「AppleCPUId=3」はId（サロゲートキー）で３つ目のデータにアクセスしている訳ですが、「A11」とか「A16」といったナチュラル（自然）キーの方が、他のシステムからアクセスしやすかったりすることがあると思います。

まず、Detail ScreenでAdd Input Parameterをします。（ここではInName）
Is Mandatory（必須）はNoにしておきます。
（YesだとWarningになってしまいます。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/d26bf03a-e28b-9bc3-ae74-4e9ce9ec411d.png)

次に、①DetailのAggregateを開き、②Filterの③Filter Conditionを④このようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/99701ab4-2bfc-d614-fcb2-b56f71cb2957.png)

Idの値がある時はIdで、InNameがある時はNameでAgrregateします。

これで
https\://personal-12345678.outsystemscloud.com/AppleDevice/AppleCPUDetail?InName=A16
「InName=A16」、ナチュラルキーでアクセスできるようになりました。

が、New（新規）になってしまっています。
既存のデータなのでEdit（編集）でなければいけません。
このままではSaveを押した際に新規登録になってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/7c33f197-a217-54d1-a8be-27711f32f344.png)

原因はDetail ScreenのInput ParameterであるIdがNull、セットされていない為です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/c7a29f74-8790-a7fa-f61c-79b30ed8ff14.png)

参照だけが目的なら閲覧モードにする等ありますが、ここでは編集機能の正常化を図ります。

Detail ScreenのAggregateを選択、EventのOn After FetchでNew Client Actionを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/c633cfa0-4a6a-df8d-4784-c2368637b560.png)

作成されたClient Actionを開き、Assignを配置、AggregateでGetしたIdをDetail ScreenのInput ParameterであるIdにセットしてあげます。
（これはIdでアクセスしてきた場合も動きますが無害のはずです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/dd3e6d35-72c5-1750-82fc-5544ed7628d3.png)

これでEditになりましたし、Saveボタンも更新で機能します。
（アクセスした際、一瞬Newが表示されるのはご愛敬）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/7cc56bc4-472b-e3f1-31c3-d5924bf33f87.png)
ProxmoxでWindowsVMにGPUパススルーする

# はじめに

Proxmoxのホストになっているワークステーションはオンボードグラフィックがない代わりにPCIにGPUが刺さってた。
ゲームも画像AIも全然やったことないので、よくわからないけど、使わないのはもったいないので「GPUパススルー」ってのをやってみる。


# 環境

仮想化のホスト機はこんな感じ

* HP Z640
* CPU: Xeon E5-2650L v3 × 2（24コア48スレ）
* メモリ: DDR4 128GB （2400MHzがCPUで2133MHz駆動）
* ストレージ: M.2 NVMe 1TB （HP Z Turboドライブ経由）
* GPU: NVIDIA Quadro K620

このうちのGPUをホストからVMにパススルーしてWindows10で利用できるようにしてみる。


# ホスト側の設定変更

作業前にBIOSでVT-dを有効にする必要がある。
HP Z640の場合はVT-xもVT-dもセキュリティ設定の中にいるので、ちょっとわかりにくい。


BIOS設定を修正したら、GRUB設定を修正する。

```:vi /etc/default/grub
# 初期状態では以下
GRUB_CMDLINE_LINUX_DEFAULT="quiet"

# これを以下のように修正する
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
```

```:grub設定を反映
update-grub
```

これでホストを再起動したら `dmesg` にVT-dが出ているか確認する。

```:このようになっていればOK
# dmesg | grep -i virtualization
[    7.116733] DMAR: Intel(R) Virtualization Technology for Directed I/O
```


# WindowsVMを作成

**[WindowsのMediaCreationTool](https://www.microsoft.com/ja-jp/software-download/windows10)** を利用してISOファイルを生成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/05ab7ebd-9dd9-2b9b-2ee2-1f6f8cb8bcb5.png)

ISOファイルが作成できたらpveのストレージ（local）の「ISOイメージ」→「アップロード」でホストに転送する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/dbab5350-2960-a9bb-ac65-134038468701.png)


以下のようにWindowsVMを作成する。
このあとでGPUを指定するので `start=1` しないでおく。

```
qm create 999 \
  --name win-gpu \
  --cores 4 \
  --cpu host \
  --memory 8192  \
  --machine q35 \
  --bios ovmf \
  --efidisk0 local-lvm:0 \
  --boot order='sata0;sata1' \
  --sata0 local-lvm:32 \
  --sata1 local:iso/Windows.iso,media=cdrom \
  --net0 e1000,bridge=vmbr0,tag=10

# 失敗したら以下のように削除
# qm stop 999 && qm destroy 999 --purge
```

作成できたら「VM」→「ハードウェア」→「追加」から「PCIデバイス」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/ee7a603c-9803-20a7-fc9a-8ba04ef964d7.png)

別ダイアログが表示されるので「RawDevice」のプルダウンメニュから型番ぽいのを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/8100cfe7-7512-4586-5f19-cfe23515735c.png)

「全機能」をオン「PCI-Express」をオンにして「追加」する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/6a8f22c5-1974-5a2e-e12d-b900e102788a.png)

以下のように追加されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/eaba74b3-eb14-3d7e-bb17-166943e23ca8.png)



# Windows上でのGPUの認識

これでVMを起動してWindowsをインストールしたらK620のドライバもインストールしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/e67c1bc5-1803-147d-e136-4a512ccbdcf5.png)

で、リモートデスクトップ経由でVMに接続して状態を確認する。

タスクマネージャでK620として認識されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/b7371882-bec9-89dc-26f2-0e64e3d4eaa5.png)

「パススルー」ってくらいなので、まるごと見えてる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/b255b39e-8234-6652-06ee-19a29032b405.png)

センサー類もちゃんと取得できてる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/f6fbaaee-0b0b-34c5-6ed3-b2738d1dbf44.png)


# さいごに

自分には縁がない機器なので、そもそも使いどころがよくわからないのですが、GPU使って画像生成？とか高速計算とかで使うんですかね？

とりあえず、つかえた。ってことで。
【jq】関数呼び出しの引数は遅延評価

# TL; DR

```jq:sample.jq
def in_a(pathexps):
  .a | pathexps;

in_a(.b)
```

```bash
$ echo '{"a": {"b": 1}}' | jq -f sample.jq
1
```

# はじめに

9/7に、jqの新バージョンが5年ぶりにリリースされました :tada:

https://github.com/jqlang/jq/releases/tag/jq-1.7

便利な関数もたくさん追加されており、例えば `pick` では指定したパスの要素のみを抜き出せます。

```bash
$ jq -n '{"a": 1, "b": {"c": 2, "d": 3}, "e": 4} | pick(.a, .b.c, .x)'
{
  "a": 1,
  "b": {
    "c": 2
  },
  "x": null
}
```

ところで、JS等 **正格評価の言語では上記の関数は実装できません** 。
正格評価の場合 `pick(.a, .b.c, .x)` は `pick(1, 2, null)` に評価されてから関数呼び出しされるため、関数側ではパスが何であったか知ることができません。

そこで本記事では、jqの引数の評価について調べてみました。

# 関数に渡されるのはパスの式

結論としては、jqの引数は遅延評価されていました[^impl]。

以下のように、存在しないパスを指定してもエラーは発生しません。ということは、関数呼び出しの時点ではパスの式は値に評価されていません。

```jq:sample.jq
# 引数のpathexpsは捨てる
def capture(pathexps):
  100;

capture(.a.b.c)
```

```bash
$ echo '{"a": {"b": 1}}' | jq -f sample.jq
100
```

また、引数は **ただのパスの式** なので、パイプの後に持ってくることも可能です。

```jq:sample.jq
$ cat sample.jq
def in_a(pathexps):
  .a | pathexps;

# .a | .b と同じ
in_a(.b)
```

```bash
$ echo '{"a": {"b": 1}}' | jq -f sample.jq
1
```

ただし、ずっとパスとして扱えるわけではなく、関数本体の式で使用すると値に評価されます。

```jq:sample.jq
def idx(pathexps):
  # ここでパスの値に評価される
  pathexps;

idx(.a.b)
```

```bash
$ echo '{"a": {"b": 1}}' | jq -f sample.jq
1
```

引数を「パスを表す値」として持ちまわりたい場合は `path`  を使用します。

```bash
# パスの式を配列に変換（配列は第一級なのでそのまま変数等に代入可能）
$ jq -n 'path(.a.b[1])'
[
  "a",
  "b",
  1
]
# 再びパスとして使用する場合は getpath
$ echo '{"a": {"b": 1}}' | jq 'getpath(path(.a.b))'
1
# もちろん直接配列を使用してもよい
$ echo '{"a": {"b": 1}}' | jq 'getpath(["a", "b"])'
1
```

# pickの実装

冒頭のpickの実装は以下のようになっています。

```jq:src/builtin.jq
def pick(pathexps):
  . as $in
  | reduce path(pathexps) as $a (null;
      setpath($a; $in|getpath($a)) );
```

reduceを使って、パスの場所にその値を格納しています。パスに指定した場所だけ格納されるため、結果指定したパスのみが抜き出されるという仕組みです。


# おわりに

以上、jqの引数の評価についての紹介でした。jqは名前的にJavaScriptに似た特徴を持つと思い込んでいたので、この挙動には驚きました。

色々応用が効きそうなので、ぜひjq芸に使っていきましょう！ ~~（保守性は見なかったことにする）~~

[^impl]: 処理系まで目を通していないので実際はもう少し複雑かもしれません([VMのC実装](https://github.com/jqlang/jq/blob/e85e3582330af543f1a7b293c6b9b27f342670a2/src/jv_aux.c#L143)を追えなかった... )。ただし、`pick` の引数名が `pathexps` であることからも意図した遅延評価であると思われます。
Playwrightでテストが成功する状態になるまで待機したいときにはtoPassを使う

# expect.toPass
https://playwright.dev/docs/test-assertions#expecttopass

　PlaywrightではLocatorが見つからない場合は自動で待機してくれますが、そのLocatorのテキスト等が違う場合はテストが失敗してしまうことがありますが、expect.toPassを使用することでブロック内が合格するまでテストをリトライさせることができます。
　以下の例は配列testListの長さが10になるまテストをリトライし、一定時間成功しないとタイムアウトになり失敗します。

```
await expect(async () => {
    expect(testList.length).toBe(10);
}).toPass();
```

　リトライのインターバルやタイムアウトは以下のように指定できます。

```
await expect(async () => {
  expect(testList.length).toBe(10);
}).toPass({
  intervals: [1000, 2000, 10000],
  timeout: 60000
});
```

おわり
Promise型データの処理対応(csv出力例)

## はじめに
kintoneでのcsv出力を記載する。
kintoneの場合、データを取得する場合、kintone apiを使用するが、非同期関数でその値はPromise型になる。そのデータを扱う場合、少し慣れが必要なため、動くであろう例を記載する。


## 処理内容
ボタンクリックでcsv出力する
1.データ取得をidより行うにあたり、にkintone apiを使用する。
その時、queryで、idを絞る例を記載する。
kintone apiで取得するにあたりデータは非同期関数でpromise型になる。
その結果を直接変数に格納することはできないため、await直後に処理を行う。
2.dataを取得後、csvデータ取得、ダウンロードという流れになる。

kintoneでのcsv出力のjavascript例
```javascript

// 仮にボタンのIDが 'downloadButton' であると仮定
document.getElementById('downloadButton').addEventListener('click', handleButtonClick);



const ids = [456, 457, 458];
const queryString = `$id in (${ids.join(", ")})`;

const body = {
    app: 123, // ここにアプリIDをセット
    query: queryString
};


async function fetchKintoneRecords() {
    try {
        const data = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body);
        console.log(data);
    } catch (error) {
        console.error("Error fetching records:", error);
    }
}

function convertToCSV(records) {
  // ヘッダーの作成
  const header = ['fieldA', 'fieldB', 'fieldC'];
  const csv = records.map(record => {
      return [
          record['fieldA']['value'],
          record['fieldB']['value'],
          record['fieldC']['value']
      ].join(',');
  });
  
  return [header.join(',')].concat(csv).join('\n');
}


function downloadCSV(csv, filename) {
  const blob = new Blob([csv], { type: 'text/csv' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.setAttribute('hidden', '');
  a.setAttribute('href', url);
  a.setAttribute('download', filename);
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}

async function handleButtonClick() {
  try {
      const data = await fetchKintoneRecords();
      const csv = convertToCSV(data.records);
      downloadCSV(csv, 'kintone_data.csv');
  } catch (error) {
      console.error("Error during button click handling:", error);
  }
}


```

## 注記点
csv出力箇所のconvertToCSV()、downloadCSV()はかなりノウハウ化されているのでここでは特に記載しない。
kintoneのquery使用時、データ取得後の処理について記載する。

・<b>queryで$id限定</b>
`${...}`はテンプレートリテラル
```
const queryString = `$id in (${ids.join(",")})`;
```
ids = [1, 2, 3]の場合、ids.join(", ")は"1, 2, 3"という文字列を返す。
queryでin句を使用している。

・<b>データ取得後、そのデータを使用する</b>
fetchKintoneRecords()にて、async await、ボタンクリック時に、その関数でasync、fetchKintoneRecords()使用時にawaitでdataを取得する。
```javascript
async function fetchKintoneRecords() {
    try {
        const data = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body);
        console.log(data);
    } catch (error) {
        console.error("Error fetching records:", error);
    }
}

async function handleButtonClick() {
  try {
      const data = await fetchKintoneRecords();
      const csv = convertToCSV(data.records);
      downloadCSV(csv, 'kintone_data.csv');
  } catch (error) {
      console.error("Error during button click handling:", error);
  }
}

```
「error linker `cc` not found」解決

# Rustのコンパイルエラー対応

公式サイト

https://www.rust-lang.org/ja/tools/install

## error: linker `cc` not found

Cのコンパイラがインストールされていない場合、下記エラーが表示される。

```bash
/workspaces/rust_devcontainer (master) $ 
error: linker `cc` not found
|
= note: No such file or directory (os error 2)

error: aborting due to previous error

/workspaces/rust_devcontainer (master) $ 
```

## Ubuntuの場合

build-essentialをインストールする。

```bash
sudo apt install -y build-essential
```

インストール後、再度コンパイルすることで問題なく実行できる。

```bash
vscode ➜ /workspaces/rust_devcontainer (master) $ 
vscode ➜ /workspaces/rust_devcontainer (master) $ ./main
Hello World!
```

> 参考URL
[https://omohikane.com/rust_cargo_build_linker_cc_not_found/](https://omohikane.com/rust_cargo_build_linker_cc_not_found/)
>
AMIの無効設定ができるようになった

# はじめに
UpdateでAMI(Amazon Machine Image)に無効化設定ができる機能が追加されました。

https://aws.amazon.com/about-aws/whats-new/2023/10/amazon-ec2-amis-disabled-state/

この機能を使うことにより登録解除を行いたくないが、インスタンスの立ち上げも行わないようなイメージを無効状態にできます。

無効状態のイメージはインスタンスの立ち上げを行えず自己所有のAMIリストにも表示されません。
そのため、管理がしやすくなります。

なお、再度有効状態にすると自己所有のリストに表示されるようになり、インスタンスの立ち上げも行えるようになります。

# ためす
コンソールとAWS CLIからの無効化を試してみます。

## コンソール
コンソール上では、無効化したいAMIを選択し、アクションから「AMIを無効にする」を選択します。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/d323bbca-2f7a-4ab2-6afe-debc3eb9b7b4.png)

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/4e7ca420-5b9c-c47a-cfd8-50342df37349.png)

無効にすると、自己所有のリストに表示されなくなります。
フィルタリングを「Disabled images」に変更すると、無効化したイメージを表示することができます。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/e6741110-9938-cec0-88a0-736294bc08b3.png)

なお、無効化した状態だとEC2コンソールから当該AMIを参照してインスタンスを作成することはできません。
(当該AMIを選択することはできません)
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/f19af5d5-b5a6-1e96-57f1-0efb60b79187.png)

再度有効化したい場合は、「Disable images」に存在するイメージを選択し、「AMIを有効にする」を選択します。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/447e5835-164d-0cf6-7e8e-cd0bb9ba8470.png)

イメージを有効化すると、AMIからインスタンスを作成できるようになります。

![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/8718cf95-70a5-23c7-9b7a-76141dc4c0cd.png)

## AWS CLI
AWS CLIで無効化する場合には、`disabe-image`コマンドを利用します。
```shell
aws ec2 disable-image --image-id ami-1234567890abcdef0
```
`describe-images`コマンドでStateを確認すると、`disabled`となります。

```shell
aws ec2 describe-images --image-id ami-1234567890abcdef0 \
    --query 'Images[0].State'

> "disabled"
```

再度有効化するには`enable-image`コマンドを利用します。
```shell
aws ec2 enable-image --image-id ami-1234567890abcdef0
```

```shell
aws ec2 describe-images --image-id ami-1234567890abcdef0 \
    --query 'Images[0].State'

> "available"
```
Leetcode 515. Find Largest Value in Each Tree Row

https://leetcode.com/problems/find-largest-value-in-each-tree-row/description/

# アプローチ
- DFS


```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public HashMap<Integer, Integer> hashMap;

    public List<Integer> largestValues(TreeNode root) {
        hashMap = new HashMap<>();
        dfs(root, Integer.MIN_VALUE, hashMap);
        return hashMap.values().stream().toList();
    }


    public void dfs(TreeNode root, int depth, HashMap<Integer, Integer> hashMap) {

        if (root == null) {
            return;
        }

        int val = hashMap.getOrDefault(depth, Integer.MIN_VALUE);

        if (val <= root.val) {
            hashMap.put(depth, root.val);
        }

        dfs(root.left, depth + 1, hashMap);
        dfs(root.right, depth + 1, hashMap);
    }
}
```
Apache Sparkの実行環境の特徴

# 実行環境の全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/13d3be84-424e-ff26-c23a-dd2635be4e0f.png)

## Spark dirver

Spark driverには、いくつかの役割がある

- cluster Managerへ情報の伝達をする
- Sparkを実行するJVMのためのcluster Managrからの、メモリなどのリソースの要求
- DAGコンピューティング、スケジュール、それらをタスクとして配布することをSaprkの操作で行う
- 再びリソースを配布
- それらをSpark executerに伝達

## Spark Session

Sparkのエントリーポイント

```
//ライブラリの読み込み
import org.apache.spark.sql.SparkSession

//SparkSessionの構築
val spark = SparkSession
    .builder
    .appName("appName")
    .config("spark.sql.shuffle.partition", 6)
    .getOrCreate()

//Jsonの読み込み
val people = spark.read.json("fileName")
```

## cluster Manager

役割

- Sparkのアプリケーションの実行のリソースの管理や割り当ての役割

以下でのクラスターを管理できる

- Apache Hadoop YARN
- Apache Mesos
- Kubernetes

## Spark executor

Spark executorは、プログラムのドライバーに情報の伝達をし、
executorのタスクにおいて大事な役割を果たしています


## Deployment modes

Sparkには様々なデプロイモデルがある。
cluster ManagerはSpark's exeuter,リソースの要求を満たす限り、環境に依存はせず、
Apache Hadoop YARNやKubernetesなどでデプロイすることが出来る


## データとパーティション
データは、様々な場所に祖損されているが、
Saprkでは、論理的にパーティションやデータを扱うことが出来る

ただし、それらはネットワークが閉じ、パーティションが読み込まれたタスクのみ可能である
XcodeにJAVA_HOMEを認識させる

# 問題

Xcodeのbuild scriptをみんな知っていると思う。

![Screenshot 2023-10-23 at 0.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/582b089a-a950-15e6-4bf6-b7c5a8cda8a9.png)

そう、このやろうだよ。便利だよね？ このスクリプトに環境変数を渡したいんだ

プロジェクトチームで共通な環境変数であば User Definedの配下の変数として入れればいい。ここに入れるとXcodeもgitも管理することになる。Run Script実行の直前にXcodeが管理している環境変数全て渡すので　プロジェクト共通・チーム共通の変数であればこれ対応完了！

![Screenshot 2023-10-24 at 9.15.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/ced99192-fb62-1ea7-b1bf-bc19bffa2af6.png)


しかし、Xcodeが管理していない環境変数（開発者によって値が異なる変数）ならば　そんなこと通用しない。

JAVA_HOMEはその例の１つである。JDKは色々ある、ディレクトリーも人それぞれだ。（もう、今さら誰もJavaを使ってXcodeで何かやっている人がいないと思っているかもしれないが　Kotlin Multiplatform (KMP)というフレームワークがあり　Kotlinコードをコンパイルし.frameworkという形にすることでAndroidと共通でコードが書ける！　この仕組みはRun Scriptを利用していて、中でgradleが利用される。時々JDKのバージョンが合っていないとエラーになる。不一致エラーの場合は明示的にJAVA_HOMEをセットしてあげる必要がある。）

**大抵の人は JAVA_HOMEを設定する必要ないが、もし必要となったらこの方法が役に立つかもしれない...**

## 方法１: Xcode全体の設定を変更

Xcode > Settings > Locations > Custom Paths あたりで設定する。

![Screenshot 2023-10-24 at 22.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/824b1e69-7c70-5b07-298f-875dffb6f956.png)



上記のように自分だけの環境変数を定義する

| メリット | デメリット |
|---|---|
| シンプル、手軽 | `~/.zshenv` や `~/.zshrc`ファイルでJAVA_HOMEを既に管理している可能性がある、その場合は　２重管理になってしまうかもしれない。|

## 方法２: zshに切り替え

ステップ1: Run ScriptのShellの値を `/bin/sh` から `/bin/zsh` に変更。  

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/bbc01da6-18a0-6a8b-5f1f-c6b4f48c3f57.png" width="300">
    

ステップ2: 、`~/.zshenv`ファイルに 自分の環境変数を定義。（私はSDKMANユーザーだからこんな感じ）
      
```zsh:~/.zshenv
export JAVA_HOME="${HOME}/.sdkman/candidates/java/current"
```


| メリット | デメリット |
|---|---|
| `~/.zshenv` を利用しているので　２重管理にならない。*nix系のshellを理解している人にとっては　極自然でわかりやすい | メリットがデメリットにもなる。`~/.zshenv` の影響を受けて、`~/.zshenv`　色々と書けてしまうのでビルドにも影響するかもしれない |


:::note info
**Shellの値を`/bin/sh` から `/bin/zsh` に変えると どうしてzshenvが呼ばれるの?**

まずXcodeのRun scriptの実行のための前処理を理解しよう

Xcodeが
1. RunScriptのShell値を使って shebangにする。一時ファイル（例: `script.sh`)として保存
2. RunScriptの中身を一時ファイルにappendする
3. **Non interactive**(-cオプション)として実行する。（例: `/bin/sh -c script.sh`)

ということでscript.shの中にあるshebangで内部のシェルが決まり、Startup Fileの仕組みを活かせる！

shebangは **#!/bin/sh** だとbash利用される。bashのnon-interactiveシェルの場合は デフォルトではstartup fileとして何も呼ばれない。`~/.profile`, `~/.bash_profile`当然読み込まれないから 環境変数が読み込まれない。詳細: [Bash Startup File(Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)
> A non-interactive shell invoked with the name sh does not attempt to read any other startup files.


一方、shebangは **#!/bin/zsh** だとzshが利用される。zsh世界ではinteractiveだろうがnon-interactiveだろうが `~/.zshenv`が読まれる。ここ環境変数を置く場所だ！　詳細: [An introductionto the Z Shell - Startup Files](https://zsh.sourceforge.io/Intro/intro_3.html)

> `.zshenv' is sourced on all invocations of the shell, unless the -f option is set. It should contain commands to set the command search path, plus other important environment variables.

:::

以上！役に立ったのでしょうか？

See you later! 🐊
【Java Access Bridge】Access Bridge Explorerでエレメント情報を取得する

# 目標

Access　bridge ExplorerでJavaアプリの要素データを取得すること

# 背景

Javaアプリを自動化するため、Javaアプリのエレメント情報を取得したかった

# 環境

Windows 10

# 1. OpenJDKのダウンロード

[OpenJDK](https://jdk.java.net/21/)をダウンロード。
解凍し、任意のフォルダに移動。

# 2. システム環境変数の設定

jdk/binにパスを通す。
cmdで`java`が打てればOK

# 3. Java Access Bridgeの有効化

cmdで下記を実行。

```
$ jabswitch -enable
The Java Access Bridge has been enabled.
```

# 4. Access Bridge Explorerのダウンロード

[Access Bridge Explorer](https://github.com/google/access-bridge-explorer/releases/tag/v1.1.0)をダウンロード。
AccessBridgeExplorer.exeを実行。
Accessibility TreeにJavaアプリが表示されていればOK。

# 5. （オプション）Android Studioのインストール

Javaアプリが手元にない場合、[Android Studio](https://developer.android.com/studio)で検証してみる。
Android StudioはJavaアプリである。
起動後、Accessibility TreeにJavaアプリが表示されていればOK。

# 参考

https://github.com/google/access-bridge-explorer
pythonでのgoogle cloud storageへのアップロード時の注意点

gsutilでcpコマンドによるアップロードは下記の様に、
ローカルのファイルを指定して、格納するフォルダを指定できます。

```
gsutil cp ***.txt gs://XXX/YYY
```

しかしpythonコードで行う場合は、GCS側のファイルパスにファイル名を含む必要があるので注意。
```python
project_id  = "{ProjectName}"
bucket_name = "{BucketName}"
gcs_path    = "{GCSFilePath}"
local_path  = "{LocalFilePath}"

client = gcs.Client(project_id)
bucket = client.get_bucket(bucket_name)
# 格納するGCSのPathをファイル名込みで指定(/xxx/yyy.csv)
blob_gcs = bucket.blob(gcs_path)
# ローカルのファイルパスをファイル名こみで指定
blob_gcs.upload_from_filename(local_path)
```
要件定義に求められること

## 要件定義とは
「顧客に価値提供をしたい」と考えるビジネス側と「システムの効率性、保守性、移植性」を追い求めるエンジニアとの双方コミュニケーションにより、同じ課題・ゴールを見据えるために必要な工程。

### ビジネス側が欲しい要素
非機能要件が多め
1. 信用性
1. 機能性
1. 使用性

### エンジニア側が欲しい要素
1. 効率性
1. 保守性
1. 移植性

## 要件定義が失敗しやすい原因
ミスコミュニケーションによるところが大きい。
例えば、AIやRPAの技術を顧客に考えたいとビジネス側が思案する時、それが本当に「誰のために、なぜ必要なのか」を考えられていなければ手段が目的化しやすくなる。

## 成功させるには
### 2W1Hを意識すること
<table>
  <thead>
    <tr>
      <th>2W1H要素</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> Why </td> <td>何のために？</td>
  </tr>
  <tr>
    <td> What </td> <td>どう課題を解決するのか</td>
  </tr>
  <tr>
    <td> How </td> <td>どんなシステムを作るのか</td>
  </tr>
</table>
探索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/6dcac474-423f-1117-f666-f71babc8c1c7.png)
１：探索アルゴリズム
「探索アルゴリズム」
①線形探索（アルゴリズム）：手順の概要は１つずつ順番に、目的の値かどうかを比較していく。時間計算量：O(n)
②二分探索（アルゴリズム）：データが整列されている場合に利用できる方法である。データが昇順（小さい順）に整列されている場合は、データを前半と後半に分けて、「中央の値＞目的の値」であれば、前半を、「中央の値＜目的の値」であれば、後半を探す。時間計算量：O(logn)
③ハッシュ法（アルゴリズム）：ハッシュ関数を用いて、格納場所のアドレスを計算して、目的の異値を探す。データを事前にハッシュ表に登録しておく必要がある。時間計算量：O(１)

２：線形探索
　線形探索では、配列の先頭要素から順に探す値かどうかを調べます。

３：二分探索
　二分探索を行うためには、配列a中のデータを昇順に整列しておく必要があります。二分探索では、探索範囲の中央にあるデータとxを比較します。
AWS CLIを用いてS3データを同期する。

# はじめに
AWS S3にはクロスリージョンレプリケーション(以降はCRRと表記します。)という機能があります。
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/replication.html

CRRでは要件を満たせない場合のS3データ同期方法として、
AWS CLIを用いてS3データを同期する方法となります。


# 要件・環境イメージ
・S3バケットとS3バケットをCRRを用いずに同期したい。
・同期元のデータが削除されている場合は同期先のデータを消す。
・AWS CLIを使用できるEC2は存在する。(aws-cli/2.9.19)

![sync-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629107/5ac222e7-f515-97c1-32e4-9dc643277b44.png)


# 1. 同期コマンド
基本的な使い方としては以下のようになります。
```php
aws s3 sync <同期元S3バケット> <同期先S3バケット>
```
上記のコマンドを実行することによりS3間でデータが同期されます。
２回目を実行した場合は差分のみ同期されます。

しかしこのコマンドのままでは同期元で削除されたファイルがある場合は同期先で削除されず残ってしまいます。

同期先にはあるが、同期元にはないファイルを削除したい場合は以下の[--delete]オプションを加えたコマンドを実行します。
```php
aws s3 sync <同期元S3バケット> <同期先S3バケット> --delete
```
その他のオプションについては以下のURLを参考。
https://docs.aws.amazon.com/ja_jp/cli/latest/reference/s3/index.html
https://docs.aws.amazon.com/ja_jp/cli/latest/reference/s3/sync.html


# 2. S3データを同期するために必要な権限
S3を同期するのには以下の権限が必要となります。

```php:同期元S3バケット
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "s3://source-bucket"
        }
    ]
}
```


```php:同期先S3バケット
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": "s3://destination-bucket"
        }
    ]
}
```

# 3. 動作確認
```
$ aws s3 sync s3://source-bucket s3://destination-bucket --delete
copy: s3://source-bucket/cp/01.txt to s3://destination-bucket/test/01.txt
copy: s3://source-bucket/cp/02.txt to s3://destination-bucket/test/02.txt
copy: s3://source-bucket/cp/03.txt to s3://destination-bucket/test/03.txt
delete: s3://destination-bucket/delete/delete.txt
```

# 参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/replication.html

https://docs.aws.amazon.com/ja_jp/cli/latest/index.html

https://docs.aws.amazon.com/ja_jp/cli/latest/reference/s3/sync.html
ソースコードの保管場所はどこにするべき？(Mac版)



# はじめに
Windows歴10年以上で初めてMacBookを購入しました！
デスクトップやfinderがいまいち分からず、ソースコードをどこに保存すればよいかわからなかったので、調べた結果を書き記しておきます。

# 結論
どこでもオッケー。
(デスクトップ上でもfinderの中のアプリケーション内でも、書類内でも、ダウンロード内でもいけます！)

# 調べた結果
#### 　①Chat GPTに聞く
![IMG_7222.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823804/b789b349-f754-0e47-c05b-977bffa279c2.jpeg)

#### ②ググってみる
参考文献に載せましたが、ここに入れた方がよい場所というのは特に無く、どこに作成しても問題なさそうでした。
ただしデスクトップに配置すると、 Mac自体の動作が重くなる可能性があるそうです。


# 参考にしたサイト
https://zenn.dev/maztak/articles/03715960434485

https://qiita.com/yuktkhs/questions/880c158c873291460372

https://teratail.com/questions/10488
Webセキュリティ担当者のための脆弱性診断スタートガイド

https://www.amazon.co.jp/Web%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E6%8B%85%E5%BD%93%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E8%84%86%E5%BC%B1%E6%80%A7%E8%A8%BA%E6%96%AD%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-%E4%B8%8A%E9%87%8E%E5%AE%A3%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B%E6%96%B0%E3%81%97%E3%81%84%E6%83%85%E5%A0%B1%E6%BC%8F%E3%81%88%E3%81%84%E3%82%92%E9%98%B2%E3%81%90%E6%8A%80%E8%A1%93-%E4%B8%8A%E9%87%8E-%E5%AE%A3/dp/4798159166/ref=sr_1_1?adgrpid=51361540737&hvadid=667974777839&hvdev=c&hvlocphy=1009255&hvnetw=g&hvqmt=e&hvrand=10532770770137743428&hvtargid=kwd-333458695640&hydadcr=27265_14706050&jp-ad-ap=0&keywords=%E8%84%86%E5%BC%B1%E6%80%A7%E8%A8%BA%E6%96%AD%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%82%AC%E3%82%A4%E3%83%89&qid=1698148596&sr=8-1


本書を手に取った背景
CISSPを勉強するにあたって脆弱性診断も理解しておきたいと思ったため。
具体的にどんなことをやるのかわからなかったのでちょうどいいと思った。

本書のテーマ
webアプリの脆弱性診断を行うために必要な基礎知識、診断に必要なツール、脆弱性を効率的に見つけるための手法、報告書の書き方を学べる。

個人的なポイント
１，webアプリに関する重要な要素
URI：リソースを識別する識別子。フォーマットも決まってる

２，脆弱なアプリ
復元可能なパスワード：ソルトやストレッチングを利用しないといけない
HTTPSの不備：古いSSLのバージョン、アルゴリズムの鍵長が十分でない、信頼できないCAが発行した証明書を使ってる

３，診断ツール
OWASP　ZAP


４，いろんな脆弱性の診断リスト
診断を実施すべき箇所がまとまってる

５，google hacking database
検索エンジンを活用すると本来公開してはいけないファイルを発見できる。そのテクニックの一つがこれ。
脆弱なファイル、脆弱のあるサーバーなどいろいろわかる。
https://www.exploit-db.com/google-hacking-database

６，報告書の作成
流れ
材料を集める→報告書作成→内部レビュー→納品

７，CVSS
共通脆弱性評価システム。指標としてはすごく有名。

８，脆弱性に関するルールや法律
不正アクセス禁止法
威力業務妨害
個人情報保護など

今後やれること
・自分でサイト作って検証してみる
・今の従事しているSWGにはウェブの仕組みが関係しているので勉強をもっとする

まとめ
ウェブの仕組みがどのように悪用されているのかわかる本なので、攻撃だけ記載されている本よりもわかりやすかった。
脆弱性診断の０〜１０までわかるので、全体感を理解するにはちょうどいい。
【Swift】CIFilterで肌色を保ちながら画像の彩度を調整する

# はじめに
CIFilterに肌色を保ちながら彩度を調整できるといった便利なものがあったので使ってみました

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-10-24 at 20.48.47.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b6ba1545-6197-7de2-d7ab-5d5df56e22b5.gif)


# 実装
```swift
import SwiftUI

struct ContentView: View {
    private let image = UIImage(named: "sample1")!

    @State private var uiImage: UIImage?
    
    @State private var amount: CGFloat = 0

    var body: some View {
        ScrollView {
            VStack {
                if let uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                } else {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit()
                }

                HStack(spacing: 15) {
                    Button {
                        applyVibranceFilter()
                    } label: {
                        Text("適用")
                    }

                    Button {
                        uiImage = nil
                        amount = 0
                    } label: {
                        Text("リセット")
                    }
                }
                
                VStack {
                    Text("sharpness: \(amount)")
                    Slider(value: $amount, in: -1...1)
                }
            }
            .padding(.horizontal, 20)
        }
    }

    func applyVibranceFilter() {
        let context = CIContext()
        let inputImage = CIImage(image: image)!

        guard let filter = CIFilter(name: "CIVibrance", parameters: [
            kCIInputImageKey: inputImage,
            kCIInputAmountKey: amount
        ]) else { return }
        guard let outputImage = filter.outputImage else { return }
        guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return }
        self.uiImage = UIImage(cgImage: cgImage)
    }
}
```

# おわり
人を認識しているのか、それとも肌の色を認識してるのか気になりますね
複雑そうなフィルターなのにも関わらず実行は結構早いです
cognitoからユーザ情報の一覧を取得する

## はじめに
cognitoからユーザのメールアドレス一覧を取得しようとしたのですが、cognitoの管理画面からはエクスポートすることが出来ず、代わりにCLIから取得する方法があったのでその方法を書き記しておきます。

## AWS CLIの設定
既にAWS CLIをインストールしている人は読み飛ばしてください。

AWS CLIをインストール

```bash
$ pip install awscli
```

以下のコマンドでIAMユーザの情報を設定

```
$ aws configure
```

実行するといろいろ聞かれるのでそれぞれ情報を入力する

```bash
AWS Access Key ID [None]: <アクセスキーID>
AWS Secret Access Key [None]: <シークレットアクセスキー>
Default region name [None]: <リージョン名>
Default output format [None]: <フォーマット名>
```

`アクセスキーID`と`シークレットアクセスキー`は、コンソール画面右上のユーザメニュー > セキュリティ認証情報 > アクセスキー から発行できます。既に発行している場合はそちらを使用してください。

リージョン名は使用しているリージョン、フォーマットは`json`を指定します。
フォーマットは他にも`table`や`text`といった形式が選べます。

## ユーザ情報の取得方法

以下のコマンドで全ユーザの情報を取得できます。

```bash
$ aws cognito-idp list-users --user-pool-id <ユーザプールID> > output.json
```
ユーザプールIDはcognitoのユーザプールの管理画面から確認できます。
`ap-northeast-1_<識別子>`みたいなやつです。

`output.json`の中身↓

```bash
{
    "Users": [
        {
            "Username": "hoge",
            "Attributes": [
                {
                    "Name": "sub",
                    "Value": "xxx-xxx-xxx"
                },
                ...
            ],
            "UserCreateDate": 123456789.000,
            "UserLastModifiedDate": 123456789.000,
            ...
        },
        ...

```

これでデータを取得できたので、あとは任意のプログラムで`output.json`を読み込んで利用することが出来ます。[参考にしたサイト](https://zenn.dev/katoaki/articles/e683b951dd7d21)ではjqを使って特定の属性を抽出していました。
私はメールアドレスの一覧が欲しかったのでPythonで読み込んでメールアドレスを抽出しました。

## さいごに
ユーザ情報の取得自体はコマンドひとつで出来たので非常に簡単でしたが、私はその前の AWS CLI の設定で少し躓いたので同じ思いをする方が少しでも減れば幸いです。


## 参考サイト

https://zenn.dev/mo_ri_regen/articles/aws-cli-setting

https://zenn.dev/katoaki/articles/e683b951dd7d21
Proxmox個人的まとめ

ホスト機は以下を利用
* HP Z640 workstation
* CPU: Xeon E5-2650L v3 × 2（24コア48スレ）
* メモリ: DDR4 128GB （2400MHzがCPUで2133MHz駆動）
* ストレージ: M.2 NVMe 1TB （HP Z Turboドライブ経由）
* GPU: NVIDIA Quadro K620


https://qiita.com/bashaway/items/8fb7195bd3601dcf7162

https://qiita.com/bashaway/items/9a429ee9457f8634e4d5

https://qiita.com/bashaway/items/f79cb6dde2ec4fdf3ae7

https://qiita.com/bashaway/items/c389ff50d4c2f61e3865

https://qiita.com/bashaway/items/1c8b3b37a64f4c7bbac2

https://qiita.com/bashaway/items/56cd579a4e03fefb1977

https://qiita.com/bashaway/items/d0124733c469bba8dbed
MacでCSVを開くとき自動でBOM付きにしたい

## これはなにか
- [Excel-Bom-Opener.app](https://www.dropbox.com/scl/fi/v0srsyj7v6trnjtq4ajlm/Excel-Bom-Opener.app.zip?rlkey=02e9wgplpdearybbk2z7x7c2e&dl=0)

MacOS環境でCSVファイルをBOMつきUTF-8に変換してからExcelで開くappです。

CSVをドラッグアンドドロップするか、CSVに関連付けてダブルクリックで
文字コードをBOMつきUTF-8に変換してExcelで開きます。

### 背景と動機
AWSからCSVをダウンロードするとBOMなしのUTF-8です。
これをそのままExcelで開くと文字化けするんですよね。

テキストエディタで開いたり、nkfコマンドを使ったり、文字コードの変更は簡単ですが
ダブルクリックで自動的に変換したくてシンプルなappを作りました。

## 使い方

### 前準備
文字コードの変換に`nkf`コマンドを使います。
MacOSには標準で入ってないので下のコマンドでインストールしてください。

````
$ brew install nkf
````

### 関連付けをして使う
以下の手順でCSVファイルにappを関連付けして
ダブルクリックしたら自動でBOMつきに変換して開くようにします。

1. [zipファイル](https://www.dropbox.com/scl/fi/v0srsyj7v6trnjtq4ajlm/Excel-Bom-Opener.app.zip?rlkey=02e9wgplpdearybbk2z7x7c2e&dl=0)をダウンロード
2. 解凍して `Excel-Bom-Opener.app` をアプリケーションフォルダに移動
3. CSVファイルを右クリックして[情報を見る]を選択
3. [このアプリケーションで開く]で「Excel-Bom-Opener.app」を選択
3. [すべてを変更...]をクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191981/6464e820-d3e8-8f31-243e-ce5b862c88e7.png" width="300">

### ドラッグ&ドロップで使う

問答無用でBOMつきUTF-8に変換されるのは困る、という場合はこちら。

1. [zipファイル](https://www.dropbox.com/scl/fi/v0srsyj7v6trnjtq4ajlm/Excel-Bom-Opener.app.zip?rlkey=02e9wgplpdearybbk2z7x7c2e&dl=0)をダウンロード
2. 解凍した `Excel-Bom-Opener.app` にCSVファイルをドラッグ&ドロップ

## 付録

### appの作成方法

appにしているのはドラッグ&ドロップしたり関連付けたりするためですが
野良のappをダウンロードするなんて怖くてできないという場合は自分で作成しましょう。
（Automatorで開いて中身がシェルスクリプトだと確認するのもよいです）

1. Automator.app を起動
1. [アプリケーション]を選択して[選択]ボタン
1. 左上の検索バーに「スクリプト」と入力してエンターキー
1. 右側のテキストエディタに以下を入力し Ctrl+S で保存

````
for f in "$@"
do
  /usr/local/bin/nkf --overwrite --oc=UTF-8-BOM "$f"
  open -a "Microsoft Excel.app" "$f"
done
exit 0
````

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191981/03ab8f81-94da-2897-75e7-db9db42f18d2.png)

作り方さえ覚えれば、変換前に確認ダイアログを出すとか、Excel以外で開くとか
自分の好きに改造できるのもいいですね。
bundle install でpg-1.2.3のコンパイルエラーが出ます。

以下の環境で、bundle installを実行しようとしているのですが、
ruby3.2.2.1
PostgreSQL16.0

以下の様なコンパイルエラーがでて、先に進みません。
===================================================
pg_result.c:1590:65: error: 'rb_cData' undeclared (first use in this function)
1590 |         rb_cPGresult = rb_define_class_under( rb_mPG, "Result", rb_cData
);
      |                                                                 ^~~~~~~~
pg_result.c:1590:65: note: each undeclared identifier is reported only once for
each function it appears in
make: *** [Makefile:248: pg_result.o] エラー 1
=================================================

正しいソースコードを取得する方法はありませんでしょうか？
[Haskell] where 句は式でない

`where` 句は式でないため、`print (x where x = 23 :: Int)` のような書き方はできません (`parse error on input ‘where’` が発生します) 。

本記事では、`where` 句の書き方についてまとめます。

# 1. `where` 句を書ける場所

モジュール定義、クラス宣言およびインスタンス宣言を除くと、`where` 句を書ける場所は以下の 2 種類のみです:

- 関数定義を含む変数束縛
    - すなわち `where` の左側に `=` が必須
- `case` 式の選択肢
    - すなわち `where` の左側に `->` が必須

ちなみに無名関数では変数束縛しないため `(\x -> x * y where y = 23 :: Int)` のような書き方はできません。

参考「[4.4.3 Function and Pattern Bindings - 4 Declarations and Bindings](https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-830004.4.3)」
参考「[3.13 Case Expressions - 3 Expressions](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-460003.13)」
参考「[10 Syntax Reference](https://www.haskell.org/onlinereport/haskell2010/haskellch10.html)」

# 2. `where` 句の書き方

## 2.1. 基本

```haskell
f :: Int -> Int
f x = y
  where
    y = x * 42

main :: IO ()
main = do
    print $ f 23
```

```haskell
data T = Foo | Bar

main :: IO ()
main = do

    let x = Foo :: T

    print $ case x of
        Foo -> y where y = 23 :: Int
        Bar -> y where y = 42 :: Int
```

## 2.2. ガードを用いる場合

複数のガードを付けている場合でも、1 つの変数束縛および `case` 式の 1 つの選択肢に対して 1 つの `where` を使用することができます。

```haskell
f :: Int -> Int
f x
    | x >= 0    = y
    | otherwise = - y
  where
    y = x * 42

main :: IO ()
main = do
    print $ f 23
```

`case` 式の選択肢の場合でも変数束縛の場合と同様ですが、`case` 式内でガードを用いるとコードがややこしくなるため、そもそも関数を分ける等して `case` 式内でガードを用いない方が良いかもしれません。

```haskell
main :: IO ()
main = do

    let x = 23 :: Int

    print $ case x of
        y
            | y >= 0    -> z
            | otherwise -> - z
          where
            z = y * 42 :: Int
```

## 2.3. `do` 式内で `where` 句を書く場合

`do` 式に続けて `where` を書くと `do` 式内でなく `do` 式外に書くのと同じ意味になります。

```haskell
main :: IO ()
main = do
    print x
  where
    x = 23 :: Int
```

```haskell:意味
main :: IO ()
main = f
  where
    f = do
        print x
    x = 23 :: Int
```

`do` 式内の `let` による変数束縛で `where` 句を使用することで、`do` 式内で `where` 句を書くことができます。

```haskell
main :: IO ()
main = do
    let x = y * 42
          where
            y = 23 :: Int
    print x
```

## 2.4. どうしても式内で `where` 句を書きたい場合

`case () of _ ->` で始まる `case` 式を用いることで、式内で `where` 句を書くことができます。

```haskell
main :: IO ()
main = do

    print (case () of _ -> x where x = 23 :: Int)

    print
        $ (\x -> case () of _ -> x * y where y = 42 :: Int)
        (23 :: Int)
```
Flutterで画像やウィジェットを左右反転、上下反転する方法

画像(ImageWidget)を左右反転したかったのでググっていたのですがあまり日本語での情報がなかったので備忘録として書き遺しておきます


## ウィジェットを左右反転させる

`Transform.scale`を使います。
```dart
Column(
  children: [
    Image.network('https://picsum.photos/250?image=9'),
    SizedBox(height:15),
    Transform.scale(
      scaleX: -1,
      child: Image.network('https://picsum.photos/250?image=9'),
    ),
    Text("テスト----"),
    Transform.scale(
      scaleX: -1,
      child: Text("テスト----"),
    ),
  ],
),
```
![スクリーンショット 2023-10-24 19.42.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/1f610af8-5f56-e3d6-a1b5-9a474ba3fa0f.png)

また、

```dart
Transform.flip(
    flipX: true,
    child: Image.network('https://picsum.photos/250?image=9'),
),
```
のような書き方もできます。
動作は同じですがこっちのが直感的でいいですね...

## ウィジェットを上下反転させる

左右反転の時は`scaleX: -1,`を用いていましたが、`scaleY: -1,`に変更します。

```dart
Column(
  children: [
    Image.network('https://picsum.photos/250?image=9'),
    SizedBox(height:15),
    Transform.scale(
      scaleY: -1,
      child: Image.network('https://picsum.photos/250?image=9'),
    ),
    Text("テスト----"),
    Transform.scale(
      scaleY: -1,
      child: Text("テスト----"),
    ),
  ],
),
```
![スクリーンショット 2023-10-24 19.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/658fd08d-e853-fde4-66a6-dfabe2f09693.png)

お役に立てば幸いです。
[bigquery]カレンダーを実テーブルとして生成しておくためのクエリ 

bi系の業務でよく使う日次、週次、月次のレポートを作る際、
bigquery でカレンダーを実テーブルとして持っておくと何かと便利。

日本時間と対応するUTC、週/月の始まりをフィールドとして列挙する。

```sql
drop table if exists bi.calendar;
create table bi.calendar as 
SELECT
    cast(date as datetime) as start_jst,
    datetime_sub(datetime_add(cast(date as datetime), interval 1 day), interval 1 microsecond) as end_jst,
    
    timestamp_sub(cast(date as timestamp), interval  9 hour) as start_utc,
    timestamp_sub(timestamp_add(timestamp_sub(cast(date as timestamp), interval 9 hour),interval 1 day),interval 1 microsecond) as end_utc,
    cast(date as date) as daily,
    date_trunc(cast(date as date),week(monday)) as weekly,
    date_trunc(cast(date as date),month) as monthkly,
FROM
    UNNEST(
        GENERATE_DATE_ARRAY(
            '1900-01-01',
            '2100-12-31',
            INTERVAL 1 DAY)
    ) AS date
;
```

## 生成結果
| start_jst | end_jst | start_utc | end_utc | daily | weekly | monthkly |
| --- | --- | --- | --- | --- | --- | --- |
| 1900-01-01T00:00:00 | 1900-01-01T23:59:59.999999 | 1899-12-31 15:00:00 UTC | 1900-01-01 14:59:59.999999 UTC | 1900/1/1 | 1900/1/1 | 1900/1/1 |
| 1900-01-02T00:00:00 | 1900-01-02T23:59:59.999999 | 1900-01-01 15:00:00 UTC | 1900-01-02 14:59:59.999999 UTC | 1900/1/2 | 1900/1/1 | 1900/1/1 |
| 1900-01-03T00:00:00 | 1900-01-03T23:59:59.999999 | 1900-01-02 15:00:00 UTC | 1900-01-03 14:59:59.999999 UTC | 1900/1/3 | 1900/1/1 | 1900/1/1 |

...
| start_jst | end_jst | start_utc | end_utc | daily | weekly | monthkly |
| --- | --- | --- | --- | --- | --- | --- |
| 2023-10-23T00:00:00 | 2023-10-23T23:59:59.999999 | 2023-10-22 15:00:00 UTC | 2023-10-23 14:59:59.999999 UTC | 2023/10/23 | 2023/10/23 | 2023/10/1 |
| 2023-10-24T00:00:00 | 2023-10-24T23:59:59.999999 | 2023-10-23 15:00:00 UTC | 2023-10-24 14:59:59.999999 UTC | 2023/10/24 | 2023/10/23 | 2023/10/1 |
| 2023-10-25T00:00:00 | 2023-10-25T23:59:59.999999 | 2023-10-24 15:00:00 UTC | 2023-10-25 14:59:59.999999 UTC | 2023/10/25 | 2023/10/23 | 2023/10/1 |
| 2023-10-26T00:00:00 | 2023-10-26T23:59:59.999999 | 2023-10-25 15:00:00 UTC | 2023-10-26 14:59:59.999999 UTC | 2023/10/26 | 2023/10/23 | 2023/10/1 |
デカ文字)ESP32でカラー液晶、赤外線距離計を作って遊ぶ5(結合テスト)(完


カラー液晶表示部は、流用


https://qiita.com/caa45040/items/564e37edabf02358cc3f


テスト内容

3.3V 、GND、 TXを繋いでテストする


![o_cop693.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f6164567-23cc-957a-cd8a-e8f028fe21ff.jpeg)
AWS RDS（MySQL）に接続する際、SSL証明書を使っているかの確認方法

## 概要
この記事では、AWS RDS（MySQL）に接続する際、SSL証明書を使っているかどうか確認する方法を記載します。
SSL証明書の更新方法は紹介しません

## 背景
先日AWSから下記タイトルのメールが来ました。

**[アクションが必要] 2024 年 8 月 22 日までに Amazon RDS および Amazon Aurora SSL/TLS 証明書を更新してください | [Action required] Update Your Amazon RDS and Amazon Aurora SSL/TLS Certificates by August 22, 2024 [AWS Account: xxxxxxxxxx] [AP-NORTHEAST-1]**

どうやらRDSの接続にSSL証明書を使っている場合は更新を行う必要があるようです。

証明書の設定をした覚えが無いので、対応の必要はないだろうと考えていたのですが
「使っていない事の確認はどうやればよいのだろう？」
と分からなくなったので、確認に使った方法を記事にします。


## 確認方法
基本的には下記AWSドキュメントに方法が載っていので、それを参照する

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/ssl-certificate-rotation-mysql.html


mysql以外の確認方法は以下の「DB インスタンスの変更による CA 証明書の更新」の項を参照

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL-certificate-rotation.html


### 方法１　コマンドラインからDBにログインする
コマンドラインからDBへのログインを試してみる
もしログインに証明書が必須になっている場合、この時点で失敗する。

```
$ mysql -u my_user -p
```

### 方法２　　設定ファイルを確認する
接続に証明書を使っているならば、下記のような設定ファイルに証明書のPathが設定されているはずなので、それが無いか確認する
・``my.cnf``など、DBの設定ファイル
・DBに接続しているアプリの設定ファイル（WordPressのwp-config.phpとか）

### 方法３　ユーザのログイン方法一覧を表示する
DBによって確認方法は異なるが、MySQLにおいては下記コマンドでユーザ毎のログイン方法一覧を表示することができる

下記の例ではadminとwebapp1が接続にSSLを用いていることがわかる
```
mysql> SELECT id, user, host, connection_type 
       FROM performance_schema.threads pst 
       INNER JOIN information_schema.processlist isp 
       ON pst.processlist_id = isp.id; 


## 出力結果　 ##

+----+-----------------+------------------+-----------------+
| id | user            | host             | connection_type |
+----+-----------------+------------------+-----------------+
|  8 | admin           | 10.0.4.249:42590 | SSL/TLS         |
|  4 | event_scheduler | localhost        | NULL            |
| 10 | webapp1         | 159.28.1.1:42189 | SSL/TLS         |
+----+-----------------+------------------+-----------------+
3 rows in set (0.00 sec)            
        
```
LeagueCSV でsjisのCSVを読むときの地雷

# LeagueCSV でsjisのCSVを読むときの地雷
LeagueCSV は php でCSVを読み書きする時にとても便利である。
だが、内部エンコーディングと違うエンコーディングのものを読もうとする時に一つ地雷(バグ)が埋まっている。

```
$reader = Reader::createFromPath(ファイル名, 'r');
$reader->setHeaderOffset(0);
CharsetConverter::addTo($reader, 'SJIS-win', 'UTF-8');
```

一見、ちゃんと動く。ところが、時々変な箇所がピンポイントで文字化けしてしまう。
しばらく悩んだところで気づいた。__マルチバイトの文字を泣き別れにしてね？固定長バッファで読むだけ読んで、マルチバイト文字の境界にぶち当たってもしれっと変換して終わりにしてないか？__

試しに
```
$reader = Reader::createFromString(mb_convert_encoding(file_get_contents(ファイル名), 'UTF-8', 'SJIS-win'));
$reader->setHeaderOffset(0);
```

こうしてみた。__ものの見事に治った__

やれやれ。
Readerで使うのはダメだな。Writerでも、行単位でバッファフラッシュさせないと(スレッショルドを1にしないと)だめかもしれない。
C#でOpen APIのSwaggerにXMLコメントを反映したい

# 1. はじめに
* C#でOpenAPIのAPIドキュメントにコメントを追加したい
* コメントはソースコードのXMLコメントを使用したい

# 2. 開発環境
* C#
* .NET 6
* Visual Studio 2022
* Windows 11
* Swashbackle.AspNetCore (NuGet)
 
# 3. Swashbackle.AspNetCoreのインストール
* Nugetより```Swashbackle.AspNetCore```をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/2c4aabf9-46d9-cd12-53fb-34424a2dd5ff.png)
＊　適用ボタンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/641cb2e1-a322-8ec7-dc9c-6bd0a4b9f052.png)

# 4. プロジェクトのプロパティ変更
* プロジェクトを右クリックして、プロパティを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/595acad4-73b5-5c14-7812-028e9d7e61e4.png)

* 「ドキュメントファイル > APIドキュメントファイルを含むファイルを生成します。」にチェックをする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/68f98f03-fceb-b609-35d1-5196f2065e9b.png)

# 5. Program.csの修正
```Csharp:Program.cs
// builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerGen(options =>
{
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});
```

# 6. 動作確認
* Controllerに追加したXMLコメントが反映できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/828a3709-d7ce-624d-8b52-3bd8e3d68cb4.png)

## 7. 参考文献

https://tech.robotpayment.co.jp/entry/2022/10/06/080000
Pythonで「Pythonでの文の区切りと長い文を途中で改行して入力する方法」の動作を確認してみた

# 概要

Pythonで「Pythonでの文の区切りと長い文を途中で改行して入力する方法」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/ini/index3.html

# 実装

以下のファイルを作成しました。
```sample3-2.py
num = 10 + 20 + 30 + 40 + \
    50 + 60 + 70
print(num)
```

以下のコマンドを実行しました。
```
$ python3 sample3-2.py 
280
```
# まとめ
何かの役に立てばと。
「オブジェクト設計スタイルガイド」を読んで

[オブジェクト設計スタイルガイド](https://www.amazon.co.jp/dp/4814400330)を読んだので印象に残ったポイントと感想を書く。

# 感想

## privateスコープについて

恥ずかしながらprivateスコープのことを「同一インスタンスのみからアクセス可能」だと思っていたが、「同一クラスからもアクセス可能」らしい。
頻繁に使用することはないだろうが、イミュータブルオブジェクトのモディファイアメソッド内なんかでは役立ちそう。

```php
class Position
{
    /** (略)コンストラクタ **/

    /**
     * この書き方だと、コンストラクタ引数が増えた場合にこのメソッドも修正が必要だが
     */
    public function toTheLeft(int $steps): Position
    {
        return new Position(
            $this->x - $steps,
            $this->y,
        );
    }

    /**
     * この書き方ならその必要がない
     */
    public function toTheLeft(int $steps): Position
    {
        $copy = clone $this;
        $copy->x -= $steps;
        return $copy;
    }
}
```

## サービスの依存

- サービスが依存する他のサービスや設定はコンストラクタで渡す
- サービスのコンストラクタ引数は全て必須にする
- 注入はコンストラクタのみ、セッタによる注入はしない
- サービスが行うタスクに関連するデータはメソッド引数として渡す

あたりが印象に残った。

自動車か何かの組み立て工場で例えると
- ベルトコンベア、作業員、その他作業に必要な機械←コンストラクタで注入
- 組み立て対象の部品←メソッドの引数として渡す。

のような感じだろうか。依存の注入をセッタでしてしまうと、生産ラインを動かすタイミングで作業員がいない、みたいなことが起こりうるので良くない。

## オブジェクトのミュータブル、イミュータブルの話

- イミュータブルオブジェクトを優先する
    - PHP標準のDateTimeで意図しない挙動を踏んだことがあるのでよく分かる。
- モディファイアメソッド
    - ミュータブルオブジェクトではコマンドメソッド
    - イミュータブルオブジェクトでは変更されたコピーを返す

標準関数なんかも破壊的な変更をするようなものは使い方を誤るとバグの原因になるため、オブジェクト設計に限らずイミュータブルなものを優先するのは重要な考え方だと感じる。

## クエリメソッド、コマンドメソッド

- システムの境界を超える場合、クエリ・コマンドのいずれに対しても抽象を定義する。
- テスト時には、クエリはスタブ、コマンドはモックにする。
    - コマンドは副作用があるので呼び出し回数（と引数）の検証をすべき←特に印象深い

テストダブルに関しては、クエリメソッドに対しても呼び出し回数の検証を書いてしまい、本体コードの変更に伴ってテストがコケる、といったことを度々経験しているので、明確に意識するようになった。ホワイトボックステストにせざるを得ない場合でも多少はテストの壊れやすさを緩和できそう。

## リードモデル

あるユースケースでエンティティの属性の読み取りのみをしている場合、責務を分割し、そのユースケースに特化した読み取り専用のオブジェクトを新たに定義する＝リードモデル

以前とあるアプリケーションにて履歴画面を表示する機能を実装した際に、履歴に表示する内容をプロパティに持った読み取り専用の`History`オブジェクトを作ったことがある。これもある種のリードモデルだと言ってよさそう。

## その他

- 名前付きコンストラクタ
    - メソッド名にドメインの名前を使う
    - 通常のコンストラクタをprivateにして塞ぐ
        - 想定する使い方を第三者に強制する意味で重要
    - (感想)名前付きコンストラクタはクラス内の上の方、privateコンストラクタのすぐ下にまとめて定義しておきたい。下の方に散らばっていると埋もれて気づかれなくなりそう
- ドメインイベントやイベントリスナの概念、あまり馴染みがなかったので新鮮だった
- サービスの振る舞いの変更
    - 抽象に依存して実装を交換可能にする
    - 「振る舞いの変更」のために継承は使うな
        - こういった設計の本を読むと十中八九これを言っている気がする。みんな継承で痛い目見てきたんだなぁ
        - 使い所：型の厳密な階層の定義