OmniAICreator/Qiita-1.07M huggingface dataset:
ゼロから始めるプログラム学習（C#）_006

##    はじめに

 プログラミング言語 __<font color="blue">　【C#『シーシャープ』】</font>__ を使用して
 プログラムを最初から学習するための記載。 


　　　前回：ゼロから始めるプログラム学習（C#）_005
　　　https://qiita.com/nekoozi/items/5c49ee31f6e999738634



## <font color="green">デリゲートとラムダ式</font>

### 1･･･ <font color="red">デリゲートを使わない場合</font>
>通常、関数（メソッド）は直接呼び出して使います。
### 通常のメソッド
```C#
public void Greet()
{
    Console.WriteLine("Hello!");
}

// 呼び出し
Greet(); // 出力: Hello!
````

### 2･･･ <font color="red">デリゲートを使う場合</font>
>デリゲートを使うと、「関数を代入できる変数」として扱うことができます。ここでは、アクセス範囲を限定するために 修飾子 private を使用します。

### デリゲートを使った例
```C#
// デリゲートの定義
private delegate void Printer(string s);

// メソッド
private void PrintMessage(string msg)
{
    Console.WriteLine(msg);
}

// デリゲートを使用
public void Execute()
{
    Printer printer = PrintMessage;
    printer("Hello!");
}
````

```C#
// 戻り値の型 デリゲート名(関数が引き受ける仮引数);
private delegate void Printer(string s);

/** このデリゲート　Printer　は、1つの文字列を受け取り、
    処理を行うが、結果として何も値を返さない関数

    void: デリゲートが参照するメソッドの戻り値の型
         （ここでは「何も値を返さない」）。

    delegate: デリゲートを宣言するためのキーワード。

    (string s): デリゲートが参照するメソッドが
     受け取る引数の型 と名前　s（任意で設定が必要、
     実際のメソッドでこの名前を使用する必要はありません）。
 **/



private void PrintMessage(string msg)
{
    Console.WriteLine(msg);
}

/** このメソッドは string msg という文字列を受け取り、
    その文字列をコンソールに出力します。
 **/



public void Execute()
{
    /** Printer型の変数printerを作成し、
        メソッドPrintMessageを登録します。
     **/

        Printer printer = PrintMessage;


    // デリゲートを使用してメソッドを呼び出します。
    printer("Hello!"); // 出力: Hello!
}

````
### 3･･･ <font color="red">匿名メソッドを使用する場合</font>
>匿名メソッドは、名前を持たないメソッドを定義し、デリゲート型の変数に直接処理ロジックを記述できる機能です。

### 匿名メソッド
 Printer printer = delegate (string msg)
左側がデリゲート型の変数 printer で
イコールを挟んだ右側が処理ロジックの記述

```C#

// デリゲートの定義
private delegate void Printer(string s);

// 匿名メソッドを使用
public void ExecuteWithAnonymousMethod()
{
    Printer printer = delegate (string msg)
    {
        Console.WriteLine(msg);
    };

    printer("Hello!"); // 出力: Hello!
}

````

### 4･･･ <font color="red">ラムダ式を使用する場合</font>
>匿名メソッドをさらに簡潔に記述する方法がラムダ式です。

### ラムダ式
 Printer printer = (msg) => Console.WriteLine(msg);
左側がデリゲート型の変数 printer で
右側の　(msg)　は　デリゲートが受け取る引数を指定します。
さらに　アロー演算子 (=>) の右側へ処理ロジックの記述

```C#
// デリゲートの定義
private delegate void Printer(string s);

// ラムダ式を使用
public void ExecuteWithLambda()
{

    // 引数が一つの場合は()を省略可能。
    Printer printer = msg => Console.WriteLine(msg);

    // デリゲートでメソッドを実行
    printer("Hello!"); // 出力: Hello!
}

````
--------------------------------------------------------------

　　　次回：ゼロから始めるプログラム学習（C#）_007
　　　https://qiita.com/nekoozi/items/c07643603fd0cc92ca53


## 参考文献

C#関連情報サイト様

https://qiita.com/toRisouP/items/98cc4966d392b7f21c30

https://csharp-learn.com/intro-to-lamda/
ViteのVanillaテンプレートでブログをはじめてみる

# はじめに

ViteのVanillaのTemplateを使い、

VanillaのHTML、Css、JavascriptでBlogを作りたくなったので作ってみる。

※正直なところ、無理にVite使わずに、、普通に静的ファイルを配置・公開するのが一番手っ取り早いのでご注意ください🥲

# 事前準備

・Node.jsインストール済

（パッケージマネージャはnpmを想定）

（Viteは現時点のv6.0.2を想定）

# プロジェクトの構成

下記コマンドでテンプレートを用いる。

VanillaのJavaScriptの場合

``` bash
npm create vite@latest myblog -- --template vanilla
```

VanillaのTypeScriptの場合

``` bash
npm create vite@latest myblog -- --template vanilla-ts
```

恐らく、下記のような構成でtemplateが出来上がる(node_modulesは省略)

```
│  .gitignore
│  index.html
│  package.json
│
├─public
│      略
│
└─src
        counter.js
        javascript.svg
        main.js
        style.css
```

これをはMenu(index.html)以外の投稿はすべて/posts/の配下に来るような下記の構成にする

```
│   .gitignore
│   index.html
│   main.css
│   main.js
│   vite.config.js
│
├─public
│      略
│
└───posts
        aboutme.html
        dummypost.html
        policy.html
```


# vite.config.js(vite.config.ts)の設定

vite.configをなにも設定しないと/posts/配下のhtmlはエントリポイントに含まれていない。

これを含まれるようにするため、

vite.configを下記のように

エントリーネームをファイル名が一致するような形式で設定する

```
import { defineConfig } from 'vite';
import { resolve, relative } from 'path';
import { globSync } from 'glob';

const posts = globSync('posts/*.html')
  .reduce((acc, curr) => {
    const key = relative('posts', curr).replace('.html', '')
    acc[key] = curr
    return acc
  }, {})
posts['main'] = resolve(__dirname, 'index.html');

export default defineConfig({
  build: {
    rollupOptions: {
      input: posts
    },
  },
});
```

参考

https://ja.vite.dev/config/build-options#build-rollupoptions

https://rollupjs.org/configuration-options/#input

※重要な箇所はこれで終わり！！


# 残りは自分の好きななようにカスタマイズ

私は、Menu画面を下記のような感じでレスポンシブ対応

Headerもそれっぽく作ってDarkModeに対応

Footerもそれっぽく作ってみる

![スクリーンショット ViteのVanillaテンプレートでブログをはじめてみよう_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/21c35906-5e60-065c-805d-bc4a00a3ae59.jpeg)

![スクリーンショット ViteのVanillaテンプレートでブログをはじめてみよう_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/65632895-09d6-14ef-5b4e-357eb18ec541.jpeg)

![スクリーンショット ViteのVanillaテンプレートでブログをはじめてみよう_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/33f4eee5-b839-bc5f-8577-be7f801357f9.jpeg)

![スクリーンショット ViteのVanillaテンプレートでブログをはじめてみよう_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/c1a5e098-af25-8a9f-cde9-7bf0768455a9.jpeg)

完成！

・GitHubPagesにデプロイする

(商用利用不可なので商用利用の場合は、ほかのサービスにデプロイしてください)

デモURL

https://shisojuice.github.io/vite_VanillaBlog/

Lighthouseのスコア

![ViteのVanillaテンプレートでブログをはじめてみよう_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/19493377-76a4-fdb6-b0a3-c049d453837b.jpeg)

# 今回の成果物

ソース

https://github.com/shisojuice/vite_VanillaBlog


# まとめ

マイブームで1周回ってVanillaのJavascriptやCss、HTMLが楽しいので記事にしました。

最近だと、マークダウンでBlogを作るならAstroもおすすめです。

今回は、なんとなくViteを使いたかったので記事にしましたが、

デプロイ時のMinifyやキャッシュ対策なども、

ほかのライブラリを使っても、できるのでViteにこだわる必要はありません🫡
雑に静的hostingするだけの express スニペット

`express.static()` で `./www` 配下をホスティングするだけのスニペットです。

```package.json
{
  "name": "static file hosting",
  "version": "0.1.0",
  "description": "static file hosting",
  "main": "app.mjs",
  "type":"module",
  "scripts": {
    "start": "node ./app.mjs"
  },
  "author": "your name",
  "license": "your license",
  "dependencies": {
    "express": "^4.21.1"
  }
}
```

```app.mjs .js
import http from 'http';
import express from 'express';

const LISTEN_IP = "127.0.0.1";
const LISTEN_PORT = 3000;

let webServer;
let app;

await runExpressApp();
await runWebServer();

async function runExpressApp() {
  app = express();
  app.use(express.urlencoded({ extended: true }));
  app.use(express.json({ extended: true }));
  app.use('/',express.static("./www"));
}

async function runWebServer() {
  webServer = http.createServer(app);
  webServer.on('error', (err) => {
    console.error('starting web server failed:', err.message);
  });

  await new Promise((resolve) => {
    webServer.listen(LISTEN_PORT, () => {
      console.log('server is running PORT:'+LISTEN_PORT);
      resolve();
    });
  });
}
```

## 利用方法

```
npm i
npm start
```

ファイルを `./www/index.html` とかに入れれば`http://localhost:3000` で表示されます。
ログイン機能実装後のテスト

# ログイン機能実装後のテストについて
ログイン機能実装後のテストで嵌ってしまったので、備忘録として残す。

## 嵌ったこと
SpringBootでWebアプリを作成した後、認証機能を追加しテストを行ったときに、getメソッドのテストでは認証認可のテストは成功しているのに、postメソッドのテストでは403が返ってきて、認可にエラーが発生してしまった。

## 試したこと
走らせたコードを抜粋して示す。
```java:テスト1
@Test
void test() throws Exception {    
    mockMvc.perform(get("/cart")
            .with(user(userDetails)))
        .andExpect(status().isOk())
}
```
ステータスコードは200を返し、テストは通過する。
認証認可も問題なし。

次は以下のテストを走らせた。
```java:テスト2
@Test
void test() throws Exception {
    mockMvc.perform(post("/cart/add")
            .param("productId", 1)
            .with(user(userDetails)))
        .andExpect(status().is3xxRedirection())
}
```
302のステータスコードが返ってくることを期待したが、403が返ってきた。
「テスト1」では認証認可は問題なしだったのになぜ？
SecurityConfigを確認しても権限の設定は間違ってはいない、、、


### 調べてみると 
Spring SecurityのCSRF機能を有効にしている場合は、POSTのHTTPメソッドを使用したリクエストに対して自動的にCSRFトークンチェックが行なわれる。そのため、HTTPメソッドを使用してリクエストを行なうには、有効なCSRFトークン値をリクエストパラメータまたはリクエストヘッダーに含める必要があるとのこと。

「テスト2」に有効なCSRFトークン値をリクエストパラメータに設定し、再度テストを走らせてみた。
```java:テスト3
@Test
void test() throws Exception {
    mockMvc.perform(post("/cart/add")
            .param("productId", 1)
            .with(csrf())  // csrfメソッドを追加
            .with(user(userDetails)))
        .andExpect(status().is3xxRedirection())
}
```
今度は302のステータスコードが返ってきて、無事テストが通過した。

## まとめ
postメソッドのテストを行う場合は、CSRFトークン値をリクエストパラメータに含める。

## 参考
https://spring.pleiades.io/spring-security/reference/servlet/test/mockmvc/csrf.html
git addさえするとデータは取り戻せる？？

# はじめに
Gitを使っていると、誤って削除したファイルやコミットを戻したいと思うことがありませんか？
`tab`を押してると、「`git reset --hard`してしまったぁ〜！！」なんてこともあるかもしれません（脳死ポチポチ絶対ダメ）

**実は、`git add`を一度でも行っていれば、データを復元できる可能性が高いのです。**

# Gitの神機能Blobオブジェクト
Gitの内部では、`git add`を実行すると、ファイルの内容は**Blobオブジェクト**として**Gitのオブジェクトデータベースに保存**されます。これは、ファイルが一度でも Git の追跡対象になると、その内容が完全に失われることはないことを意味します。

## Gitオブジェクトの仕組み
Gitには4つの主要なオブジェクトがあり、互いに密接に関連しています：

```mermaid
graph TD
    A[Commit Object] -->|contains reference to| B[Tree Object]
    B -->|contains references to| C[Blob Objects]
    B -->|contains references to| D[Tree Objects]
    E[Tag Object] -->|points to| A
    classDef gitObject fill:#f9f,stroke:#333,stroke-width:2px;
    class A,B,C,D,E gitObject;
```

- **Blob Object**: ファイルの実際の内容を保存
- **Tree Object**: ディレクトリ構造とファイル名を管理
- **Commit Object**: プロジェクトのスナップショットを記録
- **Tag Object**: 特定のコミットに名前を付ける

# 失われたデータを取り戻す：git fsck

### git fsck
`git fsck`は、どこからも参照されていないオブジェクト（ダングリングオブジェクト）を見つけ出す、いわば「データレスキュー隊長」のようなコマンドです。

```bash
git fsck --lost-found
Checking object directories: 100% (256/256), done.
dangling blob <blob_hash>
```



## 復元の実践ステップ

### 1. 対象のblobを特定
下記のコマンドで自身の復元したいコードを探します。
```bash
# ダングリングオブジェクトを探す
git fsck --lost-found
# 出力例
# Checking object directories: 100% (256/256), done.
# dangling blob <blob_hash>

# ダングリングオブジェクトの内容を確認
git cat-file -p <blob_hash>

```

### 2. ファイルとして復元
`1. `で復元したい内容を見つけたら、以下のコマンドを実行してみましょう。
たったこれだけ！
```bash
# ダングリングBlobをファイルに復元
git show <dangling-blob-hash> > recovered_file.txt
```


:::note warn
### 注意点
- この方法は、git addを少なくとも1回実行している場合にのみ有効です。
- 長期間経過すると、ガベージコレクションによってオブジェクトが削除される可能性があります。
- リモートリポジトリにプッシュしていない場合に最も効果的です。
:::


# 実際に復元できるか試してみよう
```bash
# ファイルを作成してgit addする
echo "test content" > testfile.txt
git add testfile.txt

# ファイルを削除
rm testfile.txt
```

```bash
# ダングリングオブジェクトを確認
git fsck

# オブジェクトを確認
git cat-file -p <dangling-blob-hash>

# オブジェクトをファイルとして復元
git show <dangling-blob-hash> > recovered_file.txt
```

# 終わりに
実は、**`git add`は単なるステージングコマンドではありません！**
それは、あなたの大切なコードを安全に保存するための**最初の一歩であり、最も信頼できる入り口**なのです。

**こまめな`commit`ができなくても、`git add`が あなたのコードを守るかもしれません！**
社会人3年目が転職活動で気づいたこと


# はじめに

某Sier勤務の私が社会人３年目の時に転職活動をしたので、その体験談をご紹介します。

# きっかけ

あるシステムの保守運用を３年ほどしていた私ですが、
学べることは学んでしまい仕事に余裕が生まれ暇を持て余していました。
次第に「このままでいいのか？」と不安と焦りが募り転職活動をすることにしました。

# まずはエージェントに登録

有名な転職エージェントに２つほど登録してみました
すると、バンバン募集が飛んでくるのですが
数が多すぎてみる気になれませんでした。

いいな。と思うものも沢山あるものの、
ありすぎて困る状態に陥りました

# エージェントさんに相談

ある日
「面談しませんか？」とメールがきました
これを逃すと、転職活動が進まないと思った私は面談してみることにしました。

希望や、まだ自分の中で決め切れていないことなどを相談
するとなんとなーく話が進み、履歴書出してみましょうという話に。
結局10個ほど出すことになりました。

１０件の内訳は以下です。
現在従事している仕事に近いものが4件
全く関係ない業種4件
現在従事している仕事と近いポジションだが、扱う技術が違うもの2件

# 選考

6件面接に進み、他は不合格でした（すべて全く関係ない業種）
この6件の面接を、日程調整してやっていくのですが
仕事と、家庭（育児）をしながらだったのでかなり時間の捻出には苦労しました。

その中で手ごたえのある面接は１件。３件不合格。
当時かなり無理をして転職活動の時間を捻出していたことと、
その企業さまの条件面から残りは辞退しました。

結局手ごたえのあった面接の１件も、
よく考えて辞退することになり私の転職活動は終わってしまいました。

# 気づき

何故うまくいかなかったのかと振り返ったのですが、
あとになって思った最大の気づきは
「したいことがない」ということです。

転職活動の動機は冒頭記載したとおり
「今のままではいけない」という焦りでした。

言い換えると、「今の状態から脱却したい」というだけで
転職する必要性が本当にあるかというのないわけです。
（部署異動を希望するなど選択肢は色々ある）

また、「したいこと」があれば今の職場でもチャレンジできるかもしれないわけです。

今を脱却したいというだけでは志望理由も薄くなります。
よく面接でも、「部署異動はしないの？」と言われていました。
それっぽい言葉を見繕って回答するものの、やはり面接官の方には見透かされていたのかもしれません。

# 最後に

私の結論は
「したいこと」を見つけてから異動、今の職場でしたいことができないか、転職するか最適だと思う行動を選ぶ。
これが最適だと思いました。

その後、Azureの道を進みたいと思うようになり、
上司と相談して今の職場でしたいことをさせてもらえることになりました。

一度道を決めるとAzureの時間を確保するために、自分のAzure以外の業務を任せられる人を作ったりと様々な工夫をしながら前に進めています。
Gitリポジトリのルートの絶対パス動的取得は git rev-parse --show-toplevel が便利

この記事は、なんか作ろうの会 Advent Calendar 2024　の3日目の記事として書かれました。

# 結論
Git管理しているリポジトリで、リポジトリのルートの絶対パスを環境に依らず取得するには、以下のコマンドが便利です。

```sh
git rev-parse --show-toplevel
```

# はじめに
Git管理しているリポジトリに何らかのスクリプトを配置したとき、リポジトリのルートの絶対パスが欲しくなることがよくありませんか？　私はよくあります。
たとえば、スクリプト内で別のディレクトリやファイルを処理するとき、リポジトリのルートの絶対パスがあればそこを起点にリポジトリ内のパスを容易に構築できて可読性もよいです。

- スクリプトを実行するディレクトリによらない
- スクリプトが存在するディレクトリによらない

このような条件を満たすパスの取得方法が望まれます。

# ケーススタディ
## 前提

以下のようなディレクトリ構造があります。
```
$ pwd
/tmp/20241203-advent

$ tree
.
├── deep
│   └── path
│       └── script.sh
├── input
│   └── sample.txt
└── output
    └── result.txt

5 directories, 3 files
```
このとき、`deep/path/script.sh` を使って `input/sample.txt` の内容を `output/result.txt` に追記することを考えます。

また、`script.sh` は後々べつのディレクトリに動かす可能性があります。

## 案1. 相対パスを使う

```deep/path/script.sh
#!/bin/bash
cat ../../input/sample.txt >> ../../output/result.txt
```

上記のコマンドは、`deep/path` にcdしていて、 `./script.sh` などと実行されることが前提です。
スクリプトの実行位置によってエラーになるので、あまり良い手とは言えないでしょう。

## 案2. `dirname` や `realpath` を使う

```deep/path/script.sh
#!/bin/bash
cat "$(dirname $(dirname $(dirname $0)))/input/sample.txt" >> "$(dirname $(dirname $(dirname $0)))/output/result.txt"
```

Gitリポジトリのルートまで `dirname` でさかのぼる案です。どのディレクトリにいる状態でスクリプトを実行するか、には結果が左右されなくなりましたが、今度はスクリプトが存在する位置によってエラーになる可能性が出てきてしまいます。
たとえば `deep/path/script.sh` を `deep/path/hoge/script.sh` に移動したら、このスクリプトは成立しなくなります。

## 案3. `git rev-parse --show-toplevel` を使う

```deep/path/script.sh
#!/bin/bash
cat "$(git rev-parse --show-toplevel)/input/sample.txt" >> "$(git rev-parse --show-toplevel)/output/result.txt"
```

満を持して、gitコマンドを使うパターンです。このパターンであれば、リポジトリのルートであればどこで実行しても結果が変わりません。`$(git rev-parse --show-toplevel)` がリポジトリのルートの絶対パスで展開されます。スクリプトをリポジトリ内の別のディレクトリに移動しても、返されるパスは変わらないので保守性が高いです。
また、gitのtoplevelを表示しようとしている、というのはコマンドについての知識が無くても何となく雰囲気から読み取ることができ、可読性も高いです。

制約として実行位置および実行されるスクリプトがともにリポジトリのルート以下の階層である、という前提は置かれます。しかし、むしろgitリポジトリ外で実行したりgitリポジトリ外のディレクトリにアクセスしたりする方が特殊かと思われますので、問題になることは少ないでしょう。

# おわりに
Gitリポジトリのルートの絶対パスは意外と欲しくなることが多いのではないかと個人的には思っています。少なくとも自分は表題のコマンドをそらんじられるようになるくらいには欲しいと思う機会がありました。

ちょっとしたテクニック的なことではありますが、どなたかのお役に立てばとても嬉しく思います。
C#でGoogleカレンダーを表示してみた

## 前提
これの記事が人生初記事になります。
見苦しいところばかりですが、それを承知の上で見てください。

### 自端末の環境
・Win11
・WPF4.8

#### コード
``` Calender.cs
// Googleカレンダーの埋め込みURL
private string calendarUrl = "";

private void Calendar_Load(object sender, EventArgs e) => LoadCalender();

/// <summary>
/// カレンダー画面を読み込む
/// </summary>
private async void LoadCalender()
{
    // WebView2の初期化
    await this.viewCalendar.EnsureCoreWebView2Async();
    // WebView2でURLを表示
    viewCalendar.CoreWebView2.Navigate(calendarUrl);
}
```

#### 実行結果
![スクリーンショット 2024-12-03 225814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3915167/05d8219b-a586-68ed-59fe-bea68e085809.png)


↑のような画面になります。
>自分のメールアドレスが映っていたので隠しました><

### GoogleカレンダーのURL取得方法
***
**Googleカレンダーを公開して埋め込みコードを取得します。**
**1.** Googleカレンダーにログインします。

**2.** カレンダーの共有設定を開く
・左側の「マイカレンダー」リストから対象のカレンダーにカーソルを合わせて、右の「︙（3点メニュー）」をクリック。
・「設定と共有」を選択。

**3.** カレンダーを公開
・「アクセス権限」のセクションに移動。
・「一般公開する」にチェックを入れます。
・「OK」をクリックして確認。

**4.** 埋め込みコードを取得
・設定ページの「統合」セクションに進む。
・「このカレンダーを埋め込む」という項目の下にあるURLをコピーします。

>自分のカレンダーを公開してるので自己責任でお願いします。
Win2D その5 画像読み込みとエフェクト

# エフェクト処理
Win2Dでは組み込みのエフェクトがあり、例えば、ぼかし、エッジ処理、エンボス加工などを簡単に行うためことができるようになってます。
今回はガウシアンブラーの組み込みエフェクトを使って選択した範囲にぼかしを加える処理を行っていきます。

# 準備
xamlに以下を追加します。
```diff_xml
<canvas:CanvasControl
    x:Name="canvas"
+   CreateResources="Canvas_CreateResources"
    Draw="Canvas_Draw"
    PointerMoved="Canvas_PointerMoved"
    PointerPressed="Canvas_PointerPressed"
    PointerReleased="Canvas_PointerReleased"
    />
```
画像を読み込む際`CreateResources`イベントから読み込むため追加します。

# 画像取り込み
ぼかすための元となる画像を取り込む処理です。
`MainWindow.xaml.cs`に記述していきます。
```csharp
 // 元となるBitMapのフィールド
 CanvasBitmap bitmap;
 
 // xamlで指定したイベントCreateResourcesから呼び出す
 private void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
 {
     // 非同期処理で下の処理を呼び出すようにラップしている
     args.TrackAsyncAction(CanvasCreateResourceAsync(sender).AsAsyncAction());
 }

 // 画像をファイルから読み込むので非同期処理
 async Task CanvasCreateResourceAsync(CanvasControl sender)
 {
    // Windows.ApplicationModel.Package.Current.InstalledPathでこのプロジェクトのパスを取得し、Asset内のファイルを呼び出している
    bitmap = await CanvasBitmap.LoadAsync(sender, Windows.ApplicationModel.Package.Current.InstalledPath + "/Assets/microsoft365_vision.jpg");
 }
```
`Bitmap`は`CanvasBitmap`クラスで保持します。これはWin2D用のBitmapを扱うクラスです。
xamlに登録された`CreateResources`イベントから`LoadAsync`で`Bitmap`を非同期で取得しています。
プロジェクトのパスの取得はWinUI3のお約束的なものとなります。
※画像のプロパティで「出力ディレクトリにコピー」を「常にコピー」または「新しい場合はコピー」に変更しておくこと

# ガウシアンブラーエフェクト
ガウシアンブラーは以下のような形で簡単に追加できます。
```diff_c_sharp
// ブラーされた画像を保持する
ICanvasImage effectImage;

// 描画する際、この関数を呼び出すこととする。
private void CreateEffect()
{
    effectImage = CreateGaussianBlur();
}

// ガウシアンブラーされたイメージを作成する。
private ICanvasImage CreateGaussianBlur()
{
    // マウスのドラッグからブラーする範囲を取得
    var rect = new Rect(pointerDrag.StartLocation, pointerDrag.CurrentLocation);
    // 組み込みのブラーエフェクトクラス
    var blurEffect = new GaussianBlurEffect
    {
        // Sourceには元となる画像を入れる。
        // 指定した範囲をクロップすることで選択した範囲のみがブラーされることとする
        Source = new CropEffect
        {
            // 元のBitmap
            Source = bitmap,
            // クロップする範囲
            SourceRectangle = rect,
        }
        // ブラーの強さ
        BlurAmount = 5.0f
    };

    return blurEffect;
}
```
マウスのドラッグを離したときにブラーする範囲が確定されるので、その時に`CreateEffect()`を呼び出せば、範囲が指定されたぼかし画像を作成できます。
```diff_c_sharp
 private void Canvas_PointerReleased(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
 {
     if (mouseDown == false)
         return;
+    CreateEffect();
     mouseDown = false;
     canvas.Invalidate();
 }
```

# 描画処理
描画処理は以下になります。
```csharp
 private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
 {
     var ds = args.DrawingSession;
     // 元のBitmapを描画
     ds.DrawImage(bitmap);
     if (effectImage != null)
     {
         // その上に範囲指定されたブラー画像が上書きされるイメージ
         ds.DrawImage(effectImage);
     }     
 }
```
描画は元の画像を表示した上にクロップしたブラー画像を重ねるイメージになっています。
これで気に入らないやつの顔をぼかしまくってください。

# その他エフェクト
Win2Dにはぼかし以外に様々なエフェクトを組み込んでいます。
以下のページを参考にしていろいろなエフェクトを試してみてください。
[Win2Dエフェクト](https://microsoft.github.io/Win2D/WinUI3/html/N_Microsoft_Graphics_Canvas_Effects.htm)
個人的に便利だと思ったFigmaのショートカット

# はじめに
最近、Figmaを使うことが多いのですが、効率よく作業するためのショートカットはないかなと思い、調べた備忘録です。

Figmaとは何かはこちら。

https://www.figma.com/ja-jp/

# 便利だと思ったショートカット
※ Macを使用しているのでMacのキーで記載しています。

他にもたくさんのショートカットがありますが、それらを見たい場合は `Ctrl + Shift + ?`でFigma内から見ることができます。

## 基本
- 色の選択（`Ctrl + C`）

## ツール
- 移動（`V`）
- フレーム（`F`）
- テキスト（`T`）
- 線（`L`）
- コメント（`C`）

## 表示
- UIの表示/非表示（`Ctrl + \`）

## シェイプ
- 塗りの削除（`⌥ + /`)
- 線の削除（`Shift + /`)

## 選択
- 親要素選択（`Shift + Enter`）
- 子要素選択（`Enter`）
- 次の要素選択（`Tab`）
- 前の要素選択（`Shift + Tab`）

## 編集
- 複製（`⌘ ＋ D`）
- 選択範囲の名前を変更（`⌘ ＋ R`）

## 変換
- 画像配置（`Shift + ⌘ ＋ K`）

# まとめ
ショートカットを覚えてより効率的にFigmaを使いこなせるようになりたいです。

# 参考

https://noroshi.design/blog/figma-shortcut
複雑なタスクに関連する最近のLLM

狭い用途ですが込み入った課題を解決するLLMを3つ紹介します。

[1. 心電図画像を理解するためのマルチモーダルLLM](##心電図画像を理解するためのマルチモーダルLLM)
[2. AIフィードバックによる長文向けLLMの改善](##AIフィードバックによる長文向けLLMの改善)
[3. 社会的な関係性を推論するLLM「SocialGPT」](##社会的な関係性を推論するLLM「SocialGPT」)


## 心電図画像を理解するためのマルチモーダルLLM
### Teach Multimodal LLMs to Comprehend Electrocardiographic Images
**ECG (心電図, ElectroCardioGram)** を解釈する「Pulse」という名前のLLMが、オハイオ大学とカーネギーメロン大学のチームによって発表されました。

心電図をこのように説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/1b266faf-841f-4e13-0cd3-8c94f69eb11b.png)

この研究は**現実的な状況に対応できるようにデザインされている**のが特徴的でした。学習データは、電子データ、紙に印刷された心電図画像、さらにはくしゃくしゃの紙の心電図画像に基づいています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/5a3eac26-9edb-3950-f97f-faae44ac8116.png)

精度は **82.4%** で、GPT-4oのようなオープンソースのモデルが 50％ なので約 30％ ほど高く、このタスクに特化したモデルよりも約15％高いようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/d8df4341-e7c1-648d-5240-14c4c8d33bb5.png)

## AIフィードバックによる長文向けLLMの改善
### LongReward: Improving Long-context Large Language Models with AI Feedback

近年のLLMは文脈も十分に理解できますが、中々解決できていない課題があるようです。それは、**長文における文脈理解は報酬を設計するためのアノテーションが難しいため、QAペアはLLM自身が自動的に合成することが多ため、ハルシネーションを引き起こしやすい**ということです。

そこで、この研究では、信頼性の高い長文の文脈理解の報酬モデルを作成することでこの課題を解決できると考えました。そして、**有用性、論理性、忠実性、完全性**という4つの人間指向の次元に基づくモデル回答に対して報酬を提供する「LongReward」という方法を考案しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/25f0033d-8582-bb9e-736b-4bb41dd0d3af.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/071af076-05aa-c34a-dbb8-d9abe615c378.png)

この方法によってモデルの長文だけでなく短いコンテキストの解釈の性能を大幅に向上させました。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/ecab62ed-93ac-e2db-f325-f92ee9a14375.png">


※これはDPO(Direct Preference Optimization)という技術の実験になります。DPOについて解説している記事を参考に載せました。

## 社会的な関係性を推論するLLM「SocialGPT」
### SocialGPT: Prompting LLMs for Social Relation Reasoning via Greedy Segment Optimization

画像から友人や同僚、配偶者などの間の**社会的な関係を精度よく推測する方法**が発表されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/4a382457-061e-13e6-6a8a-aa67bba370db.png)

これまでは単純な画像と回答のペアだけでトレーニングすると解釈に限界がありました。そこで、これを解決するために、**Vision Foundation Model (VFM)** の認識能力とLLMの推論能力を備えたモジュールを使用しました。簡単に言えば、**画像から読み取れるストーリーをテキスト情報として出力すること**を間に挟んでいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/83cb0317-c17a-ef87-9956-a0aab3bfe1b1.png)

スコアはこれまでの方法とそれほど大きな差はありませんが精度が約 **67%** あるようです。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/a645a04c-3e42-b17f-8e9e-dd9930696801.png">

## 参考
### 各arXiv論文はこちらです。

- Teach Multimodal LLMs to Comprehend Electrocardiographic Images

https://arxiv.org/abs/2410.19008

- LongReward: Improving Long-context Large Language Models with AI Feedback

https://arxiv.org/abs/2410.21252

- SocialGPT: Prompting LLMs for Social Relation Reasoning via Greedy Segment Optimization

https://arxiv.org/abs/2410.21411

### その他

DPOの詳しい解説記事

https://qiita.com/kunishou/items/7a2850ffc9c692c22a02
Node.jsで構築するシンプルなREST API

## はじめに

近年、ウェブ開発においてREST APIは欠かせない要素となっています。Node.jsは非同期I/Oを得意とするため、高性能なAPIサーバーを構築するのに適しています。本記事では、Node.jsとExpressを使用してシンプルなREST APIを構築する方法を解説します。

## 環境設定

- **Node.js**：最新版（公式サイトからインストール）
- **テキストエディタ**：Visual Studio Codeなど
- **APIテストツール**：Postman、curl、またはブラウザの拡張機能

## プロジェクトの初期化

まず、新しいプロジェクト用のディレクトリを作成し、`npm init`で初期化します。

```bash
mkdir simple-rest-api
cd simple-rest-api
npm init -y
```

## Expressの導入と基本設定

ExpressはNode.js用の軽量なウェブフレームワークです。下記の流れで導入を進めます。

### インストール

```bash
npm install express
```

### 基本的なサーバーの設定

`index.js`というファイルを作成し、以下のコードを追加します。

```js
const express = require('express');
const app = express();
const port = 3000;

// JSONデータを扱うためのミドルウェア
app.use(express.json());

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});
```

## RESTfulルートの作成

基本的なCRUD（Create, Read, Update, Delete）操作を行うためのルートを設定します。

## データの管理（モックデータ）

実際のデータベースを使用せず、モックデータを配列で管理します。

```js
let users = [
  { id: 1, name: '太郎' },
  { id: 2, name: '花子' },
];
```

## CRUD操作の実装

### 1. データの取得（Read）

### 全ユーザーを取得

```js
app.get('/users', (req, res) => {
  res.json(users);
});
```

### 特定のユーザーを取得

```js
app.get('/users/:id', (req, res) => {
  const id = Number(req.params.id);
  const user = users.find(u => u.id === id);
  if (user) {
    res.json(user);
  } else {
    res.status(404).send('ユーザーが見つかりません');
  }
});
```

### 2. データの追加（Create）

```js
app.post('/users', (req, res) => {
  const newUser = {
    id: users.length + 1,
    name: req.body.name,
  };
  users.push(newUser);
  res.status(201).json(newUser);
});
```

### 3. データの更新（Update）

```js
app.put('/users/:id', (req, res) => {
  const id = Number(req.params.id);
  const user = users.find(u => u.id === id);
  if (user) {
    user.name = req.body.name || user.name;
    res.json(user);
  } else {
    res.status(404).send('ユーザーが見つかりません');
  }
});
```

### 4. データの削除（Delete）

```js
app.delete('/users/:id', (req, res) => {
  const id = Number(req.params.id);
  users = users.filter(u => u.id !== id);
  res.status(204).send();
});
```

## サーバーの起動とテスト

### サーバーの起動

```bash
node index.js
```

ブラウザまたはAPIテストツールで以下のURLにアクセスして動作を確認します。

- **全ユーザー取得**：`GET http://localhost:3000/users`
- **ユーザー取得**：`GET http://localhost:3000/users/1`
- **ユーザー追加**：`POST http://localhost:3000/users`（ボディに`{"name": "新しいユーザー"}`）
- **ユーザー更新**：`PUT http://localhost:3000/users/1`（ボディに`{"name": "更新されたユーザー"}`）
- **ユーザー削除**：`DELETE http://localhost:3000/users/1`

## 次のステップ

下記のようなアップデート案が考えられるかと思います。

- **データベースの導入**：MySQLやMongoDBなどのデータベースを接続して、永続的なデータ管理を実現
- **エラーハンドリング**：エラー時の応答を統一し、APIの信頼性を向上
- **認証と認可**：JWTなどを使用してセキュアなAPIに拡張
- **APIドキュメンテーション**：Swaggerなどのツールを使って、自動的にAPIドキュメントを生成

## まとめ

今回の記事では、Node.jsとExpressを使ってシンプルなREST APIを構築する方法を紹介しました。基本的なCRUD操作を実装することで、RESTful APIの基礎を理解できたかと思います。次のステップでは、データベースの導入やセキュリティ強化など、実践的な機能追加に挑戦してみてください。

**お問い合わせやご意見がありましたら、お気軽にご連絡ください。**

## おわりに
弊社では、フリーランスエンジニアの方を募集しております！
熱意を持って新しいプロジェクトに挑戦したい方、様々な大規模開発プロジェクトに興味のある方は、下記フォームにてあなたの経歴をご回答ください！
👉 フォームは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSfY9lckFjAJ_Ddc4rdHDSIFoV4NFHw1q2HriK2aa_jvVhp8QQ/formResponse)
たくさんのご応募、お待ちしております！
初めてデータベーススペシャリスト試験を受けてきた 午後Ⅱ試験のまとめ

## はじめに

今日は、データベーススペシャリスト試験の午後Ⅱ試験についてまとめます。

## 本文

### 午後Ⅱ試験のまとめ

- **試験情報**
  - **実施日**: 2024年10月13日
  - **問題**: [IPA公式サイト](https://www.ipa.go.jp/shiken/mondai-kaiotu/2024r06.html)

### 午後Ⅱ試験の傾向

午後Ⅱ試験は2問構成で、その中から1問を選択して解答します。私は問2のデータベース設計を選びました。

- **問1**: オートリース会社の車両保守業務におけるデータベースの実装と運用に関する問題でした。現行のオンライン処理とバッチ処理の説明、アプリケーションプログラムのCRUD図の読み込み、適切なバックアップ・リカバリの処理や所要時間が問われました

- **問2**: 車体部品メーカーの資材調達業務のデータベース設計に関する問題でした。資材の保管、在庫管理、発注、納入依頼、納入といった一連の業務を記録するデータベースで、欠落しているリレーションシップの記入や関係スキーマの属性名の穴埋めが問われました

### 間違えた問題とその分析

午後問題の解答例は12月24日に発表されるため、正確な間違いは分かりませんが、問1のデータベース実装の問題が私の対策した想定していたものと異なり、過去問で経験のない形式でした。当初はデータベース設計・実装の問題を選択する予定でしたが、見慣れない形式だったため急遽計画を変更し、問2の概念データモデリングを選びました。

問2は概念データモデリングに特化した問題で、リレーションシップの記入と関係スキーマの属性名の穴埋めが中心でした。比較的簡単に解けると感じ、丁寧に問題を解いていきました。しかし、その結果、後半で時間が不足し、焦って解答することになってしまいました。時間配分が大きな反省点です。（解答例が公開されたら追記します。）

### 来年に向けて

データベース設計・実装の問題の方が解きやすいと感じていたものの、見慣れない形式の問題でパスしてしまったため、来年はさまざまな形式のデータベース設計・実装の問題を徹底的に解いていきたいと思います。

## まとめ

今回のデータベーススペシャリスト試験を通じて、準備不足が浮き彫りになりました。午後Ⅱ試験に関しては、時間配分の重要性を痛感しました。問題を丁寧に解くことも大切ですが、全体の時間を意識しながらバランスよく進める必要があります。来年の試験に向けて、より多くの問題形式に慣れ、時間内に解答を終える練習を積んでいきます。
明日からはデータベースに関して勉強した内容をまとめていきます。
Azure CLIでterraformで必要な情報を抜き出す

Azureで必要な項目がterraformで必要なものを出力する方法のメモ

まず

```
az login
az account list
```

subscription_idを入手

subscription_idをメモした後

```
az account set --subscription="subscription_id"

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/subscription_id"
```
で

  "appId": "",
  "displayName": "",
  "password": "",
  "tenant": ""

を入手。

appId is the client_id。
password is the client_secret。
tenant is the tenant_id。

これで必要な情報はそろう。


参照
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret
MERGE文のUPDATEでターゲットカラムを参照して値に基づいた処理を反映する方法

## 概要

MERGE 文にて UPDATE する際にターゲットテーブルのカラムに基づいて処理を実施する方法について紹介します。例えば、 ターゲットテーブルに REVISION のようなカラムがあった場合に、下記のように記述することで処理のたびに 1 を加算するような処理を実行できます。今までそういった処理を実装したことがなかったので気付かなかったため、記事にしておきます。

```sql
    target.revison = target.revison + 1,
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/97936543-f756-8e0c-821f-2ecdabc7845b.png)

## 検証コードと実行結果

### カタログとスキーマを作成

```sql
%sql
CREATE CATALOG IF NOT EXISTS meget_test;
CREATE SCHEMA IF NOT EXISTS meget_test.schema_01;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8ec6bdc5-dc1d-1634-ad81-a1092ff71349.png)


### テーブルの作成と`REVISON`が`0`のデータの挿入

```sql
%sql
CREATE OR REPLACE TABLE meget_test.schema_01.table_01
(
  id int,
  revison int,
  update_at TIMESTAMP
);
INSERT INTO meget_test.schema_01.table_01
SELECT
  1,
  0,
  current_timestamp()
;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f2e93b60-84d1-fa9f-8bdc-59d21a279bca.png)


```sql
%sql
SELECT * FROM meget_test.schema_01.table_01
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/6b1c873d-e267-a412-5693-22ead09b2533.png)


### MEREGE 文により UPDATE を実行

```sql
%sql
WITH src AS (
  SELECT 1 AS ID
)
MERGE INTO meget_test.schema_01.table_01 AS target
USING src AS source
ON target.id = source.id
WHEN MATCHED THEN
  UPDATE SET 
    target.revison = target.revison + 1,
    target.update_at = current_timestamp()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f8109f7b-f4ed-bbc2-56a2-bafc6c552d76.png)


### REVISION が 1 となっていることを確認

```sql
%sql
SELECT * FROM meget_test.schema_01.table_01
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8b7886d6-47a8-dbbf-420b-0f525a19fe9e.png)

### 複数回の MERGE 文の実行により REVISION 列が加算されることを確認

```sql
%sql
WITH src AS (
  SELECT 1 AS ID
)
MERGE INTO meget_test.schema_01.table_01 AS target
USING src AS source
ON target.id = source.id
WHEN MATCHED THEN
  UPDATE SET 
    target.revison = target.revison + 1,
    target.update_at = current_timestamp();
SELECT * FROM meget_test.schema_01.table_01;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/96487186-26c2-521c-ef5b-a41cd92723e2.png)

### 作成したカタログを削除

```sql
%sql
DROP CATALOG IF EXISTS meget_test CASCADE;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/40faa15d-aeeb-f48a-db85-680a0ebb13de.png)
Git,Githubの操作復習大全

## 概要
- 本記事は、未完成状態にあります。著者が経験したGit,GitHubにおける操作や、「あれ...この操作どうやるんだっけ？」という疑問に対して著者が著者のために作成する記事となります。
この操作もよく使うので、記載して欲しい！！という内容がありましたら、是非コメントお願いいたします。
- 操作環境としては、Macbook,Warp,VScodeを使用しております。

### 基本操作
- file操作
```
cat file_name
```
- fileの作成
```
touch file_name
```
- ディレクトリの作成
```
mkdir directory_name
```
- fileの編集
```
code file_name
```
- file名の変更
```
git mv file_name new_file_name
```
- fileの移動（上段）、ディレクトリの移動（下段）
```

### ローカルとGithubの繋ぎ込み
### Githubからローカルへの落とし込み
### .DS_Storeの無視（Mac向け）
### git push origin main
### branch関連
【TIPS】マップリストにpandasのget_dummiesっぽいダミー値処理をする②

この記事は、[Elixir Advent Calendar 2024 シリーズ3](https://qiita.com/advent-calendar/2024/elixir) の7日目です

---

【本コラムは、10分で読め、5分で試せます】

[piacere](https://twitter.com/piacere_ex) です、ご覧いただいてありがとございます :bow:

[get_dummies①のコラム](https://qiita.com/piacerex/items/84763dc2050d1648f434) では、通番による数値化を行いましたが、値のバリエーションごとに列生成するpandasのget_dummiesと全く同じ仕様に改造してみましょう

たとえば、下記マップリストのc1／c3キーをダミー値処理すると、下記の結果のように、c1／c3の値のバリエーションが列生成された上で0か1かの数値化されます

```diff_elixir
maplist = [
  %{"c1" => "v1", "c2" => 2, "c3" => true}, 
  %{"c1" => "v1", "c2" => 5, "c3" => false}
]
keys = ["c1", "c3"]

結果：[
  %{"c1_v1" => 1, "c1_v2" => 0, "c2" => 2, "c3_true" => 1, "c3_false" => 0}, 
  %{"c1_v1" => 0, "c1_v2" => 1, "c2" => 5, "c3_true" => 0, "c3_false" => 1}
]
```

これを実装すると、こんなコードになります

```diff_elixir
maplist = [
  %{"c1" => "v1", "c2" => 2, "c3" => true}, 
  %{"c1" => "v2", "c2" => 5, "c3" => false}
]
keys = ["c1", "c3"]

Enum.reduce(keys, maplist, fn key, acc -> 
  uniqs = 
    Enum.map(maplist, & &1[key]) 
    |> Enum.uniq 
  acc
  |> Enum.map(fn map -> 
      Enum.reduce(uniqs, map, & Map.put(&2, "#{key}_#{&1}", 
        if map[key] == &1 do 1 else 0 end
      ) |> Map.delete(key)) 
    end)
end)

結果：[
  %{"c1_v1" => 1, "c1_v2" => 0, "c2" => 2, "c3_true" => 1, "c3_false" => 0}, 
  %{"c1_v1" => 0, "c1_v2" => 1, "c2" => 5, "c3_true" => 0, "c3_false" => 1}
]
```

コード解説ですが、全体としては、ダミー値処理を各キーごとに行い、ダミー値化した結果をaccに積み続けるところまでは、get_dummies①と同じです

最初に、各キーごとに、カテゴリ値に値のバリエーションをEnum.uniqでユニーク化したものを、下記のように `uniqs` として保持します

```diff_elixir:c1分
uniqs = ["v1", "v2"]
```

```diff_elixir:c3分
uniqs = [false, true]
```

次に、Enum.mapでマップリストを回し、各マップをMap.putを使って列生成し、元の値に合わせたダミー値の割り当てを行い、マップ更新しつつ、元のキー／値をマップから削除します

# p.s.このコラムが、面白かったり、役に立ったら…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) にて、どうぞ応援よろしくお願いします :bow:
イベントオブジェクトにはどのようなプロパティがあるか

## はじめに
本記事は[イベントとイベントリスナー](https://qiita.com/axoloto210/items/bcd567e377f9b07fc569)の続きの記事になります。
イベントが発生した際に、どの要素でどのようなイベントが発生したのかなどの情報を含むオブジェクトである、イベントオブジェクトについてみていきます。

## イベントオブジェクトとは
イベントオブジェクトとは、発生したイベントに関する情報をもつオブジェクトです。
イベントが発生するとブラウザによって生成され、windowオブジェクト、documentオブジェクト、その配下のオブジェクト... という順でイベントが発生した要素へと渡されていきます[^1]。

## イベントオブジェクトに含まれるプロパティ
イベントオブジェクトに含まれる主なプロパティとしては以下のようなものがあります。
### type
`type`は発生したイベントの種類を表す文字列で、`click`や`keydown`などの値を持ちます。
`addEventListener`の第1引数に設定した文字列と`type`が同じときに設定したイベントハンドラーが呼び出されます。

### target
`target`はイベントが発生した要素への参照をもちます。

`target`にどのような情報が含まれるかは、`console.dir()`を使うと詳細に確認することができます[^2]。
```js
 const btn = document.getElementById("btn");
    btn.addEventListener("click", (e) => {
      console.dir(e.target);
    });
```

### currentTarget
`currentTarget`には現在イベントを処理している要素の参照がはいっています。
キャプチャリングやバブリングによってイベントの発生源ではない要素でもイベントが処理されることがあり、その場合に`target`と`currentTarget`の値が異なることになります。

### bubbles
`bubbles`にはboolean値がはいっており、バブリングが起こる場合には`true`、起こらない場合には`false`をとります。

### cancelable
`cancelable`にはboolean値がはいっており、イベントがキャンセル可能かを表します[^3]。
`click`や`submit`などはキャンセル可能なため、`true`が格納されていますが、`load`や`DOMContentLoaded`、`scroll`はキャンセルができないため、`false`が格納されています。

### eventPhase
`eventPhase`にはどのフェーズで処理がされているかを表す数値が格納されています。
各数値はそれぞれ以下に対応しています。
`0`: `NONE`
`1`: `CAPTURING_PHASE`
`2`: `AT_TARGET`
`3`: `BUBBLING_PHASE`


## イベントオブジェクトに含まれるメソッド
### preventDefault()
`preventDefault()`を呼び出すことで、デフォルトの動作を無効化することができます。
`submit`イベントでの通常のフォーム送信を停止したり、リンクの`click`イベントで通常のページ遷移を抑止するためなどに使用できます。

### stopPropagation()
`stopPropagation()`を呼び出すことで、イベントの伝播を止めることができます。
例えばキャプチャフェーズで呼び出されたときには、続くターゲットフェーズ、バブリングフェーズでの伝播も起こらなくなります。

同じ要素に複数のイベントリスナーが設定されている時には、`stopPropagation()`が呼び出されても、その要素に設定されたイベントリスナーによる処理は全て実行されます。
`stopImmediatePropagation()`を呼び出した場合には、同じ要素のイベントリスナーであっても呼び出し以降の処理については行われなくなります。

https://dom.spec.whatwg.org/#interface-event

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Events#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88

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

[^1]:`addEventListner`の第3引数に`true`や`{capture:true}`が設定されているときには、この伝播の過程でも設定されたイベントハンドラが呼び出されます。（キャプチャーフェーズ）
[^2]:`console.dir()`はオブジェクトのプロパティ全てをコンソール上に表示します。
[^3]: キャンセル可能であるとは、`preventDefault()`によってデフォルトの動作を止められることを指します。
カイゼンとカイカク（および対話）

# アジャイルを組織に浸透させるには

IPAが発行している[DX白書2023](https://www.ipa.go.jp/publish/wp-dx/dx-2023.html)によると、IT部門においてアジャイルの原則とアプローチに取り込んでいる企業は米国においては、78.8％（取り入れている・一部取り入れている）に対して、日本では49％らしいです。また、前回の[DX白書2021](https://www.ipa.go.jp/publish/wp-dx/dx-2021.html)時点では日本が42.7%だったので徐々に広まっているということかと思います。

とはいえ、まだ半数の企業が取り入れられていないのには、もちろん理由があるでしょう。

# 日本のプロダクトではアジャイルは適さない？

という仮説にははっきりとNOと言いたいです。

そもそもDX白書を出しているIPA（情報処理推進機構）は経済産業省の機関ですし、そのIPAが[アジャイルソフトウェア開発宣言の読みとき方](https://www.ipa.go.jp/jinzai/skill-standard/plus-it-ui/itssplus/ps6vr70000001i7c-att/000065601.pdf)なんてのも出しているのをみても、国を挙げて広めていこうという流れは明らかですし、不確実性の高い現代において、多くのプロダクトでアジャイルなアプローチが有効であることは広く知られているところです。

# カイゼンとカイカク

年に一度、半期に一度、月１度、週１度と頻度はどうあれ、振り返りを取り入れているチームは多いと思います。
トヨタから始まったカイゼンという取り組みはとても日本の企業文化には取り入れやすいものですね。

しかし、予測計画型のウォータフォールのプロセスでいくら振り返りをしてもウォータフォールがうまくなるだけで、そのカイゼンからアジャイルの原則を取り入れようとかScrumにしようとはなりません。

もっと予測をうまくやろう、計画をうまくやろうという方向には向かいますが、そもそも予測が難しい、そもそも計画がずれる前提でという話にはならないのです。

以下はすごくざっくり略していますが、[学習する組織](https://www.amazon.co.jp/dp/4862761011)で紹介されている氷山モデルというものです。

![氷山モデル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/5ffabc58-ec7b-4abe-fe91-4186684dfbb2.jpeg)

起きている出来事は当然認識できるもので、ここは振り返りでカイゼンできるものです。しかし、そもそも予測が難しい、そもそも計画はずれやすいといった意識・無意識の前提については振り返りでは気が付かない部分になります。

書籍から学んだり、勉強会やITイベントなどからこのメンタルモデルに気が付き、組織やチームを変えたいとなったとき初めてメンタルモデルを認識するのです。

この組織やチームを変えたいとなったとき、振り返りではなんともならないので、やることはカイゼンではなく「改革」になります。

チェンジマネジメントで語られている[ADKARモデル](https://ataway-cm.jp/methodology-overview/adkar-model/)やアジャイルを広めるためのパターン集である[FEARLESS CHANGE](https://www.amazon.co.jp/dp/462108786X)なども「改革」を前提にしたもです。


# 改革には抵抗が伴う

税制改革や政治改革、享保の改革や天保の改革を見てもわかるように改革には痛みが伴います。今までやってきた仕事の仕方が変わる、キャリアに影響があるかもしれない、組織構造も変わるかも知れない、そもそもうまくいくかどうかがわからないと考えれば当然です。

チェンジマネジメントにしても、FEARLESS CHANGEにしても抵抗があることを考慮して書かれているものですが、多分日本ってこの抵抗が米国に比べてより強いんじゃないかと思うのです。
少し別の言い方で言うと、日本人は対話が苦手なのではないか？と思うのです。

# 日本人は対話が苦手？

たとえば、ADKARモデルで言えば、認知をしてもらい(AWARENESS)→変えたいという欲求を持ってもらい(DESIRE)→知識を得(KNOWLEDGE)→能力として身につけて(ABLITY)→定着する(REINFORCEMENT)という流れを説明していますが、そもそも認知をしてもらうまでのハードルが高いんです。

そもそも変えようとすることに抵抗があるのだからいくら認知してもらっても変えようという気にはならない。

FEARLESS CHANGEにしても、小さくはじめるにも、仲間を見つけるにも何をするにしてもまずは抵抗を乗り越えなければいけない。

そうしたときに何よりも必要なのが「対話」というものです。
まず説得する、説明する、認知をしてもらうのではなく、相手には別のナラティブ（物語）の中で意味のあるものがあるという前提に立つ。相手の背後にある課題を知る。そのうえで相手にとって意味のある取り組みは何かを考える。それが変えたいと思っているものであれば変わっていこうと思える。
こういうことが必要になります。そして日本人ってこういうの苦手な人が多い気がします。

# 勇気を出して対話をしよう

こういう対話というのは、相手の内面を知るということでもあるので、ここに飛び込んでいくのはすごく勇気がいることだと思うんです。多くの日本人の苦手なところです。

しかし、ここに素晴らしい解決策はありません。まずは勇気を出すこと。認知（AWARENESS）でも情熱を持って伝えるエバンジェリストでもなく、対話と勇気。これをFEARLESS CHANGEのパターンの最初に付け加えたいです。

ひとつ勇気が出る材料があるとすれば、変えたいと思う側はさきほどの氷山モデルの埋まっている部分。メンタルモデルに気がついているということ。相手のナラティブや課題を知ってともに乗り越えようとしたときに、この部分の認知が非常に有効であるということです。

勇気を出してやっていきましょう！


※ 対話については[他者と働く─「わかりあえなさ」から始める組織論](https://www.amazon.co.jp/dp/B07Y5FF3M4/)という本を参考にしました。
エヴァ？エバー？ Japan Evangelistの活動について

こんにちは、こんばんは！
このカレンダーを企画しているPromotion SGのリーダーの遠藤です。

趣味は、旅行・スポーツ観戦・ガジェットなどです。
今年、予想外に良かったガジェットはClaw A1Mです。
もちろんポータブルゲーミングPCとしては、ROG Ally Xとかの方が良いとは思うのですが、
Core Ultra5/メモリ16GのモバイルPCと見ると破格のお安さなので、
ドラクエ3やスト6などを手軽に遊びつつ、旅行時の文書作成などにも重宝してます。
また、Mac mini(M4 Pro)は予想通り凄く良いです。

では、本題に入りましょう！

# Japan Evangelistの活動で目指していきたいもの
昨日登場した中村さんも[触れていました](https://www.linuxfoundation.jp/press-release/2024/08/linux-foundation-japan-evangelist-program/)が、
今年Linux Foundation Japanは[Evangelistプログラム](https://www.linuxfoundation.org/japan-evangelist-program)を開始しました。
このプログラムは日本におけるLFプロジェクトのプロモーション活動を、よりコミュニティドリブンで行うことを目的としており、分野の異なる5人が初代Japan Evangelistとして就任しました。
今年の本アドベントカレンダーはそれを記念して、12/3から12/7まで5日連続して各Evangelistが自身の分野のコミュニティ活動を紹介していきます。

私の専門はOSPO/Open Chainとなっており、以下のような活動に力を入れています。

**■様々な層へのオープンソース、コミュニティの重要性の訴求**
日本におけるオープンソースコミュニティ活動をより活性化していくため、
エンジニア、リーガル、経営層、学生など様々な層にオープンソースやコミュニティ活動がなぜ重要なのかをお伝えする活動を行っています。

**■OSPOの普及支援**
組織におけるオープンソースの活用推進の「一つ」のアプローチとしてOSPO(Open Source Program Office)があります。
もちろん、OSPOを設置したからといって急に企業文化が変わるわけではありません。
しかし、組織にオープンソースコミュニティ活動の推進に向き合う人材をオフィシャルに配置することは、決して無駄にはならないと考えています。
[福安さんが触れていたように](https://qiita.com/fukuyasu/items/31db7c726f025c056ab9)、日本でも少しづつOSPOが増えていきました。
Open ChainやTO DO Groupなどとも連携してOSPOを設置したいと思う組織を増やし、その活動を支援しています。
うちもOSPO設置したいとお考えの方、是非お声がけください！

# 今年の具体的な活動
では、今年の活動例を見ていきましょう！

**■OSSJ Japan Evangelist Panel**
[Open Source Summit Japan 2024](https://events.linuxfoundation.org/open-source-summit-japan/)にてEvangelistが全員ではじめて登壇する[パネルディスカッション](https://ossaidevjapan24.sched.com/event/1jKCb/oss-sustainability-in-japan-open-collaboration-model-to-spin-up-the-oss-3p-cycle-yuichi-nakamura-ayumi-watanabe-hitachi-shingo-fujimoto-fujitsu-masato-endo-toyota-munehiro-ikeda-cybertrust-japan-moderated-by-nori-fukuyasu-the-linux-foundatio)を行いました。
ここではオープンソースのサステナビリティを担保するために日本においてコミュニティ活動をより活性化させるための課題と、課題解決のための取組についてのディスカッションを行いました。
そのエッセンスは、本アドベントカレンダーでも共有されると思いますので、お楽しみに！
![OSSJ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537313/02158a18-406e-b0cb-ffe9-2aca3de0bbc5.jpeg)


**■Harvard Japan Day**
Harvard大学で行われたボストンの学生の皆さんに日本のカルチャーやビジネスについて知って頂くためのイベントのパネルに参加してきました。
今回のテーマは如何にして日本のユニコーン企業増やしていくかというとても興味深いものでしたが、私はオープンイノベーションの観点から、スタートアップが周りを巻き込んでスケールアップしていくための施策に関してお話させて頂きました。
![Harvard.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537313/a2b93d5c-87c7-4fc7-1699-0310b8851897.jpeg)

**■ITmedia OSPO新連載**
これまでOpen Chain Japan WG Promotion SGでは、ITmediaさんとOSSコンプラやSBOMに関する2本の連載を企画してきました。
そんな中、今年は[「始めよう！　企業としてのオープンソース活動」](https://atmarkit.itmedia.co.jp/ait/series/39643/)という連載を立ち上げました。
この連載では、企業が組織としてオープンソース活動に何のために、どう取り組むかをキーパーソンのインタビューなども交えながら様々な視点から探っていくと共に、OSPOの活動紹介も行う予定です。

# 来年の展望
今年は昨年に続き、日本企業におけるOSPOの設置が少しづつ増えてきました。
来年もこの動きを後押ししていくと共に、
パブリックセクターやアカデミーセクターのコミュニティ活動の活性化やOSPO設置にも取り組んでいきたいと思っています。
ソフトウエアが社会の基盤になっている昨今、オープンソースの継続性に貢献していくことも、ある意味SDGsかなと思っています。


明日は、BlockchainのEvangelistである藤本さんの登場です。
お楽しみに！
notion用の開発マニュアルテンプレート

Web 開発向けのマニュアルテンプレ

そのまま貼り付けて、各項目( `- xxx` ) をページ ( `/page` )へ置換する

```
# 最初に読む

## 新規参画者向け
- 開発者用チュートリアル
- FAQ(詰まった時に読む)
- 用語集

## 全体把握
- キックオフ資料
- ユーザー向けパンフレット・操作資料

## 環境構築
- アカウント準備
- 環境構築
- ログイン情報

---

# 全体計画

## 長期
- ビジョン
- マイルストーン

## 中・短期
(長期マイルストーンを xxx へ落とし込みしている)

---

# 設計関連

## システム概要
- 全体構成図
- インフラ構成図
- 外部サービス

## 設計ドキュメント
- 基本設計
- 画面(ワイヤー)設計
- API設計
- DB設計
- 定期バッチ設計
- 環境変数・固定値管理

---

# DevOps

## 開発プロセス
- ブランチ運用
- レビュー方針
- テスト方針
- リリースフロー
- バージョン管理

## CI/CD
- デプロイ構成全体図
- パイプライン詳細構成
  - CI
  - CD
- アプリケーションデプロイ
  - To Staging
  - To Production 🔒
- インフラデプロイ
  - To Staging
  - To Production 🔒

---

# 保守運用

## Staging 環境
- アクセス方法
- 定期メンテナンス手順
- デプロイ手順
- ロールバック手順

## Production 環境 🔒
- アクセス方法
- 定期メンテナンス手順
- デプロイ手順
- ロールバック手順

## データ管理
- DB 直接参照
  - To Staging
  - To Production 🔒
- バックアップ・リストア
  - To Staging
  - To Production 🔒

## 監視・モニタリング
- アラート通知設定
- 月次レポート集計方法

---

# 作業記録

## 記録一覧
- 定型作業
- アップデートなど単発作業
- 本番リリースチェックリスト
- 引継記録

---

# その他

## 離任手続き
- 離任作業チェックリスト

## 管理者専用 🔒
- 秘匿情報管理
  - システム本番アカウント(動作確認用)
  - AWS root アカウント(社内ドライブへ退避済)
  - VPN鍵
  - DB踏み台鍵
  - サーバー鍵
```
Tips: fetchしたデータをBlobに変換してIndexedDBに保存する

## 初めに

https://qiita.com/getty104/items/88ec78dcafe7b03e9682

では、Base64でデータの保存を行いましたが、IndexedDBはBlobデータのままでも
データの保存を行うことが可能です。
この記事では、fetchしたデータをBlobに変換し、IndexedDBに保存する方法について記事にします。

## IndexedDBとは
IndexedDBとは、ブラウザに多様なデータを保存するためのAPIです。
詳しくは↓をご覧ください。

https://qiita.com/getty104/items/88ec78dcafe7b03e9682#indexeddb%E3%81%A8%E3%81%AF

↓に記載の通り、IndexedDBにはBlob形式のオブジェクトも保存が可能です。

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

## 実装
今回も前回の記事と同じく

https://github.com/jakearchibald/idb-keyval

を用いて実装します。
コードは以下の通りです。

```ts
import { set, get, clear } from "idb-keyval";

export const getAudioCache = async (url: string) => {
  const blob = await get<Blob>(url);
  return URL.createObjectURL(blob);
};

export const cacheAudio = async (url: string) => {
  const response = await fetch(url);
  const blob = await response.blob();
  await set(url, blob);
  return data;
};

export const clearAudioCache = async () => {
  await clear();
};
```

前回の記事と異なる点は以下の二つです。

## getAudioCache
Blobデータをそのまま返すのではなく、urlを引数でとっているためそのままURLで返すようなインターフェースに変更しました。
BlobデータをURLに変更するため、`URL.createObjectUrl`を用いています。

https://developer.mozilla.org/ja/docs/Web/API/URL/createObjectURL_static

これにより、`cacheAudio`を利用する、しないに関わらず外部の処理の実装はほとんど変化させずに利用できると思います。

## cacheAudio

こちらは前回の記事ではBase64に変換する処理にしていましたが、今回はBlobをそのまま保存するようにしています。
書籍「kintone完全マニュアル」について

# はじめに
秀和システムの「完全マニュアル」シリーズの1つ、「kintone完全マニュアル」が2025年1月に発売予定です。
https://amzn.asia/d/3s4o0vZ
このような書籍があると、多くの皆さまに喜んでいただけるかな、と思って執筆しました。
ほぼ原稿ができあがり、予定通り発売できそうで、ほっとしています。

# 1.kintoneの書籍はもっとたくさんあっていい
Excelが多くの人たちに利用されているように、kintoneも全世界で使った方が、絶対便利だと思います。
そのためには、Excelの書籍のように、kintoneの書籍も書店に並んでいてほしいですが、今のところ、まだまだ数少ないです。
この本が、あちこちの書店に並んでくれたらいいなと思ってます。

# 2.職場でkintoneを利用する人たちが、参考にできる書籍があるといい
職場でkintoneを利用することになった、という人が、最初に行うのは、
* kintoneへのログイン
* アプリを開き、レコードを表示する
* レコードを登録し、編集する

というような操作だと思います。
kintoneの利用のはじめのところから解説してある書籍があると、kintoneの利用を広げやすくなるなと思ってます。

# 3.kintone認定アソシエイト試験対策テキストでは、詳しすぎる
kintoneでアプリを作ったり、システムを構築をする、という方や、
お客様にkintoneでサービスを提供する、という方には、
kintone認定アソシエイトの資格を取得することをお勧めします。
kintoneのすべての機能が試験範囲なので、合格できれば、kintoneでできることと、できないことがはっきりわかります。
改善したい業務があったとして、それがkintoneでできることならkintoneを利用して改善し、そうでなければkintone以外で改善する、とすればうまくいくと思います。
kintone認定アソシエイト試験対策テキストは、試験に合格できるよう、試験範囲を網羅して記述されています。
ただ、職場でkintoneを利用することになったから、kintoneの使い方を学習したい、という方には、明らかに試験対策は過剰です。
まずは利用にあたって必要なことから、順を追って書かれているテキストがあるといいなと思ってました。

# 4.「完全マニュアル」シリーズは初心者向け
会社でkintoneを導入したけれど、使い方がよくわからない初心者ユーザーが、机の上に置いておいて困った時に見ればわかる、というふうに使ってほしいです。
また、アプリを自分で作りたい方や、kintoneをもっとみんなに使いこなしてほしい管理者にも、役に立ててほしいです。
そのため、本の構成を大きく3つに分けました。
1. 利用者向け(1章〜4章)
2. アプリ作成者向け(5章〜7章）
3. 管理者むけ(8章〜10章)

自分が必要なところを読んでもらえば、kintoneをうまく利用できるようになると思います。

# 5.kintoneを自分が利用したり、周りに利用してもらうのに役立つと思います
kintoneは、自分が利用できるだけでなく、周りの人たちが利用できるようになると、データや連絡を共有できてとても便利です。
自分が利用できるようになるためにも、周りの人が利用できるようになってもらうためにも、この書籍を活用してもらえると嬉しいです。
【GoogleSite】学校広報用にWebサイトを作成　②制作編

## この記事のポイント
* Googleサイトの使い方
→とても簡単な解説とTips
* メディア（写真・動画など）の管理の仕方
→Googleドライブで共有ドライブを作ろう
* **この記事は企画編・作成編・運用編の三部作です**
本編は②制作編です
①企画編については[こちら](https://qiita.com/mi_tomo_11_8/private/3b57e0f263fc2e561ed9#%E6%9B%B4%E6%96%B0%E3%83%95%E3%83%AD%E3%83%BC%E6%95%99%E5%93%A1%E7%AE%A1%E7%90%86%E8%81%B7%E3%81%AB%E3%82%88%E3%82%8B%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF/　)

## Googleサイトの使い方
ここではGoogleサイトの使い方について簡単に解説します。
※GoogleWorkspaceアカウントを持っている前提で話が進みます。
※各アクセス権限について設定されていない場合は組織のGoogleアカウント管理者にお問い合わせください。
※使用ブラウザはChromeを想定しています。

※卒業するとアカウントが自動で消去される組織（学校）の場合は，
**サイト用アカウントを組織の管理者に作成してもらい，そのアカウントで作成して下さい。**
（オーナーが消えて，サイトデータななくなることを防ぐためです。）


**Googleサイトでの作成方法**
1.[Googleサイト](https://sites.google.com/new)にアクセスします。
2.「空白のサイト」でサイトを新規作成
3.左上に「無題のサイト」と表示されているので，自分サイト名の変更します。
※ここでのサイトタイトルがGoogle検索結果に表示されるのでよく考えましょう。

この記事ではGoogleサイトの詳しい使い方については省略します。
これ以降はGoogleサイトの作り方に従って広報用のサイトを作成して下さい。

# Tips 表の入れ方
Googleサイトでは表を挿入する機能がありませんが，表を挿入したいときは多くあると思います。その時は"挿入"タブな内の"埋め込み"から"HTML"を選択しHTMLで表を記述することで表の挿入ができます。
HTMLでの表を記述する方法についてはGoogle等で検索してみてください。（ここでは著作権等への配慮で掲載しません…）

# メディア等の管理方法
学校について広報する際は写真や動画PDF書類などを掲載することが多くあると思います。それらのメディアについては**共有ドライブ**を利用して管理しましょう。

共有ドライブとはGoogleドライブにアクセスし,"共有ドライブ"のタブを選択することで作成できます。
※GoogleWorkspaceや権限の関係で作成できない場合は組織の管理者にお問い合わせください。
※個人のアカウントでは共有ドライブは作成できません。

**注意**
学校を卒業するとアカウントが自動で削除される学校（大半がこのパターンだと思います）の場合は生徒アカウントではなく **サイト用のアカウントを新たに組織の管理者に頼んで作成し，そのアカウントを共有ドライブのオーナー及び管理者にするようにしましょう。** このようにすることで，卒業と同時にアカウントが消去され，その人がオーナーだったサイト，メディアが消える可能性をなくすことができます。

## 終わりに
以上で制作編を終わります。Googleサイトがノーコードでユーザーフレンドリーなサービスだったので思った以上に書くことが少なかったですが，自分が制作したときには気づかず，直すハメになったり，困ったことをTips的に書きました。
次回は運用編です。

最後まで駄文にお付き合いいただきありがとうございます。
Javaを基礎から学ぶその4　配列をもっと知る

この記事は[JavaとPythonを基礎から学びたい私のための Advent Calendar 2024](https://qiita.com/advent-calendar/2024/aruhitonocalendar)の4日目の記事です。
配列について詳しく見ます。ざっくりとした説明は[こちら](https://qiita.com/Aruhimanahito/items/cb797a130e7c9be4a3d3)からどうぞ。
# 配列について
たくさんの数値や数を入れることができるということを昨日学習しました。入れている数字や文字は「要素」と呼ばれているようです。0から順番に入れるのではなく、空いている場所に入れることができるようです。（入っていない場所はnullになるっぽい）
# 配列の宣言
空の配列を作るときは
```
 String[] Hairetu=new String[2];
```
で行けました。ちなみに昨日はint型の配列でしたがこの通りString型の配列もできるようです。要素入りは下のほう。
```
int[] A={0,2,3,5,8};
```
## 要素の追加
用意した配列に、後から要素を追加することができるようです。
```
  Hairetu[1]="Winter";
  Hairetu[0]="December";
```
配列の、[　]の中の数字の場所に入ります。
ただし、同じ場所(例えば[1])に2つ入れようとした場合、
```
  Hairetu[1]="Winter";
  Hairetu[1]="December";
```
この時は先に入れていた方が上書きされて消えてしまうようです。入れたい場所から後ろの部分をひとつづつずらして無理やりねじ込むことは普通にはできないようです。
## 配列をコピーする
二つ以上の配列があるときに、配列の中身をコピーすることができるようです。
```
 System.arraycopy(B, 0, A, 0, A.length);
```
コピー元、コピー先の開始位置やコピーの長さを変えることができるのは便利そうです。
# 要素を並び替える
要素は並び替えられるみたいです.
```
import java.util.Arrays;
```
importが必要な点に注意。あとは
```
 Arrays.sort(Hairetu);
```
sortを使うと文字を並び替えられるようです。
## どうしても配列だけを使って要素をひとつだけ消したいとき
調べたところ、通常はlist型に変換して、必要な操作（今回は消す操作）してからまた配列に戻すといったことが必要なようです。
```
Hairetu[1]="Winter";
Hairetu[0]="December";
Hairetu[3]="Natuyasumi";//消したい
Hairetu[4]="Kotatu";
```
それでも、どうしてもListを使いたくない！という人がこの世のどこかに一人くらい入ると思います。そんな人のために、ここまで学んだ知識を生かして途中の要素を消すものを作ってみました。多分動きます。自分は動きました。
```
public class B {
    public static void main(String[] args){
         String[] Hairetu=new String[4];
         String[] HairetuB=new String[Hairetu.length];
         int DelNumber=0;
        Hairetu[1]="Winter";
        Hairetu[0]="December";
        Hairetu[2]="Natuyasumi";//消したい
        Hairetu[3]="Kotatu";
        for(int i=0;i<Hairetu.length;i++){
            if(i==2){
                //消す
                DelNumber++;
                continue;
               
            }
            
            HairetuB[i-DelNumber]=Hairetu[i];
        }
        
       Hairetu=new String[HairetuB.length-DelNumber];
       System.arraycopy(HairetuB, 0, Hairetu, 0, Hairetu.length);
       for(String j:Hairetu){

        System.out.println(j);
    }

    }
}
```
配列を二つ使ったやり方です。元の配列で2つ目が消したいときのやつです。
for文でコピー先にコピーしながら、コピーしたくないやつの処理を飛ばしています。飛ばしたままにするとnullが入ってしまうので、ずれた分を補正(今回は「DelNumber」という名前のint型)を使ってずれを補正しています。このままでもいいのですが、最後に元の配列の長さを今の長さに戻して入れなおしています。
こんな感じでも行けます。が、おとなしくListを使った方がいいような気もします。
ちなみに、頑張れば要素を上書きされずに一つずつずらしながらねじ込むこともできそうです。
# まとめ
配列は空いている場所に要素を入れることはできるが、空いていないと入れるのは難しい。また、消すのも簡単ではな。ただ、コピーはできるし、Listに変換もできるため、いざとなったら変換していい感じに使えばいい。
参考文献

https://magazine.techacademy.jp/magazine/19079

https://www.sejuku.net/blog/14461

https://www.javadrive.jp/start/array/index4.html