OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby 小数点の計算結果の誤差について

## なぜ小数点の計算結果は誤差が生じるのか
```
x = 122 * 1.1
puts x
#出力結果は134.2000000000002となる
```
実際に計算をしてみると計算結果は「134.2」となります。
なぜ、このような間違いが起きるのでしょうか？
コンピューターが2進数であることに起因しているようです。

引用
数値として2進浮動小数点数が用いられる場合
定数を10進表記で表していても内部では2進数で処理される
有限の2進数で小数を表した場合の計算は、常に誤差を伴いうる
と言うことを覚えていただいた方が良いでしょう。
引用元
https://ja.stackoverflow.com/questions/49377/javascript%e3%81%ae%e6%8e%9b%e3%81%91%e7%ae%97%e3%81%ae%e7%b5%90%e6%9e%9c%e3%81%8c%e8%a8%88%e7%ae%97%e6%a9%9f%e3%81%ae%e7%b5%90%e6%9e%9c%e3%81%a8%e7%95%b0%e3%81%aa%e3%82%8b%e3%81%ae%e3%81%af%e3%81%aa%e3%81%9c%e3%81%a7%e3%81%99%e3%81%8b/49380#49380

## 解決法
```
x = 122 * 1.1.rationalize
puts x.to_f
#出力結果は134.2となる
```
.rationalizeを使うことで有理数に変換することができます。
```
1.1.rationalize
#返り値は11/10となる
```
小数点の出力結果が欲しいので
.to_fのfloat型（小数型）にもどします。
以上の2点をすることで求めている答えになります。
BASICって何だ！

# BAISCは
Beginners' All-purpose Symbolic Instruction Code
の略でこれを和訳してみると
「初心者向けの汎用シンボリック命令コード」と訳される
初心者向けのプログラミング言語で通常はインタープリタで供給される。

# なんで初心者向けか？
1980年ごろのPCは、BASICインタープリタを搭載したパーソナルコンピュータが一般的だった。
（ちょっと脱線）
このベーシックを供給していたのがマイクロソフトで、パソコンを操作するための言語を乗っけていた。この頃からやっぱりパソコン基本ソスとはマイクロソフトだったりする。

で、なんで初心者向けかというと今の言語に比べると単純であることが１つ挙げられる。
現在の言語は、多くの場合オブジェクト指向と呼ばれる概念が取り入れられているが、そのような概念がなく行番号の順に書かれている構文を解析して順次実行されるようになっているのみで複雑ながいねんが無いので理解しやすい言語です。

# BASICの欠点
BASICの欠点は、大きなプログラムを書く際に以下のようなことが起きました。
プログラムを作る際には、必ずいろいろなデータを保持するため、変数を使いますがプログラムが大きくなるとこの変数につける名前がかぶってしまう、という問題が置きました。

# なので・・・
BASICは初心者向けの言語だけど大きなプログラムを作るには向かない！
ということが言えます。

このようなことを防ぐために構造化という概念が取り入れられ、そのご構造化されたデータを扱うためのメソッドと呼ばれるカプル化された構造の中で実行される処理コードが追加された事でオブジェクト指向につながっていきます。
構造化の概念やオブジェクト指向という概念は、結構理解するのが難しい概念であるためそのような概念がないBASICは理解しやすい言語と言えます。
PostgreSQLにprismaで接続できなかった時の対処法


## はじめに

Next.jsでPrismaを使ってPostgreSQLに接続する際にハマったポイントと、その解決法について紹介します。

## 環境

- Next.js v14
- Prisma 5.16.0
- PostgreSQL

## 問題の概要

以下の通り、Prismaを使ってPostgreSQLに接続しようとしたところ、接続エラーが発生してしました。


```prisma:schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

// その他のスキーマ定義...
```


```env:.env
DATABASE_URL='postgresql://postgres.*******:P@ssword@aws-0-ap-northeast-1.***.***:****/***'
```

```:エラーメッセージ
PS C:\Users\USER\Dev\*****\*****> npx prisma db push
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "*****.********.***:****"

Error: P1001: Can't reach database server at `*****.********.***:****`

Please make sure your database server is running at `*****.********.***:****`.
```

## 対処

エラーコードをGithub Copilotに投げる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725241/810979cf-4ab1-2743-b8db-1b11209c5b68.png)
指示に従って設定を確認するも効果なし

パスワードを変更したら治った＜＜なぜ？

## 今回の原因と解決方法

今回の問題は、パスワードに`@`が含まれていたために発生しました。この場合、接続文字列が正しく解析されずにエラーが起こります。
URLエンコードでこの問題を解決しようとしましたが`@`のエンコード値である`%25`はそのまま認識されてしまうので、この問題をURLエンコードで解決することはできません。
唯一の解決策(多分)は、データベースのパスワードを変更することです。
【Ruby】RubyMineでRubyのバージョンを変えるときには気をつけろー！

どうもこんにちは。

今回は、RubyMineでRubyのバージョンを変えたいのに変わらない問題の原因がわかったので紹介します。

https://scrapbox.io/siroemk/RubyMine%E3%81%A7rbenv%E3%81%8C%E5%8F%8D%E6%98%A0%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E4%BB%B6

# 何が起きていた？

`bundle install`を実行したかったのですが、バージョンが違うよとエラーが出てきてしまいました。

```sh
% bundle install
Your Ruby version is 2.7.6, but your Gemfile specified 3.2.2
```

確認すると、`2.7.6`を使用している状態となっていました。

```sh
$ rbenv versions
  system
* 2.7.6 (set by RBENV_VERSION environment variable)
  3.2.2
  3.2.3
  3.3.0
```

`3.2.2`を使用したいので、以下のコマンドを叩きます。

```sh
$ rbenv local 3.2.2
```

結果は？

```sh
$ rbenv versions
  system
* 2.7.6 (set by RBENV_VERSION environment variable)
  3.2.2
  3.2.3
  3.3.0
```

変わらないやなかい！

# 調べてみると...

調べてみると、RubyMineでは**ターミナルは`rbenv shell`でバージョンを使って起動している**らしいです。なので`rbenv local`が効かないんだとか。

ということは...

こうすればいいんじゃないか？

```sh
$ rbenv shell 3.2.2
```

果たして結果は...

```sh
% rbenv versions   
  system
  2.7.6
* 3.2.2 (set by RBENV_VERSION environment variable)
  3.2.3
  3.3.0
```

おぉーーーー!

無事に`bundle install`も実行されました！

以上
json_encode($example);（←何故か変換できない）

# 何故か変換できない

ひゃっはー、php8.1でenum使えるようになっとるやん。
早速、使ってみたろ…。

いやぁ、見事にハマりました。
エラーも出ないし、ネタっぽいですがマジで何故か変換できないですｗ
割と、ハマりどころな可能性もあるのでメモを残しておきたいと思います。

## 兎にも角にも問題のコード

```php
enum Type {
    case A;
    case B;
}

class Example {
    public Type $type;
    public string $id;
    public string $name;

    public function __construct(Type $type, string $id, string $name) {
        $this->type = $type;
        $this->id = $id;
        $this->name = $name;
    }
}
$example = new Example(Type::A, "test name", "test id");
echo json_encode($example);
// 期待する出力
// {"name":"test name","id":"test id","type":"A"}
```

ここのハマりどころは、json_encodeが文句を言わないところです。
enumが変換出来ていない事に気づくには、小一時間かかりました。(結構複雑なコードだったので除外するのに時間が掛かった)
そして、サンプルコードを準備してclaudeに質問するズバリ解決方法を教えてくれました。

## 結論、enumはそのままでは変換できない

コードの問題は、enumのエンコードらしいので、以下の様にJsonSerializableを実装する必要があるようです。
知らなければ対処不能ですね。

```php
enum Type implements JsonSerializable {
    case A;
    case B;

    public function jsonSerialize(): mixed {
        return $this->name;
    }
}
```

## 超個人的な雑談と感想

仕事で結構、生成AIを利用するようになりました。
色んな生成AIありますが、私が主に利用しているのは、Claude, ChatGPT, Geminiです。
今年にはいってから、ハルシネーション問題も大分少なくなった気がするのは気のせいでしょうか。
ますます、仕事がはかどっちゃいますよね？

さて、そんな生成AIの個人的な感想を残しておこうかと思います。

２０２４年０６月の利用した無料版の生成AIの個人的な感想として
Claude > ChatGPT > Gemini
今月の回答精度は、ChatGPTよりClaudeが良かった感じです。

ちなみに、２０２４年０４月の利用した感想は
ChatGPT > Claude > Geminiでした

※あくまでもこの感想は、コード生成の結果のみのことなので他の生成物に関しては別の感想を持つ可能性があります。
AWS CodeBuildで「error parsing HTTP 403 response body: unexpected end of JSON input: “”」が発生したときの解消方法

## はじめに

CodeBuildで見たことがないエラーを発見したのでメモ

「error parsing HTTP 403 response body: unexpected end of JSON input: “”」の解消方法をメモします。

## 発生タイミング

AWS CodeBuildでECRから取り出したイメージをベースイメージとしてビルドして他のECRにイメージをpushしようとした際に発生した。

```text
[Container] 2024/06/28 09:15:23.085024 Running command docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
The push refers to repository [{AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image]
afd960e1af2e: Preparing
8b81268b176d: Preparing
2e78ae41ac62: Preparing
error parsing HTTP 403 response body: unexpected end of JSON input: ""

[Container] 2024/06/28 09:15:25.142451 Command did not exit successfully docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG exit status 1
[Container] 2024/06/28 09:15:25.148466 Phase complete: POST_BUILD State: FAILED
[Container] 2024/06/28 09:15:25.148486 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG. Reason: exit status 1
```

## 解消方法

CodeBuildのサービスロールに以下の権限を追加します。

```text
ecr:BatchCheckLayerAvailability
```

IAMポリシーの実装例

`Resource`セクションにはpush先のECRリポジトリを指定します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ecr:BatchCheckLayerAvailability"
            ],
            "Resource": [
                "arn:aws:ecr:ap-northeast-1:{AWS_ACCOUNT_ID}:repository/test-image"
            ],
            "Effect": "Allow"
        }
    ]
}
```

## 再実行して動作確認

```text
[Container] 2024/06/28 09:18:17.185879 Running command docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
The push refers to repository [{AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image]
afd960e1af2e: Preparing
8b81268b176d: Preparing
2e78ae41ac62: Preparing
afd960e1af2e: Layer already exists
2e78ae41ac62: Pushed
8b81268b176d: Pushed
latest: digest: sha256:74c1326b79e7654abf2a0aa4ef5865abea07c9c0fbf38f148b3fe9dcf3cb9c60 size: 949

[Container] 2024/06/28 09:18:37.971738 Phase complete: POST_BUILD State: SUCCEEDED
```
初学者Webエンジニアが1ヶ月半でCCNAを合格するまでの修行録（ほぼ精神論）

初学者WebエンジニアがあるきっかけでCCNA（ネットワーク試験）を受けることとなり、1ヶ月半の修行を経て無事合格するまでの体験談です。
コツというコツはあまり共有できてないですがよかったら参考にしてください（脳筋系です）

### CCNA概要
CCNAとは、ネットワーク関連機器の世界最大手である「シスコシステムズ社」が実施する資格試験のひとつです。
基礎的なネットワーク、シスコシステムズ社の製品（Ciscoルーター、Catalystスイッチなど）に関する知識を問う試験であり、世界中のネットワークエンジニアが取得しています。

### WebエンジニアがCCNAを学ぶメリット
Webエンジニアとネットワークエンジニアとでは技術領域が大きく異なります。
Webエンジニアとしては一見無駄なようにも思える学習ですが、実際に学習をしてみて感じたメリットもあります。
* TCP/IPなどインターネット通信技術に関する基礎的な知見が得られる
* Webエンジニアとして案件獲得の間口が少し広がる
* 基本情報技術者試験と比べて資格保持者が少なくちょっとかっこいい

どれも必須なメリットばかりではないですが、Webエンジニアとしての学習を重ねつつネットワークの勉強も少し頑張ればライバルたちに一歩差をつけられるかも（なんせ1ヶ月半で取れますからお得です！）

### 学習スケジュール
1ヶ月半で合格するための具体的な学習法とスケジュールに関しては以下のような感じです。

#### 0~2週間目

https://www.udemy.com/course/ccna-full/

CCNAの学習教材というと白本などが有名ですが、私としては断然動画教材をオススメします。

この2週間での目標は、とにかく大雑把に全ての範囲に目を通すことです。
満員電車でも、入浴中でも、トイレ中でもとにかく暇さえあれば動画を視聴してください。音声のみでも意味は十分あります。
理解が追いつかない項目があっても構わず先に進んでください（理解度が60％くらいあれば良いと思います）

（ネットワークエンジニアとして活躍していきたい場合は書籍を購入してより深い知識をつけるのも良いかもしれません）

#### 2~4週間目

https://mondai.ping-t.com/g

こちらのPing-tというCCNA受講者の中では大変有名な学習サイトでひたすら問題を解いていきます。

問題数がかなり多く、さらに初めは全く解けないと思います。（私は正答率20％ほどでした）

問題を解く→間違えた問題の解説をみる→次に進む
このルーティンをひたすら繰り返してください。
問題が解けずやる気をなくす苦行を2週間ほど続け、4週目に入る頃急に正答率が爆上がりするタイミングが来ます。（この期間が一番辛いですが修行です耐えてください）

というのも莫大な暗記を強いられるCCNAですが、問題の傾向としてはそこまでパターンはありません。
何度も問題を解いているうちに似たような問題に遭遇しまくるはずです。
似た問題で正解できて嬉しい！似た問題でまた間違えて悔しい！という体験で確実に記憶が定着していきます。

ここまでくれば最後の仕上げです。（Ping-tで正答率が85％くらいまでいけば次に行きましょう）

#### 4~6週間目

https://www.9tut.com/

この9tutという海外サイト、、ヤバいです。

CCNAの問題がまんま載っています。正直、ここに載っている問題を丸暗記すれば受かってしまうほどにまんまですが、しっかりとこれまでの手順を踏んで学習することをオススメします（CCNAに合格することだけが目的ではないはず）

最後の仕上げとしてこの9tutを利用してより本番に近い問題を解いていきます。
ここで9tut活用のコツがあるのですが次項に記載させていただきます。


### CCNA攻略のためのtips
ほぼ精神論になってしまったので
ここではそんな中でも少し有益な学習の際のコツというかマインドについて軽く触れていきます。

* 一周目で完璧を目指すな！

学習し初めは聞き慣れない用語ばかりで頭に入ってこないと思いますが、何となくで聞き流してOKです。
覚えようとしても正直厳しいです、、
重要な単語はのちに嫌というほど何度も目にすることになるので自然と理解していきます。

* Cisco語をマスターせよ！

CCNAを運営する Cisco社は海外企業ゆえに日本で実施されるCCNAの問題文には少しクセがあります。
これが結構厄介で、Ping-tなどで学習をした際には見覚えのない単語がやたらと出題され蓋を開けてみたら言い方違いの単語だったなんてこともあります。（イメージとしてはツールで無理やり翻訳した不自然な日本語）

この Cisco語を攻略するのにもってこいなのが前項で取り上げた9tutという学習サイトです。
手間ではありますが、9tut(英語)の問題をお好きなツールで翻訳するとかなりいい感じにCiscoナイズされた問題が完成します。
これを試験までの時間が許す限りひたすら解いていくと、試験本番にテンパるみたいなことにならず、非常にリラックスして実力を発揮できるはずです。

### まとめ
ここまで私のCCNA修行録をまとめてきましたが、ほぼ精神論になってしまいました。
もっと、具体的に「この分野は〜」とか「時間配分を〜」など共有できると良いのですが、正直1ヶ月半で合格するという短期目標のためには気合いしかないと思っています。
ひたすら問題数をこなして、同じ問題で何度も間違えてをどれだけ試験までに繰り返せるかな気がしています。

同じようなどなたかの多少の参考になれば幸いです。
Denoで型レベルプログラミングの単体テストを書く

# はじめに

Deno公式が公開しているライブラリ `@std/testing`で、Deno環境では型レベルプログラミングのユニットテストを書くことができると知ったので方法を共有します。  

手前味噌ながら型レベルプログラミングについては別の拙稿にて紹介していますのでご参照ください。

https://qiita.com/umiushi_1/items/4aa25df3343c5b2be62d


# 環境構築

Denoを利用できるセットアップが必要です。

https://docs.deno.com/runtime/manual/getting_started/installation

上記のページに従い、インストール等を行ってください。

# 作業ディレクトリを切る

```sh
# 各自の所定の作業ディレクトリから
mkdir deno-type-test
cd deno-type-test
deno init
```

```console
✅ Project initialized

Run these commands to get started

  # Run the program
  deno run main.ts

  # Run the program and watch for file changes
  deno task dev

  # Run the tests
  deno test
```

上記のように表示されればOKです。

ちなみにフォルダ内は以下のようになっています。

```console
.
├── deno.json
├── main.ts
└── main_test.ts
```

# 実際に型レベルプログラミングを行う

```ts:main.ts
/**
 * 型引数に配列を渡したときに、渡した要素の型を返す型レベルプログラミング.
 */
export type ArrayOf<T extends unknown[]> = T extends (infer E)[] ? E : never;

```

これに対するテストを書いてみましょう。まず、テスト用にパッケージを追加します。

`@std/testing`は[JSR](https://jsr.io/@std/testing)で公開されていますので、`deno add`コマンドで追加することができます。

```sh
# deno-type-testにいる状態で
deno add @std/testing
```

以下のように追加された旨コンソール表示されます。

```console
Add @std/testing - jsr:@std/testing@^0.225.3
```

# テストを書く

では実際にテストを書きます。
`@std/testing/types`の`AssertTrue`と`IsExact`を利用します。
`AssertTrue`は型引数の型がtrueかを判定します。
`IsExact`は二つの型引数を取り、それらが一致するかを判定します。

参考）

https://jsr.io/@std/testing@0.225.3/doc/types/~/AssertTrue

https://jsr.io/@std/testing@0.225.3/doc/types/~/IsExact


```ts:main_test.ts
import type { AssertTrue, IsExact } from "@std/testing/types";
import { ArrayOf } from "./main.ts";

Deno.test("ArrayOf", async (t) => {
  await t.step("Tがnumber[]のとき、型がnumberとなること", () => {
    type Expected = number;
    type Actual = ArrayOf<number[]>;
    type _ = AssertTrue<IsExact<Expected, Actual>>;
  });

  await t.step(
    "Tが(string | number)[]のとき、型がstring | numberとなること",
    () => {
      type Expected = string | number;
      type Actual = ArrayOf<(string | number)[]>;
      type _ = AssertTrue<IsExact<Expected, Actual>>;
    }
  );

  await t.step("Tが ('a' | 1)[]のとき、型が 'a'|1となること", () => {
    type Expected = "a" | 1;
    type Actual = ArrayOf<("a" | 1)[]>;
    type _ = AssertTrue<IsExact<Expected, Actual>>;
  });
});

```

# テストを実行する

```sh
# 所定のディレクトリ上で
deno test
```

```console
Check file:///path/to/deno-type-test/main_test.ts
running 1 test from ./main_test.ts
ArrayOf ...
  Tがnumber[]のとき、型がnumberとなること ... ok (1ms)
  Tが(string | number)[]のとき、型がstring | numberとなること ... ok (0ms)
  Tが ('a' | 1)[]のとき、型が 'a'|1となること ... ok (0ms)
ArrayOf ... ok (2ms)

ok | 1 passed (3 steps) | 0 failed (3ms)
```


以上です。
ただし、カバレッジは取れないようです。

# おわりに

今回はDeno環境で型レベルプログラミングの単体テストを書く方法について紹介しました。
上記の方法の場合はDeno環境に限定されますが、IsExactの実装は公開されていますし、LICENSEもMITとなっていますので、同様の型定義を利用してNode環境などでも型レベルプログラミングの単体テストを実施することが可能だと思います。

https://jsr.io/@std/testing/0.225.3/types.ts#L162

ちなみにJSRは(ESM前提なら)Node環境などにも依存関係として追加できますが、このライブラリはDeno環境での利用前提のためうまく動きません。
Select タグの初期選択値について

新人エンジニアの三上です。
今回は Option タグの初期選択値表示の際に気付いたことをまとめてみます。

## Select タグについて
select タグを使用することで、セレクトボックスを画面に表示し、選択した値を送信することができる。

（実装例）
```Vue.js
<form>
    <select>
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
</form>
```

## Option タグについて
select タグとともに使用し、セレクトボックス内の選択肢を実装する。
option タグの value がその選択肢の値を表す。

## 初期選択について
option タグ内の value と 対象 model の値が一致させることで、初期選択値を表示できる。
以下にサンプルソースコードを示す。

```Vue.js
<template>
    <form>
        <select v-model="sampleForm.sample">
            <option value="ABC">1</option>
            <option value="+ABC">2</option>
            <option value="AAA">3</option>
        </select>
    </form>
</template>

<script>
    const sampleForm = ref({
        sample: '+' + 'ABC'
    })
</script>
```
上記のサンプルのソースから表示されるセレクトボックスの初期選択値を表にまとめてみる。

|value|model|初期表示|
|:-:|:-:|:-:|
|ABC|+ABC|✖|
|+ABC|+ABC|●|
|AAA|+ABC|✖|

画面の表示としては、「2」が表示される。

## まとめ
model を使用した Select の初期選択を実装するためには、model の値と value の値を揃える必要がある。
セレクトボックスの初期表示が想定通りにならない場合、この2つが不一致となっている可能性がある。
今回のサンプルのソースで言えば、「+」を消すことで初期表示が異なる。
value に合わせて、model を修正することで任意の選択肢を初期表示することができる。

以上、三上でした。
Renovateでサポート外マネージャのバージョン管理をする

こんにちは、サーバエンジニアの池脇と申します。

私の担当プロジェクトではRenovateを使って依存関係のあるパッケージのバージョン管理を行なっています。
ところが全てのパッケージがRenovateに対応しているわけではないため、対応外のパッケージが更新されると自動生成時にバージョン更新が入ってしまいノイズになってしまうことがありました。
今回はそのノイズを抑制するためにRenovate対応外のパッケージをバージョン管理できるようにします。

## Renovateとは

https://docs.renovatebot.com/

上述の通り、プロジェクト内の依存関係にあるパッケージのバージョン管理を自動で行ってくれるツールです。自動マージも可能ですが、弊プロジェクトではPRを作成し確認後にマージする方式で運用しています。
以下のような状況を解決する手段として有用です。

- ライブラリが古いバージョンのまま運用され、固定されがちである
- 定期的にバージョンを手動でチェックして更新している

## Renovate対象外のバージョン管理はどうやるのか？
最初に書いた通り、今回はRenovateに対応していないパッケージのバージョン管理を行います。(今回Renovateの使い方については解説しないため、気になる方は公式等をご確認ください)
どのように対応するのか、まずは実際の管理対象(`buf.gen.yaml`)と設定ファイル(`renovate.json`)から抜粋したものをご覧ください。

```yaml
version: v1
plugins:
  - plugin: buf.build/protocolbuffers/go:v1.34.1 # renovate: depName=protocolbuffers/protobuf-go
    out: generated
  - plugin: buf.build/connectrpc/go:v1.16.2 # renovate: depName=connectrpc/connect-go
    out: generated
  - plugin: buf.build/bufbuild/validate-go:v1.0.4 # renovate: depName=bufbuild/protoc-gen-validate
    out: generated

buf.gen.yamlから抜粋
```

```json
  "customManagers": [
    {
      "customType": "regex",
      "fileMatch": ["^buf.gen.yaml$"],
      "matchStrings": [
        "- plugin: buf\\.build/(.*):(?<currentValue>[^\\s]+) # renovate: depName=(?<depName>[^\\s]+)"
      ],
      "datasourceTemplate": "github-releases"
    }
  ]

renovate.jsonから抜粋
```
今回はProto APIマネージドツールである「[Buf](https://github.com/bufbuild/buf)」のプラグインのバージョンをRenovateで管理します。
もちろん既存では対応していないファイル形式であるため`customManagers`を利用して対応します。

https://docs.renovatebot.com/modules/manager/regex/

今回使用している`customManagers`の各オプションについては次の通りです。
- `customType`
  - `regex`固定
  - 指定せずとも動くが警告が出るので設定しましょう
- `fileMatch`
  - 必須オプション
  - 管理対象にしたいパッケージのバージョンが記載されているファイルの名前を指定
- `matchStrings`
  - 必須オプション
  - 正規表現で管理対象にしたいパッケージのバージョンが記載されている文字列を取得
  - 名前付きのキャプチャ(`<currentValue>`や`<depName>`)を使用
  - `<currentValue>`については必ず含める必要がある
  - `<depName>`は`datasource`で参照する名前をキャプチャする(今回はGitHubのリポジトリ名)
- `datasourceTemplate`
  - `matchString`で`datasource`をキャプチャしていない場合にこちらで指定
  - 今回は`github-releases`を参照していますが、`npm`等、自分の参照したいもの記載

上記の例のように記載することで該当するGitHubリポジトリを参照してBufプラグインのバージョンを管理することができます。

![スクリーンショット 2024-06-28 16.39.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/f2565a4a-8ab0-9ea9-6bac-4a39d14e4a3e.png)
Renovateが自動的に作成しているIssueにも反映されていることが確認できました！

## まとめ
今回はRenovateでサポートされていないパッケージのバージョン管理を行う方法をご紹介しました。
`customManagers`を使うことで色々なファイルに対応可能なので、バージョン管理にお困りの方は是非試してみてください。

以上、池脇でした。

## 参考
- [Renovateってなぁに](https://zenn.dev/takamin55/scraps/87bcceca29364a)
- [Renovateで正規表現を使い独自フォーマットファイルの依存を自動更新をする](https://swfz.hatenablog.com/entry/2020/06/09/031148)
超初心者コード

# 初心者の私が変なコードを作ってみた
初心者の私が、コードを作ってみた。
スパゲティコードなので、あまり参考にしないでほしい。
## 経緯
ツイッターをなんとなく見ていると、何か作りたくなったから。
以下はコードである。

```c#
using System;
//ク*データ
namespace prb_data
{
    static class Programs
    {
        static void Main(string[] args)
        {
            Console.WriteLine("これは3より大きい?(3を含めないよ!)"); //記述の通り
            while (true) //処理ループ
            {
                try //妥当な場合
                {
                    int a = int.Parse(Console.ReadLine());
                    if (a > 3) //3より大きいデータの場合
                    {
                        Console.WriteLine("大きい");//大きい場合の文
                        Console.WriteLine("終了"); //終了した際の文
                        break; //終了
                    }
                    else //3以下の場合
                    {
                        Console.WriteLine("小さい"); //小さい ループの最初へ戻る
                    }
                }
                catch //不当な場合
                {
                    Console.WriteLine("エラー!"); //エラー文を表示する ループの最初へ戻る
                }
            }
        }
    }
}
```
# 結果
4以上であれば、終了する。
このように3未満であれば小さいを返し、ループに戻る。
また文字などを入力するとエラーを返し、ループに戻る。

## 総評
0点だと思う。
修正点があれば、ご教示ください。
よろしくお願いします。

## 最後に
投稿するのがはじめてなので、色々汚いですがご了承ください。
最後までご覧いただき、ありがとうございました。
エンジニアにコミュニケーション能力って必要？？

## 自己紹介
まず初めに軽く自己紹介をさせて頂きます。

株式会社PRUM営業の赤坂留莉子(29)です！

前職は別業界だったので、
IT未経験で2023年9月、弊社に入社しました:pray_tone3:

## 今回はエンジニアにコミュニケーション力は必要なのか？
についてお話ししたいと思います。

結論からお話しさせていただくと、めちゃくちゃ必要です。

そんなんわかってるよ！当たり前や！と思う方ばかりだと思うのですが、
意外と出来ていないこと多かったりするんですよね。。。

あと、仕事をする上ではもちろん必要なのですが、
プライベートでも役に立つので、当たり前のことを当たり前にする。ということを
もう一度振り返ってみてみてください😊

## 具体的に何が必要なんだ？

①相手に興味を持つ

まず相手のことを知りたいですよ。と示すことが大切で、

・相手が話をしているときは、相手が話を終えるまで聞く
・相手が話している内容に対して興味を示し、共感する
・相手の話を肯定する

上記３つを気をつけていれば、
相手はちゃんと聞いてくれている。わかってくれた！！
と嬉しくなります:blush:

②表情や目線、相槌にも気を付ける

話を聞きながら顔が怖くなってませんか？
相手の目や顔をみて話を聞けていますか？

目線が色々な所を見ていたりすると、聞いているのかな？という印象を持たれてしまったり、
顔が無表情だったら、何考えてるかわからない人。みたいな印象になりかねないです・・。

少し意識するだけですぐに変えることが出来るので
意識してみてください。

③ミラーリング

これは、相手の動作を鏡のように真似をする。
というコミュニケーション手法です。

手の組み方からお茶を飲むタイミングまで、相手のすべての行動が対象になります。 
ただやりすぎるとこの手法を知っている方だと、時に不快感を与えてしまいます。
そこだけ注意しましょう。

共通点を探すや共通の話題が一番良いかもしれないです。


以上です。
上記３点を気を付けるだけで、コミュニケーション能力がかなり上がるので
再度気をつけてみてください。:relaxed::thumbsup_tone3:


## 最後に

>人間関係とは自分を映す鏡だ。
だから、素敵な人と出会いたいなら、まずは自分が素敵な人にならなければいけない。
いい仕事場で働きたいなら、まずは自分がいい仕事ができるようにならなければいけない

メンタリストDAIGOが言っていた私が大好きな言葉です。
本当にその通りだと思うので、
みなさんもより素敵な人、コミュニケーション力のある人を目指して
頑張りましょう:muscle_tone5:
X（旧Twitter）での正しいAltタグのつけ方

Altタグというのは、代替テキストであり、視覚に障害がある人など、多くの人が情報にアクセスするための手段である。

Web製作の場面では「SEO対策（検索件数の上位としてヒットすること）」として紹介されていることが多いが、やっぱり、本来的にはいろいろな人がWebにアクセスして適切に情報を得られるようにするためのものである。

Ｘの投稿画像にも、Altタグをつけることができる。
（「説明を追加」がそれだ。）

# 画像に説明を追加する

画像を投稿する前に……。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/abcf8c1f-b40a-63f0-e370-88c308ad9eb8.png)


「📝件の説明を追加」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/812b5109-d33b-8708-417b-e8f9704b57c5.png)

説明を書く。
（よく見ると一筆書きというのは不正確で、一筆書き「風」である）

「代替テキストとは？」ではこう説明されている。

>説明を追加
目が不自由な利用者も含め、多くの利用者が画像を理解できるように説明（代替テキストとも呼ばれます）を追加できます。簡潔にすることをおすすめしますが、画像の前後関係をよく理解できるように画像の内容を正確に説明してください。

（参考）わかりやすい記事。

https://qiita.com/silane1001/items/3c61627a098725a83866

これはポストに収まらない小説を書いたり、AI生成画像のプロンプトを書いたり、素材の権利表記をする欄ではない。

とはいいつつ、俺も日常のポストではわざわざやらないのだが（なんか、余計な欄があると、ただのアイスクリームに「世界一おいしいアイスクリーム」、なんてボケをかましそうになる……。ただ「サーティワンのアイスクリーム」と書いてあったほうが本来的だ）、妙な事を書くよりはないほうが心証はよいと思う。

あったほうが間違いなくいい。

Xでは、公式アカウントでここまでやっているのはかなり希少。

やっぱり、この欄を拡張スペースとして使うのは、切実にそれを必要としている人を横目に便利な棚だと思っていろいろ邪魔なものを置いてしまうような行為ではあると思うので、とくに企業の公式アカウントには、間違った使い方（例：詳細はAltで！）はしてほしくないなーと思っている。

とくに、公的な、ニュース系のアカウントには気を使ってほしい。

あと、きちんとALTを使っているのを見るとすごくいいなと思うので、ぜひ広まってほしい。
広報的には、これをちゃんと使うと少ない労力でかなり差をつけられてよさそうである。ほんとに使ってるところは少ない。
AWSのリソースベースポリシーについて！！

# :one:はじめに
AWSにてCDK開発を行っていた際に、作成したリソースの連携が権限エラーで上手く動かないことがありました。調べてみるとリソースベースポリシーというものが関係しており、そこにたどり着くまでに、結構困らされました。
同じような方が増えないように、リソースベースポリシーについて解説してみようと思います。

## :two:リソースベースポリシーとは
ユーザーガイドによると・・・
> Amazon S3 バケットなどのリソースにアタッチする JSON ポリシードキュメントです。これらのポリシーでは、そのリソースに対して特定のアクションを実行するために指定されたプリンシパルのアクセス許可を付与するとともに、このアクセス許可が適用される条件を定義します。リソースベースのポリシーはインラインポリシーです。マネージド型のリソースベースのポリシーはありません

つまり、一般的なロールやユーザーに付与するポリシーではなく、リソースに対して付与するポリシーになります。
そして、付与したリソースに対して誰（何）からアクセスを許可するかを定義するものです。

## :three:実際にみてみる
EventBridgeRuleからLambdaを呼び出す例を見てみます。

### Lambdaを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/4fa75c06-ca4d-de83-cce9-179eeaf32136.png)

### EventBridgeを作成
先ほど作成したLambdaをターゲットとするEventBridgeRuleを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/2a1c6ba2-c199-5725-dca4-e798082d5e46.png)

### イベントを検知させる
正常に呼び出されることが確認できました。
EventBridgeにはLambdaを呼び出す権限がないのになぜ・・・？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/a31fd23f-b222-d681-a7e4-c2e32c09d1ec.png)

### Lambdaのリソースポリシーが設定されているから！
先ほど作成したLambdaを見てみるとリソースベースポリシーが自動で設定されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/007a97bd-2d36-e2e6-fd8e-0ae3514e9986.png)

### リソースベースポリシーを削除してみる
エラーメッセージを見るためにRuleにデッドレターキューを設定して実行してみました。
権限エラーが起きていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/e33ea2e7-b6fa-0d3b-8f43-8083a40baaa2.png)

## :four:つまり・・・
一部リソースでは、リソースベースポリシーが無いと正常に動かないものがあり、コンソール上の作業では自動的に適切なポリシーが付与されるものもあります。
そのため、あまり意識してこなかった部分でしたが、CDKでは明示的にこのリソースベースポリシーを作成しないといけないわけです！
リソースベースポリシーの設定があるかどうかは以下サイトから確認が可能です。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/79f15c12-36f4-4ae8-22e6-ee93a325ecfc.png)

## :five:さいごに
適切な権限設定しているはずなのに(本当はできていない)動かないってときは、リソースベースポリシーが原因かも:spy:
aws test

https://www.bing.com/spotlight?spotlightid=DS_SeaTurtleLadyElliott&setlang=ja-jp&mkt=ja-jp&q=%E3%82%AF%E3%82%A4%E3%83%BC%E3%83%B3%E3%82%BA%E3%83%A9%E3%83%B3%E3%83%89%E5%B7%9E%E3%83%AC%E3%83%87%E3%82%A3%E3%83%BC%20%E3%82%A8%E3%83%AA%E3%82%AA%E3%83%83%E3%83%88%E5%B3%B6%E4%BB%98%E8%BF%91%E3%81%AE%E3%82%A2%E3%82%AA%E3%82%A6%E3%83%9F%E3%82%AC%E3%83%A1%E3%80%81%E3%82%AA%E3%83%BC%E3%82%B9%E3%83%88%E3%83%A9%E3%83%AA%E3%82%A2&carindexpill=0&carindeximg=0&textorimgcar=text&isfullscreen=true&carscrlimgv2=0&form=SLVFUL&ssid=NONE&trsid=NONE&chevclk=false
Debian 12 ゲストマシンに VirtualBox Guest Additions をインストール

# 環境

- Debian 12 ( gnome ) Stable
- VirtualBox 6.1.48_Ubuntu r159471


# Guest Additions CD

「Guest Additions CD イメージを挿入」として、 CD をマウント

 ファイルマネージャから開くと VBoxLinuxAdditons.run が見える。これをダブルクリックして実行。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fcc7cd43-60ff-4489-57c6-bd97a9112ed7.png)

# エラー

以下のようにエラーが出る。

```

Verifying archive integrity... All good.
Uncompressing VirtualBox 6.1.48 Guest Additions for Linux........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: S etting up modules
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Kernel headers not found for target kernel 
6.1.0-21-amd64. Please install them and execute
  /sbin/rcvboxadd setup
VirtualBox Guest Additions: Running kernel modules will not be replaced until 
the system is restarted
```

エラー対処。以下のようにして Kernel headers をインストール。

```
# uname -r
6.1.0-21-amd64
# apt search linux-headers-$(uname -r)
Sorting... Done
Full Text Search... Done
linux-headers-6.1.0-21-amd64/stable-security 6.1.90-1 amd64
  Header files for Linux 6.1.0-21-amd64

# apt install linux-headers-$(uname -r)

```


再度 VBoxLinuxAdditons.run を実行して再起動
新人エンジニア、主キーとインデックスの区別がついていなかった件について

### 主キーとインデックスって違うらしい

「主キーとインデックスは全く別物でした！」という、少し考えれば当たり前のことを言うための記事です。

…でも、本気で同じだと思っていたんです。初学者の思い込みって怖い。

ということで、「なんで勘違いしちゃったのかなー？」というところまで含めて、書けたらいいなと思います。

### 気づいたきかけ~ITパスポートの過去問〜

きっかけは、こちらの[ITパスポートの過去問](https://www.itpassportsiken.com/kakomon/25_aki/q51.html)です。

問題：関係データベースの表に設定する主キー、外部キーおよびインデックスのうち、１つの表に対して複数設定できるものだけを全て上げたものはどれか。

![スクリーンショット 2024-06-27 18.54.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638231/2909b8ac-7f65-f6ee-728f-c2f560d33216.png)


…え？主キーとインデックスって同じじゃないの…？と思って、調べてみました。

### 主キーとインデックスの違い

調べ始めたら、すぐ先人に出会いました。混乱しちゃってたの、自分だけじゃなかったみたい！よかった！（まとめてくださりありがとうございます🙇‍♀️）

https://qiita.com/pirorirori_n712/items/b47ade3fdaf8b4a109ba

上の記事で、重要なことは書いてくださっているのですが、改めてまとめるとこういうことみたいです。

主キーとは、

- PRIMARY KEY制約を設定して作られたカラムのなかのデータのこと
- レコードがテーブル内で一意であることを確定させるためための役割
- 重複とNullが許されない

インデックスとは、

- 検索を速く容易にするために、任意のデータに貼り付けるもの
- 検索アルゴリズムに適したインデックスを貼る必要がある

なるほど、主キーが「テーブル内でデータを一意に確定させる」ために存在しているのに対して、インデックスは「素早く検索するためにデータに貼る添字」としての役割をしているのですね。

両者は全く違うもののようですが、なぜ主キーとインデックスが同じものだと勘違いしていたのでしょうか。実は、主キーを作成すると、自動的にインデックスが貼られるそうなのです。加えて、初学者が作成するアプリケーションでは、データの検索アルゴリズムで主キーを使うことが多いので、主キーとインデックスを混同したり、はたまた主キーをインデックスと呼んでしまったりするのかもしれません。

### 色々なインデックス方式

主キーとインデックスの違いがわかったところで、インデックスについてもう少し深ぼってみました。

インデックスの役割は「検索を容易にするための添字」でしたが、インデックスの貼り方にもいくつかの種類があるようです、

- Bツリーインデックス

いわゆる「木構造」でデータが整理されています。階層的になっているため、データの検索が素早く行えます。

- ビットマップインデックス

ある値が存在するか否かを、0,1で表現する方法です。ユニークな値が少ないカラムに向いています。検索対象の値が多いカラムでは、ビットが多くなりすぎて、検索に時間がかかってしまいます。

- ハッシュインデックス

検索対象の値をハッシュ化した値をインデックスとして用います。例えば、date型で日付を含んだ値から特定の月のデータのみを抽出したいとき、月単位でハッシュ化してインデックスとして用意しておくと、バラバラの日付から探索するよりも、容易に目的のレコードを集めることができます。

### まとめ

まだまだ、雰囲気でわかった気になっている概念や言葉がたくさんありそうです。初学者的な浅く広くの学習に加えて、時には丁寧な勉強も必要そうです。
JavaScriptでオセロを作った(オブジェクト指向)

まずはクラス図から。

![pLRFKji-4BxxANJu7SnWNe3v3GEajD2IbbAcJ8VX8DjRHnD5xaXo8CFmxjMkR6TTfoIvzK0iVVld-rPhhJbrNbhVB7II55ew9yvhQKlnaWXn92QWzSFZmwF84IJeVMCAhseZAl2Jnbem_aRB5TY9r3gNnNpeLSoagM23HrxN6gGHOCeFSW64NIn3jgaqiW8hW6t8Ii9kWp_OOBPn4KstZ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1445577/da65dd3f-c05d-8c75-6570-cc9cb2b54c3e.png)

進行を管理するGame, 盤面を管理するBoardとCell, ディスクの種類と状態を管理するDiskとDiskState, それを使うPlayer, 画面表示に関連するEventManager, BoardRenderer, ゲームのルールを司るRuleValidatorがあります。

HTMLとエントリーポイントのmain.jsはたったこれだけで記述できます。
```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.1/underscore-min.js"></script>
    <style>
      .othello td {
        width: 50px;
        height: 50px;
        background-color: greenyellow;
        text-align: center;
        vertical-align: middle;
        border: 1px solid #000;
      }
      .othello .black {
        background-color: black;
        border-radius: 50%;
        width: 30px;
        height: 30px;
        margin: auto;
      }
      .othello .white {
        background-color: white;
        border-radius: 50%;
        width: 30px;
        height: 30px;
        margin: auto;
      }
      /* マウスオーバー時のハイライト */
      .highlight {
        background-color: rgba(
          255,
          255,
          255,
          0.3
        ) !important; /* 半透明の緑色でハイライト */
      }
      /* 半透明の黒丸と白丸 */
      .black-highlight {
        background-color: rgba(0, 0, 0, 0.5) !important;
        border-radius: 50%;
        width: 30px;
        height: 30px;
        margin: auto;
      }

      .white-highlight {
        background-color: rgba(255, 255, 255, 0.5) !important;
        border-radius: 50%;
        width: 30px;
        height: 30px;
        margin: auto;
      }
    </style>
  </head>
  <body>
    <table class="othello" id="board"></table>
    <script type="module" src="./src/main.js"></script>
  </body>
</html>
```

```js
"use strict";
import { Game } from "./game.js";

// ゲーム開始
$(function () {
  const game = new Game();
});

```
https://github.com/paseri3739/othello
Dartの面倒な警告を自動で解決しよう

# こんなときありませんか？

Dartのコードを書いていて警告がでる。
例えばこんなとき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288957/9b139cfe-8830-3f73-cdb1-900fcfc65418.png)
```
info: Use 'const' with the constructor to improve performance. (prefer_const_constructors at [untitled] lib\main.dart:22)
```

パフォーマンスのためにconstをつけるといいよって警告がでる。
ありがたいんだけどね...
しかも大抵は一個だけじゃなく沢山ある...

# 使い方

## 修正内容を確認する
```Bash
dart fix --dry-run
```

## 一括で修正する
```Bash
dart fix --apply
```

実行すると警告が出ていたところにconstが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288957/b92b1022-809f-f062-b4d8-8e91e311ecc0.png)

# まとめ

dart fixはDartの警告のほとんど全部を自動で解決してくれます。
意外と知られていないのでぜひ使ってみてください！
エンジニアの人にスーツを好きになってもらいたい

突然ですが、皆さんはスーツって好きですか？
現在エンジニアの採用業務をしているのですが、スーツ嫌いで…というお話を聞くことも多く、元スーツ屋さんで働いていた私は少し寂しくも思っています。
（エンジニアでもたまにスーツを着ないといけない…なんて場面もあるかもしれません）
そんなスーツ嫌いな人にも、少しでもスーツのことを知って好きなってもらいたいな…という内容です。

## スーツの歴史

『元々は軍隊の戦闘服』
スーツ発祥の地はイギリス！

>もともとは農作業着だったスーツ
スーツの始まりは元々農民が来ていた農作業着あるいは、外出着でした。「フロック」と呼ばれたこの衣服は素材を上質化し、仕立ても洗練されていきました。そして、一般市民の外出着「フロックコート」に進化していきます。
フロックコートは軍人や貴族、航海士といったさまざまな職種に拡がり、動きやすいようアレンジされていったのです。現在でもスーツは、イギリス軍の将官の正装として使用されています。

>現在のスーツの原型は1848年頃に誕生した、「ラウンジジャケット」といわれています。ラウンジジャケットは、貴族の間で親しまれていた衣類とされています。そのため、スーツに対して品や格を感じる理由は”ココ”にあると考えられているのです。

現代ではスーツはビジネスマンの戦闘服とも呼ばれています。

## スーツは大きく分けて3種類に分類される

**1. ブリティッシュスタイル（イギリス）**
**2. イタリアンスタイル**
**3. アメリカンスタイル**
###


### 【ブリティッシュスタイルの特徴】
・かっちりスタイル
・他者への礼節のために装う（フォーマルな装い）
・肩にボリュームがあり、細身に見える効果
・重量感がある
（英国紳士ってやつですね！）

![front-view-confident-mature-male-posing 小.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803590/c2008d77-b907-f099-a406-077bb4316e86.jpeg)
著作者：<a href="https://jp.freepik.com/free-photo/front-view-confident-mature-male-posing_10145293.htm#query=%E3%83%B4%E3%82%A3%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B8%E3%81%AE%E8%8B%B1%E5%9B%BD%E7%B4%B3%E5%A3%AB&position=3&from_view=keyword&track=ais_user&uuid=170ad0e5-1af8-49e4-a4d5-351647f46f7e">Freepik</a>
###

### 【イタリアンスタイル】
・やわらかで、体に沿ったラインに沿ったシルエットの美しさ、エレガントさ
・肩から自然につながる様なナチュラルショルダーが特徴（肩パッドが薄め）
・生地も柔らかで軽やか
・Vゾーン深め

![スクリーンショット 2024-06-15 2.04.48 小.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803590/3b1fa290-6fea-6145-d99a-a22cfeca4c36.jpeg)

![full-shot-man-suit-working-stairs 小.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803590/3b656faa-d342-5071-0ab7-4f1eb5c5ba1e.jpeg)
<a href="https://jp.freepik.com/free-photo/full-shot-man-suit-working-stairs_5237470.htm#fromView=search&page=1&position=6&uuid=b7157f10-645c-4498-ba4d-01e184b3229f">著作者：freepik</a>
###
### 【アメリカンスタイルの特徴】
・ゆったりとしたシルエット
・機能性や動きやすさ重視
・フロントダーツをなくしてウエストのくびれを緩くしている
・量産型の大量生産でどんな体型の人でも似合うように

![スクリーンショット 2024-06-14 23.54.28 小.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803590/572ea3e3-d342-cf53-237e-ccd54beabb38.jpeg)


![stylish-young-businessman-standing-front-wallpaper 小.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803590/3dd42e09-6df0-b57a-57ab-848e4ff92ed4.jpeg)

好みのスタイルを見つけてみてください！

【参考記事】
https://www.ordersuit.info/info/article/etc/suit-history/
https://asm.asahi.com/article/12837263

## さいごに
採用業務に関わるようになり、身だしなみや第一印象ってやっぱり大事だなぁと思う今日この頃です。
お客様先で働く機会のあるエンジニアの方や、就職活動をしている方などにまずはスーツに興味を持ってもらえたらと思います。

:::note info
※弊社での面接はスーツでなくてもOKです！！
:::

##
PRUMのエンジニアの95%以上は、未経験からの採用です。
ぜひ、求人をチェックしてみてください！

▼ Wantedly求人
https://www.wantedly.com/companies/company_8173074

▼ コーポレートサイト
https://prum.jp/

VISION 『日本で一番エンジニアが成長する会社を創る』
OpenCVで作った画像をGStreamerでネットワーク送信する (C++バージョン）

OpenCVは言わずと知れたComputer Visionのライブラリ群ですが，画像・動画ファイルは作れてもストリーミング周りは弱いです（あるのかな）．それを補うためにffmpegやGStreamerと組み合わせる仕様ができていますが，いまいち使い方の文献が多くないように思います．

そこで本稿では，Windows, vcpkg, C++の環境下での実施方法についてまとめてみます．元は卒論指導用です．とりえあず細かいことは省略して書きます．追々詳細化します．

# 環境構築
1. Visual Studio 2022でC++によるアプリケーション開発をする環境を整えてください．
2. vcpkgを導入してください
2. vcpkgでOpenCVを入れます．つけるオプションは自由ですが，最低限，
    ```
    vcpkg install opencv4[gstreamer,ffmpeg]:x64-windows
    ```
    が良さそうです
4. 上の方法でOpenCVを入れると，gstreamerの1.22.5が入るようです（2024年6月28日現在）．この状態で入るGStreamerは各種プラグインなどが入っていないようなので，別にインストールし，環境変数(``GST_PLUGIN_PATH``)を設定する必要があります．このとき，**別にインストールするGStreamerとvcpkgでOpenCVとともにインストールされるGStreamerのバージョンが一致していないと，どうやらうまく動かないようです**．古いGStreamerは公式の[アーカイブ](https://gstreamer.freedesktop.org/data/pkg/windows/1.22.5/msvc/)からダウンロードできます．MSVCの方が良いみたいです．無印とDevelの両方を入れます．
4. GStreamerのインストールが完了したら，``GST_PLUGIN_PATH``を環境変数に設定します．私の環境では，``C:\gstreamer\1.0\msvc_x86_64\lib\gstreamer-1.0``でした．


# 動かしてみよう
[こちら](https://stackoverflow.com/questions/61394756/how-to-use-opencv-videowriter-with-gstreamer)のStackOverflowの回答を参考にしました．

``cv::VideoWriter``や``cv::VideoCapture``を使うようです．サンプルのように，``gst-launch-1.0``で記述するようなパイプラインを``.open``メソッドの引数に指定します．このとき，``appsrc``や``appsink``がOpenCVとの窓口になるみたいです．下のサンプルの場合は，``cv::VideoWriter``経由でフレームを書き込むと，``appsrc``に流れるようです．こちらが正しく実行できれば，下図のように``autovideosink``のウィンドウでOpenCVで作成したフレームが表示されます．

パイプラインを所望のシステムになるように構築するだけですから，ストリーミングでもファイル蓄積でも，簡単にできます．

```C++:OpenCV_GStreamer_sample
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{

    cv::VideoWriter out;
    out.open("appsrc ! videoconvert ! autovideosink",
        cv::CAP_GSTREAMER,
        0,
        16,
        cv::Size(640, 480),
        true);

    cv::Mat frame(480, 640, CV_8UC3, cv::Scalar(0, 255, 0));

    int count = 0;
    while(1)
    {
        rectangle(frame, Rect(0, 0, 640, 480), Scalar(0, 255, 0), -1);

        frame = Mat(480, 640, CV_8UC3, cv::Scalar(0, 255, 0));

        cv::putText(frame, to_string(count++), Point(100,100), FONT_HERSHEY_SCRIPT_SIMPLEX, 3.0, Scalar::all(255), 3, 8);

        out << frame;
        //imshow("sent", frame);        

        int c = waitKey(100);

        if (c == 'q')
            break;

    }

    return 0;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641672/fb8c48ba-0b8c-f3b2-e45d-14430bca469f.png)

# RTPストリーミングのサンプル（H.264エンコード）
``VideoWriter``の``.open``メソッドで指定するパイプラインをRTPでストリーミングするように変えてみます．こちらも先ほどのStackOverflowの回答を参考にしています．

```c++
    cv::VideoWriter out;
out.open("appsrc ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5000",
    cv::CAP_GSTREAMER,
    0,
    16,
    cv::Size(640, 480),
    true);

```

受信側は``gst-launch-1.0``を使って
```
gst-launch-1.0 udpsrc port=5000 ! application/x-rtp ! rtph264depay ! h264parse ! decodebin ! autovideosink
```

にして見ます．受信側から起動して，RTPストリーミング開始すれば，ローカルホスト経由ですが``autovideosink``のウィンドウで再生されました．

# まとめ
これは便利・・・．時間を見つけてもうちょっとちゃんと記事を書きます．あしからず．
Claude先生に日記を書いてもらった

Claude 3.5 Sonnetを今日初めて使いました。
生成AI系はちょっとだけChatGPTに質問したことがあるくらいのレベルです。
なので質問の仕方（プロンプト？）もぎこちない状態。

・アンソロピックについて
・Python、Anacondaについて
・MeCabについて
・Pythonでのスクレイピングについて
・SnowflakeとDatabricksの比較
・SnowPro Coreの勉強方法について
・サンフランシスコの治安について

こんなことを質問してました。
そして最後に、「今日質問したことを日記形式でまとめてください」と依頼しました。
その結果が以下のoutputです。
アンソロピックとスクレイピングについては省略された模様。

:::note info
2024年6月28日 金曜日

今日は多岐にわたる興味深いトピックについて学ぶ機会がありました。

まず、Pythonプログラミングについて深く掘り下げました。Anacondaを使用した環境構築から始まり、仮想環境の作成と管理について学びました。特に、仮想環境が他の環境に影響を与えずに独立して機能する点が印象的でした。

次に、自然言語処理に関連して、MeCabライブラリについて学びました。日本語の形態素解析において重要なこのツールの使用方法や、システムレベルでのインストールの重要性を理解しました。

データ可視化の分野では、Pythonを使用してワードクラウド画像を作成する方法について学びました。この技術を説明する際の効果的なアプローチについても考えました。

データプラットフォームの比較では、SnowflakeとDatabricksの違いについて学びました。それぞれの特徴や強みを理解し、用途に応じた選択の重要性を認識しました。

また、Snowflakeの認定資格であるSnowPro Coreの取得方法についても情報を得ました。効果的な学習戦略や利用可能なリソースについて理解を深めました。

最後に、サンフランシスコの治安状況について学びました。複雑な要因が絡み合う都市の安全性について、バランスの取れた見方を持つことの重要性を再認識しました。

今日学んだ多様なトピックは、技術からデータ管理、都市問題まで幅広い分野に及び、それぞれが深い洞察を提供してくれました。これらの知識を今後どのように活用していけるか、楽しみです。
:::

日記書けるじゃん。
Twitchの検索をカスタマイズしたい

## はじめに

その昔、Vueの勉強のついでに当時興味があったTwitch APIを利用してみようと思って触った遺産があったのですが、最近また勉強しようと思って掘り出しました。

本記事は、VueでTwitch APIを活用して検索機能をいじくるアプリケーションの雛形を紹介するていで次掘り返すときにすぐ再開できるようにする備忘録です。

## 実装

https://github.com/yus-sasaki/TwitchSearchService

[StreamsList.vue](https://github.com/yus-sasaki/TwitchSearchService/blob/main/project/src/components/StreamsList.vue)にTwitch APIを使って、ゲームタイトルを検索するとそのゲームを配信してるリストが表示されて、そこからさらにタイトルで検索できる非常に簡素な画面が実装してあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/d074db52-a094-0b01-5ae5-cdc9d2e7100d.png)

## Twitch APIの利用準備

Twitch APIを利用するには[Twitch API | Twitch Developers](https://dev.twitch.tv/api/)にアクセスして、登録し、クライアントIDなるものを取得した上でOAuth認証のアクセストークンの用意が必要です。

https://dev.twitch.tv/api/

取得した情報を[twitch_config.json](https://github.com/yus-sasaki/TwitchSearchService/blob/main/config/twitch_config.json)に入れるとそれをaxiosのヘッダに入れてAPIを利用するように実装してます。

## Twitch APIで何ができるか

基本は以下のリファレンスに各APIとその結果が書いてあるので、やりたいことを実現できるAPI探して利用すればOKです。現状のリポジトリで使っているAPIを紹介します。

https://dev.twitch.tv/docs/api/reference

### ゲームタイトルを検索する

[リファレンス](https://dev.twitch.tv/docs/api/reference/#search-categories)

[ソースコードでの利用箇所](https://github.com/yus-sasaki/TwitchSearchService/blob/main/project/src/components/StreamsList.vue#L86)

```
AxiosInstance.get('https://api.twitch.tv/helix/search/categories?query='+searchkey)
```
searchkeyにはテキストボックスで入力した内容が入り、検索に一致するゲームのカテゴリ一覧を返してくれます。

## Twitch APIで配信を検索する

[リファレンス](https://dev.twitch.tv/docs/api/reference/#search-channels)

[ソースコードでの利用箇所](https://github.com/yus-sasaki/TwitchSearchService/blob/main/project/src/components/StreamsList.vue#L102)

```
AxiosInstance.get('https://api.twitch.tv/helix/streams?game_id=' + this.selectCategory + '&type=live&first=100&language=ja')
```

this.selectCategoryには、先に検索しておいたゲームカテゴリ内で選択したカテゴリが入り、他にもオプションで配信中(type=live)、先頭から100件(first=100)、言語は日本語(language=ja)と指定しています。

```
this.channelLists = streams.filter(s => (s.title.indexOf(serchkey) != -1));
```

その結果をテキストボックスの内容でフィルタして検索しているのが、リポジトリのコードです。

## 他のAPI

大体画面で見えている情報は取れますが、気になっているのだとクリップも取れるので、気になったゲームのクリップなんかもタイトルで検索したりできそうです。

https://dev.twitch.tv/docs/api/reference/#get-clips
【ServiceNow】 新旧のUIを切り替える方法

## 概要
ServiceNowのUIがSan diegoから変更され、それ以前のUIとボタン配置や設定方法が異なるため、旧UIベースのドキュメントが使えなくなったり不便なことが度々発生しています。
そのため、UIを切り替える方法を記載しておきます。

## 前提条件
ServiceNow San diego以降

## 手順
### 1 [sys_properties.list]を入力してプロパティの一覧を表示する
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/d1f0e3a3-6324-da3e-a00a-522a1a9b2e3c.png)

### 2 [Name]が"glide.ui.polaris.experience"のプロパティを検索して表示する
![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/132b7e1d-6c5a-0947-52cd-b5a521fc6c85.png)

### 3 [Value]を"false"に変更する
![03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/6c461f34-96cc-4809-8867-a0c09f03311c.png)
![04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/6fa0b382-fd72-93c5-ad54-ac2163c88105.png)

### 4 ServiceNowを再度立ち上げると、旧UIが表示されます
![05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/e2275999-b7d0-f315-0f58-b1b7512f1bd4.png)

### 5 [Name]が"glide.ui.polaris.experience"のプロパティの[Value]を"true"に変更して、ServiceNowを再度立ち上げると、新UIに戻ります
![06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/dbaa3d3e-d729-99e4-43f9-9782c0f1f661.png)

![07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/2b98a5de-07d6-0e37-0eb9-54d197426ef1.png)

備考：再読み込みでもUIは切り替わりますが、新UI⇒旧UI の場合、アプリケーションナビゲーターが正しく表示されません。
![08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626186/4060be97-6b6d-fabd-c06c-36b883f0ed0d.png)
CodePipelineでECSに継続的デプロイメントがしたい

# はじめに
あるところにECS上で動いているWebアプリケーション（tomcat環境）がありました。
ソースコードはCodeCommitで管理されているようです。
CICDなるものに興味があった私は、変更がプッシュされたことをトリガーに最終的にECSで実行されているコンテナが置き換わり、変更が反映されるようにしてみよう思いました。

# やりたいことのイメージ
1. CodeCommitにプッシュでCodePipelineが起動
2. CodeBuildでDockerイメージを作成
3. DockerイメージをECRリポジトリにプッシュ
4. ECRリポジトリのイメージをもとにECSのタスク定義を更新
5. 新しいタスク定義を使用しECSクラスターのサービスを更新
6. コンテナの置き換えが発生

# ファイル群
```Dockerfile: Dockerfile
FROM tomcat:9
COPY ./WebContent /usr/local/tomcat/webapps/myproject
```

```yml: docker-compose.yml
version: '3'

services:
  appserver:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    ports:
      - 8080:8080

```

```yml: buildspec.yml
version: 0.2

phases:
  pre_build:
    commands:
      - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
  build:
    commands:
      - docker-compose build appserver
      - docker tag src-appserver $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
  post_build:
    commands:
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
      - printf '[{"name":"$ECS_CONTAINER_NAME","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest > imagedefinitions.json
      - |
        cat <<EOT > appspec.yml
        version: 0.0
        Resources:
          - TargetService:
              Type: AWS::ECS::Service
              Properties:
                TaskDefinition: "arn:aws:ecs:$AWS_REGION:$AWS_ACCOUNT_ID:task-definition/$ECS_TASK_NAME"
                LoadBalancerInfo:
                  ContainerName: "$ECS_CONTAINER_NAME"
        EOT
artifacts:
  files:
    - imagedefinitions.json
    - appspec.yml
```

# CodePipelineの設定

パイプラインの作成をしていきます。
buildspec.ymlで環境変数を使用しているので、パイプラインレベルで環境変数を定義しておきます。
- AWS_ACCOUNT_ID（アカウントID：12桁の数字）
- AWS_REGION（利用するリージョン）
- ECR_REPOSITORY_NAME（ECRリポジトリの名称）
- ECS_TASK_NAME（ECSタスク定義の名称）
- ECS_CONTAINER_NAME（タスク内で実行されるコンテナの名称）

## CodeCommit
ソースプロバイダーにCodeCommitを指定して、トリガーにしたいリポジトリとブランチを選択します。
その他の設定はデフォルトにしておきます。
## CodeBuild
ビルドプロジェクトを作成して、CodeBuildで指定します。
基本はデフォルト設定ですが、「buildspecファイルを使用する」を選択しておきます。
また、CodeBuildレベルでも環境変数を設定できるのですが、今回はパイプラインレベルで設定しているのでその値を利用します。

以下のように#{variables.AWS_ACCOUNT_ID}と記述することで、パイプラインレベルの環境変数の値を呼び出せます。

（例）
名前　AWS_ACCOUNT_ID　値　#{variables.AWS_ACCOUNT_ID}　タイプ　プレーンテキスト

上手く設定できていれば、 実行時にimagedefinitions.jsonとappspec.ymlがBuild Artfactとして作成されます。

## CodeDeploy
デプロイプロバイダーに Amazon ECSを指定します。
クラスター名とサービス名を選択し、デプロイ先を決定します。

CodeBuildでプッシュしたDockerイメージとimagedefinitions.jsonでタスク定義を更新し、appspec.ymlでサービスの更新をしています。

# さいごに
今回ビルドフェーズではDockerイメージの作成だけを行っています。
コンパイルが必要な場合、別途記述を足して下さい。
また、LoadBalancerの記述も環境によって修正が必要かもしれません。
ご覧いただきありがとうございました。
[初心者][備忘録]Blazor Server と Blazor WebAssembly の違い

# はじめに

数年前にBlazorを使ってちょっとしたWebアプリを作って遊んだことがあったのですが、
(サンプルを適当にいじって表示内容をちょっと変えるだけのような）
正直、全然理解せずに使っていて、なんとなく動いたからヨシとしていました。
今回、改めて学ぶ機会があったので、まとめておきます。

私は普段、C#でWindowsのデスクトップアプリを開発しています。
Webの技術を体系的に学び、しっかり活用した経験がなく用語の理解も怪しいので、超初歩的な内容になってます。
最近、MicrosoftLearnでBlazorを学んでいますが、Webの技術用語とかに明るくないと、厳しいものがある感じがしてます....

(応用情報技術者試験の取得のために勉強した範囲でなんとなく見たことある用語はあるのですが、何せ丸暗記で、試験受けた瞬間に忘れました。)

## Blazor

Blazorは、C#を使ってWebアプリケーションを作るためのツールです。
Blazorのホスティングモデル(アプリケーションがどこで実行されるかという基本的な仕組みのこと)には「Blazor Server」と「Blazor WebAssembly」というものがあり、これらの違いについて、まとめます。
Blazorのホスティングモデルにはもう一つのバリエーションとして「Blazor Hybrid」がありますが、今回は割愛します。

## Blazor Serverとは

Blazor Serverは、アプリケーションのUIがサーバーで実行され(アプリのロジックがサーバーで動き)、クライアントはSignalRを介してリアルタイムにUIの更新を受け取るモデル（画面の更新だけがユーザーのブラウザに送られる仕組み）です。

### 特徴

- 軽い動作
  - ユーザーのブラウザでは、画面の表示だけを行うため軽く動きます
- 即時起動
  - ユーザーが初めてアプリにアクセスした際、ブラウザは単にUIの表示のみを行い、サーバーから必要なデータやコンポーネントの更新情報を受け取るため、起動が早いです
- サーバー依存
  - すべての処理はサーバー側で行われ、SignalRという技術を使って、サーバーからブラウザへのリアルタイムな更新をします
  - ネットワーク接続が切れるとアプリケーションが使用できなくなります
- 高負荷時の対応が必要
  - アクセスが増えた場合、サーバーの能力を増強するなど対応しないと(スケーラビリティがないと)、応答が悪くなったり、サーバーが停止する可能性があります

## Blazor WebAssemblyとは？

Blazor WebAssemblyは、アプリのすべてがユーザーのブラウザで動く仕組みです。

### 特徴

- オフライン対応
  - アプリケーションがクライアントのブラウザで実行されます
  - アプリケーションのすべてのコードがブラウザにダウンロードされるため、一度ダウンロードすればその後はインターネット接続がなくても動作します
- 初期読み込みが重くなりやすい
  - クライアントのブラウザで全てのコードを実行するため、初回のアプリケーションの読み込みには全体のアセンブリや必要なリソースをダウンロードする必要があり、読み込みが重くなりやすいです


※WebAssemblyとは、ブラウザで動作するバイナリ形式のプログラム。JavaScriptよりも高速に動作する。

# まとめ

やっと色々な用語がはらおちしてきた気がします。
しょーもない事務作業を快適にするためのツールを作りたいとき　〜セキュア意識の高い会社編〜

# Pythonインストールできないんだけど！
なんかいつもこれ同じ作業してるよな、自動化出来ないかな…よしやったる！

　↓

みんなー！こんなツール作ったよー、使ってみてー！

　↓

そして起こる「ちょっと、俺、.pyとかいう拡張子使えないんだけど」の声。

会社のPCって外部のアクセス禁止だったり新規ソフトウェアのインストール制限があったりと、色々制約がありますよね。この制約のせいで、作ったはいいが使えなかった、みたいな理不尽なハマり方したり、一方で試してみたら意外とこれ動いちゃうんだ！？みたいなこともあったりするので、ここではそんな~~ずる賢い~~業務改善を必死に考える社員のみんなに、どれでやれば利用可能なツールづくりができるのか、その選択肢を載せていくよ。

# Python + exe化ツール(Pyinstaller)
やっぱ中身含めてファイル操作系でちょこちょこやるならPythonが楽だよね。ただ、Pythonインストールできないんだよな…そんなあなたに、Pyinstaller。これを使うと必要な機能をexeファイルにパッケージしちゃうから、会社環境でも簡単実行できちゃう！やったね！
まあ、会社利用ツールを作成する外部作業PCがあって、そこから会社のセキュアなPCにexeファイルを送り込めちゃうセキュリティホール、身元不明内exeファイルを実行できる権限と勇気、怒られる覚悟が必要だよ。

利便性：★★★★★
安全性：★★☆☆☆
その前にそのセキュリティホール塞げよの声：★★★☆☆

# Power Apps + Power Automate
現在おそらく最も会社的にもセーフな王道方式。Teams/SharePoint連携による他の方への展開も出来て、頑張ればファイル操作から条件トリガーの自動実行まで幅広い可能性が秘められてます。~~お金が潤沢な企業なら~~Copilotを使ったコーディングも可能。今後はきっともっと簡単に作れるように！？
ただし、アプリ作成権限が与えられておらず、情シス相談が必要なケースもあり〼。また、処理量によっては追いつかず、Exception書いてるのに無言で処理実行停止→お休みなさい、を普通にしますので、定期的に実行監視が必要。加えて、こういうチート作業をしようとしているプログラマ気質な人からすると、コピペで入れ子操作が狂ったりする融通の効かなさや、マウスでドリルダウン選択を強いられてしまうローコード開発環境オンリーのため、お気軽に発狂できて自己鍛錬になります。そしてMS社特有のネーミングセンス、アンチSEOなプロダクト名のため、開発情報がまず引っかからないこと、そして、Power Automateの英語版およびPower Automate Desktopという亜種のせいで実はできないことがヒットする始末です。

利便性：★★☆☆☆
安全性：★★★★☆
MS社へのイライラ募り度：★★★★★★★★★


# Excelマクロ（VBA)
色々試して色々と諦めた人が行き着く~~自動化の掃きだめ~~約束の地。Excelという社内利用率最強のアプリで、Excel外部含めてファイルを好き勝手いじれるのは非常に魅力的。Excelは実行環境だったんや！運用現場で重宝され、マクロ作ってればDXだ！って言い張れるところも熱い。
ただ、セキュリティ的には非常に危うく、めっちゃ警告出てくる。それにも関わらず知らん人から受け取ったxlsmを不意に使う同僚がいたら私はどうしたらいいですか。そして、デザインはどう上手く作ってもWin98時代のウィンドウしか作れないのでデザイナー発狂。まあ自分で使うツールなら我慢して使いますかね…？

利便性：★★★★☆
安全性：☆☆☆☆☆
DX活動やってる感：★★★★☆

# Office365 OfficeScript
ExcelマクロのOffice365版みたいなやつ。なんとJavascript（ライク）でマクロがかけちゃうツール。MS社としてはVBAで空けてしまったローカルPCへのセキュリティホールを鑑みてこちらに移行させたいんだろうな、という気概を感じられます。マクロと同じく、操作の記録→コード化もできるので比較的作成も簡単。
が、対象はWebブラウザ版Office。操作性がローカルOfficeと異なり、Excel編集してるとできないことにぶち当たってローカルPCアプリで開き直すことが多く、結果、せっかく作ったスクリプトがみんなに活用されず涙を流す。涙の数だけ強くなれ。Excelマクロの要領で作っても多分失敗します。

利便性：★★☆☆☆
安全性：★★★☆☆
知名度：☆☆☆☆☆

# Office365 OfficeScript + Power Apps + Power Automate
ひとつで苦戦するなら全混ぜじゃあ！OfficeScriptはなんと、前述のPower Automateをつなぐことも出来て、Excel外のトリガーでExcelスクリプトを動かす、というトリッキーなことが出来ちゃう素敵仕様なのです。この３つを使えば、PowerAppsでUIを作り、トリガー部をAutomateで拾い、OfficeScriptを実行、という数珠繋ぎなことができます。
問題はわかりますね？この3言語全部使えないと作れません。学習コストがでかーい！！！

利便性：★★★☆☆
安全性：★★★☆☆
これ内製開発でやるの無理ないっすか？という部下の声：★★★★☆

# Excel Python
一時期話題になった。まあこれはExcelで閉じてるので、多分ここに書いた他の選択肢を検討してる人からすると対象外だと思います。

# コマンドプロンプト / PowerShell
最強。これが塞がれている環境は今のところ見たことがない。ファイルの一括リネーム等、上手くコンパクトに考えれば活躍の場は広い。ただし、前時代プログラミング言語なので作るのは大変。正規表現。正規表現。

利便性：★★★★☆
安全性：★★☆☆☆
プロっぽさ：★★★★★

# Webブラウザ+HTML+Javascript
環境が許されれば実は一番小回りの効く有用なツール。ローカルストレージを利用したメモ帳的運用や、フォーマットを決めておけば簡易なフォーム入力等で入稿作業的に定期報告系の資料を作る運用ができる。
ローカルで開くと一部機能を実行できない問題があったり、環境設定に難あり。自社からアクセスできるウェブサーバやらAWS S3やらに置ける立場なら作業は非常に捗る。セキュリティはちゃんとかけよう。ただ、ここまでちゃんとやると、これもうほとんどSaaSサービス作ってるんだよなあ。ツールとは。

利便性：★★★★★
安全性：★★★★☆
必要な開発力：★★★★☆

# RPA
PCの外から操作を記録してやればええんや！という身も蓋もない方法。ただ、ほぼすべての作業を肩代わりできる自動化最強ツール。
たまに意図しないずれ方などして変な操作が生き残ったりするので、自動で動く画面を見守る運用が必要になり、俺は一体何をしているんだろう？という気持ちに陥る。ターゲットとするボタンをクリックするといったきめ細やかな調整や前段処理がロスした時の挽回方法など、難しいことをやろうとするほどハマるので注意。改善業務のはずが、その担当者になると業務が増えて不幸になる不思議。

利便性：★☆☆☆☆
安全性：★☆☆☆☆
でもこれが業務なので…という諦めの声：★★★★★
【備忘録】@Scheduled アノテーションの話

今製造してるSpring bootのプロジェクトで、バッチ処理ってどうやってるんやろな～と思って調べた内容をまとめていきます。

<h2><code>@Scheduled</code>アノテーション</h2>
<code>@Scheduled</code>アノテーションを使用すると、任意のタイミングで処理を走らせることが出来るようです。

使い方は↓

<h2>使い方</h2>
使い方はシンプルで、流したいメソッドにこのアノテーションをつければいいです。

```java
@Scheduled
private void exampleMethod() {
    // ここに処理を記述
}
```

こんな感じですね。

注意点としては、このメソッドを記述してるクラスに<code>@Configuration</code>と<code>@EnableScheduling</code>を付与してあげる必要があります。

```java
@Configuration
@EnableScheduling
pubic class ExampleClass {

    @Scheduled
    private void exampleMethod() {
        // ここに処理を記述
    }
    
}
```

上記のような構造で記述することによって、＠Scheduledアノテーションを有効にすることが出来ます。


<h2>実行タイミングの指定</h2>
実行タイミングを指定することが出来ます。

指定方法もいくつかあります。

<h3>fixedRate</h3>
これを使うとシンプルな定期的実行がされます。（〇秒毎）

```java
@Scheduled(fixedRate = 5000)
```
上記の記述で5秒毎に実行されることとなります。

単位はデフォルトでミリ秒です。（timeUnit で単位を指定することは可能です。）

<h3>fixedDelay</h3>
これは、処理が実行終了してから任意のタイミングで実行するように指定できます。

```java
@Scheduled(fixedDelay = 5000)
```
たとえば、上記の様に記述した場合は処理自体が10秒かかるとしたら、15秒に1回処理が流れるイメージになります。

他にもcron等があるようですが、いまいち理解できなかったのでまとめるのはまた今度ということにします。

<h2>参考</h2>
<a href = https://qiita.com/nannany_stores/items/f99c727be84a9e74da3e>Springの @Scheduled について</a>