OmniAICreator/Qiita-1.07M huggingface dataset:
SWA/Amplify、使ってみませんか？

## SWA/Amplifyってなんでしょう？
- どちらも、SPA形式のWebアプリをホスティングするためのサービス
- SWA：Azure
- Amplify：AWS

----
## 要は・・・
- 静的ファイルの配信
- APIバックエンド環境の提供

----
## 何が嬉しいのか
- SPA形式のWebアプリにて必要なのは・・・
　静的ファイルの配信 + API
- この２つの環境を統合した形で提供するのが、SWA/Amplify

----
## 利点
- 安い：サーバーレスアーキクチャにより動作した分のみ課金となる
  休眠期間があったり、スモールスタートしたい場合に最適
  ※ストレージはデータ量に応じた課金もあり
- 認証が組み込まれている：楽かつ堅牢に実装できる
- CI/CD（ビルドとデプロイ）が組み込まれていて公開が簡単
- GitHubなどのプルリクと連動して検証用サイトが自動で作成される
  etc...

----
## 使えるフロントエンドフレームワーク
- SWA：Angular/Blazor(WASM)/Next.js/Nuxt/**React**/Vue.js
- Amplify：Angular/Next.js/Nuxt/**React**/Vue.js/
- 理論上はnpmでビルド出来ればなんでもいける
  (蛇足)ElmはSWA/Amplifyのどちらも実績あり！

----
## 仕組み
- 複数のPaaSの組み合わせで実現されている
- 手動でも構築できるが、非常に手間がかかる


----
## APIについて
- SWA：Azure FunctionによるAPIで実装
- Amplify：GraphQLがデフォルト。ストレージはDynamoDB
- アクセス制御は慎重に設定する必要あり
  SWA/Amplify（というかサーバーレスアーキテクチャ）を扱う際の最大の鬼門

----
## 最後に
グローバルに稼働するWebアプリを数百円（どうかしたら数十円）で公開できるってすごいと思いませんか？
Gitと連携できるので、バックエンドなしで静的サイトとして使うのもアリだと思います。
ぜひ一度使ってみてください。
Dartの定数式で使える演算子一覧と、定数式について

## 定数式で使える演算子一覧
```dart:.dart
数値演算子://+は文字結合も含むが、その他の型は不可能;Listも不可能
    +,-, *,/,~/,%,-x
論理演算子:
    !,&&,||
比較演算子:
    <,<=,>,>=,==,!=
ビット演算子:
    |,^,&,~x,<<,>>,>>>
型://定数式(定数コンストラクタも)は、Type promotionを起こす
    as,is,is!
三項演算子://ここと、ここより上は定数コンストラクタでも使用可能;
    BooL?a:b
配列・マップアクセス://ここ以下は定数コンストラクタでは使用不可。恐らくコレクション系の操作だから。
    a[b]
コレクションif:
    const Map m={if (i is int) i: 'int'}// ;
スプレット演算子:
    ...,?...// ;
```
関数呼び出しや、ゲッター・セッターの呼び出しは定数式で行えない。
## 定数式について
定数式で使える演算子と定数だけを含む式を定数式と言い、定数式はコンパイル時に計算され、その式の位置に計算結果が置かれる。
なので、定数式の内容は実行時のパフォーマンスに影響しない。
私は、パターンが同じ定数式があるなら定数コンストラクタを利用する。
定数式を直接書き込むよりはほんの少し負担が上がるが、記述を関数呼び出しの様に短くでき、実行時に計算するどの方法よりも軽いからです。
それらの例はこちら>>
https://qiita.com/drafts/c4144b5d2f18898e6ac8/edit

## コンパイル時定数
コンパイル時に生成され、計算できる定数。
同じ値のコンパイル時定数は同じインスタンスになる。
##

何か補足したいことが出たら、適宜補足します。
初心者エンジニアが時間を無駄にしないために

# はじめに
今回は初心者エンジニアの人が陥りがちな時間の使い方と、それに対する効果的な対策について自分の体験談とともに述べたいと思います。

これは初心者のみならず、ある程度経験を積んでいるエンジニアにも有効な方法だと思いますので良ければ見てみてください。

# 半日悩んでいたことが1分で解決した話
私は今年、新卒でエンジニアとして配属され、研修の一環としてプログラミングをしていました。
実装をしていくうえで、思った通りにコードが動かないということは多々ありましたが、元々大学でプログラミングを習っていたこともあり、大抵は自分の力で解決できました。
しかしある時、どうしても原因のわからない問題が発生しました。
エラーが発生してしまうまでの処理を1つ1つ追っていき、処理の度にそれぞれの変数の値を確認し、エラーの発生する1つ前の処理までは正しく動いていることがわかっていましたが、なぜかその次の処理に移る段階でエラーとなってしまうのです。
結局半日かかってもエラーの原因がわからず途方に暮れてしまったため、同期に一から状況を説明し、原因を一緒に考えてもらうことにしました。
そして、自分の実装している機能を1から説明し、エラーが発生するまでの処理を1つずつ丁寧に説明していくうえで、あることに気が付きました。
**これ、変数名を間違えている以外に原因が考えられなくね？**
そして、変数名を確認してみると、見事に変数名を間違えていたことが判明し、結局相談してから1分も経たないうちに自力で解決してしまいました。

# 人に説明することの大切さ
今回、私が変数名のミスに気付くのまでに半日もかけてしまった理由として、**こんなところで間違えないだろうという先入観があったから**だと思います。
しかし、実際には**こういうところにこそミスが発生しやすい**と思います。
プログラミングを一人でしていると、何となくわかった気になってしまっていることや、無意識に確認を怠ってしまうことなどがよくあると思います。
しかし、人に状況を説明するためには、自分の中では当たり前の前提や、自分ではわざわざ詳しく確認していなかった部分についても丁寧に解説する必要があります。
こうしてもれなく丁寧に状況を説明していくことで思考が整理され、まだ確認していなかった部分に気づいたりするのです。

# 困ったら人に頼ろう！
個人的にエンジニアの人にありがちだなと思うのが、なるべく人に頼らず自力で何とかしようとすることです。
もちろんそれは素晴らしい姿勢だと思いますが、どうしても一人で実装をしていると視野が狭くなってしまいがちです。
今回のように、**半日もかけて原因究明していたことがただの変数名の間違いだったと気づいた時の喪失感は計り知れません。**
自分でいろいろ考えて解決しようとする姿勢は大事ですが、**困ったら人に頼る**というのもエンジニアに必要なスキルなのかなと思います。

# おわりに
今回は、私と同じ苦しみを味わうエンジニアが1人でも減ればいいなと思い、この記事を書きました。
みなさんはぜひ、**適度に**人に頼りつつ立派なエンジニアになってください。

最後までお読みいただきありがとうございました！
Float型とInt型でDate型の分を揃える

`Float`型を経由した変換結果を`Int`型と一致させた上で、再び`Float`型として取得します。

以下はその具体的なコード例です：

```kotlin
import java.util.Date
import java.util.Calendar

fun intToDate(unixTime: Int): Date {
    val millis = unixTime * 1000L
    return Date(millis)
}

fun floatToDate(unixTime: Int): Date {
    val floatTime = unixTime.toFloat()
    val millis = (floatTime * 1000).toLong()
    return Date(millis)
}

fun truncateToMinutes(date: Date): Date {
    val calendar = Calendar.getInstance()
    calendar.time = date
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)
    return calendar.time
}

fun alignFloatDateToInt(floatDate: Date, intDate: Date): Date {
    val calendar = Calendar.getInstance()
    calendar.time = floatDate

    val intCalendar = Calendar.getInstance()
    intCalendar.time = intDate

    // Align minutes and truncate seconds and milliseconds
    calendar.set(Calendar.MINUTE, intCalendar.get(Calendar.MINUTE))
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)

    return calendar.time
}

fun dateToFloat(date: Date): Float {
    return (date.time / 1000.0).toFloat()
}

fun main() {
    val unixTime: Int = 1625097600 // 2021-07-01 00:00:00 UTC

    val dateFromInt = intToDate(unixTime)
    val dateFromFloat = floatToDate(unixTime)

    // Align float date to int date in minutes
    val alignedDateFromFloat = alignFloatDateToInt(dateFromFloat, dateFromInt)

    println("Date from Int: $dateFromInt")
    println("Aligned Date from Float: $alignedDateFromFloat")

    // Convert aligned date to Float
    val floatFromAlignedDate = dateToFloat(alignedDateFromFloat)

    println("Float from aligned date: $floatFromAlignedDate")
}

main()
```

このコードでの手順は以下の通りです：

1. `intToDate`関数で`Int`型のUnix Timeを`Date`型に変換します。
2. `floatToDate`関数で`Float`型を経由して`Date`型に変換します。
3. `alignFloatDateToInt`関数で、`Float`型の変換結果の日付を`Int`型の変換結果の日付に合わせます。
4. `dateToFloat`関数で、調整後の`Date`型を`Float`型に変換します。

この方法により、`Float`型を経由した変換結果を`Int`型と一致させた上で、再び`Float`型として取得することができます。
WSL2内にNext.jsが動作するDocker環境を用意した

# これはなに？

以前に Node.jsが動作するDocker環境を作成しました

https://qiita.com/acronhub/items/4ce965e7684ef6aed0d4

そこから、Next.jsが動作する環境にしたいと思います

# 環境

- Windows11
    - WSL2
        - Ubuntu 20.04
    - Docker Desktop
- VS Code
    - Remote WSL

# 新規プロジェクト作成

以下のコマンドで、対話しながらプロジェクトを作成していきます

```console
$ docker compose run --rm app yarn create next-app my-app
```

# 余分なファイルを削除＆コピー

前回までので、nodeが動くことを確認するために作成したファイルを削除します

- .gitignore
- main.js
- package.json
- yarn.lock
- node_mobules

作成されたmy-appフォルダの中身をルートディレクトリにコピーします
my-appフォルダは必要なくなったので削除します

```console
$ docker compose run --rm app rm -rf my-app
```

以下のようなフォルダになります

![folder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/46f9ed0a-6206-0122-023e-bd6e26a36cc2.png)

# モジュールのインストール

```console
$ docker compose run --rm app yarn install
```

# Next.jsのビルド

```console
$ docker compose run --rm app yarn next build
```

# コンテナ起動

作成したイメージからコンテナを作成して起動します

```console
$ docker compose up
```

ブラウザで `http://localhost:3000`にアクセスすると以下のような画面が表示されます

![next_js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/401a0ffb-3009-bf2f-0c57-e2a1c3ca1de3.png)

# 最後に
誰かの参考になれば幸いです:relaxed:
Denoでのシグナルを使ったプロセス停止ハンドリング


## この記事の概要
この記事は、常時実行している処理のプロセスを修了した際に処理途中で停止を防ぐ方法を学びましたので記事として残します。
間違った情報を記載している可能性がありますので温かい目で読んでいただければと思います。

## 通常のプロセス停止
以下に擬似的に処理を100%で完了と表示されるサンプルコードをDeno（TypeScript）で記述しています。
```typescript
console.log("Start");

while(true) {

  for (let i = 1; i <= 10; i++) {
    console.log(`${i*10}%`);

    if( i === 10 ) {
      console.log("Complete!");
    }

    // 1秒まつ
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
  
}

console.log("Exit");

```
今回常時実行を無限ループで表現しており、実際にこのコードを実行するとこのようなlogが表示されます。
何かしらDB操作やユーザーへのレスポンス、batch処理などの１つが完了するまでを100%と想像してください。

![スクリーンショット 2024-07-12 23.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479561/6599bf6e-0595-789d-82ad-05e5578a1ecb.png)

次に実行途中で`Ctrl+C`を入力するともちろん実行プロセスは停止されるので画像のように中途半端な40%で処理が停止しています。
Macのlocalであれば`SIGINT`というシグナルが返ってきていることがわかります。


![スクリーンショット 2024-07-12 21.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479561/a648f959-2a2d-4615-bc03-c059dd069ed6.png)

これがもし、実際に動いているサービスのコードだとしたら何かしら（デプロイによるコンテナの切り替えなど）でランタイムが停止する時に実行中の処理が中途半端な状態で止まるかもしれません。
DB操作のようにトランザクション処理などがない機能であればユーザーへ影響が出るかもしれません。


## シグナルを使ったプロセス停止ハンドリング
私は今まであまり意識したことがなかったのですが（ダメですね）
Unix系の環境ではプロセス停止時にシグナルが送信されているということで、それを使ったハンドリングに挑戦してみました。

参考
[wiki「シグナル (Unix)」](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B0%E3%83%8A%E3%83%AB_(Unix))

[Denoのドキュメント](https://docs.deno.com/examples/os-signals/)に従って以下のようにコードを修正しました。

`SIGINT`を受信したらwhileを回すための変数をfalseに切り替えるという処理です。
```typescript
console.log("Start");

let executable = true;

function sigIntHandler() {
  console.log("SIGINT received");
  executable = false;
}

Deno.addSignalListener("SIGINT", sigIntHandler);

while(executable) {

  for (let i = 1; i <= 10; i++) {
    console.log(`${i*10}%`);

    if( i === 10 ) {
      console.log("Complete!");
    }

    // 1秒まつ
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
}

Deno.removeSignalListener("SIGINT", sigIntHandler);
console.log("Exit");

```

実際に実行して、途中のタイミングで同じように`Ctrl+C`を入力します。

![スクリーンショット 2024-07-12 21.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479561/008a3e67-a82a-d732-22f0-4a75077f55fa.png)

`SIGINT`を受信した後も処理は進み、100％とキリがいいところまで処理が完了した上で修了しました。
今回はlocalでの検証だったため`SIGINT`でハンドリングしましたが環境によってハンドリングに使うシグナルの種類は変更が必要です。
例えばAWS　ECSのコンテナシャットダウン時には`SIGTERM`が送信されます。
[ECS のアプリケーションを正常にシャットダウンする方法](https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs/)

## まとめ
- デプロイ時などアプリのプロセス停止時に実行中の処理が途中で終わっていいものかは意識したい
- シグナルを使った停止ハンドリングを使うことで実行途中の処理を完了させてからアプリを停止できる

今回上記のような学びを得ましたが、初めて触る概念であり今後も学習や実務の中で身につけていきたいと思います。
この記事をよんでくださった方、ありがとうございました。
type-challenges 中級編13: RequiredByKeys、Mutable、OmitByType

# type-challenges 中級編13: RequiredByKeys、Mutable、OmitByType

## はじめに

[GitHubのtype-challengesリポジトリ](https://github.com/type-challenges)は、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。

### 1. RequiredByKeys

この課題では、ジェネリック型 `T` と `K` を受け取り、`K` に指定されたプロパティのみを必須にする型を実装します。`K` が指定されていない場合は、全てのプロパティを必須にします。

#### 例

```typescript
interface User {
  name?: string
  age?: number
  address?: string
}

type UserRequiredName = RequiredByKeys<User, 'name'> // { name: string; age?: number; address?: string }
```

#### 私の回答

```typescript
type MergeObj<T> = {
  [k in keyof T]: T[k]
}

type RequiredByKeys<T, K = keyof T> = MergeObj<{
  [k in keyof T as k extends K ? never : k]: T[k]
} & {
  [k in Exclude<keyof T, Exclude<keyof T, K>>]: T[k] extends infer P | undefined ? P : never
}>
```

#### 解き方

- 前回解いた`PartialByKeys` と同様に、まず `K` に指定されたプロパティを除外したオブジェクト型を生成し、次に `K` に指定されたプロパティのみを必須にしたオブジェクト型を生成します。
- 最後にこれらのオブジェクト型をマージして、指定されたプロパティのみが必須になるようにします。
:::note warn
いやなんか無駄な記述多すぎる感、、
:::

他の人の回答も見てみるとこんな回答がありました。

```typescript
type RequiredByKeys<
  T, 
  K extends keyof T = keyof T,
  O = Omit<T, K> & { [P in K]-?: T[P] }
> = { [P in keyof O]: O[P] }
```
:::note info
Omitのことを忘れていました、、
 `{ [P in K]-?: T[P] }`
`-?` でオプショナル消せるのかよ、、、、
:::


### 2. Mutable

この課題では、オブジェクト型 `T` の全てのプロパティをミュータブル（非読み取り専用）にする型を実装します。

#### 例

```typescript
interface Todo {
  readonly title: string
  readonly description: string
  readonly completed: boolean
}

type MutableTodo = Mutable<Todo> // { title: string; description: string; completed: boolean; }
```

#### 私の回答

```typescript
type Mutable<T> = T extends Readonly<Array<unknown>> ?
  T extends Readonly<[...infer A]> ? A : never
: {
  [k in Exclude<keyof T, Exclude<T,''>>]: T[k]
}
```
:::note warn
これも無駄な記述多すぎる感がありますね、、
:::
他の人の回答

```typescript
type Mutable<T> = {
  -readonly [K in keyof T]: T[K]
}
```

#### 解き方

- `Mutable` は、プロパティを再定義して、`readonly` 修飾子を削除することで実装できます。
- 他の人の回答のように、`-readonly` 修飾子を使用すると、全てのプロパティをミュータブルにすることができます。
:::note info


いや`readonly`も`-readonly`で消せるんかい！！

:::
### 3. OmitByType

この課題では、ジェネリック型 `T` から、型 `U` に割り当て可能なプロパティを除外する型を実装します。

#### 例

```typescript
type OmitBoolean = OmitByType<{
  name: string
  count: number
  isReadonly: boolean
  isEnable: boolean
}, boolean> // { name: string; count: number }
```

#### 私の回答

```typescript
type OmitByType<T, U> = {
  [k in keyof T as T[k] extends U ? never : k ]: T[k]
}
```

#### 解き方

- `OmitByType` は、`PickByType` の逆の操作を行います。
- プロパティの型が `U` に割り当て可能かどうかをチェックし、割り当て可能なプロパティを除外します。
:::note info


これはいつもの`as`でどうにかなりますね。
:::
## まとめ

これらの課題を通じて、TypeScriptの型システムをより深く理解することができます。特にテンプレートリテラル型や再帰的な型の使用法について学ぶことで、より柔軟で強力な型を作成するスキルが身につきます。ぜひこれらの課題に挑戦して、型の理解を深めてください。

### 参考記事

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [type-challenges GitHubリポジトリ](https://github.com/type-challenges/type-challenges)
Unity6 で ビルド設定を複数作成できるようになった！

## 「Build Settings...」から「Build Profiles」に変更
Unity6 Preview版 を試しに触っていて実機ビルドしようとした時、
「**Build Settings...**」のメニュー項目が消えていて「**Build Profiles**」に変わっていた。
| 〜 Unity2022 | Unity6 |
|:-:|:-:|
| <img width="200px" alt="スクリーンショット 2024-07-16 13.42.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/2f209337-a392-96f8-909b-cc420cccf350.png"> |  <img width="200px" alt="スクリーンショット 2024-07-16 13.42.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/d74c062e-d5f6-7215-d979-d73bdfaad2cd.png"> |

``Build Profiles`` を軽く触った感じ、
同じプラットフォームでも複数のビルド設定ができるようになったみたいです。

例えば、
開発版のビルド時は "Development Build" 有効にして、"アプリ名"は "Dev" にして...
みたいな設定をしておいて、
`Build Profile` を切り替えるだけで、各環境ごとに設定した内容でアプリビルドができるので、開発現場の状況次第では便利になるかもです。

<img width="400px" alt="スクリーンショット 2024-07-16 11.46.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88968/61019941-6bfd-a940-b9ff-ba6d9472bd38.png">


||設定ファイルの保存パス|
|:-|:-|
|ProjectSettings（今まで）|**ProjectSettings/ProjectSettings.asset**|
|BuildProfile（Unity6以降）|**Assets/Settings/Build Profiles/[プロファイル名].assset**|


[追記 2024/7/18]
↓ JenkinsなどCIツールでアプリビルドする際に、batchmodeでBuildProfileを切り替えてビルドする方法はこちら。

https://qiita.com/OnederAppli/items/580559a5835a28b65a27
RAGとは？

## はじめに
生成AIの回答の精度を上げる手法として、RAG(Retrieval-Augmented Generation, 検索拡張生成)が注目されています。この記事では、RAGについて簡単にまとめてみました。

## RAGとは？
RAGとは、大規模言語モデルによるテキスト生成に、外部情報の検索を組み合わせることで、回答精度を向上させる技術のことです。

https://www.nri.com/jp/knowledge/glossary/lst/alphabet/rag


## ファインチューニングとの違い
生成AIの回答の精度を上げる手法で、RAGのほかにファインチューニングもあります。

ファインチューニングは、特定のデータセットに対して学習を行うことで、回答の精度を上げる手法です。ただし、ファインチューニングには以下ような問題点が挙げられます。

- 新しい情報に対して回答できるようにするため都度学習を行う必要がある
- 機密情報が学習に使われてしまう恐れがある

RAGでは、外部の情報を使って回答を生成するため、新しい情報に対して回答できるようにするために学習したり、学習に機密情報が使われる恐れはありません。

## RAGの応用例
RAGを使うことで、社内マニュアルなどの検索は簡略化できると思われます。社内マニュアルは機密情報を扱っている場合があり、その内容を学習に使うことは憚れます。RAGを使えば、その内容を学習せずに回答内容に利用することができます。

機密情報を扱っていなかった内容だとしても簡略化できることがあります。それは、サービスのマニュアルを調べることやカスタマーサポートです。普段はユーザーが提供されているマニュアルを調べたり、調べたりしてわからないことがあればカスタマーサポートにお問い合わせしていたことも、RAGを使えば簡略化できます。

## さいごに
今回は、RAG(Retrieval-Augmented Generation, 検索拡張生成)について簡単にまとめました。
痒いところに手が届くAWS便利ツールがAIで5分で作れた件

## 概要

毎回AWSの操作でちょっと不便だったものをAIを使ってシェルのアプリ化をしてみました。ほぼ一発で綺麗に動作してくれました。

書き出されたコードは以下に置いておきます。

https://github.com/michihitoTakami/benri_tools

以下こんなスクリプトを書きました、というのを置いておきます。

## AWS CLIを実行の為の2段階認証を対話形式で実行するプログラム

### 入力したプロンプト
```
以下のコマンドでAWSの2段階認証で返ってくるJSONの内容を出力する内容に変換して表示するスクリプトを書いてほしい。
[ ]の箇所はコマンドラインで対話形式で入力出来るようにしたい。
~/.aws/credentialsの内容を参照して、profile名の一覧を取得して選択出来る様にしてほしい。尚profile名は[]でくくられた文字列である。
~/.aws/mfaから各行のリストを取得して、mfa_arnを選択できるようにしてほしい。
かならずシェルスクリプト形式で書くこと。

# コマンド
aws sts get-session-token --serial-number [mfa_arn] --profile [aws_profile] --token-code [token_code]

# 返ってくるJSON例
export AWS_ACCESS_KEY_ID="AAAAAAAAAAAAAAAAAAAAAA"
export AWS_SECRET_ACCESS_KEY="BBBBBBBBBBBBBBBBBBBBBBB"
export AWS_SESSION_TOKEN="CCCCCCCCCCCCCCCCCCCCCCCCCCC"

# 出力してほしい内容
export AWS_ACCESS_KEY_ID="AAAAAAAAAAAAAAAAAAAAAA"
export AWS_SECRET_ACCESS_KEY="BBBBBBBBBBBBBBBBBBBBBBB"
export AWS_SESSION_TOKEN="CCCCCCCCCCCCCCCCCCCCCCCCCCC"

# ~/.aws/credentialsのサンプル
[credential_name1]
aws_access_key_id=AAAAAAAAAAAAAAA
aws_secret_access_key=BBBBBBBBBBBBB
[credential_name2]
aws_access_key_id=AAAAAAACCCCCC
aws_secret_access_key=BDDDDDDDDDDDD
```

## ECS EXECを自動化するプロンプト
### 入力したプロンプト

```
ECS EXECをクラスター→タスク→コンテナの順で選択して、ECS環境に入れるシェルスクリプトを書いてほしい。
クラスターは以下のコマンドで一覧を取得すること
aws ecs list-clusters
タスクは以下のコマンドで一覧を取得すること
aws ecs list-tasks --cluster [指定したクラスター]
コンテナは以下のコマンドで一覧を取得する
aws ecs describe-tasks --tasks [指定したタスク] --cluster [指定したクラスター]
```

コレは特に改造なしで使用可能です。もしサービスまで指定したい場合は

```
ECS EXECをクラスター→サービス→タスク→コンテナの順で選択して、ECS環境に入れるシェルスクリプトを書いてほしい。
クラスターは以下のコマンドで一覧を取得すること
aws ecs list-clusters
サービスは以下のコマンドで一覧を取得すること
aws ecs list-services --cluster [指定したクラスター]
タスクは以下のコマンドで一覧を取得すること
aws ecs list-tasks --cluster [指定したクラスター] --service-name [指定したサービス]
コンテナは以下のコマンドで一覧を取得する
aws ecs describe-tasks --tasks [指定したタスク] --cluster [指定したクラスター]
```
とかでも良い感じです。

## 他にあっても良さそうなもの
 - Credentialを切り替えるツール
 - AWSアクセスポータルにSSOでアクセスしたのち、紐づくAWSアカウントのクレデンシャルを自動で取ってくるアプリ(出来るの？)
 - その他何かあれば、コメントください
type-challenges 中級編12: StartsWith、EndsWith、PartialByKeys

# type-challenges 中級編12: StartsWith、EndsWith、PartialByKeys

## はじめに

[GitHubのtype-challengesリポジトリ](https://github.com/type-challenges)は、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。

### 1. StartsWith

この課題では、2つの文字列型 `T` と `U` を受け取り、`T` が `U` で始まるかどうかを判定する型を実装します。

#### 例

```typescript
type a = StartsWith<'abc', 'ac'> // expected to be false
type b = StartsWith<'abc', 'ab'> // expected to be true
type c = StartsWith<'abc', 'abcd'> // expected to be false
```

#### 私の回答

```typescript
type StartsWith<T extends string, U extends string> = 
  T extends `${U}${infer Rest}` ? true : false
```

#### 解き方

- テンプレートリテラル型を使用して、文字列 `T` が `U` で始まるかどうかを判定します。
- `T` が `${U}${infer Rest}` に一致する場合、`T` は `U` で始まることを意味し、`true` を返します。それ以外の場合は `false` を返します。

:::note info
文字列リテラルで型を推定してあげれば簡単ですね。
:::


### 2. EndsWith

この課題では、2つの文字列型 `T` と `U` を受け取り、`T` が `U` で終わるかどうかを判定する型を実装します。

#### 例

```typescript
type a = EndsWith<'abc', 'bc'> // expected to be true
type b = EndsWith<'abc', 'abc'> // expected to be true
type c = EndsWith<'abc', 'd'> // expected to be false
```

#### 私の回答

```typescript
type EndsWith<T extends string, U extends string>  = 
  T extends `${infer Rest}${U}` ? true : false
```

#### 解き方

- テンプレートリテラル型を使用して、文字列 `T` が `U` で終わるかどうかを判定します。
- `T` が `${infer Rest}${U}` に一致する場合、`T` は `U` で終わることを意味し、`true` を返します。それ以外の場合は `false` を返します。

:::note info
StartWithと一緒！
:::
### 3. PartialByKeys

この課題では、ジェネリック型 `T` と `K` を受け取り、`K` に指定されたプロパティのみをオプショナルにする型を実装します。`K` が指定されていない場合は、全てのプロパティをオプショナルにします。

#### 例

```typescript
interface User {
  name: string
  age: number
  address: string
}

type UserPartialName = PartialByKeys<User, 'name'> // { name?:string; age:number; address:string }
```

#### 私の回答

```typescript
type MergeObj<T> = {
  [k in keyof T]: T[k]
}

type PartialByKeys<T, K = keyof T> = MergeObj<{
  [k in keyof T as k extends K ? never : k]: T[k]
} & {
  [k in keyof T as k extends K ? k : never]?: T[k]
}>
```

#### 解き方

- `PartialByKeys` は、まず `K` に指定されたプロパティを除外したオブジェクト型を生成し、次に `K` に指定されたプロパティのみをオプショナルにしたオブジェクト型を生成します。
- 最後にこれらのオブジェクト型をマージして、指定されたプロパティのみがオプショナルになるようにします。



```ts
{
  [k in keyof T]: T[k]
}
```
パターンの応用でした。
```ts
type a = {
    xxx: aaa
}&
{
    yyy: bbb
}
```
は
```ts
type MergeObj<T> = {
  [k in keyof T]: T[k]
}
```
で
```ts
type a = {
    xxx: aaa
    yyy: bbb
}
```
にできることも覚えておきましょう
## まとめ

これらの課題を通じて、TypeScriptの型システムをより深く理解することができます。特にテンプレートリテラル型や再帰的な型の使用法について学ぶことで、より柔軟で強力な型を作成するスキルが身につきます。ぜひこれらの課題に挑戦して、型の理解を深めてください。

### 参考記事

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [type-challenges GitHubリポジトリ](https://github.com/type-challenges/type-challenges)
3つ以上のテーブルを日付で結合する(SPSS Modeler データ加工逆引き6-11)

# 3つ以上のテーブルを日付で結合する

![スクリーンショット 2024-07-16 13.47.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a2014aaa-e399-f350-114d-21a487e9f7a0.png)

## 1.想定される利用目的

・異なるN個のテーブルを適切に結合する

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/3tables.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-07-16 13.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/898654f0-9519-a9c8-a69a-bbd1ed943ea5.png)

a.入力するデータのひとつめは以下の通りです。実績情報をもつ15日間のデータです。
![スクリーンショット 2024-07-16 13.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f98c9514-3214-c75c-7b5c-56d132ff3d7b.png)

b.入力するデータふたつめは以下の通りです。特売実績のある3日間のデータです。
![スクリーンショット 2024-07-16 13.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fe6919fe-604a-594c-d0de-455af0420edc.png)

c.入力するデータみっつめは以下の通りです。気象情報をもつ15日間のデータです。
![スクリーンショット 2024-07-16 13.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1f07c4db-0962-4727-90d7-c5f56527b478.png)

d.[フィールド作成]ノードを編集します。ダミーフィールドを作成します。
![スクリーンショット 2024-07-16 13.52.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2c8a8558-cb6d-e853-2644-2b42adac49ae.png)

[プレビュー]します。
![スクリーンショット 2024-07-16 13.52.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a0c82c8f-22f4-7fae-4df8-1bc1d5526c84.png)

e.[レコード結合]ノードを編集します。[レコード結合方法]を[キー]にして[結合キー]に[日付]を選択します。
[部分外部結合]を選択した上で[データの選択]ボタンで[実績]にチェックを入れて主テーブルにします。
![スクリーンショット 2024-07-16 13.53.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5035bf03-a930-5589-7762-603b4a4e6045.png)


[プレビュー]します。特売のなかった日がNULLになっています。
![スクリーンショット 2024-07-16 13.53.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ebe5fa0d-d049-e723-29f0-2221f6b3ff76.png)

f.[置換]ノードを編集します。

![スクリーンショット 2024-07-16 15.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/29d8d2fb-8c6a-09bb-5ef5-69994b2fb983.png)

[テーブル]を実行します。
![スクリーンショット 2024-07-16 13.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a1cf3caa-d73d-6211-3ea6-94441eae96be.png)

#### 注意事項

dのダミー変数作成を行わないと特売情報の欠落したテーブルが作成されるので注意します。

## 4.参考情報

#### レコード結合を解説した記事

https://qiita.com/416nishimaki/items/be61a82c12cd83558def

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
【a = a + 1】改めて変数代入を「気持ち悪いもの」として見直して自らを戒める【a += 1】


なんてことはない備忘録なのですが、受講生（元・プログラミング未経験者）の方と真剣に議論したので置いておきます。

## 本稿の目的（プログラマー／エンジニアを目指す全ての方へ）
- to 学童: 学校の教育が全てではないよ
- to 学生: 本気でやりたいなら今すぐプログラミングを覚えるより、数学(アルゴリズム)と英語(公式ドキュメントを読む)と統計学(データ分析)をやろう。
  - 勉強が嫌いなら（だと思うので）、「アルテリオス計算式」を採用したRPGゲームを１本でいいからガッツリやりこんで欲しい
- to 社会人: プログラミング言語は人間がシステム開発をしやすいようにシステム側から人間に歩み寄っているものだが、人間側がシステムに歩み寄らなくてよいという事ではない（特にAIを使ってプロンプトエンジニアリングする時）

一人でも多くの人がプログラマーとしてご活躍できることをお祈りしています。
一緒にお仕事できることを楽しみにしています。

## 本題
### 問題のコード（コメントアウト記号は`#`だったり`//`しますが、ここではpythonを使用）
きっと、違和感を持たない人も多いであろうよくあるコードです。

``` python
a = 10
a = a + 1 # ←　なんで？
print(a)  # 11
```

IT講師は違和感を忘れないで欲しい（違和感を持つ必要はない）

### 何が言いたいか、結論
- 数学のイコールは比較。プログラミング世界のイコールは代入
- 数学のイコールに相当するものは、プログラミング世界では==という
- 実行順は=の右側の処理が最初に実施され、右側の処理の答えを=の左側で指定した変数などに代入する

配列編もあるんですが、これはいったん置いておきます。

### 将来の自分に跳ね返ってくる危険な魔法の言葉「数学のルールとプログラミングのルールは違う」
だいぶ端折るので本筋が分かりにくいかもですが、以下のようなやり取りがありました。

- 最初
  - 私「数学では、(=)イコールは同じものか比較しますが、プログラミングの世界では=(イコール)は右にあるものを左に写す事を意味します」
  - 私「たとえば、`a = a + 1`は、aの要素に1を追加して、aの値を更新すると読みます」
  - 私「直前でaの値を10に更新するという処理をやってます」
  - 受講生さん「はえー」
- 機械学習の単元にて
  - 私「これからは数学的な考え方（よくあるのが離散・線形）をやっていきます」
  - 受講生「先日教えていただいた(`a = a + 1`)はどうなりますか？」
  - 私「そこはプログラミングの考え方で良いですよ」
  - 受講生「それだと、数学の考え方とは何を指しますか」
  - 私「コード上はプログラミングの世界です。これから機械学習用を学ぶにあたって、どのようなアルゴリズムがあって処理されるか、という事で〜（これが専門用語の羅列っぽく聞こえた可能性あり）」

〜

受講生「プログラミングに数学は必要ですね！」

（この後も色々ありましたが、最終的には納得と理解をされています。本題ではないので割愛）

〜

※注
よく気付ける方なので将来にとても期待しています。
が、当時の私の説明の仕方がよくなく、行き着くとプログラミングの世界でも数学の考え方（ただし、数学的な概念ではない）は必要だよ、という話をしていなかったなと思いました。

---

### どうすれば良かったか？
コードの書き方やコードの組み立て方はプログラミング思考アルゴリズムが必要で、機械学習のライブラリを学習するときは数学的思考アルゴリズムが必要
まとめて「アルゴリズム」という表現をしてしまったので、これがややこしいのだろうと考えます。

### プログラミング的、数学的思考アリゴリズムとは
おそらく色々なところで議題に上がっている事だとは思いますが、私のイメージレベルの意訳です。

- 数学的: 問題を分析し、仮説を立てる
  - エラーメッセージなどを読み、問題点を探す。解決方法を模索する
- プログラミング的: 目的を達成する手段を考える
  - 仮説に基づき実装する

と、あえて分類します。
プログラミングに注力するだけでも数学的アルゴリズムの考え方は必要だし、機械学習などで言えば理論や仮説を立てた後にプログラミング的アルゴリズムによる実装方法への変換が求められる、という図です。
なかなか説明が難しいのですが、ここでいうアルゴリズムとは、「その場その場で解決アプローチを考え、道筋を立てる事」という目標を立てて、そのために必要な考え方の種類が色々あるよ、という事でまずは定義を置きます。

※学者・専門家ではないので表現が正しくない可能性が高いです
※想定するペルソナは数学者でもプログラマーでもない方です。60代文系の方にプログラミングを教えるというのが目的です

## コラム： 高齢者がプログラミングを始めるのは遅いのか？
そんなことはない。
たまたま私が担当した受講生の方だけにとどまらないです。

たとえば、若宮正子さんの例や、私の身近でもすごい例で鈴木 富司氏（トミ爺さん）の例もあります。
なんなら、もう20年も昔の話ですが、私の祖父も現役引退後に学生であった私といっしょにWebサイト作成を勉強して一緒に作ったぐらいでした。
今は故人になってしまっていますが、生きていればChatGPTも使っていただろうな、と思ってます。

## 仮説「1 = 2の証明」のように見える？
```
a = 1
a = a(1) + 1

↑これが「1 = 2」
```

より `1 = 2` になってしまっているように見える事が混乱の一つで、数学世界の「=」をプログラミング世界では「==」と表記するというルールを一緒に説明しないと混乱の元になる可能性がありそうです。
同様に、if文の式の説明時にはTrue(言語に依存するが数値で0ではないもの。基本的に1)/False(0)で判断していることもポイントだと考えます。
今回の例で言うと`if(a)`と`if(a==1)`の違いとも言えます。あわせて`if(a=1)`についても解説しておくと良さそうです。
shell scriptで言えば`a=1`の結果`$?`が正常終了になります。

こういった言語依存の挙動についても理解が必要になってくるため、数学的にプログラミング世界を見つめようとすると色々と齟齬が発生してしまう事を認識してもらう必要があります。

## 「プログラミングの世界では数学の考え方は適用されない」と「プログラミング（アルゴリズム）には数学的知識や応用が必要」は別である
「全員にこの方針をもって指導すべきである」という話ではなく、数学に強い人にとってプログラミングの世界と数学の世界の違いを分かりやすく説明する必要がある場合に、どのように指導方針を立てるのか一つの参考にすると良いかもしれない方法として意識してもらうのが良いです。
前者については分かりやすいですが、後者を教えるのが難しくなってくる事が多いと思われますので、大枠の方針として採用して個別具体の対応を検討していく必要はありそうです。
仮想デバイスでGoogleアカウント認証をした時に気を付けること


:::note warn
厳密にはやらかしではないが、当時は相当やらかしたと思ったのでやらかしカテゴリにする
:::

見知らぬ端末情報が追加された事にアカウントジャックされたか？と本気で錯覚した時の話である。

## 結論：開発用アカウントと個人利用のアカウントは分けよう
仮想環境上に構築した仮想デバイスでGoogle認証を行うと、仮想デバイスが登録される。

何を当たり前の話をしているのか、と思うかもしれないが、モバイルアプリにGoogleサービスを使う場合はあるあるではないだろうか？
特に当時は開発用のアカウントと通常利用のアカウントを分けなかったので、心当たりのないデバイスが登録された事に余計に大騒ぎになってしまったということもあり、落ち着いて考えれば「そりゃそうでしょ」という話でしかないが備忘録として残す。

## 発端
まず、私は普段外出しないため、スマートデバイスを持ち歩くという事をしない
そして、いわゆるスマホゲーはやってない
さらに、電話が嫌いである

家族からは「スマホを持たせても連絡がつかない」とクレームが来るぐらいだったため、現在はPCでも使えるサービスを活用することで連絡手段を確立できている。具体的にはLINE、Slack、discordなどである。
特に業務でSlackしか使わないためメールも見ないので、必要なメール登録はSlackワークスペースのメールアドレスを活用しているという徹底ぶりである。

このような運用をしているため、外出するために必ずGoogle公式が提供している「スマートフォンを探す」が手放せない。

https://myaccount.google.com/find-your-phone

## 原因： 仮想デバイスに位置情報を付与している
当時、これに気付かなかった
設定次第で位置情報もいじれるので、たとえば位置情報に依存するアプリを作る場合には非常に便利、なのだが残念ながら当時は位置情報を使う想定をしていなかった。
国外ならどこかのサーバーを拠点にアクセスしているのだろう、という方向で考えることもできたので気にしなかったが、残念ながら生活圏内（多少足を伸ばせばいける程度）だったのが余計に混乱を生じる事になった。
そのため「このスマホは誰のだ？」と「心当たりのないスマホから認証されてる」という事が余計に混乱を生じる事になる。

## 言いたい事
これからスマホアプリ開発をする際に仮想デバイスを使う場合は本稿に留意しておきたい。
特にスマホを普段使いしている場合は、開発終了後に自分のアカウントに仮想デバイスを追加している事に気付きにくい可能性が高い。
Linux(UNIX)にLogin

# GUIでLinux(UNIX)にログインすると・・・
GUIにログインするときは、gnomeデスクトップの場合はgdmというプログラムからユーザー名とパスワードを入力してログインします。

この場合、gdmによってgnomeセッションマネージャが起動される。
これでウインドウシステムが使えるようになるのですが、gdmを使っているからと言って必ずgnomeを使わないといけない！
ということはないのでディストリビューションで使用できるデスクトップ環境を複数インストールすれば違うデスクトップ環境を使うことができる。

　　　[いろんなデスクトップ環境の動画](https://youtu.be/TOsjb43QCrI)

# CUIでログインすると
他のホストからSSHでログインする場合
ssh user@hostname
でログインすると/etc/passwdのユーザー名の最後に書かれているプログラムが起動される。
大抵の場合/bin/bashと書かれているのでbashが起動される。

# ならばこの部分をpythonに書き換えると
CUIで起動するとpythonが当然のごとく起動する。
で、GUIで起動すると・・・
セッションマネージャが起動するため選択したセッションが起動する。
ここでターミナルプログラムを起動すると python　が起動する！！
英語文書濾過

英語文書の地味な濾過装置を紹介します。固定辞書に登録された文字列を1文字に置換していき、縮んだ分は末尾に空白が埋め込んでいきます。結果として圧縮しやすい文字列が生成されるかもしれないという代物。
符号130～250は辞書番号に該当し、254はescape符号で辞書番号自体を符号化する為に用います。
```js
const wordList="0ac0ad0ai0al0am0an0ar0as0at0ea0ec0ed0ee0el0en0er0es0et0id0ie0ig0il0in0io0is0it0of0ol0on0oo0or0os0ou0ow0ul0un0ur0us0ba0be0ca0ce0co0ch0de0di0ge0gh0ha0he0hi0ho0ra0re0ri0ro0rs0la0le0li0lo0ld0ll0ly0se0si0so0sh0ss0st0ma0me0mi0ne0nc0nd0ng0nt0pa0pe0ta0te0ti0to0th0tr0wa0ve0all0and0but0dow0for0had0hav0her0him0his0man0mor0not0now0one0out0she0the0was0wer0whi0whe0wit0you0any0are0that0said0with0have0this0from0were0tion".split(0);

function MakeWordTree(W,e){
	for(var i=256,j,c,p,s=130,l=W.length,n=1,T=[],I=[];i;)T[--i]=[];
	for(;++i<l;I[T[p].s=s++]=i)
		for(j=p=0;c=W[i].charCodeAt(j++);)
			p=T[p][c-=97]?T[p][c]:T[p][c]=n++;
	I.cs=s;return e?T:I
}
/*
engCuting(A,B,size)
@A	:要素が0～255の数値配列
@B	:変換先配列. A==Bでも良いが,Aは上書きされる
@size	:Aの配列長. 省略するとA.lengthを採用
返値	:要素が0～255の数値配列

engCuted(A,size)
@A	:要素が0～255の数値配列
@size	:Aの配列長. 省略するとA.lengthを採用
返値	:要素が0～255の数値配列
*/
function engCuting(A,B,size){
	A[size-1]>-1||(size=A.length);
	if(size<8)return;
	var i=0,j,p=0,o=0,a,O=[],T=MakeWordTree(wordList,1);
	for(size-=5;i<size;){
		if(o>size-11)return;
		if(A[i]>96&&A[i]<123){
			for(var s=0,l=p=j=0;a=A[i+j++]-97>>>0,a<26&&T[p][a];)T[p=T[p][a]].s&&(s=T[p].s,l=j);
			if(s){O[o++]=s;i+=l;continue}
			O[o++]=A[i++];
		}else A[i]>129&&(O[o++]=254),O[o++]=A[i++],p=0
	}
	for(size+=5;i<size;O[o++]=A[i++])if(A[i]>129)O[o++]=254;
	if(o>size*0.9)return;
	for(i=o;i++<size;)O[o++]=32;
	B instanceof Array||(B=Array(size));
	for(;o;)B[--o]=O[o];
	return B
}

function engCuted(A,size){
	A[size-1]>-1||(size=A.length);
	for(var i=0,j,o=0,p,c,O=[],W=wordList,I=MakeWordTree(W),m=I.cs;o<size;)
		if((c=A[i++])>129&&c<m)
			for(p=I[c],j=0;(c=W[p].charCodeAt(j++))&&o<size;)O[o++]=c;
		else if(c===254&&i<size&&A[i]>129)O[o++]=A[i++];
		else O[o++]=c;
	return O
}
```
```js:使用例
let A=Array.from("That that is is that that is not is not is that it it is",a=>a.charCodeAt());
let e=engCuting(A,null), d=engCuted(e)
console.log(e,d)
```
## 参考文献
[csc_filters](https://github.com/fusiyuan2010/CSC/blob/master/src/libcsc/csc_filters.cpp)
フリーランスエンジニアになりたい人向け 補助金活用セミナー抜粋


:::note alert
- 本稿は昔に行った勉強会のお蔵出しネタのため、最新でない可能性がある
- 私の場合はうまくいかなかったが、活用している人もいるそうなので今回公開に踏み切った
:::

既に技術を持っている人も、そうでない人も活用できるという実績を私の受講生が活用している例とともに紹介する

## 補助金の種類
- 助成金（審査なし）
  - 特定就職困難者雇用開発助成金
- キャリアアップ助成金
  - 補助金（審査あり。加点式なのでどんどん出すべき）
- IT導入補助金
  - HP作りたい人（エンジニア以外？）
- 小規模事業者持続化補助金
  - 売上出したい人
- ものづくり補助金
- 事業再構築補助金

他にもあるが、使いやすいものを抜粋している

## これからエンジニアを目指す人はIT導入補助金とキャリアアップ補助金を目指そう
要はプログラミングスクールに通うための費用や教材費をこれらの補助金を活用する事で、実質割引率として半額以上も狙っていけるようだ。
ただし、利用には一定の要件があるようで、この要件に当てはまる場合が対象になるとのこと。

## 開業後は小規模事業者持続化補助金とものづくり補助金を目指す
オリジナルアプリを作成するための開発費、という名目で申請できそう

## とはいえ、ただ申請すればよいというわけでもないらしい？
ここからは受け売りのため信憑性は不明だが、自分で申請するのと認定機関を依頼・経由することで承認率が変わる？という話があった
具体的には、申請する際の勘所について知識がある場合とそうでない場合での書類通過率らしいが、就活における履歴書添削サービスに相当するものだろうか
個人で申請すると通らないが、有料の機関を通すと通過するというのが人材サービスのような疑問を感じなくもないが、何度も「過去に一度でも承認されていれば通りやすい」という事なので、役所的なアレなのだろう

つまり、一回審査を通すために認定機関を使って、以降は自力で申請できるということらしい。
システム的にどうなん？と思わないでもないが、逆にいうと満額費用を支払うよりは補助金を活用して安くできる方法がわかっているなら多少手間でも活用した方が良いだろう
一時期前の持続化給付金と同じものと考える事もできそうだ

### 注意：それでも私は失敗している
という事実があるので、万能ではない事は認識されたし。
こういった役所系システムにありがちな「落ちた理由」は残念ながら非開示のため分からない。
（申請する補助金の種類を間違えたか、個人で申請したため事業性が認められなかったか、色々考える事はあるが…）

## プログラマーを目指す時にプログラミングスクールを使うならぜひ活用したい
これからエンジニアを目指す人のためのリスキリングと想定すると、認定機関を使ってでも費用を抑えられる可能性があるなら活用した方がいい。
学生も含めてプログラミングスクールの入所・入会料も決して安くない金額なので、費用負担を抑えて学習機会を掴んでほしい。

:::note warn
普段、筆者は教える側の立場である事が多いのでスクール運営や入会・入所の手引きは専門外である。使える補助金などはスクール自体やカリキュラム自体が認可を得ているかも確認してほしい
:::
【JavaScript】View Transitions APIの使い方

## はじめに
現代のウェブ開発において、ユーザーエクスペリエンス（UX）は非常に重要な要素となっています。
その中でも、ページ遷移の際の滑らかなアニメーションはユーザーにとって直感的で心地よい体験を提供します。

この記事では、直感的で心地よい体験を提供するために、View Transitions APIを用いて、簡単かつ効果的にページ遷移アニメーションを実装する方法をご紹介しようと思います。


## View Transitions APIとは？
View Transitions APIは、ウェブページ間の遷移を滑らかにするための新しいAPIです。
このAPIを使用することで、異なる DOM でのアニメーションを実装することができます。

詳しくは、こちらをご覧ください！

https://developer.mozilla.org/ja/docs/Web/API/View_Transitions_API

https://ics.media/entry/230510/



## View Transitions API の使い方
### ① HTMLファイル準備する
まずは、HTMLファイルを準備します！
以下のようなDOMを用意しました。

```index.html
<!-- トランディション前のDOM -->
<div id="index">
  <h1>記事リスト</h1>
  <button className="listLink" id="open">
    【CSS・JavaScript】View Transitions APIの使い方
  </button>
</div>

<!-- トランディション後のDOM -->
<div id="show" hidden>
  <button id="close">戻る</button>
  <h1 className="listTitle">【CSS・JavaScript】View Transitions APIの使い方</h1>
</div>
```

HTMLファイルには、トランディション前と後のDOM両方を記述します。
そして、トランディション後のDOM には、`hidden` 属性を追加し、見えないようにします。

### ② CSSファイルを記載する
まずは、それぞれのスタイルシートに　`@view-transition` と `view-transition-name` を指定します。

```index.css
@view-transition {
  navigation: auto;
}

.listLink {
  view-transition-name: show-title;
}

.listTitle {
  view-transition-name: show-title;
}
```

### ③ JavaScriptファイルを記述する
そして、次にJavaScriptファイルを用意します。

```index.js
const button = document.getElementById("button");
const index = document.getElementById("index");
const show = document.getElementById("show");

button.addEventListener("click", () => {
  document.startViewTransition(() => {
    if (index && show) {
      index.hidden = true;
      show.hidden = false;
    }
  })
})
```

ボタンを押した時に、`startViewTransition()` を使い、`hidden` 属性を切り替え、ページ切り替え時のトランジションをします。


### 完成！！！
すると以下のGIF画像のようになります。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/795e6c06-0a4a-f16f-34cf-8be64d9046c3.gif)


## まとめ
この記事では、直感的で心地よい体験を提供するために、View Transitions APIを用いて、簡単かつ効果的にページ遷移アニメーションを実装する方法をご紹介しようと思います。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
RT1310のターゲット

armbm-mrubyのRT1310のターゲットはWZR2-G300NとMZK-W04Nの二種類です。

この二つは微妙に違っています。

メモリは16MでFlash 4M(CFI)は共通です。

I2C,SPIは両方とも使われていないようです。

シリアルは両方とも出てますが、WZR2はVCC,GND,TX,RXですがMZKはVCC,RX,GND,TXです。

Ethernet SwitchがWZR2はIP175CでMZKがRTL8305SCです。

WIFIチップはWZR2はオンボードですが、MZKはmini PCIカードです。

u-bootはWZR2は64KですがMZKは128Kです。

imageの圧縮のサポートも違うようです。

u-bootのtftpbootはWZR2はクライアントでMZKはサーバーです。

u-bootで使えるネットワークは両方ともLAN側です。

WZR2は普通のu-boot imageですが、MZKは先頭に20バイトのなんらかの情報が追加されてます。

u-bootの環境変数はWZRはu-bootの直後にありますが、MZKはFlashの最後にあります。

MAC0がWZR2はLAN側ですがMZKはWAN側です。

JTAGはWZR2は20pinのピンヘッダーがありますが、MZKはパッドだけです。

https://github.com/yamori813/armbm-mruby

WZR2はRT1310.mkでMZKはRT1310_MZK.mkにしました。

RT1310ではFreeBSDやNetBSDも動かしたのですが、メモリが少なかったり、USBが無かったりするので、mrubyで使うことにしました。

MZKは10年以上前に普通に使うためにヨドバシカメラで買ってきたもので、WZR2はハードオフで324円などで購入したものです。
Blender 4.2で星空を作ろう

Blender 4.2 LTSがリリースされました！

https://www.blender.org/

さっそく、次のような星空を作ってみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/af995d56-931d-f3eb-7dbf-02bb6e0f1d2d.png" width="480">

## まずは、アドオンをインストールしよう

次のリンク先からアドオンをダウンロードしてください。ダウンロードしたZIPファイルは**解凍せずに**使います。

https://github.com/SaitoTsutomu/StarrySky/archive/refs/heads/master.zip

次の手順でアドオンをインストールします。

* 編集メニューのプリファレンスを選ぶ
* 左のタブの中からアドオンを選ぶ
* 右上の `v` のボタンの「ディスクからインストール…」を選ぶ（下図）
* ダウンロードしたファイルを選択し、「ディスクからインストール」を押す

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/3b4de8d6-8f54-cb32-3be4-a2894b013fd1.png)

## 星空を作る

最初に、立方体があれば削除してください。
次に、オブジェクトメニュー（下図）の一番下にある「Starry Sky」を選んでください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/f55807e4-73d0-058d-2e1a-92cc7a090667.png)

:::note info
**ノート**
メニューが選びにくいときは、メニュー表示後に上矢印を押してEnterを押してください。
:::

星空が作成されました！

## 説明

しくみについては、次の記事を参照してください。

https://qiita.com/SaitoTsutomu/items/1161fce06ade74be4d5d

アドオンの詳細については、GitHubを参照してください。

https://github.com/SaitoTsutomu/StarrySky

データは、次のサイトからダウンロードして加工したものをアドオンに組み込んでいます。

http://astro.starfree.jp/commons/hip/

先程の記事との違いです。

* Blender 4.2で動くように修正した
* 簡単に、使えるようにアドオンにした
* データをアドオンに埋め込んだ
* コンポジターを作成しブルームを設定した
* pandasがなくても使えるようにした

BlenderのPythonで、pandasっぽいことをしてみたいときに、参考になるかもしれません。

## Blender 4.2対応の記事について

下記の記事は、Blender 4.2で動作確認しています。

https://qiita.com/SaitoTsutomu/items/19792b3a66a49ab33bbc

https://qiita.com/SaitoTsutomu/items/9c7aae103bf13d72dd5c

https://qiita.com/SaitoTsutomu/items/33b376c82a96434672d3

https://qiita.com/SaitoTsutomu/items/711989ba3e5ebcb78730

https://qiita.com/SaitoTsutomu/items/4ff1e6c1bb9a34a8128b

https://qiita.com/SaitoTsutomu/items/ea976764e13e408420e8

https://qiita.com/SaitoTsutomu/items/20ce443d0b0675716705

https://qiita.com/SaitoTsutomu/items/7c96f67cfb88cc39d9f3

https://qiita.com/SaitoTsutomu/items/72734602fcf3f993f8e3

https://qiita.com/SaitoTsutomu/items/b608c80d70a54718ec78

https://qiita.com/SaitoTsutomu/items/2425a51139b79c6d87fa

https://qiita.com/SaitoTsutomu/items/8c39e65fa2fc443d87b7

https://qiita.com/SaitoTsutomu/items/dda5b92ba636728bbb39

以上
WSL2内にNode.jsが動作するDocker環境を用意した(Docker Compose)

# これはなに？

前回の続きになります

https://qiita.com/acronhub/items/49523a7edf79f18ae11d

Docker Compose のボリュームマウントを利用して、コンテナ内のフォルダーの内容を変更できるようにします

- マウントしない場合は、イメージにフォルダーの内容を保存しているため、変更するにはイメージの再作成が必要になります
- docker コマンドを直接使う場合であっても、コマンドラインオプションを付けることでボリュームマウントすることもできます

# 環境

- Windows11
    - WSL2
        - Ubuntu 20.04
    - Docker Desktop
- VS Code
    - Remote WSL

# 準備

必要なファイルを作成します

## .dockerignore

ボリュームマウントするので不要になったファイル・フォルダを管理外として設定します

```.dockerignore
node_modules
```

## docker-compose.yml
以下に、部分ごとに説明します

```docker-compose.yml
services:
  app:
    build: .
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
      - app_node_modules:/app/node_modules

volumes:
  app_node_modules:
```

### 名前付きボリューム

```yaml
    volumes:
      - ./:/app
      - app_node_modules:/app/node_modules

volumes:
  app_node_modules:
```

`./`と書くことで、コンテナのフォルダ(`/app`) にホスト側のフォルダーをマウントしています
ローカルのnode_modulesフォルダに実行環境が左右されてしまいます

それを防ぐために、名前付きボリュームの`app_node_modules` で別に管理します


# yarn.lockを更新

`app_node_modules` を `/app/node_modules` にマウントした状態で`yarn install`をしてコンテナから参照できるフォルダーの内容を更新します

```console
$ docker compose run --rm app yarn install
```

# コンテナ起動

実行されて `Hello World!`が表示されました
```console
$ docker compose up 

[+] Running 1/0
 ✔ Container corp-test-app-1  Recreated
Attaching to app-1
app-1  | yarn run v1.22.22
app-1  | warning package.json: No license field
app-1  | $ node main.js
app-1  | Hello World!
app-1  | Done in 0.07s.
app-1 exited with code 0
```

# 最後に

誰かの参考になれば幸いです:relaxed:
Fiori Launchpad起動時に"Your connection is not private"の警告が出ないようにする（HTTPで接続）

## 問題
ABAP Cloud Developer Trial環境のFiori LaunchpadのURLにアクセスすると、"Your connection is not private"という警告が出ます。"Advanced"オプションから警告を無視して接続することは可能ですが、毎回この画面が出るのを何とかできないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ec6c491b-a4b1-5b5a-b16f-206a82ad3dba.png)

## 警告の理由
警告が出る理由は、ABAP環境が使っている証明書がブラウザが信頼する認証局によって署名されたものではないためです。
Not secure > Certificate is not validをクリックしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9c21a7c8-1cbd-e9d8-2609-1bcf4cf89ab2.png)
すると、"Issued To"と"Issued By"が同じになっていて、いわゆる「オレオレ証明書」が使われていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8d648cb2-b511-7c06-0e8d-7de4cf61ff68.png)

## 解決の方向性
解決の方向性には2つあります。

- HTTPS接続で、ブラウザが信頼する認証局によって証明された証明書を使う
- HTTPで接続する

一つ目の方向性では、(1)正規の認証局によって署名する (2)ローカルの認証局によって署名し、ローカルの認証局の証明書をブラウザに信頼させる、という2つの方法があります。業務で使う環境の場合は(1)が望ましいですが、トライアル環境であれば(2)でも十分です。(2)の手順については、以下のブログで詳しく説明されています。

https://community.sap.com/t5/technology-blogs-by-members/resolve-annoying-self-signed-ssl-certificate-issue-on-abap-1909-developer/ba-p/13519843

本記事では、もっとお手軽に「HTTPで接続する」方法によって回避してみます。

## HTTPで接続するには
ABAP Cloud Developer Trial環境のFiori LaunchpadのURLは以下のようになっています。
`https://vhcala4hci:50001/sap/bc/ui2/flp?sap-client=001&sap-language=EN#Shell-home`
これを、HTTPで接続するようにプロトコルとポートを変更して接続してみます。
`http://vhcala4hci:50000/sap/bc/ui2/flp?sap-client=001&sap-language=EN#Shell-home`
しかし、これでは自動的にHTTPSにリダイレクトされ、おなじみの警告が出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/cfc47b05-c3cf-26cb-aa9a-065958189cda.png)

実は、Fiori LaunchpadのログインページはデフォルトでHTTPSを使うように設定されており、HTTPで接続するためにはICFノードの設定が必要です。設定方法については以下のKBAに記載があります。

https://me.sap.com/notes/0001789344

この設定を行った後、HTTPのURLでアクセスすれば警告画面が出ずにログインページが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/1ac3f65d-666d-382e-7e15-ee4fc2fb6ebc.png)

## 参考
- https://me.sap.com/notes/0001789344
- https://community.sap.com/t5/technology-blogs-by-members/the-forbidden-error-when-opening-an-on-premise-fiori-application-on-sap-btp/ba-p/13759686
インストルメントを利用したPGO (Clang)

PGO(Profile-Guided Optimization)[^1]はコンパイラにおけるフィードバック最適化の一つです。コードの実行時プロファイルをコンパイラにフィードバックして、リコンパイルすることで、より効果的な最適化ができるというものになります。
LLVMでは手法の異なるPGOが複数あるようです。この記事では、インストルメントを利用したPGOについて、特性を簡単に纏めてみます。記載する情報の多くは"The many faces of LLVM PGO and FDO"[^2]を参考にしています。

### インストルメントを利用したPGOの手順

インストルメントはコンパイルにおいて、実行バイナリの各ブロックに計測モジュールを埋め込むことで、実行プロファイルを取得するものです。
PGOでは以下のステップで最適化を行います。

1. インストルメントオプションを付けてソースをコンパイル
2. コンパイルした実行バイナリを実行（プロファイルが生成）
3. コンパイラにプロファイルを読み込ませて再度ソースをコンパイル

ここで、1, 3で指定するオプションにより、インストルメントを埋め込むフェーズや、適用されるPGO最適化が異なります。

### Clang Front-end PGO
1のオプション: `-fprofile-instr-generate`
3のオプション: `-fprofile-instr-use`
Clangのフロントエンドで、ソースコードレベルでインストルメントが挿入されます。このインストルメントにより取得されたプロファイルは、デバック行情報を利用してコードへマッピングされることになります。このレベルでの情報（プロファイル）は、後続の最適化の影響（インライン化、アンロール、テール複製、CFGの簡略化など）を考慮できないため、プロファイルの精度損失が大きくなります。

### IR PGO
1のオプション: `-fprofile-generate`
3のオプション: `-fprofile-use`
LLVM IRレベルでインストルメントが挿入されます。コンパイルの後半で挿入されるため、プロファイルの精度は落ちにくいという特徴があります。具体的には初期のインライン化のあとに行われるようです[^3]。

### CSIR PGO
1のオプション: `-fcs-profile-generate`
3のオプション: `-fprofile-use`
CSIR PGOのインストルメント挿入はIR PGOよりもさらに後段で行われます。具体的にはインライン化のあとのようです。これにより、プロファイルが複製コードの情報を持つことができるようになり、精度が向上します。CSIR PGOはIR PGOと併用することができるようです。[^4]

[^1]: https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization
[^2]: https://aaupov.github.io/blog/2023/07/09/pgo
[^3]: https://lpc.events/event/7/contributions/798/attachments/661/1214/LTO_PGO_and_AutoFDO_-_Plumbers_2020_-_Tolvanen_Wendling_Desaulniers.pdf
[^4]: https://github.com/llvm/llvm-project/issues/56274#issuecomment-1406427363
気になっているUnityのアセット

個人的に気になっているアセットの備忘録です。

前記事で触れている趣味の「街づくり」関連で調べています。

https://qiita.com/joule/items/15ad6e5bf61b59aaac33

#### Forest Environment - Dynamic Nature

https://assetstore.unity.com/packages/3d/vegetation/forest-environment-dynamic-nature-150668

木や下層植物、岩など自然林を表現できるアセット。木の枝片やマッシュルームのオブジェクトまである。レビューを見ると低解像度でもよく見えるように最適化されているらしい。バージョンの更新頻度も高い。

<img width=800, alt=image1, src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490241/81b8eb76-8938-e62b-d603-977f0104ce9b.png>

#### Meadow Environment - Dynamic Nature

https://assetstore.unity.com/packages/3d/vegetation/meadow-environment-dynamic-nature-132195

Forest Environmentと同じNature Manufacture[^1]から出ている牧草地のアセット。
先ほどと同様にクオリティが高く、草花のほか、岩や薪などのオブジェクトもある。

<img width=800, alt=image2, src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490241/b0ab44d6-4353-f816-d9ca-553ecbeac243.png>

#### River Auto Material 3

https://assetstore.unity.com/packages/tools/terrain/r-a-m-3-river-auto-material-3-287456

Forest Environmentと同じNature Manufacture[^1]から出ている河川のアセット。
河川だけではなく、海や湖、滝なども表現できる。

<img width=800, alt=image3, src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490241/3f260d8c-6c60-8b55-de83-e615d53ad82e.png>


#### Fantastic City Generator

https://assetstore.unity.com/packages/3d/environments/urban/fantastic-city-generator-157625

都市部を作るためのアセット。値段は高めだが、街を作るのに十分な種類のオブジェクトが揃っている。

<img width=800, alt=image4, src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490241/3c56efda-eb2e-5dbd-7ac2-94c6a0cbee29.png>


[^1]:https://naturemanufacture.com
DeepL APIのチュートリアルをTypeScriptで実行

友人の@y-vectorfieldさんがDeepL API[^1]を紹介してくれたので、TypeScriptでやってみました。

https://qiita.com/y-vectorfield/items/c57ad904bb874797963a

はじめにプロジェクトのセットアップをしていきます。`npm`, `npx`を使ってプロジェクトを立ち上げます。

```console
$ mkdir <project> && cd <project>
$ npm init -y
$ npm install typescript --save-dev
$ npm install deepl-node --save-dev
$ npx tsc --init --rootDir src --outDir dist --esModuleInterop \
  --resolveJsonModule --lib es6,dom --module commonjs
```

package.jsonの`main`, `scripts`を修正します。

```json:package.json
  "main": "dist/deepl.js",
  "scripts": {
    "start": "npx tsc && node dist/deepl.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
```

`src/deepl.ts`を作成します。

```typescript: src/deepl.ts
import * as deepl from 'deepl-node';

const authKey = "f63c02c5-f056-..."; // Replace with your key
const translator = new deepl.Translator(authKey);

(async () => {
    const result = await translator.translateText('Hello, world!', null, 'ja');
    console.log(result.text);
})();
```

`npm start`でコンパイル・実行します。

```console
$ npm start
:
こんにちは、世界よ！
```

できました👏
いつも有益な情報をくれるy-vectorfieldさんには感謝しています。

npm: 10.2.4

[^1]: https://developers.deepl.com/docs/v/ja
Kokkosのチュートリアルをやってみた #2

Kokkos[^1]の勉強をしています。本記事は"The Kokkos Lectures - module 2"[^2]を参考にしています。
[前記事](https://qiita.com/joule/items/a2a556eef7495571d8ee)ではコードに触れていなかったので、見ていきたいと思います。

### Tutorial Exercise 01
Exercise 01[^3]では、Beginの通常コードをKokkosの対応コードに書き換えるという問題でした。

まず、Kokkosに対応するため、`Kokkos_Core.hpp`をインクルードし、Kokkosランタイムの`initialize()`と`finalize()`を挿入します。

```c++: Solutionのコード
#include <Kokkos_Core.hpp>
:
Kokkos::initialize( argc, argv );
{
:
}
Kokkos::finalize();
```

次にループの対応箇所を見ていきます。
配列x, yの初期化は1次元のループ、配列Aの初期化は2次元のループです。

```c++: Beginのコード
// Initialize y vector.
// EXERCISE: Convert outer loop to Kokkos::parallel_for.
for ( int i = 0; i < N; ++i ) {
  y[ i ] = 1;
}

// Initialize x vector.
// EXERCISE: Convert outer loop to Kokkos::parallel_for.
for ( int i = 0; i < M; ++i ) {
  x[ i ] = 1;
}

// Initialize A matrix, note 2D indexing computation.
// EXERCISE: Convert outer loop to Kokkos::parallel_for.
for ( int j = 0; j < N; ++j ) {
  for ( int i = 0; i < M; ++i ) {
    A[ j * M + i ] = 1;
  }
}
```

これをKokkosで書き換えたコードは以下です。

```c++: Solutionのコード
// Initialize y vector.
Kokkos::parallel_for( "y_init", N, KOKKOS_LAMBDA ( int i ) {
  y[ i ] = 1;
});

// Initialize x vector.
Kokkos::parallel_for( "x_init", M, KOKKOS_LAMBDA ( int i ) {
  x[ i ] = 1;
});

// Initialize A matrix, note 2D indexing computation.
Kokkos::parallel_for( "matrix_init", N, KOKKOS_LAMBDA ( int j ) {
  for ( int i = 0; i < M; ++i ) {
    A[ j * M + i ] = 1;
  }
});
```

`KOKKOS_LAMBDA`は`[=]`と書いても大丈夫です。
`KOKKOS_LAMBDA`の式はそれぞれの`i`または`j`についてfunctorに割り当てられ、演算されます。

参考）Kokkos::parallel_forの使い方[^4]

```c++: Usage
Kokkos::parallel_for(name, policy, functor);
```

Timerの計測している箇所を見ていきます。

```c++: Beginのコード
  // EXERCISE: Convert outer loop to Kokkos::parallel_reduce.
  for ( int j = 0; j < N; ++j ) {
    double temp2 = 0;

    for ( int i = 0; i < M; ++i ) {
      temp2 += A[ j * M + i ] * x[ i ];
    }

    result += y[ j ] * temp2;
  }
```

これをKokkosで書き換えたコードは以下です。

```c++:
  Kokkos::parallel_reduce( "yAx", N, KOKKOS_LAMBDA ( int j, double &update ) {
    double temp2 = 0;

    for ( int i = 0; i < M; ++i ) {
      temp2 += A[ j * M + i ] * x[ i ];
    }

    update += y[ j ] * temp2;
  }, result );
```

リダクション演算なので、`parallel_reduce`を使い、一時変数として`update`を用意します。
`KOKKOS_LAMBDA`の式はそれぞれの`j`についてfunctorに割り当てられ、演算されます。
最後に`result`へ値を格納します。
`KOKKOS_LAMBDA`は`[=]`と書いても大丈夫です。

参考）Kokkos::parallel_reduceの使い方[^5]

```c++:Usage
Kokkos::parallel_reduce(const std::string& name,
                        const ExecPolicy& policy,
                        const FunctorType& functor);
```

以上が、Tutorial Exercise 01のコード対応箇所でした。

[^1]: https://github.com/kokkos/kokkos
[^2]: https://www.youtube.com/watch?v=O-asHTtO7O4&t=134s
[^3]: https://github.com/kokkos/kokkos-tutorials/tree/main/Exercises/01
[^4]: https://kokkos.org/kokkos-core-wiki/API/core/parallel-dispatch/parallel_for.html
[^5]: https://kokkos.org/kokkos-core-wiki/API/core/parallel-dispatch/parallel_reduce.html
en_core_web_smが見つからない場合

## 問題
spacyを使ったpythonファイルをコマンドライン実行しようとしたところ、下記のエラーコードが発生した。
```python
OSError: [E050] Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.
```

## 解決
とりあえずエラーコードで調べたところ、下記コードを実行すればen_core_web_smがダウンロードされ、うまくいくらしい
```
python -m spacy download en_core_web_sm
```
(参考：https://github.com/explosion/spaCy/discussions/10895)

初心者ゆえにどのような原因で上記エラーが発生したかまで特定することは叶わなかったので、詳細の説明は有識者にゆだねたいと思う。