OmniAICreator/Qiita-1.07M huggingface dataset:
「Amazon Bedrock」複数AIエージェントの協調機能ハンズオン

## はじめに
re:Invent 2024にて、AWSはAmazon Bedrockの新機能「multi-agent collaboration capability」が発表されました。
なんと「スーパーバイザーエージェント」というエージェント作れば、複数のエージェントを指揮できる仕組みらしいです。
![2024-bedrock-mac-demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/8cee3d6b-ca98-09c6-1c08-5255d32b1ca3.png)

[公式ドキュメント](https://aws.amazon.com/jp/blogs/aws/introducing-multi-agent-collaboration-capability-for-amazon-bedrock/)

## ハンズオン
百聞は一見にしかず、
東京リージョンも利用できるらしいので、早速試してみましょう。

複数のエージェントが必要なので、まずは普通のエージェントを1つ用意しましょう:point_up_tone1:

下記の記事では、リアルタイムの天気情報を取得できるエージェントの作り方をハンズオン形式で紹介していますので、その天気情報取得用エージェントを先に作りましょう。

https://qiita.com/Syoitu/items/45174f5cae5f4ce4fe12

天気情報取得用エージェントは下記のプロンプトを指定してあります。
```
あなたはリアルタイムの天気情報を取得してユーザーに回答するエージェントです。以下の条件に従って行動してください：

1.ユーザーからの一般質問に関して、任意に回答してください。
2.ユーザーから天気情報に関する質問はアクション使って回答してください。
3.ユーザーから日本語で都市名を指定された場合、その都市名を英語に翻訳してから使ってください。

ユーザーが指定しない場合、デフォルトの都市名は「Tokyo」としてください。
```
天気情報を取得できるアクションがあるため、質問された際にアクションを使って情報を取得し、一般的なテキストで情報を返します。

![312CA15A-2B66-4B7E-85A7-2D1B970C23D0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/9b56abeb-d054-3d19-c550-71c14f0484d2.jpeg)


次に、新規でマルチコラボレーション機能有効化のエージェントを用意しましょう。

`Enable multi-agent collaboration`のチェック入れるだけでいいです。

![145FAB4F-2A82-4655-A39F-4E07559228EB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/9504ea05-7879-679e-8ab4-1aefb472dbf0.jpeg)

下記のプロンプトを指定します、どんな回答でもjson形式にフォーマットしてくれます。

```
あなたは優れてるエージェントです、通常の質問がきた際に君が持ってる知識で回答してください。

天気情報の質問が来たら、協力者を呼んでください。
回答する際に必ずjson形式に変換して出力してください。
```

そしてエージェント作成画面の一番下にある`Multi-agent collaboration`を編集します。
![7128B5E2-77DB-431A-88D0-D9CDEFCFC91D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/16ab437f-07fe-6106-7cec-0c639edb0103.jpeg)


Collaboration configuration
- Supervisor 

エージェントの最終応答を、今回作ったコラボレーション機能を有効化しているこのエージェントにしてもらいましょう

Collaborator agent
- 先ほど作った天気情報取得エージェントを指定します

Collaborator instruction
- やってほしいことのプロンプトを入力します

Enable conversation history sharing
- チェクを入れます

![CE606D03-A39A-4818-AF0B-4630AB5CE211.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/a374e5be-ea02-4f5f-4434-f482dea8c9aa.jpeg)

設定完了しましたら、`Save and exit`して実際試して見ましょう。

テストの結果は下記の図の通り、天気に対する質問に対して協力エージェントを呼び出し、最終的な回答を自信のある役割でJSON形式にフォーマットしてくれました。
![89424DA4-A9C7-468E-AAC9-2C8B75375B88.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/132528fc-e0bd-d72f-e3fb-2a3162eaf3f4.jpeg)

## 最後に

数年前からジョブ型雇用という言葉を耳にするようになり、今ではエージェントもジョブ型に移行しつつあるように感じます。
エージェントだけで専門家が揃ったチームを構築することも、現実のものとなりつつあります。
これからは応用の可能性を探りながら試していきたいと思います。
nvim@2024

ども

https://github.com/kqnade/dotfiles/tree/main/.config/nvim

設定はここに

## 概要

最適化に最適化を繰り返してだいぶ早いnvimを作った

## 使っているプラグイン

- akinsho/toggleterm.nvim
- nvim-neo-tree/neo-tree.nvim
- simeji/winresizer
- ojroques/nvim-bufdel
- nvim-telescope/telescope.nvim

- nvim-treesitter/nvim-treesitter
- neovim/nvim-lspconfig
- nvimtools/none-ls.nvim
- hrsh7th/nvim-cmp
  - lukas-reineke/cmp-under-comparator
  - saadparwaiz1/cmp_luasnip
  - hrsh7th/cmp-nvim-lsp
  - hrsh7th/cmp-nvim-lua
  - andersevenrud/cmp-tmux
  - hrsh7th/cmp-path
  - f3fora/cmp-spell
  - hrsh7th/cmp-buffer
  - ray-x/cmp-treesitter
- folke/tokyonight.nvim
- nvim-lualine/lualine.nvim
- rcarriga/nvim-notify
- danilamihailov/beacon.nvim

## こだわっているところ

- IDE化しつつも起動は素早く
- かっこいい見た目
- 最新のトレンドを取り入れる

## 起動時間

平均20msです。
wslだと60msくらい

## 今後

今後はnixOSへの乗り換えとともに設定が大きく変わる予定なので来年もこの記事書きたいね
【CDK】TypeScriptで書いたコードをLambdaで動かす

## はじめに

TypeScriptで書いたコードをLambdaで動かす場合JavaScriptへのトランスパイルとパッケージのバンドルが必要です。

CDKでLambdaを作る方法はいくつかあるのですが、TypeScriptに適した書き方を見つけるのに少し戸惑ったので残しておきます。

## 結論

`aws-cdk-lib/aws-lambda-nodejs` パッケージの [NodejsFunction](
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html) を使うと良いです。

JavaScriptで書いたコードも同様の書き方でバンドルしてくれます。

```ts
import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';

new lambda.NodejsFunction(
  this,
  'TypeScriptLambdaFunction',
  {
    functionName: `lambdaFunction`,
    entry: 'src/handler.ts',
    handler: 'handlerFunction',
    runtime: lambda.Runtime.NODEJS_20_X,
  }
);
```

## 余談

簡潔に書きすぎたので余談をします。

CDKでLambdaを作る時の他の書き方を紹介します。

### コードを直書きする方法

短いコードであればこの方法が良さそうですね。

```ts
import * as lambda from 'aws-cdk-lib/aws-lambda';

const fn = new lambda.Function(this, 'MyFunction', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'),
  deadLetterQueueEnabled: true,
});
```

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#lambda-with-dlq

### ローカルファイルを指定する方法

指定したディレクトリをzip化してアップロードするだけです。
バンドルが不要だったり別途バンドルする場合はこれが良いのかもしれません。

```ts
import * as lambda from 'aws-cdk-lib/aws-lambda';

const fn = new lambda.Function(this, 'MyFunction', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
});
```

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#execution-role

### S3上のzipファイルを使う方法

CI/CDの都合上S3にコードを置きたい場合に使えそうですね。
もしくは複数チームで共通のコードを使う時とか。

```ts
import * as lambda from 'aws-cdk-lib/aws-lambda';

const cfnFunction = new lambda.CfnFunction(this, 'MyCfnFunction', {
  code: {
    s3Bucket: 's3Bucket',
    s3Key: 's3Key',
  }
})
```

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.CfnFunction.html

### ECRのイメージを使う方法

CI/CDの都合上ECRにイメージを置きたい場合に使えそうですね。
もしくは複数チームで共通のイメージを使う時とか。

```ts
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ecr from 'aws-cdk-lib/aws-ecr';

const repo = new ecr.Repository(this, 'Repository');

new lambda.DockerImageFunction(this, 'ECRFunction', {
  code: lambda.DockerImageCode.fromEcr(repo),
});
```

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#docker-images

### fromDockerBuild

多分コンテナでビルドしたコードを指定できる。
正直ちゃんと理解できてないです :bow: 
コンテナ上でビルドしたい場合には良いのかもしれません。

https://aws.amazon.com/jp/blogs/news/improve-collaboration-between-teams-by-using-aws-cdk-constructs/

## おわりに

余談が長くなりましたね笑
知らない書き方もあって個人的にも勉強になりました。

それでは良いLambdaライフを！

## 参考

https://dev.classmethod.jp/articles/lambda-bundling-via-aws-cdk/
jax.lax.condの使い方

# はじめに
### jaxと、この記事の説明
- jaxは高速な並列計算が得意なpythonライブラリで、XLAでのコンパイル時に、いい感じに最適化できて高速になるらしい
- 高速化のためには<font color="#0072BC">**if文も関数に置き換えないといけない…**</font>
- この記事は、[この記事](https://qiita.com/shibaura/items/d3ea05c3f392ed0ba7d9)の仲間

### なぜjax？
<font color="#a9a9a9">私は他人のソースコードが全部jaxで書いてあったので、仕方なく手を出している</font>

# jax.lax.condの使い方

jax.lax.condは三項演算子とほぼ同じ使い方をする
（**配列などには使えないので注意！** [^1] ）
[^1]: じゃあ配列を一気に操作したい場合はどうするかというと、「jax.where」を使います。これは別記事で書きます。

```python:fori_loopの使い方
import jax
import jax.numpy as jnp

def true_fun(x, y):
    return x + y

def false_fun(x, y):
    return x - y

x = jnp.array(3.0)  # 入力1
y = jnp.array(2.0)  # 入力2
result = jax.lax.cond(
    x > 0,     # 判定式
    true_fun,  # 判定式がtrueのときに実行する関数
    false_fun, # 判定式がfalseのときに実行するか関数
    *(x, y),   # 関数に渡す引数たち（わかりやすさのためにタプル形式を展開して与えているが、そのままx, yと書いてもOK）
)
print(result)  # 5.0
```

公式サイトに書いてある動作の疑似コードは以下の通り:
> ```python
> def cond(pred, true_fun, false_fun, *operands):
>  if pred:
>    return true_fun(*operands)
>  else:
>    return false_fun(*operands)
>
># 次の三項演算子の記述と同じ
># return true_func(*operands) if pred else false_fun(*operands) 
>```

# 疑問と回答
Q. じゃあ、普通の次のようなif文はどう書けばいい？
```python
if x > 0:
    x = x*2
```
A. 次のように解釈しなおして書けばOK
```python
x = x*2 if x > 0 else x
```

# おわりに
- jax.lax.condは**配列に使えない**って、実際ほぼ出番無いのでは…
- 次は配列におけるif文操作の本題「**jax.where**」を書きます
Python3 基礎試験に合格したので感想などを書いてみる

問題の内容などは書いてはいけないらしいので、公開されている情報に基づいてふわっと書きますね。
学習期間は約２ヶ月弱といったところです。

## １．受験のきっかけ
ハローワークに訪問した際、職業訓練の内容としてpython3の資格などの取得に向けた講習等が行われているのを見かけ、「どの程度のレベルの問題なのだろうか」と疑問に思ったので受験してみました。


## ２．私のスペック

高等学校情報の免許を所持、基本情報技術者、非理数系。よく職場にいるPCにちょっと詳しいだけのヤツです。

趣味ですが、フレームワークに手を出すくらいにはpythonを色々かじっているので、プログラミング言語の中では一番触っているものだと思います。

## ３．対策したこと

### 公式テキスト
Pythonチュートリアル 第4版
Guido van Rossum　著、鴨澤 眞夫　訳

https://www.oreilly.co.jp/books/9784873119359/

ただこの本は翻訳がいまいちで（すみません）、ややわかりにくい言い回しが多く、他の言語を全く触ったことがない人には理解するのは難しいと思うので、適宜ググる必要はあると思う。

外部ライブラリについては、試験範囲に含まれないので注意。あくまでの素のpythonの機能についてだけです。


### 模擬試験
Python 3 エンジニア認定基礎 模擬試験

https://study.prime-strategy.co.jp/

私はこれをひたすら95%以上取れるまでやりました。知らない事も多かったので勉強になりました。

### 参考になりそうなYouTubeチャンネル

Pythonプログラミング VTuber サプー

https://www.youtube.com/channel/UC5Kgc_HNzx4GJ-w4QMeeKiQ

動画のほうが良い人はこちらのVTuberの解説が参考になると思います。
この動画を見て合格したという合格報告もコメント欄に見られますね。

### コーディングが全てではない

試験ではVScodeを起動することはできませんし、すべての計算（もし必要になる場合でも）は暗算で行う必要があります。一般論になってしまいますが、コードが書けるだけではなく、試験対策そのものも必要になるかと思います。

初心者スタートなら、ガンガン書いたほうが良いです。
Progateからスタートすることをお勧めします。

https://prog-8.com/

## ４．注意点
PythonチュートリアルはWEBでも読めるっぽいです（私は買って読みました）。
こちらの方が翻訳がわかりやすいような気がするのですが…

https://docs.python.org/ja/3/tutorial/

公式テキストですが、試験に出ない部分もあるのでよく注意してください。

CBTでの受験になりますが、メモ用紙等は使えないので、基本情報技術者試験などのようにはいきません。ただ、逆に言えばメモ用紙が使えない中でみんな受験しているということになります。

基礎試験、実践試験、データ分析試験など種類がいろいろあり、テキストも異なるので申し込み前にきちんと確認しましょう。

何日か前までなら試験日を変更することができるようです。


## 感想

・網羅的に物事を理解することの大切さを実感することができた。

・オライリー・ジャパンの本は難しそうと思っていたけれど、読んでみたら意外とそうでもなかった。

・今まで使わなかったpythonの書き方の存在意義がわかって良かった。

・ベンダー系の資格に興味を持つきっかけになった。今後も受けてみたいと思う。

・合格証のようなものが届く（まだ届いていない）らしいので、嬉しい。
C#で単体テスト

### 概要

C#の単体テストプロジェクトを使って、テストソースを書いて実行する形でテストする方法について

### C#で単体テストを実行するまでの手順

①VisualStudioでWindowsFormプロジェクト等、処理を書きたいプロジェクトを作成する。
②テスト対象となるクラス、メソッド、処理を実装する(ここでは計算を行うCaluculatorクラス)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926100/37430759-753a-b407-d1a9-98b5794e26df.png)

③プロジェクトを右クリック、追加→新しいプロジェクトを選択し
単体テストプロジェクトを作成する。
![スクリーンショット 2024-12-09 222240.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926100/31553352-e78e-ae8e-8345-1f53fde4cb81.png)

④作成したテストプロジェクト内にテストソースを書く。
ここでは第一引数と第二引数の値が同値であるかを検証するAreEqualメソッドを使用し、計算結果と期待値を比較

```
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace CalculationTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var result = Calculation.Sum(4, 7);
            Assert.AreEqual(11, result);
        }
    }
}
```
⑤メニューからテスト→テストエクスプローラーを開きテストを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926100/fa0bd609-0697-df95-507a-7d3081fa49c6.png)
AlmaLinuxにFirebase CLIを入れる

# はじめに
仮想環境上にAlmaLinux環境を構築できたので、本来の目的である
Firebase Hosting のデプロイ環境を作ってまいります。

# 環境
AlmaLinux9 (VMWareの仮想マシン)

# 作業の手順
大した作業は行わないのですが、Firebaseの公式ドキュメントを見ながら進めます。
https://firebase.google.com/docs/hosting?hl=ja

## Firebase CLI をインストールする
前回の記事で、node.jsをインストールしているので、npmを使えます。
以下のコマンドを実行。
```
npm install -g firebase-tools
```

ちょっと時間はかかったけど、すんなりインストール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/960d540d-1700-7d56-d2b7-47da4f95bb05.png)

## Firebaseにログイン
以下のコマンドで、Firebaseにログインします。
```
firebase login
```
Firebaseが情報収集するけどいいか？と聞かれるのでYesを選択。
URLが発行されるので、ブラウザに貼りつけて表示。

<br/>

見覚えのある、Googleにログイン画面が表示されるので、
ログインしたいアカウントを選択し、認証をすすめる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/22eb5670-5444-ec34-f324-debdba3e47a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/b9e4baeb-d70c-16dd-7c7c-e0f3376b632f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/5cfa7b7f-cf9e-c54e-9f9d-696241cd6b92.png)

<br/>

おっと、ダメだった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/1ed4f8a7-4cab-6c2a-3b5a-2fb3992d3803.png)


もう一回、公式ページを読み直すと、以下とのこと。
>注: firebase login コマンドは、マシン上の localhost に接続するウェブページを開きます。リモートマシンを使用していて localhost にアクセスできない場合は、--no-localhost フラグを指定してコマンドを実行します。

<br/>

仮想マシンのホスト側でブラウザ開いちゃったからですね。
では、もう一回
```
firebase login --no-localhost
```

先ほどと同じようにログインアカウントを選んで、権限など許可していくと、
確認画面が出てきた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/0a6cc631-ea4c-eb8d-8d39-d6ce67a8815e.png)

<br/>

セッションIDも聞かれるので、合っているよボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/e05ff95e-6d0e-cc4f-debd-93dd23b0630b.png)

<br/>

認証コードが渡されるので、これをAlmaLinuxに入力。
おぉ、ログインできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/b8aed1cb-816d-84ed-120f-137a1a4f7e8f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/0cdd0078-cd55-ce97-9a21-a32822d85db9.png)

<br/>

後は公式情報をもとに、Firebaseのプロジェクト一覧を表示してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/5e1ccaa3-7514-de6c-53fb-301ec92b4d68.png)

ちゃんとインストールできていたみたいですね。

<br/>

次回は、デプロイを行いたいと思います。
なぜ、わたしの見積もりはズレるの？

この問題を解消するために、よくあるつまづきポイントを洗い出し、すぐに実践できる小さなアドバイスにまとめました。
自分自身がつまづいた経験をもとに、こうすれば解決できたなという内容になっています。（つまり過去の自分に見せたい！）

## 1. タスクの粒度が粗い
:::note warn
問題: タスクが大きすぎて全体像がぼんやりしている。
:::
まず、タスクを小さく切り分ける:
例: 「レポート作成」ではなく「データ収集」「資料作成」「文章執筆」に分ける。
1時間以内で終わるレベルにする: 大きすぎるタスクは不正確な見積もりの原因になる。

## 2. 一度に複数の問題を解決しようとする
:::note warn
問題: 解決すべきことが多すぎて集中力が散漫になる。
:::

一つの課題に集中する: "今日やるのはこれだけ" と決めて取り組む。
To-Doリストの見直し: 一度にやるタスクを3つまでに絞る。

## 3. マルチタスクとコンテキストスイッチ
:::note warn
問題: 同時に複数のタスクを進めようとすると効率が悪くなる。
:::

ポモドーロ・テクニックを試す: 25分間1つのタスクだけに集中し、5分間の休憩を取る。
通知をオフにする: スマホやメールの通知を切り、集中を妨げない。

## 4. 完了の定義が曖昧

:::note warn
問題: タスクが「終わった」と判断できない。
:::

完了の条件を明確にする: 例: 「顧客に提出する」または「レビューを受ける」。
ゴールを紙に書き出す: 作業開始前に、「これができたら完了」と明確にする。

## 5. 優先度をつけずにタスクを並べる
:::note warn
問題: 重要度が低いタスクに時間を使ってしまう。
:::

「緊急度×重要度」のマトリックスを使う: タスクを4つの象限に分け、重要度の高いものから着手。
朝一で優先順位を決める: 1日の最初に最重要タスクを確認する。
## 6. ハマってもずるずる時間を使う
:::note warn
問題: 問題に詰まり、進めなくなってしまう。
:::

制限時間を設ける: 30分で解決しなければ次のアクションを考える。
相談する癖をつける: ハマったらすぐに上司や同僚に相談する。

## 7. やらなくていいことまでやる

:::note warn
問題: 本質的でない作業に時間を費やす。
:::
タスク開始前に「やらないことリスト」を作る: 例: 完全なデザインより最低限のデザインに留める。
チェックポイントを設ける: 適宜、「ここで十分か？」と振り返る。
## 8. 手戻りが多くなる

:::note warn
問題: 最初の段階で十分に準備せず、後から修正が多くなる。
:::

開始前にレビューを受ける: 計画や初期設計を他人に確認してもらう。
プロトタイプを作る: 最初に簡単な形で試し、方向性を確認する。

## まとめ

すべてを解決する魔法のようなツールを探し出すかもしれない。
他の人がつかっているツールが良いものに見えるかもしれない。
でも銀の弾丸はありません。こつこつ積み重ねていきましょう。
ブラウザ拡張機能で使えるイベントについて

# 概要

これは[初心者のブラウザ拡張機能 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/browser-extension)の8日目の記事です。

イベントの使い方と種類について説明します。

# 基本的な使い方

```javascript:main.js
function callback() {
    console.log("Event Call !");
}

document.addEventListener("event type", callback)
```

ブラウザ拡張機能でイベントを使う場合は、ほとんどが生成されたイベントをキャッチして何らかの処理を行う場合だと思います。

基本的に`document.addEventListener`を使ってイベントのリスナーを追加し、設定したコールバック関数で処理します。

イベントの処理は`Content script`、`Background script`の両方で扱えます。

[EventTarget: addEventListener() メソッド](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener)

# イベントの種類

Mozillaのサイトにまとまっているため、サイトへのリンクを記載します。

DOMに関するイベントはこちら。
たとえば`MouseEvent`はマウスのクリックやダブルクリックで発生するイベントがあります。
[Event を基にしたインターフェイス](https://developer.mozilla.org/ja/docs/Web/API/Event#event_%E3%82%92%E5%9F%BA%E3%81%AB%E3%81%97%E3%81%9F%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9)

拡張機能でよく使うのはDocument関連のイベント。これらを使うとページが読み込まれたタイミングで処理を行うなどが可能です。
[Document イベント](https://developer.mozilla.org/ja/docs/Web/API/Document#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88)


[インターフェイス](https://developer.mozilla.org/ja/docs/Web/API#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9)というページで調べたいインターフェイスをクリックすると詳細が記載されているページへ遷移します。イベントについても確認できます。
繰り返し

### 背景
昨日のスクリプトは同じブロックの塊が繰り返しているような部分がありましたので、繰り返し処理をしてみました。

### Scratch
ループのブロックはコントロールのところにありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/087214a6-7358-0f3a-52dc-2b8e61af333b.png)

回数指定のループを使い昨日のScratchを書き直しました。
昨日のScratchを右に並べてましたが、下のほうにある2回繰り返している部分をループにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/2b3b5f5e-b20d-3680-a593-68803c7a1fdc.png)


### spheroV2
ループ変数をiとしてfor文にしました。

```
import time

from spherov2 import scanner
from spherov2.sphero_edu import EventType, SpheroEduAPI
from spherov2.types import Color

print("Testing Starting...")
print("Connecting to Bolt...")
toy = scanner.find_BOLT()

if toy is not None:
    print("Connected.")
    with SpheroEduAPI(toy) as droid:
        print("Testing Start...")
        
        droid.reset_aim()

        droid.set_stabilization(False)

        droid.calibrate_compass()
        time.sleep(1)

        a = 0
        droid.set_compass_direction(a)
        time.sleep(1)
        print(a)

        for i in range(2):
            a += 90            
            droid.set_compass_direction(a)
            time.sleep(1)
            print(a)


        # for a in range(3):
        #     droid.set_compass_direction(a * 90)
        #     time.sleep(1)
        #     print(a)

        print("Testing End...")
  
```

実行結果はこちらのようになりました。
```
git\spherov2.py\spherov2\test>python BoltTest_compass3.py
Testing Starting...
Connecting to Bolt...
Connected.
Testing Start...
0
90
180
Testing End...
```

a=0のときの部分もfor文にまとめる場合はコメントアウト部分のように直すこともできます。

### まとめ
Scratchの繰り返し作業を作成してみました。
条件付きループで書き直してみると暗黙として使っている部分に気づくことができて面白そうです。
【TryHackMe】Cyber Kill Chain：Walkthrough

# 概要

TryHackMe「Cyber Kill Chain」のWalkthroughです。

https://tryhackme.com/r/room/cyberkillchainzmt

# Task2

## **Q1**.*What is the name of the Intel Gathering Tool that is a web-based interface to the common tools and resources for open-source intelligence?*

**A**.**OSINT Framework**

## **Q2**.*What is the definition for the email gathering process during the stage of reconnaissance?*

**A**.**email harvesting**

# Task3

## **Q1**.*This term is referred to as a group of commands that perform a specific task. You can think of them as subroutines or functions that contain the code that most users use to automate routine tasks. But malicious actors tend to use them for malicious purposes and include them in Microsoft Office documents. Can you provide the term for it?*

**A**.**Macro**

# Task4

## **Q1**.*What is the name of the attack when it is performed against a specific group of people, and the attacker seeks to infect the website that the mentioned group of people is constantly visiting.*

**A**.**Watering hole attack**

# Task5

## **Q1**.*Can you provide the name for a cyberattack targeting a software vulnerability that is unknown to the antivirus or software vendors?*

**A**.**Zero-day**

# Task6

## **Q1**.*Can you provide the technique used to modify file time attributes to hide new or changes to existing files?*

**A**.**Timestomping**

## **Q2**.*Can you name the malicious script planted by an attacker on the webserver to maintain access to the compromised system and enables the webserver to be accessed remotely?*

**A**.**web shell**

# Task7

## **Q1**.*What is the C2 communication where the victim makes regular DNS requests to a DNS server and domain which belong to an attacker.*

**A**.**DNS Tunneling**

# Task8

## **Q1**.*Can you provide a technology included in Microsoft Windows that can create backup copies or snapshots of files or volumes on the computer, even when they are in use?*

**A**.**Shadow Copy**

# Task9

## **Q1**.*What is the flag after you complete the static site?*

シナリオをCyber Kill Chainにあてはめます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/29b63790-4929-94fb-f155-46652bcea940.png)

**A**.**THM{7HR347_1N73L_12_4w35om3}**
【基本情報】独学マラソン 疎行列 Day 32

:::note worn
この記事は自分用の備忘録です。
:::

# 疎行列とは
0がいっぱいある行列（二次元配列）

```
[
  [3, 0, 0, 0, 0],
  [0, 2, 2, 0, 0],
  [0, 0, 0, 1, 3],
  [0, 0, 0, 2, 0],
  [0, 0, 0, 0, 1]
]
```

# やること
0がいっぱいあるとデータとして効率が悪いので、0をなくした良い感じのデータに変換せよ

## やってみる


```sparseMatrix.ts
// 元データ
const matrix: number[][] = [
  [3, 0, 0, 0, 0],
  [0, 2, 2, 0, 0],
  [0, 0, 0, 1, 3],
  [0, 0, 0, 2, 0],
  [0, 0, 0, 0, 1]
];

// 圧縮データ構造の型
type SparseMatrix = [number[], number[], number[]];

// 疎行列を圧縮データ構造に変換する関数
function transformSparseMatrix(matrix: number[][]): SparseMatrix {
  const sparseMatrix: SparseMatrix = [[], [], []];

  for (let i = 0; i < matrix.length; i++) {        
    for (let j = 0; j < matrix[i].length; j++) {    
      if (matrix[i][j] !== 0) {                    
        sparseMatrix[0].push(i + 1);        // rowを入れる
        sparseMatrix[1].push(j + 1);        // columnを入れる   
        sparseMatrix[2].push(matrix[i][j]); // 値を入れる
      }
    }
  }

  return sparseMatrix;
}

// 疎行列を圧縮データ構造に変換
const result: SparseMatrix = transformSparseMatrix(matrix);

// 結果の表示
console.log("行番号:", result[0]);
console.log("列番号:", result[1]);
console.log("値:", result[2]);
```

## 実行!!

![スクリーンショット 2024-12-09 22.17.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/8c536224-9e81-3a50-b3ee-5e8025a778b2.png)

(1,1)->3
(2,2)->2
(2,3)->2
...

合っている！

## **感想**
めっちゃ数Cだった。

# **参考**

https://qiita.com/KQTS/items/e5500ba6e2681456e268

https://www.ipa.go.jp/shiken/syllabus/ps6vr7000000oett-att/fe_kamoku_b_sample.pdf
【Unity】何となく使ってるアクセス修飾子を調べた

# はじめに
この記事は[Hamster Output Advent Calendar 2024](https://qiita.com/advent-calendar/2024/game_hamster)の10目の記事です！

今まで、アクセス修飾子をつける時に多分こういう感じなんだなと考えていて、つける時にもやもやしていました。**そこで、アドベントカレンダー走ってるし、アウトプットしちゃえ！というノリで作った記事です。**

# アクセス修飾子って何...?

クラスやメソッド、変数の前につける**public**や**private**のことを**アクセス修飾子**といいます。

```C#
public class Test : MonoBehaviour
{
    private void Start()
    {
        
    }

    private void Update()
    {
        
    }
}
```

Microsoftの公式ページにはこう書かれています。
> **アクセス修飾子は、メンバーまたは型の宣言されたアクセシビリティを指定するときに使用されるキーワードです。**

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/access-modifiers

なるほど、型に対するセキュリティやルール見たいな感じですね。アクセス修飾子が5つあるらしいので、それぞれの違いを調べて見ます。

# それぞれのアクセス修飾子の違い

### ・public
**アクセス制限なし！どのクラスからでも参照可能！**

僕も初めて作ったゲームではpublicしか付けてませんでした。後は制作期間が短いゲーム制作とかも...

色々な記事にも書いてあったりしますが、ゲーム開発に慣れてきたら何でもかんでもpublicにするのは止めましょう！半年~1年立った後にゲームをブラッシュアップするぞ～ってなった時に地獄を見ます(2敗)

### ・protected
**継承されていればアクセスできる。していなければアクセスできないという考え方で良いと思います。**

下にprotectedを使ったクラスと利用するクラスを用意して、いつも通りアクセスして見ますが...クラス参照はできても、変数は参照出来ません。

```C#
public class TestProtected : MonoBehaviour
{
    protected int _num = 999;
}

public class Test : MonoBehaviour
{
    private TestProtected _testProtected;

    private void Start()
    {
        _testProtected = GetComponent<TestProtected>();
        
        // この下がエラーになる
        _testProtected._num += 1;
    }
}
```

TestクラスにTestProtectedを継承すると、アクセスできるようになります！

```C#
public class TestProtected : MonoBehaviour
{
    protected int _num = 999;
}

public class Test : TestProtected
{
    private void Start()
    {
        // 継承なので変数をそのまま利用できる
        _num += 1;
    }
}
```

思い返してみれば、protectedを利用したこともなければ継承もあまり使っていないのでは........

### ・internal
**同じアセンブリ内ならアクセスできる！それ以外ならアクセスできない！**

正直に言うとinternalに関しては、最近使いだしたばかりなので、アセンブリが～とか良く分かりません。何でも、コンパイル単位でアクセスが許可される~~~という。

Unityでこのアクセス修飾子だけを付けても意味がないです。**Assembly Definition**と一緒に使うことで利用できるようになります。中間言語が~~など様々なことがありますが、また今度別記事にてアウトプットします。

### ・protected internal
protectedとinternalの組み合わせです。

### ・private
**どこからもアクセスできない。使えるのは定義したクラスのみ**
C#では、アクセス修飾子を何も宣言しなかった場合、デフォルトでprivateになります。
```C#
// 何も宣言しなければデフォルトでprivateになる
int _num;
```

動作確認でクラスを作ってましたが、class自体もアクセス修飾子が無ければデフォルトでpublic見たいです。interfaceもデフォルトでpublicなので同じですね。

### ・private protected
privateとprotectedの組み合わせです。

### ・file
>宣言された型は現在のソース ファイルでのみ表示されます。 ファイル スコープ型は一般にソース ジェネレーターに使用されます。

C#のバージョン11から追加された見たいです。全く分かりません。

# まとめ
使ったこともあるけど、ほとんど使ったことがないアクセス修飾子ばかり！！！
fileに関してはC#バージョン11見たいなので、ゲーム開発で使うのはまだなさそう。
起業するならElixirシリーズ. 折り返し地点 今までのリンク集

2024年アドベントカレンダーシリーズ Elixirシリーズですが、ほぼ起業の話しメインになってしまいましたが、いや、Elixirの話しも少し入ってますよ。もちろん。。

一気読みしてもそんなにボリューム無いのでまだ読んでない方は是非

https://qiita.com/Yoosuke/items/e41b767ff5900d0b1489

https://qiita.com/Yoosuke/items/f83a6aa4c0f8e3d18000

https://qiita.com/Yoosuke/items/d97baa64033286b27877

https://qiita.com/Yoosuke/items/e537c59eca29534109ee

https://qiita.com/Yoosuke/items/e7d17d7022014b48b4be

https://qiita.com/Yoosuke/items/2536d27937588bb129bb

https://qiita.com/Yoosuke/items/a189163acf8a1306df7a

https://qiita.com/Yoosuke/items/0e255bece9794f654d85

https://qiita.com/Yoosuke/items/8212a16c7653324016bd

https://qiita.com/Yoosuke/private/ab5a8de08e56e9736d73

https://qiita.com/Yoosuke/private/1f7f39e1ec19dd54f477

https://qiita.com/Yoosuke/private/419d5b1ab52ce9f86737

後半もぜひ読んでくださいね。
2D 図形の定義

## 初めに

今回の記事は2Dにおける図形の定義における必要な要素を考えます

## 今回の図形

1. 直線
1. 円
1. 長方形・正方形
1. カプセル

今回はこの４つの図形に注目していきます

## 直線の定義

直線とは２点間の間を無数の点が集まったもの

1. ２点の座標を用いて線を引く
float sx, float sy, float ex, float ey
sx sy 始点の座標
ex ey 終点の座標

1. １点の座標と終点までのベクトルと大きさ
float sx, float sy, float vx, float vy, float length
sx sy 始点の座標
vx vy 終点までのベクトル(正規化されているとよき)
length 長さ

## 円の定義

中心点からの距離が等しい場所に無数の点を集めたもの

1. 中心点の座標と半径
float cx, float cy, float length
cx cy 中心点の座標
length 半径

## 長方形・正方形の定義
４つの直線からなっていて対になる辺が並行ですべての角が90°で固定されているもの

1. 左上座標と右下座標
float sx, float sy, float ex, float ey
sx sy 左上座標
ex ey 右下座標

1. 左上座標と隣接する点のうち片方までのベクトル　隣接する点までの距離
float sx, float sy, float vx, float vy float lenDown, float lenRight
sx sy 左上座標
vx vy 隣接する点の片方までのベクトル(正規化されてたらよき)
lenDown 左上から左下までの距離
lenRight 左上から右上までの距離

## カプセルの定義
2点間の直線からの距離が等しい点の集まり

1. 始点と終点と半径
float sx, float sy, float ex, float ey,float length
sx sy 始点の座標
ex ey 終点の座標
length　半径

## 最後に

今回は2Dの図形の定義について考えました
図形にはぞれぞれ特徴があり定義の仕方もいろいろあります
今回考えたもの以外にも定義方法はあると思うので考えてみてください
人それぞれが使いやすい定義方法があると思うのでそういうのも考えてみてください
ABC383Fを解いた【動的計画法】

筆者はレート800前後の茶～緑コーダ

ABC383当日にACできなかったF問題を解いていく

https://atcoder.jp/contests/abc383/tasks/abc383_f

# 実装コード

公式解説によると以下のようにDPのテーブルを作ればいいようだ。
> dp[c][p]= 色が c 以下の商品から p 円分購入したときの満足度の最大値

テーブルの更新方法とかは公式解説のコードを丸々Pythonに移しただけです

```python:main.py
import sys
from collections import defaultdict
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

INF = float('inf')

def main():
    N, X, K = rLI()
    P = [0]*N
    U = [0]*N
    C = [0]*N
    ids = defaultdict(list)
    for i in range(N):
        P[i],U[i],C[i] = rLI()
        ids[C[i]-1].append(i)
    # for k in sorted(ids.keys()):
    #     err(k,ids[k])
    dp = [[-INF]*-~X for _ in range(-~N)]
    dp[0][0] = 0
    for i in range(N):
        for idx in ids[i]:
            # err(i,idx,P[idx])
            for j in range(X,P[idx]-1,-1):
                # if N == 3:err(i,j-P[idx],dp[i][j-P[idx]])
                if dp[i][j-P[idx]] != -INF:
                     dp[i + 1][j] = max(dp[i + 1][j], dp[i][j - P[idx]] + U[idx] + K)
                if dp[i + 1][j - P[idx]] != -INF:
                    dp[i + 1][j] = max(dp[i + 1][j], dp[i + 1][j - P[idx]] + U[idx])
        
        for j in range(X+1):
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j])
            # if N==3:err(i+1,j,dp[i + 1][j])
    print(max(dp[N]))
    
        
if __name__ == '__main__':
    main()

```

# まとめ

ABC383Fを解いた。動的計画法を実装した。

F問題ともなると動的計画法一つでも
テーブルの更新方法が複雑過ぎて理解が難しかった。

この問題を解くには時期尚早な気がしてきたが
とりあえず目を通すだけでも勉強にはなった…ハズ。

いつかADTで出されたときに空でかけるようになりたい。
いいコードを書くために、いいコードを知る方法５選

## はじめに
すぐに効果が出にくいけれど今からでも試せて、積み重ねていくことでプログラマとしての強い土台ができるものをまとめてみます。

1. 公式ドキュメントを読む
言語やライブラリの「ベストプラクティス」を知る
1. オープンソースプロジェクトを読む
実際に使われている質の高いコードに触れる
1. コードレビューを受ける
経験者からのフィードバックを得る
1. リファクタリングを学ぶ
コードをシンプルで読みやすく改善する方法を学ぶ
1. 自分の過去のコードを見直す
成長を実感し、「気づき」を得る

## 1. 公式ドキュメントを読む
例えば、Rubyを学んでいるなら、公式のリファレンスやガイドを読みましょう。公式ドキュメントには、その言語やライブラリを作った人たちが意図した正しい使い方が記載されています。

### なぜこれがいいコードにつながるのか？
公式ドキュメントには、その言語の「ベストプラクティス」が詰まっています。これを知ることで、他の人にも理解しやすく、効率的に動くコードを書くことができるようになります。

https://www.ruby-lang.org/ja/documentation/

https://railsguides.jp/

## 2. オープンソースプロジェクトを読む
GitHubなどで公開されているオープンソースのプロジェクトを見ると、多くの実際に使われているコードに触れることができます。
自作アプリなどで使っているgemを見たり、Railsであれば本体のコードでもよいでしょう。


### なぜこれがいいコードにつながるのか？
公開されているコードの多くは、経験豊富なプログラマーによって書かれており、読みやすさやメンテナンス性が意識されています。自分が書いたコードと比べてみることで、改善点や新しい書き方を学べます。

https://github.com/heartcombo/simple_form

https://github.com/rails/rails

## 3. コードレビューを受ける
自分で書いたコードを他の人に見てもらい、フィードバックをもらうことも大事です。特に、経験者のレビューは宝の山です。

### なぜこれがいいコードにつながるのか？
自分では気づかない癖や間違いを指摘してもらえることで、コードを書くスキルが飛躍的に向上します。また、レビューアーの視点を知ることで、他の人が何を「いい」と感じるかも理解できます。


https://techbookfest.org/product/50CLAnEpRNhFNKzgq1aK78?productVariantID=gmDHaevdhz4T3T4eiGjWHe


## 4. 書籍やブログで「リファクタリング」を学ぶ
リファクタリングとは、コードの動作を変えずに構造を改善する作業のことです。これに特化した書籍やブログはたくさんあります。
リファクタリングをするためにまずはテストが書けていることも重要です。

### なぜこれがいいコードにつながるのか？
リファクタリングを学ぶことで、「もっとシンプルで読みやすいコード」にする方法が身につきます。これにより、自分のコードを客観的に見直す力が養われます。

https://leanpub.com/everydayrailsrspec-jp

https://amzn.asia/d/2kdf3fF

https://fukabori.fm/episode/114


## 5. 自分の過去のコードを見直す

学び始めた頃のコードをもう一度読み返してみましょう。

### なぜこれがいいコードにつながるのか？
最初は「これで動いているから大丈夫！」と思っていたコードが、後から見ると「なんでこんな書き方をしたんだろう？」と思うことがあります。この「気づき」こそが成長の証であり、いいコードを書くための大きな一歩です。

## まとめ

「いいコードを書く」の前に「いいコードを知ること」が大事という話でした。
これらの方法を試してみることで、徐々に「いいコード」の感覚がつかめてくるはずです。初めてのうちは時間がかかるかもしれませんが、焦らずに取り組みましょう！
Zedのリモートサーバーやってみた

# はじめに

この記事は、Qiita Advent Calendar 7日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/2b60d47a2d0e64a273c3

# 本編

前回の記事でZedを紹介しました。

https://qiita.com/0_terarin_0/items/9b53545f9e252835caee

ZedとはRust製のコードエディターでとてもシンプルなのが僕的に好きなポイントです。

https://zed.dev/

今回はこのRust製のエディターをAWS上に建てたインスタンスを開発機に見立ててリモート接続して開発してみたいと思います。

## AWSでインスタンスを立てる

別になんたっていいと思います。僕は今回はFedoraを無料枠内のEC2インスタンスで立てました。ちなみに、FedoraってOSイメージでなかなか出てこなかって、調べたらFedoraの公式ホームページから選択できるっぽいですね。

https://fedoraproject.org/cloud/download/

キーペアを作成してダウンロードしたら、```~/.ssh```フォルダに移動。そして忘れずにpemファイルの権限を変更しなければいけません。（大事）

```zsh
mv ~/Downloads/___.pem ~/.ssh/
chmod 600 ___.pem
```

## 接続

SSHで接続します。

```zsh
ssh -i ~/.ssh/___.pem USER@IP
```

さて、無事接続できましたでしょうか。

僕はここで、IPの固定をしていなかったりアクセス制限をしたりしたいのでここはTailscaleをインストールしました。Tailscaleについてはホームページを下にはっつけときます。（今回のアドカレでいつか取り扱うかも）

https://tailscale.com/

ここまでできたら、あとはリポジトリの準備です。僕はローカルにあるリポジトリをもともとGitHubに同期していましたのでそれをそのままクローンしました。

```zsh
sudo dnf install gh
gh auth login
gh repo clone
```

ここまでできたら準備完了です。ZedでCmd＋Ctl＋Oを押して、SSH接続したときのコマンドをそのままにゅ力してフォルダを指定すると、勝手に色々インストールされて見事につながります。

## 使い勝手

さて、使い勝手はと言いますと、ローカルで開発している時と全く変わらないです。僕は所詮Qiitaの記事を編集しているとかそういうレベルなのでどちらかというとストレージとしての利用ですが、全くもたつかないですし、だからといって何か困ることもないです。これならいろんなところから使う人にとってはSSHのキーだけ運べばいいので楽なのかもしれない。

# 最後に

いや〜なんか思いつきでやったことを記事にしたのですがこれ意外となしじゃないですね。ローカルの方がいつどうなるかわからないので今後とりあえずQiitaの記事はこの方法で編集していきたいと思います。
Arcaeaポテンシャル計算をExcelで作ってみた

# はじめに
皆さんはArcaea(アーケア)をご存じだろうか？Arcaeaとはスマートフォンで遊べる超感覚リズムゲームです。2d/3dの複合的な操作、グラフィックデザインの美しさ、圧倒的な音楽のクオリティ。
基本無料で遊べるとは思えないゲームです。私も大好きでよくプレイしています。
そんなArcaea、ゲーム内にはプレイヤーの実力を表すポテンシャルというものが存在する。楽曲のレベル、プレイヤーがたたき出した総合スコアによってポテンシャルが付与されます。
今回はこのポテンシャルが付与されるな内部計算の部分を自分で作ってみたいと思いました。


# 譜面定数について
Arcaeaの曲にはすべての楽曲に譜面定数というものが存在している。表記上は同じ難易度9の曲であっても9.0や9.5など0.1刻みで細かく決められている。


# スコア＆ポテンシャルについて
ArcaeaはMAX10000000+その曲のコンボ数でスコアが定められている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/88848536-0a3c-769d-a9f8-93b7c7624935.png)


スコアによって特定の値が譜面定数に加わりその曲のポテンシャルになる。
このポテンシャル数値best30曲（べ枠）に直近プレイした30曲のポテンシャル数値上位10曲（リセント枠）のポテンシャルを足して40で割ったものがプレイヤーのポテンシャルとなる。
(Arcaeaやってないと少しわかりずらいかもしれない)


# プログラムについて
今回はExcelを利用してべ枠の平均部分だけ作っていこうと思う。（リセント枠は時間がなく間に合わなかったので気が向けば作ろうと思う。）
流れとしては、事前に曲名とその曲の譜面定数を登録しておき、スコアを入力するだけでポテンシャル、評価、べ枠内での順位を返してくれる計算ツールとなっている。
分けて紹介していこう。

これが全体の見た目となっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/5bfbbe6d-18fa-d039-b39b-a2b217772b08.png)


***


スコアを入力した画面がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/28a71c2a-02d2-786e-735e-a46e670b6fb0.png)

***
各項目の計算式を見ていこう。

これは評価を出す計算式である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/6bb99262-7b2f-6b41-e2f3-5b6460fbc1b3.png)
最初のIF文はスコアが書かれてないときに空白を返す文である。
次からのIF文はスコアの値によって特定の文字を返している文です。
これによって実際のゲームと同じ評価を出すことができます。

***

これは実際のポテンシャルの計算式となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/4d8078c4-352d-2627-f167-13d70d5874bb.png)

最初のIF文は先ほどと一緒なので説明は省略する。
B6(譜面定数）に　H6(スコア)によってどの値を足すか分岐させている。
MAX関数は、引数として渡された数値の中で最大値を返します。ここでは、0と次の計算結果を比較しています。
つまり、ポテンシャルが0未満になる場合は、0を返し、それ以外の場合は計算結果をそのまま返します。これによって下限が０に設定することができました。

***
これはポテンシャルの数値に対する順位を表している。
上位30曲は自身のべ枠平均で使われていると一目見てわかるように色を付けている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/76eb6727-dcdc-3af5-79a8-2b196b456de2.png)
最初はこれまでと同じIF文。
そして、RANK関数を使ってその値が全範囲の楽曲中で何番目に大きいかを計算し、値を返してます。
***
これがべ枠の平均を求める式である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943853/37b43f85-d11a-ed48-36ff-ad7c7845768b.png)
AVERAGEIFで順位が30位以内の楽曲のポテンシャルを抽出してその平均を出すものとなっている。

# まとめ
久々にExcelで物を作ったので楽しかった。IF文でゴリ押しして作っているのでもっと簡潔にまとまるとこや説明文で違うとこがあれば教えてほしいです。Arcaea面白いからみんなやってね。
起業するならElixirシリーズSTEP12. 機能を特定せよ

https://qiita.com/Yoosuke/private/1f7f39e1ec19dd54f477

こちらの続き

## 機能を特定せよ

さて、戦略を作ったら、戦略を実行するために必要な機能を特定します。
機能が特定できなければ、その機能を実行する為に必要な能力が定められません。

戦略を実行するために「何をしなければならないか」を具体的な作業レベルまで落とし込むことが機能特定の本質です。

機能特定をする方法などは、ここでは語りませんが、もし知りたい方は、ぜひこちらのアンケートにご協力ください。ちなみに、普段はオープンに教えてない事なのでこの2024年のアドベントカレンダーの期間のみ限定で教えます。というのもまだこちらのアンケート足りてないのでここで伝えるにもまだまだ寂しい限りでしてw

https://forms.gle/HSLBB4opRggqyYyJA

さて、少し横道にそれましたが、機能を詳細まで特定したら、機能を評価しどこで実行すべきものかを検討します。

機能の落とし込みでよくある失敗は、

**機能を抽象的にしか定義しない**

```
悪い例：「マーケティング機能」
良い例：「SNSでの商品紹介」「メルマガ配信」「影響力のある文具ブロガーとの関係構築」
```

**既存の組織構造に引きずられる**

```
悪い例：「営業部の機能」「管理部の機能」
良い例：必要な機能から考え、後から最適な組織構造を検討する
```

**リソース制約を先に考えすぎる**

```
まずは理想の機能を定義し、その後でリソースに合わせて優先順位をつける
```
などが考えられます。

上手な機能の特定は次の観点を考えて作成してみてはいかがでしょうか。

**顧客視点での機能確認**
* 顧客接点ごとに必要な機能を確認する
* 顧客の期待に応える機能が抜けていないか

**時間軸での機能確認**
* 立ち上げ期に必要な機能
* 成長期に必要な機能
* 安定期に必要な機能

**競合との差別化機能の識別**
* 自社の強みを活かせる機能
* 競合と差別化できる機能

このように段階的に機能を特定することで、必要な能力の定義や組織設計につながっていきます。特に起業初期は、全ての機能を完璧に揃える必要はなく、というかリソース的に無理なので、重要度の高い機能から順に整備していけば良いくらいの考え方で取り組んでみてください。
モジュールバンドラーについて

普段、何気なく使用している `webpack` や `vite`。

今まできちんと理解せずに使用していたなと思い、
今回はモジュールバンドラーとは何かについてまとめていきます。

# モジュールバンドラーとは
そもそもモジュールバンドラーとは何でしょうか。

[レバテックLAB](https://levtech.jp/media/article/column/detail_537/)にて下記の記述がありました。

> バンドラーとは、JavaScriptファイルやCSSファイル、画像ファイルなどの、静的アセットをまとめてバンドル化するツールです。主に、JavaScriptモジュールのバンドルに主眼が置かれていることから、モジュールバンドラーとも呼ばれます。また、単純にビルドツールと呼ばれることもありますが、表しているものはほとんど同じです。

<br />

なるほど。
その名の通り、モジュールをバンドルする（束ねる）もののようです。

各種ファイルをひとまとめにすることで、
通信時間や通信の回数を抑えることができ、
効率的に処理を実行できるのですね。

# 主な機能
ではモジュールバンドラーの主な機能をみていきましょう。

## ①モジュールの依存関係の解決
複数のJavaScriptファイル間の依存関係を解析し、それを適切な順序でまとめます。

フロントエンド開発では、JavaScriptファイルを小さなモジュールに分割し、
それらを必要な部品で組み合わせて使用する「モジュール化」が一般的な手法です。

モジュールバンドラーは、
そのモジュール化により読み込み時間が増え、
依存関係を把握しづらくなるといった問題を解決してくれます。

## ②トランスパイルと最適化
バンドルされたファイルを最適化し、コードのサイズを小さくします。

モジュールバンドラーは、
空白や改行、コメントの除去など最小化/圧縮処理、
TreeShakingといった最適化処理を行ってくれます。

また、ES6やTypeScriptなど、
モダンなJavaScriptの記法を古いブラウザ向けに変換します。

## ③アセットの統合
CSSや画像、フォントなどの非JavaScriptファイルも一緒にバンドルします。

JavaScriptファイルだけではなく、
アセットバンドルというプロセスを介して他のCSSや画像などもバンドルできます。

# 主な種類
ここまで、モジュールバンドラーについて学んできました。
ではどのような種類があるのでしょうか。

## WebPack
最も広く使用されているモジュールバンドラー。
プラグインやローダーを使用してJavaScriptファイル以外もバンドル可能。
設定が複雑。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669971/4e16afef-b9d8-8c55-ba0a-8fb13de684d9.png" width="400">

## Parcel
設定不要なゼロコンフィグアプローチを採用し、不要な初期設定なし。
様々なアセットをバンドル可能。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669971/c6f6875e-b19f-6bb3-a366-a1b993863a2a.png" width="400">

## Rollup
軽量でモダン。
コードの出力サイズを最小化することに優れている。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669971/aaf46da4-9e3d-775a-f793-9cfef515aab6.png" width="400">

## Vite
開発サーバーの起動が高速。
開発時と本番ビルド時に異なるアプローチ（Rollupを内部的に使用）を採用。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669971/1a4d1d73-8a03-002d-a555-4f5574b11a5e.png" width="400">

# おわりに
今回はモジュールバンドラーの概要についてまとめました。

今度はそれぞれ個別の種類について調べ、
まとめたいなと思います。

それでは。

# 参考文献
https://levtech.jp/media/article/column/detail_537/

https://tcd-theme.com/2021/11/javascript-webpack.html

https://kinsta.com/jp/blog/rollup-vs-webpack-vs-parcel/

https://kinsta.com/jp/blog/vite-vs-webpack/
複数アカウントが存在するWindowsマシンへのVscodeインストール

### 実現したいこと
* すべてのユーザーが利用できるvscodeと拡張機能のインストール。
* 対象OSはwindows10 / windows11
* 利用者は個別に拡張機能をインストールする権限はない。
* あくまで教育機関などに向けた大量の環境セットアップとして。

### 流れ
* codeをシステムインストールする。
* 拡張機能をc:\users\publicの配下へインストールする。
* コンテキストメニューから起動する際のふるまいも変える。
* ***1ユーザから上記の設定を行ったら、すべてのユーザーの設定が完了してほしい***

### システムインストーラのダウンロード
https://code.visualstudio.com/download#

### インストール(コマンド)
```Powershell
.\VSCodeSetup-x64-1.95.3.exe /SILENT /NORESTART /NOCANCEL /MERGETASKS="!runcode,addcontextmenufiles,addcontextmenufolders,associatewithfiles,addtopath"
```

#### コマンドの説明
* /SILENT : GUIなしでインストールする。

* /NORESTART : インストール後にシステムを再起動しない。

* /NOCANCEL : インストール中にキャンセルボタンを押せないようにする。

* /MERGETASKS : インストール中に有効または無効にするタスクを指定します。
    * !runcode: インストール後にVSCodeを自動で起動しない。
    * addcontextmenufiles: ファイルの右クリックメニューにVSCodeで開くオプションを追加。
    * addcontextmenufolders: フォルダの右クリックメニューにVSCodeで開くオプションを追加。
    * associatewithfiles: ファイルの関連付けを有効化。
    * addtopath: システムのPATHにVSCodeを追加。


### 各種拡張機能をインストール
* 拡張機能をすべてのユーザーから利用できるように、パブリックフォルダにインストールする
* & bin\codeのパス --extensions-dir 拡張機能のインストール先 --install-extension インストールする拡張機能

``` PowerShell
    & "C:\Program Files\Microsoft VS Code\bin\code" --extensions-dir "c:\users\public\code\extensions" --install-extension ms-python.python
```

ちなみに、拡張機能をインストールする際の正式名称は以下のように調べる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299794/d8a47270-e86f-0f4f-c01b-5ab3afab41c7.png)


### コンテキストメニューからcodeを利用する際のふるまいを変える
* レジストリの変更を行います。

* フォルダのバックグラウンドを右クリックしたときのふるまい
``` PowerShell
Set-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Directory\Background\shell\VSCode\command" -Name "(default)" -Value '"C:\Program Files\Microsoft VS Code\bin\code" "%V" --extensions-dir "c:\users\public\code\extensions"'
```

* フォルダを右クリックしたときのふるまい
``` PowerShell
Set-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\VSCode\command" -Name "(default)" -Value '"C:\Program Files\Microsoft VS Code\bin\code" "%V" --extensions-dir "c:\users\public\code\extensions"'
```

* その他
``` PowerShell
Set-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\*\shell\VSCode\command" -Name "(default)" -Value '"C:\Program Files\Microsoft VS Code\bin\code" "%V" --extensions-dir "c:\users\public\code\extensions"'
```

### Vscodeを起動する
* 適宜batやショートカットにしてそこからしか起動できない運用にする必要がある。

``` PowerShell
& "C:\Program Files\Microsoft VS Code\bin\code" --extensions-dir "c:\users\public\code\extensions"
```
ragas context_relevancy は無くなってるので、answer_relevancy を使おう

# 背景

以下の記事を試そうとしたら、エラーが出たので、その対処記録

https://tech-lab.sios.jp/archives/41949

# 結論

<code>context_relevancy</code> は現状無いので、<code>answer_relevancy</code> を使おう

まぁ、目的違ってたらダメだけど

GitHub issues にも挙がってた

https://github.com/explodinggradients/ragas/issues/1210


## 参考：metrics on ragas

https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/?h=relevancy

## 参考: metrics on GitHub

https://github.com/explodinggradients/ragas/tree/9f5cccc53987118c2876f0018787f8341f8c4f5a/src/ragas/metrics

# あとがき

正しい回答を人間が入れないといけないわけだけど、なんとかならんもんかな :thinking:
シェルスクリプトでread中にシグナルが発生したらどうなるか？

## はじめに

シェルスクリプトで `read` 中にシグナルが発生したらどうなるか？の実験です。

## 実験

こんなスクリプトで実験

```sh
#!/bin/sh

trap 'echo usr1' USR1
(sleep 2; kill -s USR1 $$) &
echo "read start"
read line
echo "read aborted: $?"
```

## 結果

dash と FreeBSD sh と NetBSD sh と ksh93 と ksh88 は `read` が中断される。

```console:dash
$ dash read.sh
read start
usr1
read aborted: 1
```

```console:FreeBSD sh
$ sh read.sh
read start
usr1
read aborted: 158  （128 + 30:USR1)
```

```console:NetBSD sh
$ sh read.sh
read start
usr1
read aborted: 1
```

```console:ksh93
$ ksh read.sh
read start
usr1
read aborted: 266  （128 * 2 + 10:USR1)
```

```console:ksh88 on Solaris 10
$ ksh read.sh
read start
usr1
read aborted: 0
```

bash は `read` 中に割り込まれるが中断されない。

```consonle
$ bash read.sh
read start
usr1
                    （enterを押す）
read aborted: 0
```

mksh と NetBSD ksh と OpenBSD sh/ksh と yash と zsh は `read` 中に割り込まれない。

```console
$ mksh read.sh
read start
                    （enterを押す）
usr1
read aborted: 0
```

```console:NetBSD ksh
$ sh read.sh
read start
                    （enterを押す）
usr1
read aborted: 0
```

```console:OpenBSD sh/ksh
$ sh read.sh
read start
                    （enterを押す）
usr1
read aborted: 0
```

```console
$ yash read.sh
read start
                    （enterを押す）
usr1
read aborted: 0
```

```console
$ zsh read.sh
read start
                    （enterを押す）
usr1
read aborted: 0
```

## 結論

バーラバラ
生成AIで高品質なアイコン画像を作成するTips

プロフィールのアイコン画像を作成する際、生成AIを使っても思い通りの結果にならず、不要な要素に悩まされたことはありませんか？今回は、そんなお悩みを解決し、魅力的なアイコンを簡単に作成する方法をご紹介します！この手順を踏めば、理想的なアイコンが手に入ります。

## 1. 参考画像をインターネットで探す

まず最初に、自分が目指すイメージに近い参考画像をネット上で探しましょう。色味やデザイン、雰囲気など、自分の好みに合った画像を見つけることが重要です。私の場合、特定の色合いやスタイルが気に入った画像があったので、その雰囲気を活かしたアイコンを作成することにしました。

![私が選んだ参考画像](https://storage.googleapis.com/zenn-user-upload/f5a23dbd6727-20241209.webp)

## 2. ChatGPTで画像生成のプロンプトを作成

次に、参考画像をもとにChatGPTに画像生成の指示を出します。1で選んだ参考画像を添付して、以下のようなプロンプトを入力してみてください。

```
添付した画像のキャラクターの顔を中心としたイラストを作成してください。
特に、色味や色の濃淡を添付した画像に合わせてください。
```

![](https://storage.googleapis.com/zenn-user-upload/62587af18ecd-20241209.png)

このプロンプトにより、参考画像の雰囲気や色味を反映したキャラクターの画像が生成されます。

![](https://storage.googleapis.com/zenn-user-upload/a802b0fcd4a9-20241209.png)

## 3. Canvaで画像を編集

生成されたキャラクターの画像を取得したら、デザインツールの**Canva**に移動します。Canvaは初心者でも直感的に使えるオンラインデザインプラットフォームで、多くの編集機能が備わっています。

## 4. 背景リムーバー機能で背景を削除

Canvaには、ワンクリックで背景を削除できる**背景リムーバー**機能があります。この機能を使って、キャラクターの背景を消しましょう。これにより、アイコンとして使用しやすい透過画像が完成します。

削除前
![](https://storage.googleapis.com/zenn-user-upload/97c5f7a19fed-20241209.png)

削除後
![](https://storage.googleapis.com/zenn-user-upload/94fe03cbb650-20241209.png)


## 5. 背景を単色に設定して仕上げ

![](https://storage.googleapis.com/zenn-user-upload/26150e357e79-20241209.png)

最後に、キャラクターの背景をお好みの単色に設定します。背景色は、キャラクターの色味と調和する色を選ぶと、より一体感のある仕上がりになります。

![](https://storage.googleapis.com/zenn-user-upload/de72e2a16e60-20241209.png)

以上で完成です！いかがでしょうか？この基本的な手順を活用すれば、さまざまなテイストの高品質なアイコンを簡単に作成できます。是非お試しください！

# この方法で作成した他のアイコン

## サンプル1

元画像
![](https://storage.googleapis.com/zenn-user-upload/c46bec7d6548-20241209.png)

完成したアイコン
![](https://storage.googleapis.com/zenn-user-upload/9026fc2eb42c-20241209.png)


## サンプル2

元画像
![](https://storage.googleapis.com/zenn-user-upload/ed7ea7f1cd1b-20241209.webp)

完成したアイコン

![](https://storage.googleapis.com/zenn-user-upload/afed99ba430d-20241209.png)

# 宣伝

https://www.devspot.jp

クラウドソーシングサイトで活動するエンジニアの仕事探し・提案文の作成をサポートするサービスを運用しています。AIを活用して効率的に案件に応募できます。
現在Beta版につき無料でご利用できるので、エンジニアの方はぜひ使っていただけると嬉しいです！
参照型と値型の違いをnullから考える

# はじめに
プログラミングでは参照型と値型はよく出てきて理解することは重要です。特にnullの扱いには違いがあり、この違いを意識しないと思わぬバグを生んでしまうかもしれません。
この記事では、参照型と値型の違いをnullという観点から解説していきます！

# 結論
|  | 参照型 | 値型 |
|:-:|:-:|:-:|
|メモリの扱い   |  メモリ(ヒープ)にデータが格納され、変数にはその参照アドレスが格納 | スタックにデータ自体格納  |
|nullの扱い   | nullを持てる(参照が未設定)  |  通常はnullを持てない。Nullable型では可能 |
|コピー時の動き   | 参照がコピーされる(同じオブジェクトを指す)  |  値がコピーされる(独立したデータが作られる)|

# nullの扱い
## 参照型のnull
参照型では、変数がオブジェクトを指していない場合にnullを持つことができ、nullは「参照が設定されていない」状態を表します。
nullの状態のまま、プロパティやメソッドにアクセスしようとするとnullによる例外( __NullReferenceException__ )が発生するので注意する必要があります。
```C#: NullExample.css
Person? person = null;
Console.WriteLine(person.Name);  // 例外: NullReferenceException発生
```

## 値型のnull
値型(int、double、boolなど)は通常nullを持てません。しかし、C#ではNullable型を使用することで、値型にもnullを割り当てることができます。
```c#:
int? age = null;  // int型にはnullを代入できないが、Nullable型では可能
```

# コピー
## 参照型のコピー
参照型では、コピー時に参照アドレスがコピーされるため、コピー元とコピー先が同じオブジェクトを指します。
```C#: copy1.css
Person person1 = new Person { Name = "Alice" };
Person person2 = person1;  // 参照をコピー

person2.Name = "Bob";
Console.WriteLine(person1.Name);  // 結果: Bob(同じオブジェクトを指している)
```

## 値型のコピー
値型では、コピー時に値そのものがコピーされるため、コピー元とコピー先は独立しています。
```c#: copy2.css
int num1 = 10;
int num2 = num1;  // 値をコピー

num2 = 20;
Console.WriteLine(num1);  // 結果: 10(元の値は変更されない)
```

# おわりに
参照型と値型の概念について、私はnullの扱いを交えることで理解しやすくなりました！ただし、適切なnullチェックやデフォルト値設定を忘れないように注意しましょう。
Gitについてまとめてみた

## 1.Gitとは
### バージョン管理とは何か？
→変更を記録すること

バックアップや変更履歴として活用できる

### GitHubとは違うのか？

→Gitを提供するWEBサービス

Gitはシステム

## 2.Subversionと比較する

### バージョン管理システムの種類

バージョン管理システムは以下の表のように2種類に大別される
今回はSubversionと比較する

| システム　| 種類 |
|:-:|:-:|
| Subversion, CVS | 集中型 |
| Git | 分散型 |

### それぞれの特徴

`Subversion→集中型`

- オンラインでのみ操作できる
- 変更を即時に反映できる

`Git→分散型`

- オフラインでも操作できる
- 変更を好きなタイミングに反映できる

## 3.GitHubとは

### GitHubとは
Gitを提供するWEBサービスである

Git→個人向け
GitHub→組織向け

### オープンソース

プルリクエスト(変更の提案)により意思決定がひらかれたものになっている

### GitHub Enterprise

[GitHub EnterpriseのURL](https://docs.github.com/ja/enterprise-cloud@latest/admin/overview/about-github-for-enterprises)

GitHubをオンプレミス環境で運用可能

## 4.他サービスのオンプレミス環境プラン紹介

### Bitbucketオンプレミスプラン

[BitbucketオンプレミスのURL](https://www.atlassian.com/ja/software/bitbucket/guides/getting-started/overview#a-brief-overview-of-bitbucket)

### GitLab

[GitLabのURL](https://about.gitlab.com/ja-jp/pricing/)

## まとめ

本記事はオンプレミス環境でのGit運用についての備忘録としてまとめた

## 参考

[「改訂2版 わかばちゃんと学ぶ Git使い方入門〈GitHub、SourceTree、コマンド操作対応〉」(シーアンドアール研究所) 湊川 あい](https://www.c-r.com/book/detail/1409)
Azure Database for MySQLをTerraformで作る

Azure Database for MySQLをTerraformで作りました。

```main.tf
provider "azurerm" {
  subscription_id=""
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "example-resource-group"
  location = "Japan East"
}

resource "azurerm_mysql_flexible_server" "example" {
  name                 = "example-mysql-server"
  location             = azurerm_resource_group.example.location
  resource_group_name  = azurerm_resource_group.example.name
  administrator_login = "your_admin_user"
  administrator_password = "MyStr0ngP@ssw0rd123"
  sku_name              = "GP_Standard_D2ds_v4"
  backup_retention_days = 7
  version               = "8.0.21"
}
```

sku_nameに悩みましたが、これでいけました。
Clojure: RingでTodoアプリを作る - Ringとは

![advent_calendar_2024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/f4cd8ce0-6352-a1d8-4cae-f39dd44f4def.png)

[*Advent Calendar 2024 Day 12*](https://qiita.com/advent-calendar/2024/clojure)

今日からは実際に`Todo`アプリを作っていきます

`Todo`アプリを `Ring` というライブラリを使って作っていきます

## Ringとは

Webアプリケーションを構築するためのライブラリおよび仕様です。

## 基本構造

`Ring` は以下のようなリクエストとレスポンスを扱います

- リクエスト
    - `:uri`
        - リクエストされたパス
    - `:request-method`
        - HTTPメソッド
    - `:headers`
        - HTTPヘッダーのマップ
    - `:body`
        - リクエストの本文
- レスポンス
    - `:status`
        - HTTPステータスコード
    - `:headers`
        - レスポンスヘッダーのマップ
    - `:body`
        - レスポンスボディ

### ハンドラー

ハンドラーは先ほどの**リクエストを受け取り、レスポンスを返す**関数です。

```clojure
(defn handler [request]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, World!"})
```

### ミドルウェア

`Ring`はミドルウェアを通じて機能を拡張する仕組みを持っています。
ミドルウェアはハンドラーをラップしてその動作を変更することができます。

例えばリクエストのログを出したりできます。

```clojure
(defn logging-middleware [handler]
  (fn [request]
    (println "Request received:" request)
    (handler request)))
```

### Ringを使ってみる

まず依存を追加します

```clojure:project.clj
  :dependencies [[org.clojure/clojure "1.11.1"]
                 [ring/ring-core "1.10.0"]
                 [ring/ring-jetty-adapter "1.10.0"]]
```

そしてプロジェクトのエンドポイントを指定します

```clojure:project.clj
  :main todo.core
```

名前空間`todo.core`にエントリーポイントとなる`-main`関数を作成します

```clojure:core.clj
(ns todo.core
  (:require [todo.http :as http]
            [ring.adapter.jetty :as jetty]))

(defn -main []
  (println "アプリケーションを起動します")
  (jetty/run-jetty handler {:port 3000}))
```

前の`-main`で使っていましたが、`handler`を設定します。

```clojure:core.clj
(defn handler
  [request]
  (println request)
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, World!"})
```

これで簡単なアプリケーションが起動できるようになりました。

```clojure:core.clj
(ns todo.core
  (:require [todo.http :as http]
            [ring.adapter.jetty :as jetty]))

(defn handler
  [request]
  (println request)
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, World!"})

(defn -main []
  (println "アプリケーションを起動します")
  (jetty/run-jetty handler {:port 3000}))
```

起動してみます

```bash
$ lein run
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
アプリケーションを起動します
```

起動できました。
リクエストを送ってみます

```bash
$ curl localhost:3000
Hello, World!
```

無事`Hello, World`が返ってきました

明日からは本格的にTodoアプリを作っていきます