OmniAICreator/Qiita-1.07M huggingface dataset:
("test"+3)言語別の文字列と整数の結合の振る舞い

## はじめに
言語別の文字列と整数の結合の振る舞いについてまとめました。
"test" + 3 のようなことが直接できるかです。


## **できる言語**（自動的に数値を文字列に変換して結合）

これらの言語では、**整数と文字列を直接結合できる**（整数が文字列に自動的に変換される）ため、`"test" + 3` は問題なく動作します。

- **C#**

```C#
Console.WriteLine("test" + 3);  // "test3"
```

- **Java**

```Java
System.out.println("test" + 3);  // "test3"
```

- **JavaScript**

```JavaScript
console.log("test" + 3);  // "test3"
```

- **PHP**

```PHP
echo "test" . 3;  // "test3"
// ※PHPでは`+`ではなく`.`で結合します
```

---

## **できない言語**（型エラーが発生）

これらの言語では、**整数と文字列を直接結合することはできません**。  
整数を明示的に文字列に変換する必要があります。

- **C**

```C
// Cでは文字列と整数を直接結合できません。
// フォーマット指定子を使用して結合します。
printf("test%d", 3);  // "test3"
```

- **C++**

```C++
// C++では直接結合できないため、以下の方法が必要です。
#include <string>
#include <iostream>

int main() {
    std::string result = "test" + std::to_string(3);
    std::cout << result << std::endl;  // "test3"
}
```

- **Go**

```Go
// Goでは文字列と整数を直接結合できないため、明示的な変換が必要です。
import "fmt"

func main() {
    fmt.Println(fmt.Sprintf("test%d", 3))  // "test3"
}
```

- **Python**

```Python
# Pythonでは文字列と整数を直接結合できないため、変換が必要です。
print("test" + str(3))  # "test3"
```

- **Swift**

```Swift
// Swiftでは型エラーが発生するため、整数を文字列に変換する必要があります。
let num = 3
let result = "test" + String(num)
print(result)  // "test3"
```

---

## まとめ（ついでに繰り返し演算子 `*` も）

| 演算子       | 対応する言語                                   | 例                                       | 備考                                  |
|--------------|-----------------------------------------------|------------------------------------------|---------------------------------------|
| **`+`**      | **C#, Java, JavaScript, PHP**                | `"test" + 3` → `"test3"`                 | 数値が自動的に文字列に変換され結合     |
| **`.`**      | **PHP**                                      | `"test" . 3` → `"test3"`                 | PHPでは`+`ではなく`.`で結合します      |
| **`+`**（エラー） | **C, C++, Go, Python, Swift**                 | `"test" + 3` → 型エラー                  | 明示的に数値を文字列に変換する必要あり |
| **回避方法** | **Python**                                   | `"test" + str(3)` → `"test3"`            | `str()`を使用                         |
|              | **C**                                        | `printf("test%d", 3);` → `"test3"`       | フォーマット指定子で結合               |
|              | **C++**                                      | `std::to_string(3)`を使用して結合         |                                        |
|              | **Go**                                       | `fmt.Sprintf("test%d", 3)`               | フォーマットして結合                   |
|              | **Swift**                                    | `"test" + String(3)` → `"test3"`         | 明示的に変換                          |
| **`*`**      | **Python, Ruby, PHP**                        | `"test" * 3` → `"testtesttest"`          | 文字列を指定回数繰り返す               |
|              | **Go**                                       | `strings.Repeat("test", 3)` → `"testtesttest"` | `strings.Repeat`を使用               |
Google Driveで管理している複数のスプレッドシートが更新されたらSlack通知する(GAS)

## 概要

Google Driveのフォルダ内にある複数のスプレッドシートを1つのGoogle Apps Script(GAS)でお手軽に監視できるのかが気になり、試験的に作成してみました。
大量のスプレッドシートを監視したいけど、各々のシートに対してGASを作成するのは辛いな...という方のお役に立てるかも？


今回紹介するGASを活かすには以下条件があります。ご注意ください
 - 対象スプレッドシートを特定のGoogle Driveで管理している



## 全体の流れ
以下の流れで記事を進めていきます。
1.GASの作成
2.GASのトリガー設定
3.動作確認


## GASの作成
GAS内で指定しているSlack Webhookは公式ドキュメントを参照し設定をしています。
※本記事では詳細な手順は割愛します。

https://api.slack.com/messaging/webhooks

GASのコードは以下です。
今回は15分以内に更新されたスプレッドシート名と更新者のメールアドレスを通知します。

```javascript
var SLACK_WEBHOOK_URL = // Slack Webhook URLを指定

function notifyRecentChanges() {
  var folderId = //フォルダIDを指定や共有ドライブIDを指定
  var folder = DriveApp.getFolderById(folderId);

  // フォルダ内のすべてスプレッドシート情報を取得
  var files = folder.getFilesByType(MimeType.GOOGLE_SHEETS);
  var now = new Date();
  // 15分前の日時を取得
  var fifteenMinutesAgo = new Date(now.getTime() - 15 * 60 * 1000); 

  // 各ファイルの最終更新日時をチェック
  while (files.hasNext()) {
    var file = files.next();
    var lastUpdated = file.getLastUpdated();
    
    if (lastUpdated > fifteenMinutesAgo) {
      var spreadsheet = SpreadsheetApp.open(file);
      var user = Session.getActiveUser().getEmail();
      var message = {
        text: 'スプレッドシートが更新されました',
        attachments: [
          {
            title: '更新されたスプレッドシート',
            title_link: spreadsheet.getUrl(),
            text: '更新者: ' + user + '\nスプレッドシート名: ' + spreadsheet.getName(),
            color: '#36a64f'
          }
        ]
      };
      // Slack通知
      sendSlackNotification(message);
    }
  }
}

function sendSlackNotification(message) {
  var options = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(message)
  };
  
  UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
}

```

使用しているAPPの公式ドキュメントは以下です。

DriveApp

https://developers.google.com/apps-script/reference/drive/drive-app?hl=ja


SpreadsheetApp

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app?hl=ja


## GASのトリガー設定
15分以内に更新されたスプレッドシート名と更新者のメールアドレスを通知したいので、
GASコンソールで「トリガー」 > 「トリガーを追加」を選択し、トリガー作成をします。

![スクリーンショット 2024-12-21 8.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/014b7e1e-4771-0bae-a0f6-d995902c6ee2.png)


以上で完了です。動作確認してみます。

## 動作確認
今回使用している検証用スプレッドシートは以下です。
予め、特定のフォルダにまとめて格納しておきます。

![スクリーンショット 2024-12-06 23.51.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/524cf362-12ac-e5f5-1824-894e4b617ea2.png)


各々スプレッドシートを修正してみます。
※ほぼ連続で修正しました
　→ Slack通知されました。

![スクリーンショット 2024-12-21 8.59.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/ee188348-e8f3-217e-cd58-1f169fe7e525.png)



今度は、sample1だけを修正してみます。
　→ sample1だけがSlack通知されました。

![スクリーンショット 2024-12-21 8.16.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/24eb7859-092a-72ea-e05c-baa082f9bbf9.png)

以上です。



----

共有ドライブや共有フォルダで管理していれば、1つのGASでスプレッドシートをお手軽に監視することができました。
トリガー設定も柔軟にできるので便利ですね。
[re:Invent 2024新発表]生成AIのコストを削減！【Amazon Bedrock インテリジェントプロンプトルーティング】と【Amazon Bedrock プロンプトキャッシュ】について

# ■はじめに
この記事は株式会社ナレッジコミュニケーションが運営する [クラウドAI by ナレコム Advent Calendar 2024](https://qiita.com/advent-calendar/2024/knowcom-cloudai)の10日目にあたる記事になります！

本記事ではre:Invent 2024で発表されたAmazon Bedrockの新機能「インテリジェントプロンプトルーティング」と「プロンプトキャッシュ」について、ビジネスユーザー向けにサービスの概要や特徴、メリットについて簡単にご紹介致します。
生成AIを使ってるけど、本格的に利用するのは、コストが高くて運用に不安を感じている方に向けた機能となってます。

# ■背景
 生成AIは、質問や依頼に応じてテキストや画像を生成する技術です。現在、さまざまな場面で利用が広がっています。しかし活用において、以下の課題があります。
・コストの負担
・応答の遅延（レイテンシー）
・管理の煩雑さ

# ■新機能の概要
(1)Amazon Bedrock インテリジェントプロンプトルーティング
プロンプトの内容に基づいて、適切な基盤モデルを自動選択するサービスとなってます。大きな荷物はトラック、小さな荷物は自転車便で運ぶように、効率よくリクエストを処理します。
・利点:
　最大30%のコスト削減。
　モデルの選択が不要で、運用が簡単。

・仕組み
プロンプト解析: 内部モデルがプロンプトを解析し、適切なモデルを予測。
モデル選択: 予測結果に基づき、応答品質とコストのバランスを最適化するモデルを選択。
フォールバック対応: 適切なモデルがない場合は、フォールバックモデルに切り替え
※注意: プレビュー段階では英語のプロンプトのみ対応

(2)Amazon Bedrock プロンプトキャッシュ
頻繁に使用するプロンプトをキャッシュして再利用可能にするもので同じ質問を覚えておいて、すぐに答えられる仕組みとなってます。
・利点:
　最大90%のコスト削減。
　最大85%のレイテンシー短縮。

・仕組み
　プロンプトが一定のトークン数を超えるとキャッシュされる仕組み。
　各モデルのキャッシュ可能なトークン数やチェックポイント数が異なります。
例: Claude 3.5 Haikuは最大8,192トークンをキャッシュ可能。


# ■料金について
(1)Amazon Bedrock インテリジェントプロンプトルーティング
この機能自体に追加料金はかかりません。使用した基盤モデルの料金を支払います。

(2)Amazon Bedrock プロンプトキャッシュ
キャッシュに保存されたデータの読み取りは、通常の入力トークンと比較して最大90%割引されます。Amazon Novaモデルではキャッシュ書き込みに追加料金はかかりませんが、Anthropicモデルではキャッシュ書き込みに追加費用が発生します。

# ■利用可能なリージョン
(1)Amazon Bedrock インテリジェントプロンプトルーティング
・米国東部 (バージニア北部)
・米国西部 (オレゴン)

(2)Amazon Bedrock プロンプトキャッシュ
・米国西部 (オレゴン): Anthropic’s Claude 3.5 Sonnet V2 と Claude 3.5 Haiku
・米国東部 (バージニア北部): Amazon Nova Micro、Amazon Nova Lite、Amazon Nova Pro

※他のリージョンでも今後利用可能になる予定です。最新情報はAWSの公式ページをご確認ください。

# ■ユースケース
(1)Amazon Bedrock インテリジェントプロンプトルーティング
報告書やブログ記事等のテキスト生成、要約：長文の文章を簡潔に要約してくれます。必要な情報を短時間で抽出することも可能なため、複雑なレポートやニュース記事を理解する際に便利です
(2)Amazon Bedrock プロンプトキャッシュ
・ドキュメントQ&Aシステム: ユーザーが同じドキュメントに対して複数回質問する際、プロンプトキャッシュを使用するとコスト削減と高速化が可能。
・コーディングアシスタント: 同じコードコンテキストを管理する際に効率的。

# ■最後に
Amazon Bedrockの新機能「インテリジェントプロンプトルーティング」と「プロンプトキャッシュ」は、生成AIの運用効率を高め、コスト削減や応答速度向上を実現する便利なツールです。
今後もアップデートが楽しみですね！お読み頂きありがとうございました！
MongoDBの基本

# MongoDBの基本

MongoDBは、NoSQL型のデータベースで、ドキュメントオリエンテッドであり、フレキシブルなデータ構造とスケーラビリティを重視しています。この記事では、MongoDBの基本概念や使用方法を解説します。

---

## 紹介

MongoDBは、JSONライクなドキュメントを保存し、スキーマレスなデータモデルを提供します。リレーショナル型データベースと比較して、フィールドの型や構造に自由度があり、変更やスケーリングが容易です。

---

## MongoDBの基本概念

### データ構造
- **データベース**: MongoDBに保存されるデータの集合。
- **コレクション**: ドキュメントの集合で、リレーショナルDBの「テーブル」に相当。
- **ドキュメント**: JSONライクな構造のデータユニット。たとえば、一人のユーザー情報に相当する。

### BSON
MongoDBの内部では、JSONの⭐バイナリデータ型⭐として「BSON」が使われます。BSONは、JSONに例えてバイナリデータ型やインデックス情報を含むことができ、急速な検索が可能です。

---

## MongoDBの基本操作

### 1. データベースの作成
「myDatabase」という名前のデータベースを作成します。

#### CMDでの実行例
1. **MongoDBシェルを起動**
   ```bash
   mongo
   ```

2. **データベースの選択**:
   ```bash
   use myDatabase
   ```
   これは「myDatabase」という名前のデータベースに切り替えます。

3. **データベースの作成は最初のデータを挿入するときに行われます**:
   ```bash
   db.myCollection.insertOne({ name: "Taro", age: 30 })
   ```
   これにより、`myDatabase`と「myCollection」という名前のデータベースとコレクションが自動的に作成されます。

4. **データベースの確認**:
   作成されたデータベースを確認するには次のコマンドを実行します。
   ```bash
   show dbs
   ```
   この事により、現在使用可能なデータベースの一覧が表示されます。

### 2. コレクションの作成
「myCollection」という名前のコレクションを作成します。

```bash
db.createCollection("myCollection")
```

### 3. ドキュメントの挿入
一つのドキュメントをコレクションに挿入する例です。

```bash
db.myCollection.insertOne({ name: "Taro", age: 30 })
```

複数のドキュメントを一気に挿入することも可能です。

```bash
db.myCollection.insertMany([
  { name: "Hanako", age: 25 },
  { name: "Ken", age: 35 }
])
```

### 4. データ検索
すべてのドキュメントを検索します。

```bash
db.myCollection.find()
```

条件を指定して検索することも可能です。

```bash
db.myCollection.find({ age: { $gte: 30 } }) # 30歳以上
```

### 5. データ更新
名前が"Taro"のドキュメントの年齢を更新します。

```bash
db.myCollection.updateOne({ name: "Taro" }, { $set: { age: 31 } })
```

複数ドキュメントを更新することも可能です。

```bash
db.myCollection.updateMany({}, { $inc: { age: 1 } }) # 年齢を1歳増加
```

### 6. データ削除
名前が"Taro"のドキュメントを削除します。

```bash
db.myCollection.deleteOne({ name: "Taro" })
```

条件に一致するすべてのドキュメントを削除する例です。

```bash
db.myCollection.deleteMany({ age: { $lt: 20 } }) # 20歳未満を削除
```

---

## ユースケース
MongoDBは次のようなシナリオで最適です。

1. **リアルタイムアプリ**: チャットやトラッキングシステム
2. **コンテンツ管理システム**: CMSやブログ
3. **IoTデータの集約と分析**
4. **eコマースプラットフォーム**: 製品カタログの管理

---

MongoDBの基本的な概念や操作はこれです。クラウド上でのインスタンスやMongooseの利用で、MongoDBの最大ポテンシャルを生かすことができます。ぜひ試してみてください。
challenge_clubで発表した話

challenge_clubで3月に発表させてもらう機会をもらいましたので振り返りで記事を書いてみます。
# そもそもあなた誰
・情報系院卒
・半導体メーカーを経て
・Web系自社開発ベンチャーで仕事中
のスペックです。

# どの会で発表したの
[自動運転AIチャレンジ2023-SIM大会振り返り & 表彰式前夜祭 & 2024年度も頑張ろう会](https://challenge-club.connpass.com/event/310922/)です。

# きっかけは
[自動運転AIチャレンジ](https://www.jsae.or.jp/jaaic/2023ver/simulation_result/)で入賞したのでやったことを発表してみようかなというところです。

# 発表準備
うちにはubuntuしかないのでopenofficeでスライド作りました。
あと通常は無線のヘッドホンを使っていたのですが話すほうがドライバが対応していないことが直前に判明、すぐ対処法を見つけ対処しました。

# 発表してみてどうだった
自動運転AIチャレンジでやったことを中心にお話しました。
何やったのか興味ある方は私の過去記事を見てください。
話すのは全くをもってダメなので改善していかないとと思った次第。
今後のことも考えて色々勉強会で発表していこうと意思を固めました。
スタイリッシュなプロンプトUIをスクリプト実行時に実現する方法

この記事は[ソニックガーデン プログラマ アドベントカレンダー](https://qiita.com/advent-calendar/2024/sonicgarden)の22日目の記事です。

# はじめに
Rubyでスクリプト実行時に、途中でユーザの入力を求めたいシーンは多々ありますよね。
そんなときに `gets.chomp` などで文字列入力を求める方法がパッと思いつきます。

例えばこんな感じ。
```ruby
puts "名前を入力してください"
name = gets.chomp
```

ですが、毎回文字列入力を求めるのはちょっとダサいですよね。

そんなときに便利なのが、今回お伝えする `tty-prompt`というGemです。

# tty-prompt の使い方

Gem をインストール
```shell
gem install tty-prompt
```

あとは下記のようなコードを書いて実行するだけです。

```ruby
require 'tty-prompt'

prompt = TTY::Prompt.new(prefix: '[?] ', active_color: :cyan)
# テキスト入力してもらう
reason = prompt.ask("なぜこのスクリプトを実行するのですか？")

# YES/NOで選んでもらう
if prompt.no?('ステージング環境で動作確認しましたか？')
   prompt.error '必ずステージング環境でリハーサルしてください！'
  exit
end

# 複数選択肢から選ぶ
partners = prompt.multi_select('ペアオペレーションの相手は？', %w[太郎 次郎 三郎])

# 選択肢から選ぶ
container_size = prompt.select('実行するコンテナのサイズは？', %w[small medium large xlarge])


# スライダーで選択
minutes = prompt.slider('処理時間(分)の想定は？',
                        max: 60,
                        default: 5,
                        step: 5,
                        help: "左右の矢印キーで値を変更できます",
                        show_help: :always)

# 入力した情報の確認
prompt.ok "[Summary] #{minutes}分かかる想定の処理を#{container_size}のコンテナで#{partners.join(',')}と実施します"
```

上記のコードを実行するとこのようにスタイリッシュな入力プロンプトが出来上がります。

![stylish-prompt.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821/6c16fa38-b6d0-2566-a3cd-5afbb8b322b1.gif)

警告は赤色、インフォメーションは緑色で目立たせたりすることも簡単にできますね。

# 公式ドキュメント
https://github.com/piotrmurach/tty-prompt?tab=readme-ov-file#ttyprompt

サンプルで紹介していないですが、他にも複数行入力やマスク入力などさまざまなものに対応しています。
このREADMEを眺めてみるだけで、すぐに理解できるくらいサンプルも充実しています。

# まとめ
今回ご紹介したサンプルでは、選択肢は固定していましたが、実際に利用するときには選択肢候補を外部APIをコールして取得し、それをHashやArrayに変換した上で、選択肢として提示すると便利に使えるようになるかと思います。

ぜひお試しあれ！
OpenWrtのパーティションを拡張するまで

# はじめに

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

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

# 本編

この前のOpenWrtのインストール語、いろいろパッケージをダウンロードしたりして次の遊ぶ準備をしていたのですが、いつしかからか全くパッケージが入れられない状態に。何かと思って調べてみると、ディスク容量がもうない！そうなんです、ディスク容量がimgファイルを拡張しただけだと全く使えないレベルしかないので、これをまず拡張するところから始める必要があります。ということで、さっそくやっていきましょう！ちなみに、今回は下のリンク先を参考にさせていただきました。ありがとうございます。

https://www.ocawa.jp/notebook/openwrt-x86%E3%81%AE%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B5%E3%82%A4%E3%82%BA%E5%A4%89%E6%9B%B4%E6%96%B9%E6%B3%95/

## Alma Linux のイメージをダウンロード

Alma Linuxのイメージをインストールします。もちろん、ダウンロードするのはaarch64のイメージですが、Minimal ISOで大丈夫だと思います。

https://almalinux.org/ja/get-almalinux/

以下、UTMで説明しますがお使いの環境がVMware Fusionの場合は適宜操作を変えてください。

ダウンロードし終わったら、まず最初にディスクサイズを拡張します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/215e9a57-631c-c9d9-e3c8-e2d34d260d69.png)


落としてきたISOを起動構成に入れます。（VMware Fusionの場合はDVD/CDのところに入れて貰えば大丈夫です。）起動順序が落としてきたISOが先になるようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/ae2ef01b-8fb0-3edd-9a9d-cff4247d471f.png)

## いざ拡張

それでは起動していきましょう！

Troubleshooting＞Rescue AlmaLinuxでそのままレスキューモードに入ります。全て起動したらどのモードに入るか聞かれますので３を選択してください。

まず、インストールされているディスクを確認してください。確認したらそのままpartedに指定して入ります。

```zsh
lsblk

parted /dev/vdb

p
```

そのままパーティションはリサイズします。好きな割合にしてください。pで情報確認して拡張したいパーティションを選択します。

```zsh
resizepart 2 100%

p

# partedを抜ける
'Ctrl + C"
```

あとは、チェックして変更したら終わりです。

```zsh
fsck /dev/vdb2
# 聞かれたらy

resize2fs /dev/vdb2

lsblk
# 確認したい時は上のコマンド
```

これでリブートしたら綺麗にパーティションが新しくなってます！

# 最後に

今回はそもそもの話でOpenWrtで遊べるようにパーティションを拡張しました。やっぱり組み込み向けのLinuxってちょっと違って難しいですね！
起業するならElixirシリーズSTEP21. IR

https://qiita.com/Yoosuke/private/759bb9e7588a80c802fc

こちらの続きです。

経営戦略、事業戦略、機能戦略、財務戦略、コーポレートガバナンス、人材マネジメントときたら、次はIRです。

ほんとは、IRの前に管理会計など重要な事もありますが、それは財務戦略でCFOと一緒にやった方がいいのでそちらで抑えておくとして、IRについて見ていきましょう。

## IR
IRについて、特にスタートアップ企業の経営者が押さえるべきポイントを解説していきます。

### IR (Investor Relations) の基本
#### 1. IRの目的

- 投資家との適切なコミュニケーション維持
- 企業価値の適切な評価の獲得
- 安定的な資金調達の実現
- 株主・投資家からの信頼獲得

#### 2. 主なIR活動の種類

IR活動には、法定開示と任意開示の２つの考え方があります。

### 法定開示
法定開示とは、法律や規則によって義務付けられている企業情報の開示のことで、以下のような種類があります。

#### 1. 金融商品取引法に基づく開示

##### 有価証券報告書（年次）

- 企業の事業・財務状況の詳細な報告
- 事業年度終了後3ヶ月以内に提出
- 監査証明が必要

##### 四半期報告書

- 四半期ごとの事業・財務状況の報告
- 各四半期終了後45日以内に提出
- レビュー証明が必要

##### 臨時報告書

- 重要な事実が発生した場合に提出
例：大規模な合併、災害による重大な損害など

#### 2. 取引所規則に基づく開示（適時開示）

##### 決算短信（四半期含む）

- 決算期末後速やかに開示
- 基本的な財務情報と業績予想

##### 重要事実の開示

- 業績予想の修正
- 配当の変更
- 役員人事
- その他の重要な経営事項

### 任意開示
任意開示とは、法的な義務はないものの、投資家への情報提供として自主的に行う開示のことです。開示内容は任意開示なので、何でも良いと言えば良いのですが、目的は投資家に対するコミニケーションとしての役割を果たすように考慮すべきです。

また、任意開示は、法定開示を補完し、投資家との信頼関係を構築する重要なツールで、企業の実態や将来性を適切に伝えることで、企業価値の適正な評価につながります。また、積極的な情報開示は、市場からの信頼獲得にも寄与します。

しかし、気をつけなければならない点もあります。ライバルに対しても情報が筒抜けになるので、何を開示すべきかはいくつか検討すべきポイントがあり、そのポイントに気を付けて開示内容を検討する必要があります。

このあたりは細かい話しになるので、ここでは話せませんが、将来起業を目指したい学生の方やインターンシップに来た方には教えてますので、インターン希望の方は会社HPから気軽にお問い合わせください。

## まとめ
IRは単なる情報開示や投資家対応ではなく、企業価値を適切に伝え、理解を得るための重要な経営機能です。特にスタートアップ企業においては、成長フェーズに応じた適切なIR活動の設計と実施が重要になります。
経営者は自社の成長ステージに合わせて、必要なIR機能を見極め、段階的に体制を整備していくことが求められます。また、IR活動を通じて得られる投資家からのフィードバックは、経営戦略の改善にも活用できる貴重な情報源となります。
趣味でGoを触り続ける理由 ～半年間触れて感じた「直感的な好き」を言語化してみた～

これは、[Go Advent Calendar 2024](https://qiita.com/advent-calendar/2024/go)の21日目の記事です。

# はじめに  
こんにちは！私は普段Javaでバックエンド開発をしているエンジニアです。仕事でGoを使う機会は無いのですが、完全に趣味でGoを触り始め、気がつけば半年が経ちました(今年の5月中旬頃からスタート)。

Goを触り続けている理由は「直感的に好きだから！」と感じていたのですが、我ながら納得感が無かったため本記事ではこの「直感的な好き」を自分なりに言語化してみました！
本記事を通して同じようにGoを楽しむ仲間が増えれば嬉しく思います！！

:::note warn
本記事は私の個人的な感想であると同時に、他言語を下げる意図は一切ありません。炎上、ダメ、ゼッタイ。
:::

# 対象読者  
- Goに興味があるけどまだ触ったことがない方  
- 趣味として新しいプログラミング言語に挑戦したいと考えている方  
- Goを使い始めたけどモチベーションが続くか不安な方  

# 1. 「Goは開発者が幸せになれる言語です(諸説あり)」  
(繰り返しですが、これは個人的な感想です。炎上、ダメ、ゼッタイ)

私がGoを使い始めて最初に感動したのは、**開発者体験の良さ**でした。
皆さんはこんな経験をしたことが無いでしょうか？
- ソースコードの書き方やベストプラクティスがチームやプロジェクトごとに異なり、統一性を保つのに苦労する
- 特定のリンターやフォーマッター(改行はするのかしないか、インデントはTABか半角スペースかなどといったコーティング)のルールを導入するか否かを巡って議論になる
- リンターやフォーマッターを導入しても、独自ルールを確認するため、結局目視によるチェックが発生する

これらの問題を解決する要素がGoにはあると思っています。
## 1-1. リンターとフォーマッターが言語本体に組み込まれている
Goではリンター(`go vet`)とフォーマッター(`go fmt`)がGo言語本体に組み込まれています。そのため、特別な設定なしでGo公式ルールの元、ソースコードが整形可能です。

https://go.dev/blog/gofmt

# 1-2. Go自体がGoで書かれている

Go本体のソースコードがGoで書かれている点もポイントが高いです。Go本体の書き方を真似れば、Goらしい書き方が出来るという安心感があります。

https://github.com/golang/go

# 1-3. 予約語が25個しかない
Goは「シンプルさ」を追求した言語思想です。それもあり、予約語の数はプログラミング言語の中で(恐らく)最小の25個です。脳みそが小さい私にとっては嬉しいポイントです。  

https://go.dev/ref/spec#Keywords

また、Goが誕生した背景について少し触れると、その一つにはGoogle社が抱えていた開発速度の低下という課題を解決する目的がありました。その為、他にも**開発者体験の良さ**を感じさせる特徴は数多くあります、是非探してみてください！

# 2. 「Goを通じて技術的に難しいことに挑戦したい」  
そもそも私がGoを触り始めたきっかけは、「技術的に難しいことに挑戦したい」という思いからでした。その中で具体的に「マイクロサービスをやってみたい」と考えたのが始まりです。

Goは「シンプルで軽量」「並行処理が簡単に書ける」といった特性を持ち、マイクロサービスをはじめとした大規模なシステム開発に適している点が注目されています。

また、[Docker](https://github.com/docker)や[Kubernetes](https://github.com/kubernetes/kubernetes)、[Terraform](https://github.com/hashicorp/terraform)などの主要なツールがGoで書かれていることを知り、クラウドネイティブ分野での新しいアップデートやツールの誕生にも期待がされています。こうしたOSS活動にも興味があり、今後挑戦してみたいと考えています。

きっかけはマイクロサービスへの興味からでしたが、今ではもう少しマクロな視点で、スケーラブルなシステム設計や効率的な開発プロセスなど、エンジニアとしての成長に繋がるスキルを磨けることが、モチベーションを保つ理由になっています。

# 3. 「Goコミュニティ暖けぇ..」  
Goを始めたばかりの頃から、いくつかの勉強会に参加しました。そこで感じたのは、Goコミュニティの暖かさです。質問しやすい雰囲気や丁寧なサポート、そして何より「一緒に技術を楽しもう！」というエネルギーに溢れていました。Goは比較的新しい言語ということもあり、参加者は若くエネルギッシュな方が多い印象です。

また、特に印象的だったのは、同じ日に別々のGoの勉強会が開催されそうになったこと。これはGoコミュニティがそれだけ活発である証拠ですね！！

こういった方たちと一緒に技術を高め合っていけることは大きなモチベーションになっています。今後も勉強会に積極的に参加し、知識や経験をシェアしながら成長していきたいと思います。

勉強会はconnpassで「Go」と検索して良さげなものに参加してます。

https://connpass.com/



## まとめ
趣味から始めたGoですが、半年間続けてきて「直感的な好き」には確かに理由がありました。
- 開発者体験を追求したシンプルさによる「開発者の幸せ」の実感
- 技術的に難しいことに挑戦したい気持ちと、それを後押しするGoの特性
- Goコミュニティの暖かさと活発さ

半年という短い期間ですが、Goに触れる中で「好き」という感情が明確な形を持ち始めています。これからも趣味としてGoを楽しみつつ、技術を磨いていきたいと思います！

Goに興味のある方、一緒に楽しみましょう！！
Javaで「日時のエポックからのUTCミリ秒値を取得する」の動作を確認してみた

# 概要

Javaで「日時のエポックからのUTCミリ秒値を取得する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/calendar/index6.html

# 実装

以下のファイルを作成しました。

```testCalendar5.java
import java.util.Calendar;

class testCalendar5{
  public static void main(String args[]){

    Calendar calendar1 = Calendar.getInstance();

    System.out.println("日時1を2006/05/08 09:45:10に設定します");
    calendar1.clear();
    calendar1.set(2006, 4, 8, 9, 45, 10);
    long millis1 = calendar1.getTimeInMillis();
    System.out.println("エポックからの経過ミリ秒の値は" + millis1 + "です");

    Calendar calendar2 = Calendar.getInstance();

    System.out.println("日時2を2006/05/11 12:58:15に設定します");
    calendar2.clear();
    calendar2.set(2006, 4, 11, 12, 58, 15);
    long millis2 = calendar2.getTimeInMillis();
    System.out.println("エポックからの経過ミリ秒の値は" + millis2 + "です");

    long diff = millis2 - millis1;
    System.out.println("日時の差は" + diff  + "ミリ秒です");

    diff = diff / 1000;    /* 秒以下切捨て */

    long se = diff % 60;
    diff = diff / 60;

    long mi = diff % 60;
    diff = diff / 60;

    long ho = diff % 24;
    long day = diff / 24;

    System.out.println(day + "日と" + ho + "時" + mi + "分" + se + "秒");
  }
}
```

以下のコマンドを実行しました。

```
$ java testCalendar5 
日時1を2006/05/08 09:45:10に設定します
エポックからの経過ミリ秒の値は1147049110000です
日時2を2006/05/11 12:58:15に設定します
エポックからの経過ミリ秒の値は1147319895000です
日時の差は270785000ミリ秒です
3日と3時13分5秒
```

# まとめ

何かの役に立てばと。
認証の入門からパスキーまで

認証認可 Advent Calendar 2024
21日目の記事となります。

https://qiita.com/advent-calendar/2024/authn_authz

# 認証とは

認証は『**Who**』（誰がアクセスしているのか）を確認する重要なプロセスです。
そして、認証の方法は主に以下の3つの要素に分類されます。

## 認証の３要素

## 1. 知識認証（What you know）
パスワードやPINコードを使用して、ユーザーが知っている情報で確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70168/c5fccb26-3f84-982c-6459-26d55d59dfcd.png" width="250px">

### 2. 生体認証（What you are）
指紋や顔認証、虹彩認証など、ユーザーの身体的特徴を使って本人確認を行います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70168/691f8ecd-00db-7f27-f5ff-42ef664d11c6.png" width="250px">

### 3. 所有物認証（What you have）
スマートフォンやセキュリティトークンなど、ユーザーが所有している物で確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70168/cd850520-c908-cba9-f826-12fc96629511.png" width="250px">


## パスワードレス認証

パスワードレス認証は、ユーザーがパスワード（**知識認証**）を使わずに認証を行う方法です。さらに最近の認証トレンドとしては『**パスキー**』があります。

## パスキー

Webサイトのログイン時に自分のスマホ『**所有物認証**』の『**生体認証**』機能を利用する方法（広義のパスキー）が一般的だと思います。

利用するには、事前にサイト（認証サーバ）に対応したパスキー（狭義のパスキー）を作成しておく必要があります。
※広義と狭義の詳細説明は割愛

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70168/9c3f66c2-d85d-49ed-090c-8466d69d7db4.png" width="250px">

『**パスキー**』を利用することで、セキュリティが向上し、利便性も高まります。

### セキュリティ
- フィッシング耐性（SMS等のOTP認証では対策不十分）
- パスワード漏洩リスク削減（秘密情報をWebサイトとやり取りしない）

### 利便性
- ログイン失敗率削減（サイト利用者・運営者双方にメリット）
- ログインフォームの構造を変えずに利用可能（Conditional UI推奨）

# さいごに

認証技術はどんどん進化していきます。まずは、『**パスキー**』を使いこなしながら、次の世代の認証に備えていきましょう。

# おまけ宣伝
セキュリティに関係する話を書きましたが、セキュリティに関わるLT会を2025年1月23日に企画しています。
ご興味があれば是非、遊びに来てください。

https://security-any.connpass.com/event/336993/
mrubyでRuboCop

あまりruby詳しくないのでRuboCopでrubyぽく直してもらっています。

mruby on YABMの開発環境はFreeBSDのjail(BastilleBSD)にあり、RuboCopはFreeBSDのpkgでインストールしました。

いくつか引っかかったので、以下のような.rubocop.ymlを設定しています。

```yml
AllCops:
    NewCops: enable

Style/FrozenStringLiteralComment:
  Enabled: false
Style/MutableConstant:
  Enabled: false
Style/ZeroLengthPredicate:
  Enabled: false
Style/NumericPredicate:
  Enabled: false
Naming/ConstantName:
  Enabled: false
MethodLength:
  CountComments: true
  Max: 25
```

なぜこう設定したのかは忘れてしまいました。デフォルトだとコンパイルが通らなくなるものがあったような気がします。
MVCモデルとは

## はじめに
MVCモデル（Model-View-Controller）は、ソフトウェア設計における基本的なアーキテクチャの一つで、アプリケーションを三つの役割に分割することで開発効率や保守性を向上させます。
本記事では、MVCモデルの基本概念とその役割、採用するメリットや課題について解説します。

## MVCモデルとは？
MVCは、アプリケーションを以下の三つの要素に分割します

- M（Model）: データやビジネスロジックを管理。DBとデータをやり取りしたり、データの登録・更新・削除などの処理を行います。
DBから取得したデータや処理の結果についてはControllerに送ります。

- V（View）: 表示や入出力などのユーザーインターフェースを担当。(HTMLなどユーザーが実際に見る画面など)
リクエストデータをControllerに送ったり、Controllerからレスポンスデータを受け取って画面に表示したりします。

- C（Controller）: ModelとViewをつなぐ役割。Modelにデータ処理の指示を出したり、Viewに画面表示の指示を出したりします。

これにより、各部分が独立して開発・変更可能になり、効率的な開発が可能です。

## MVCのメリット

#### 開発効率の向上
コードが役割ごとに独立しており、作業を分担することができるので並行して開発が可能になります

#### 保守性・拡張性の向上
MVCはコンポーネント間の分離を通じて、変更した際に他の領域への影響を与えにくくします。
これにより、新機能の追加やバグ修正がスムーズに行えます。

#### 責任の明確化による可読性
MVCそれぞれで特定の役割を持ち、責任が明確に分担されているため、どこに何が書いてあるかが分かりやすくなります。



## MVCを活用したフレームワークの例

### Ruby on Rails
MVCモデルを厳密に採用している代表的なフレームワーク。
Ruby言語で構築され、高い生産性を持つ。

### Laravel (PHP)
PHPを使用した人気のフレームワーク。
MVCをベースに直感的な開発体験を提供。

### Spring Framework (Java)
エンタープライズ開発で広く利用される。
柔軟性とスケーラビリティが特徴。

## まとめ
MVCモデルは、Webアプリケーション開発における基本的な設計モデルです。各要素を分離することで、効率的で柔軟な開発が可能になります。
読んで頂きありがとうございます！
本記事がMVCモデルの理解に役立てば幸いです。

## 参考記事
https://zenn.dev/tya0116/articles/c2f4b75e060187

https://www.geekly.co.jp/column/cat-technology/1911_040/
Sigma.jsをReactで使おうとして "TypeError: Cannot read properties of undefined (reading 'ReactCurrentOwner')" になったら

## 結論

おそらく依存関係のどこかがReact19系列と互換性に問題があり、そのために下記エラーが生じる。

> TypeError: Cannot read properties of undefined (reading 'ReactCurrentOwner')

理想的にはReact19系列でも動くアプローチを取りたいが、現時点ではReact関連パッケージをReact18系列にダウングレードしてやるのが無難。（筆者はReact 19.0.0から18.3.1にバージョンを落とすことで解消した）

## 背景

Sigma.jsのReactのデモを個人的に動かしているAstroのプロジェクト内に組み込もうとして冒頭のエラーが生じた（組み込み時に、デモではReact v18系列だったがReact v19系列に引き上げて動かそうと試みていた）

## 参考

状況は違えど類似事象ありの模様。

https://github.com/vercel/next.js/discussions/72321
webフレームワークとは何をするものなのかーエンジニアでない普通の人が理解できない理由

## webフレームワークがなぜ必要なのか分からない ##
最近、flaskを触っていて思うのですが、（技術に疎いからこそ）
**なぜフレームワークが必要なのか分からないという人の気持ちが分かりました。**
技術に疎くない人には分からないと思うので、
エンジニアでない身から説明しようと思います。

## 理由：どうやってサイトが表示されているか理解していない ##
これは結構盲点なのですが、普通の人は
**htmlとCSSかけば、サイトが表示できる**
と思っています。
これは初学者用の本には、だいたい
「HTMLでファイルを保存して、ブラウザで開いてみましょう！」
というのを最初にやるからだと思います。
なので、なぜわざわざ仮想環境構築して、サーバーを立てて、
ブラウザにIPアドレスを打ち込まなくちゃ表示できないような
ことをするのか、訳がわからないのです。

こういう人には、
「君が書いたHTMLファイルは、どうやったら世界中の皆んながアクセスできるようになるかな」
「webページを表示するにはね、インターネットを通じしてサーバーにサイトを見してくださいって言わなくちゃいけないんだよ」
と優しく説明してあげる必要があります。

「それでね、サーバーをこのPCの中で立ててみて、実際のwebサイトと同じ原理で表示しようとしているんだよ」
と教えてあげてください。

そう考えると、
- サーバーを立てなくちゃいけないとか、
- IPアドレス普通打たないよな、検索できるようにドメインを取得しなくちゃなとか、
- HTTPのリクエストを受け付けるためのポート番号を設定しなくちゃいけないとか、
- そう言えば、私一人だけで開発するならまだいいけど、多くの人で開発するにはこの方法では大変だなとか、

色々な気づきを普通の人は得るでしょう。

## まとめ：起きている事象は同じだが、方法が違うと人は混乱する ##
人は起きている事象を理解しようとして、繰り返し再現性のある方法で仕組みを理解します。
ブラックボックスの中はよく分からないが、inputとoutputを揃えていく作業です。
最初はこれで良いでしょう。
なぜhtmlファイルをブラウザで開けば表示されるのか、理解せずとも最初は良いのです。
しかし、そこから一歩踏み込んで考える、この一歩が恐ろしく普通の人には難しいです。。。

以上の流れから、フレームワークがなぜ必要なのかというのを、普通の人に説明する際には、
**web技術を一応おさらいしておく**
ということが重要であるというのが分かりました。
AWS Nukeの実行方法を紹介します。

## はじめに
今回は私がコスト削減を目的としてあるAWS環境上の使われていないリソースを削除する取り組みで主に使用したAWS Nukeについて実行方法を紹介します。

### AWS Nukeとは？
AWS環境のリソースを一括で削除する方法の1つで、簡単に言えばタグでリソースをフィルタリングして一括削除することができるサービスです。
ただ、こちらはAWS公式ドキュメントには載っているのですが、**公式に出しているサービスではありません。**
そのため、本記事を参考に使用する際は自己責任でお願いします。

## 紹介の前に
今回使用するAWS Nukeはバージョン3.29.1です。
実行時には最新バージョンを使用してください。
最新バージョンは[こちら](https://github.com/ekristen/aws-nuke/releases)でチェックできます。

## 削除手順

### AWS Nukeの準備
#### ①AWSマネジメントコンソールにログインします。
(https://aws.amazon.com/console/)

#### ②CloudShellを起動
（画像のサービス検索 or 右上のアイコンを押下）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826238/e2432634-74ca-7666-35be-421a5f821eaf.png)
ここからはCLIで操作していきます。

#### ③ディレクトリをtmpに移動します。
```
cd /tmp/
```

#### ④AWS Nukeのtar.gzファイルをURLを使ってダウンロードします。
　こちらのURLは最新バージョンのものを使用することをオススメします。
```
wget -c https://github.com/ekristen/aws-nuke/releases/download/v3.29.1/aws-nuke-v3.29.1-linux-amd64.tar.gz

```

#### ⑤ダウンロードしたtar.gzファイルを展開します。
```
tar -zxvf aws-nuke-v3.29.1-linux-amd64.tar.gz
```

#### ⑥aws-nukeバイナリを実行して使用可能なリソースタイプのリストを表示する。
```
./aws-nuke resource-types
```

#### ⑦Nukeの設定ファイルや実行の管理に使うaws-nuke-dirという新しいディレクトリを作成
```
mkdir aws-nuke-dir
```

#### ⑧作成したaws-nuke-dirディレクトリに移動
```
cd aws-nuke-dir
```

#### ⑨aws-nukeバイナリを今いるディレクトリに移動します。
```
mv /tmp/aws-nuke ./
```

#### ⑩sudoの管理者権限でnuke-config.ymlという設定ファイルをvimを使って作成・編集します。

```
sudo vim nuke-config.yml
```
これを実行すると今まで書いたコマンドが消えたように見えると思いますがそのままで大丈夫です。
　
### 設定ファイル編集
これからymlファイルを編集して設定をしていきます。
まずは編集をしたくてもそのままだとコマンドを入力できないと思いますので「**i**」を押して編集モードに切り替えましょう。
そのあとに以下のとおりに記入します。

```
regions:
  - ap-northeast-1

blocklist:
  - 999999999999

resource-types:
  includes:
    - EC2Instance

accounts:
  123456789012:
    filters:
      __global__:
        - type: exact
          property: tag:Owner
          value: "ryota-funa"
```
この設定では「東京リージョン」の「EC2インスタンス」のうち、「バリューが'ryota-funa'である'Owner'タグが付いている」リソースを保護するものとなっています。
accountの下の12桁の数列はアカウントIDです。

一括削除の対象になるサービスは前に表示したリソースタイプのリストにあります。
どこかにメモを取っておくと設定しやすくなると思います。
　

### 実行
では、ymlファイルが設定できたところでAWS Nukeを実行してみましょう。

まずは設定ファイルを保存して閉じるために、「Esc」を押して閲覧モードに切り替えて「:wq」と打ってみてください。
設定ファイルを開く前に戻るはずです。

いきなり削除するのは少し怖い気がするので、フィルタリングをしてどのリソースを削除できるのか確認したいと思います。
#### dry-runを実行
```
./aws-nuke run --config nuke-config.yml
```
実行後、エイリアスコードの入力を求められるのでエイリアスコードを入力しましょう。

これでフィルタリング結果を見ることができるはずです。
もしフィルタリングで削除保護されているのであれば…
```
ap-northeast-1 - EC2Instance - (インスタンスID) - [Identifier: "(インスタンスID)",･･･,tag:Owner: "ryota-funa",･･･] - filtered by config
```
上のように最後に「filtered by config」と出ているはずです。

もし、「would remove」と出てしまった場合は削除対象となっているので設定ファイルを確認しましょう。

確認も終了して実際に削除する際は以下のコマンドを実行します。
#### no-dry-runを実行
```
./aws-nuke run --config nuke-config.yml --no-dry-run
```
こちらを実行し、エイリアスコードを入力するとdry-runと同じく対象リソースの一覧が出てきます。

一覧を出力した後に2回目のエイリアスコードを入力すると一覧内の「would remove」と書かれていたリソースを削除することができます。

## さいごに
今回はAWS Nukeの実行方法について紹介しました。

最新バージョンのAWS Nukeを使用する際は前バージョンのコマンドが非推奨になっているなどの変更があると考えられるので、そちらについては[GitHub](https://github.com/ekristen/aws-nuke)をご確認ください。

また、削除後に「実は必要なリソースだった」といったことが起きないようにリソースの作成者及び管理者に確認して無駄なリソースを消していきましょう。
忘れたパスワードを人工知能を使って回復する方法

はじめに

AIは人間には理解できない方法で学習することができます。
AI、特にディープラーニングの分野では、大量のデータを分析するために複雑な数学モデルを使用します。AIはこのデータに基づいて非常に正確な判断を下すことができますが、その判断がどのように行われたかはしばしば不明確です。この現象は「ブラックボックス問題」と呼ばれています。なぜなら、ユーザーが特定の結論に至る内部プロセスを見ることができない場合があるからです。

このため、私たちはこれから人工知能を使って忘れたパスワードを回復します。

この場合、GUIを備えたxcoreを使用します。

https://xcore.sell.app/

このツールのオープンコード版は

https://github.com/brannondorsey/PassGAN

上記のツールをダウンロードしてインストールしてください。インストール後に実行すると、このように表示されるはずです。まず、設定オプションを使用して次のことを行います。
![tut1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964200/596bcf35-e26c-572d-865e-b61fced8e860.png)

トレーニングを開始しましょう。これは、以前に入力したデータを基にトレーニングを行います。カスタムオプション用には、data/datas フォルダ内にデータを追加することができます。

![tut2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964200/b92e9c77-2205-ef4e-7209-af4738fbfdb6.png)

トレーニングが終了すると、このような結果が得られるはずです。

![tut3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964200/e4c7c76c-2cf8-6ca0-30a2-f0f9a9441de6.png)

次は最終段階です。それは、回復したパスワードの生成です。ここでは、優れた結果を得られる200,000エポックのモデルを使用します。また、xcoreに付属しているデフォルトモデルは約195,000エポックです。

![tut4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964200/e3d0e434-4194-a3fc-9074-f0a0bbead5a9.png)


ジェネレーターオプションをクリックしましょう。入力フィールドが表示されたら、必要なデータを入力します。たとえば、保存先の場所、先ほどトレーニングしたモデル、出力ファイル名「output.txt」、そしてサンプル数などです。その後、保存して再度ジェネレーターをクリックします。

![tut6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964200/f968068c-b181-f5fd-7c19-7856f650ca21.png)

これでプロセスが完了するはずです。ご覧のとおり、機械学習を使用してパスワードの回復に成功しました。これは間違いなく、この技術がもたらす利点の一つであり、未来を示しています。どうぞお楽しみください。良い一日をお過ごしください！
PYENVの導入忘備録

今まで特に意識することなくPYTHONはUbuntuレポジトリのデフォルトのものつかってその上で仮想環境を作ってきました。
```
apt install python3-venv python3-pip
python3 -m venv myenv
```
ところが先日あるパッケージをいれようとしたときPYTHONのVersionエラー、最新のPythonであると動かないライブラリもまだまだあるようです
```
(cutest) root@ip-172-31-18-243:/opt# python --version
Python 3.12.3
(cutest) root@ip-172-31-18-243:/opt# pip install TTS
ERROR: Ignored the following versions that require a different python version: 
```
この時PYTHON3.12をサポートする別のライブラリを使おうか、DOCKERでPTHON3.11の環境にいれようか、それともPYENVを使おうかと迷いましたが、入れたいライブラリが簡単に高性能な音声生成ができそうなので、ライブラリは外せず、あとDOCKERの接続設定もとりあえずあまりやりたくなかったので、最終的にpyenvでとりあえずやろうとしました。特定のPythonバージョンを柔軟に管理したい場合は、pyenvを使用する方法が最も便利です。その時のメモです。

まずpyenv自体インストール
```
# apt install -y build-essential curl libbz2-dev libffi-dev libreadline-dev \
    libsqlite3-dev libssl-dev zlib1g-dev liblzma-dev
# curl https://pyenv.run | bash
```
~/.bashrc の最後に以下を追加しておきます。
```
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```
ログインしなおすか以下で設定の読み込み
```
# source ~/.bashrc
# pyenv --version
pyenv 2.4.23
```
先ほどのライブラリはPython3.11は対応していたのでその中で最新のPython3.11.11をインストール(2024/12/20時点)をインストールとインストールされているVersionの確認
```
# pyenv install 3.11.11
# pyenv versions
```
私の場合はPYTHONのVERSIONごとに特定のディレクトリで整理したかったので作成してそこに関連づけました。
```
# mkdir python3.11.11 
# cd python3.11.11
# pyenv local 3.11.11
```
さてそこでやっとPython3.11.11での仮想環境作成です
```
# pyenv virtualenv 3.11.11 myenv
# pyenv activate myenv
```
再度インストールされている環境確認です
```
# pyenv versions
  system
* 3.11.11 (set by /opt/python3.11.11/.python-version)
  3.11.11/envs/myenv
  tts0_coqui --> /root/.pyenv/versions/3.11.11/envs/myenv
```
先ほど作成したPYTHON3.11.11の仮想環境myenv が3.11.11/envs/myenv　につくられているようなのでアクティベートします
```
# pyenv activate 3.11.11/envs/myenv
```
ちなみに仮想環境から抜け出るときは deactivateではなく、source deactivateで実施ください
```
# source deactivate
```
あとは自由に環境構築できます。なれないと少しややこしいですが、なれるとPYTHONのVERSSIONからフォルダーとの紐づけなど柔軟に管理できます。
プリザンターとは？kintoneとの違いも解説！

### はじめに

アドベントカレンダーを見たらプリザンターを知っている人向けの記事が多いのですが、正直なところまだまだプリザンターを知らない方もいると思いました。
その人向けの記事を作成します。
この記事を元に利用者がもっとプリザンターの利用者が増えたら良いなと思います。

---

### プリザンターとは？

プリザンター（Pleasanter）は、**株式会社インプリム**が提供するオープンソースの業務管理ツールです。業務効率化を実現できるWebデータベースソフトであり、簡単な操作でWebアプリケーションを作成できるため、プログラミングスキルがない人でも業務の効率化を実現できます。

---

### 主な特徴

1. **オープンソースのローコード開発プラットフォーム**
   - 無料で使えるオープンソースソフトウェアで、誰でも自由にカスタマイズが可能

2. **ノンプログラミングでのアプリ作成**
   - プログラミングスキルがなくても、直感的なユーザーインターフェースを通じて業務アプリケーションを簡単に開発

3. **データの一元管理**
   - 共有したいデータを入力し、保管することで業務改善や効率化を実現

4. **多機能性**
   - レスポンシブ対応で、スマートフォンやタブレットでも利用可能
   - JavaScriptやCSSを用いた細かなカスタマイズが可能

5. **柔軟な導入形態**
   - クラウド型とオンプレミス型の両方から選択可能

---

### 利用シーン

- **業務アプリケーションの迅速な開発**
  - 簡単な操作で、プロジェクト管理や顧客管理アプリを構築可能。

- **データの集約と一元管理**
  - 複数の業務アプリケーションとの連携により、データを効率的に管理。

- **情報共有と業務効率化**
  - 社内での情報共有や管理業務の効率化を実現。

- **企業独自のニーズへの対応**
  - カスタマイズによる柔軟なアプリケーション開発。

---

### プリザンターとkintoneの比較

よく比較対象として、kintoneと比べられることが多いため、簡単に以下に違いを記載します。

#### 導入環境

- **プリザンター**: オンプレミスとクラウド環境の両方に対応
- **kintone**: クラウド環境のみ

#### 価格

- **プリザンター**: 比較的安価
  - クラウド環境の場合、10ユーザーで月額1, 000円（ライトプラン）
- **kintone**: 10ユーザーの場合、ライトコースで月額7,800円

#### 機能性と操作性

- **プリザンター**: 高い拡張性と業務に合わせたカスタマイズが可能
- **kintone**: 全体的に操作性や機能性で優れており、豊富な外部連携オプションや充実したコミュニケーション機能を提供

#### 特徴

- **プリザンター**:
  - オンプレミス環境での利用が可能
  - 大容量データの共有・保管に適している
  - 高い拡張性と業務に合わせたカスタマイズが可能

- **kintone**:
  - 豊富な外部連携オプション
  - 充実したコミュニケーション機能
  - 使いやすいユーザーインターフェース

#### 導入のしやすさ

- **プリザンター**: 自社での設定や管理が必要な場合もあります
- **kintone**: 導入相談窓口やセミナーが充実しており、導入しやすい

#### 選択の基準

現状で、プリザンターを使うのか？kintoneを使うのか？という場合の選択の基準としては

- **オンプレミス環境を重視**: プリザンター
- **クラウドでのモバイル利用や情報共有を重視**: kintone
- **コスト重視**: プリザンター

両者とも業務用アプリ開発ツールとして優れていますが、企業のニーズや予算に応じて選択することが重要です。

---

### まとめ

プリザンターは、ノーコードで業務管理アプリケーションを構築できる強力なツールです。
中小企業から大企業まで幅広く利用されており、コスト削減や業務効率化を目指す企業に最適です。
初めて利用する方でも、テンプレートや直感的な操作画面を活用することでスムーズに導入できます。

企業の規模やIT環境、求める機能に応じて、メリットとデメリットを慎重に検討し、導入の是非を判断してください。ぜひ一度、公式サイトをチェックしてみてください！

以下のように追記する参考文献を記述すると良いでしょう。

---

### 参考文献

1. [プリザンター公式サイト](https://pleasanter.org/)  
   プリザンターの詳細情報、利用方法、ドキュメントは公式サイトをご参照ください

2. [kintone公式サイト](https://kintone.cybozu.co.jp/jp/ad010/)  
   kintoneの機能、導入事例、資料ダウンロードなどはこちらの公式サイトをご覧ください
GORMで発行したSQLを無理やり取得する方法


# 目的、方針
SQLを文字列として受け取ってログ出力に使いたい！（GORM自体に実行したSQLのログ出力はあるけど、個人的に融通が効かなくて。。。）
パッケージのソースに手を加える形で修正。いい感じに取得できればいいな。

# 環境
- Go    1.23.2
- GORM  1.25.10

# ソース修正

:::note alert
**注意**
修正する際は自己責任でお願いします！
:::

```go:callbacks.go
func (p *processor) Execute(db *DB) *DB {
// ...省略...
	if stmt.SQL.Len() > 0 {
		db.Logger.Trace(stmt.Context, curTime, func() (string, int64) {
			sql, vars := stmt.SQL.String(), stmt.Vars
			if filter, ok := db.Logger.(ParamsFilter); ok {
				sql, vars = filter.ParamsFilter(stmt.Context, stmt.SQL.String(), stmt.Vars...)
			}
            // ↓↓ココ！！！↓↓
			sql = db.Dialector.Explain(sql, vars...)
			db.Sql = sql
			return sql, db.RowsAffected
            // ↑↑↑↑
		}, db.Error)
	}

// ...省略...

	return db
}
```

```go:gorm.go
// DB GORM DB definition
type DB struct {
	*Config
	Error        error
	RowsAffected int64
	Statement    *Statement
	clone        int
  // ↓追加
	Sql          string
}
```

```go:db.go
	db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
    // ↓ロガーの設定これ大事
		Logger: logger.Default.LogMode(logger.Info),
	})
```

```go:select.go
	result := db.Limit(10).Find(&pokemons)
	fmt.Println(result.Sql)
  // ↓出力結果↓
  // SELECT * FROM "pokemons" WHERE "pokemons"."deleted_at" IS NULL LIMIT 10
```

# 解説

callbacks.goのExecuteメソッドですが、SQLを実行する間際になります。
db.Dialector.Explainの返り値はそのまま実行できる生SQLになります。

処理を一通り見たところ、GORMの利用者に返却されるものはDB構造体であることがわかります。
なのでDB構造体にSqlフィールドを追加して格納してあげます。

パッケージのソースはこの二つのファイルを修正して終わりになります。（意外と簡単）

```go:callbacks.go
func (p *processor) Execute(db *DB) *DB {
// ...省略...
	if stmt.SQL.Len() > 0 {
		db.Logger.Trace(stmt.Context, curTime, func() (string, int64) {
			sql, vars := stmt.SQL.String(), stmt.Vars
			if filter, ok := db.Logger.(ParamsFilter); ok {
				sql, vars = filter.ParamsFilter(stmt.Context, stmt.SQL.String(), stmt.Vars...)
			}
            // ↓↓ココ！！！↓↓
			sql = db.Dialector.Explain(sql, vars...)
			db.Sql = sql
			return sql, db.RowsAffected
            // ↑↑↑↑
		}, db.Error)
	}

// ...省略...

	return db
}
```

```go:gorm.go
// DB GORM DB definition
type DB struct {
	*Config
	Error        error
	RowsAffected int64
	Statement    *Statement
	clone        int
  // ↓追加
	Sql          string
}
```

ここからはGORMを利用するプロジェクト側になります。
DB接続する際にログの設定をします。
この設定をすることでログにSQLが出力されるようになります。
今回は生SQLをログではなく内部で文字列として受け取りたいので、上記でこねくり回しています。

GORMの中でどのようにログ出力しているか気になる方はlogger.goのTrace()をみるといいかもしれません。

```go:db.go
	db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
    // ↓ロガーの設定これ大事
		Logger: logger.Default.LogMode(logger.Info),
	})
```

最後に使い方になります。
FindやFirstの返り値にはDB構造体のデータが入っています。
Executeメソッドを通っているはずなので、db.Sqlには値が入っているはずです。
なのでresult.Sqlで取得することができます。

```go:select.go
	result := db.Limit(10).Find(&pokemons)
	fmt.Println(result.Sql)
  // ↓出力結果↓
  // SELECT * FROM "pokemons" WHERE "pokemons"."deleted_at" IS NULL LIMIT 10
```

# まとめ

こんなやり方じゃなくてもスマートなやり方あったかもなー
デバッグでここまで処理がたどり着いたけど、正直途中の処理全然意味分かってないからまずい

:::note alert
**注意**
筆者はFind関数でしか確かめておりません！
他の関数では動かない可能性があります！
:::

:::note info
変なこと言ってたら指摘などあれば嬉しいです！
:::
Rustマクロの事前知識②「出力の掟」


:::note
**この記事で伝えたいこと**

Rustマクロは構文「パーツ」だけ出力することはできず、基本的に構文要素全体を出力する必要がある
:::

こちらの記事は [Rustマクロ冬期講習アドベントカレンダー](https://qiita.com/advent-calendar/2024/rust-macro) 3日目の記事です！

> アドカレまとめ記事はこちら！: [Rustマクロ作成チートシート！](https://qiita.com/namn1125/items/d601d2cbbf2cc7b5d3dc)

[2日目の記事](https://qiita.com/namn1125/items/3288db9acdf2012f78b0)で、Rustマクロについて「出力されるトークン木は設置先のASTに組み込まれて有効なものでなければならない」と述べました。

これに伴って、というわけでもないですが、Rustのマクロとして出力できるものと、できないものがあり、今回のRustマクロシリーズ記事が参考としている[The Little Book for Rust Macros](https://veykril.github.io/tlborm/syntax-extensions/ast.html)に記載があるためここで紹介したいと思います。

ここから引用の上意訳

> (記事の終盤に差し掛かり)最後に重大な意味を持つため最も大切であるポイントを伝えます。RustマクロはASTへと解析されるため、次に示すサポートされた構文要素の箇所にしか記述することができません。Rustマクロを記述できるのは:
>
> - パターン ( `pat` )
> - 文 ( `stmt` )
> - 式 ( `expr` )
> - アイテム ( `item` 。これは `impl` ブロックを含む )
> - 型 ( `type` )
>
> 以上の箇所 **のみ** になります。
>
> 一方で次に示すような箇所ではどう逆立ちしたところでマクロを使用することは不可能です。
>
> - 識別子
> - マッチアーム (パターンではなく `=>` を含めたアーム全体を指す)
> - 構造体のフィールド

イマイチ何が出力できないかわかりにくいと思うので一言で表すと、「ある構文要素の **一部** だけを出力するマクロ」は作れないことになっています。

コードで表すとマクロで表現可能なのは次の場合です。

```rust:Rust (マクロで表現可能)
macro_rules! can {
    (pat) => {
        Some(_) | None
    };
    (stmt) => {
        let _ = "";
    };
    (expr) => {
        10 + 20 + 30
    };
    (item; $name:ident, $s:stmt) => {
        fn $name() { $s }
    };
    (type_) => {
        Option<u32>
    };
}

fn main() {
    let can!(pat) = Some(10);
    can!(stmt);
    let _ = can!(expr) + 40;

    can!(item; hoge, println!("hoge"));
    hoge();

    let _: can!(type_) = Some(10);
}
```

以下のようなマクロの使い方はできません！

```rust:Rust (コンパイルエラー)
macro_rules! cant {
    (ident; $name:ident) => {
        $name
    };
    (match_arm) => {
        Some(_) | None => (),
    };
    (strct_field) => {
        hoge: u32,
    };
}

fn main() {
    struct cant!(ident; Hoge);

    match Some(10) {
        cant!(match_arm)
    }

    struct HogeHoge {
        cant!(strct_field)
    }
}
```

1つ目も3つ目も生成しているのは構造体全体ではなく構造体の一部で、2つ目も `match` 式全体ではなくアームだけをマクロで生成しようとしています。

ある構文要素をなすためのパーツであるからといってただちにダメというわけではないです。先ほどの `can` マクロでも、ある意味で `match` 式の一部を記述しているものがあります。

許されないのは、そのパーツを抜き出した時に「**構文要素として見做せなさそうなもの**」です。

- `struct Hoge {}` の `Hoge` の部分
- `a => b` という何か
- `hoge: u32` という何か

これらは構造体の一部や `match` 式の一部ではありますが、この断片だけではRustコードとして意味を為しません！Rustのマクロは、このような中途半端な構造は出力できないようになっています。 

とはいえ、例えば「列挙体のフィールドの数分 `match` 式のマッチアームを生成する」マクロというのはしばしば書きたくなります。こういう時は、マクロの出力結果が `match` 式全体になるようにする、など、部分ではなく全体を出力することで実現しましょう。

# まとめ

要は「ヘンテコな出力は許さない」わけです。[2日目の記事](https://qiita.com/namn1125/items/3288db9acdf2012f78b0)にも書いたとおり、こういった厳格な性質のおかげで、Rustのマクロは他言語よりも安心して気軽に呼び出すことができます！
自身の感情を抽出したり、他人の感情を自身に注入したりする(クソ)アプリを作ったよ

（クソアプリアドベントカレンダー2024 シリーズ2の21日目の記事です）

## こんにちは！(元気な挨拶)
世界一優しい人間をやっています。
こばやしです。

今回はタイトルにもある通り、自身の感情を抽出したり、他人の感情を自身の注入したりする(クソ)アプリを作りました。ぜひ使ってみてください。

## アプリの概要
- 感情の抽出
    - 自身の感情を文章化して喜怒哀楽のパラメータを設定し、**抽出**できます
    - 抽出した感情は自身から切り離されます
    - 抽出した感情ともう一度会える確証はありません

![スクリーンショット 2024-12-21 2.21.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670303/5c4ef1a2-f4f2-c44f-3357-cdf666330a6c.png)

- 感情の注入
    - ランダムにロードした他人の感情を自身に**注入**できます。
    - よろしいですね！（ゴリ押し）

![スクリーンショット 2024-12-21 2.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670303/636d48e6-c068-2c76-da37-7f6ec58241f7.png)

### 感情の抽出と注入
ぜひ触ってみてください。
（titleタグ変えたのに反映されない）

https://feel-archive.vercel.app/


## ユーザーの声
- 「さっきまであった自分の感情が消えてしまった。わかってはいたが、悲しい。もう一度出会いたい」
- 「他人の感情を自身に注入したらクソな感情になりましたが、すぐに抽出してことなきを得ました。」

...ユーザーの声、募集してます。

## 実際に使ってみた
![スクリーンショット 2024-12-21 1.38.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670303/f5605f84-62b5-a42f-14ee-9dbf5b5f6eaa.png)

![スクリーンショット 2024-12-21 1.38.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670303/148dadde-f2c6-74c1-91e7-e274369a8825.png)

クソアプリの制作が終わったという達成感は電子の海に消えていきました。どこかで拾ったら教えてください。

---

## 使用した技術やサービス
- Next.js
- Supabase
- Tailwind CSS
- Radix
- Recharts
- Vercel

個人的に新しく使った技術としてはSupabaseとRadixになります。

### Supabase
SupabaseはFirebaseの代替として開発されたバックエンドサービスです。よく目にするサービスで使ってみたかったので、今回クソアプリに使えてよかったです。無料枠があるのはいいですね。

### Radix
RadixはUIコンポーネントを提供してくれるライブラリです。今回のクソアプリ制作で見た目や手触りも多少は良くしたかったので、時短も兼ねてUIコンポーネント系のライブラリを使おうとは最初から思っていました。適当に調べて適当に決めたのでRadixを選んだ理由は特にないですが、結果としてある程度整った見た目を作れました。

### その他よかった点
Next.jsとTailwind CSSの組み合わせでサクっとアプリ開発するのは楽しいですね。深夜テンションで4hくらいで作りました。

## なぜ作ろうと思ったのか
着想元は、「自分の記憶をクラウド上にアップロードしてぇなぁ！」という数年前から抱いている純粋な思いです。攻殻機動隊の外部記憶装置的なあれです。今回は記憶ではなく、よりネタっぽい感情に焦点をあてました。

また、当初このアプリは「自分がアップロードした感情が、赤の他人によって削除される」といったものでした。
「感情が削除されました。」という文言をふと思い付き、それが個人的に面白すぎました。
最終的な着地点としては「自分の感情が赤の他人に取り込まれる」アプリになりましたが、こっちの方が意味がわからなくて最高にクソだと思うので満足しています。

## 最後に
クソアプリアドベントカレンダーの担当日の深夜に開発して記事を書いているのですが、自分は一体何をやっているんだろうと笑いがとまらない時間帯がありました。深夜テンションというやつです。まぁそれも抽出したので今は無感情なのですが。

開発過程で僕の感情をいくつか抽出してあります。ロードされる感情はランダムですが、まだ個数が少ないので出会いやすいかもしれません。

最後になりますが、クソアプリアドベントカレンダー10年目、おめでとうございます。数年前にクソアプリアドベントカレンダーの存在を知り毎年楽しみにしていましたので、今回参加できたことを嬉しく思います。


## 蛇足
最初に制作していた｢間違い探し｣です。クソすぎたのでやめておきました。
![スクリーンショット 2024-11-25 11.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670303/a4110e8d-840f-d034-2806-872e4164327e.png)
day21 『ソフトウェア開発　５５の真実と１０のウソ 』

## はじめに

　本書籍は、ざっと本質的な事項を知るには良い書籍だと思います。
 
 ![５５の真実 目次2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/898aead1-58a8-e39d-fd24-f177cb890032.png)

## ポイント
### 第Ⅰ部　５５の真実
### 真実１　ソフトウェアの開発で最も重要なことは、プログラマが使うツールや技法ではなく、プログラマ自身の質である。
### 真実２　最も優秀なプログラマは最悪に比べ、２８倍優れている。
### 真実３　遅れているプロジェクトに人を追加すると、もっと遅れる。
「ブルックスの法則」
### 真実４　作業する環境は、プログラムの生産性や品質に極めて大きく影響する。
### 真実８　プロジェクトが大失敗する原因には２つある、一つは見積りミスだ。
### 真実１１　プロジェクトが進むに従って、見積りを調整することは、まずない。従って、不適切な時期に不適切な人間が実施した見積りを修正することは、ほとんどない。
### 真実２１　対象となる問題の複雑度が２５％増加するたびに、ソフトウェアによる解法の複雑度は１００％上昇する。
### 真実２３　プロジェクトが失敗する２つの原因のうち、もう一つは、仕様を確定（仕様を凍結）できないことだ。
### 真実３３　１００％のテスト網羅が可能でも、完全テストとは言えない。バグの約３５％は、パスの抜けが原因であり、４０％はパスの特定の組み合わせを実行したときに起きる。このバグは、バスを１００％カバーしてお検出できない。
### 真実４１　保守には、ソフトウェアのコストの４０％～８０％（平均６０％）がかかる。従って、ソフトウェア・ライフサイクルの最重要フェーズである。
### 真実４２　ソフトウェアのライフサイクルの保守期間におけるバグ修正は１７％に過ぎない。その他は不良修正ではなく、新しい機能を追加する作業である。
### 真実４９　バグは固まって存在する。
### 真実５２　プログラムの処理効率には、よいコーディングよりも、よい設計が大きく影響する。
### 真実５４　プログラムの大きさと処理時間には、トレードオフがある。片方をよくすると、片方が悪くなる。

### 第Ⅱ部　５＋５のウソ
### ウソ１　計測できないものは管理できない。
正しくは「計測できないものは制御できない」
### ウソ２　ソフトウェア製品の品質は管理できる。
### ウソ４　ツールや技法は、どんな状況でも適用できる。
### ウソ６　コストやスケジュールを予測する場合、まずソースコードの行数を見積もる。
### ウソ７　ランダム・テストにより、テストを最適化できる。
### ウソ８　多くの目にさらせば、バグは枯れる。
### ウソ１０　プログラムをどう書くのかを見せれば、プログラムの方法を教えられる。

## 書誌情報
- 書籍名：ソフトウェア開発　５５の真実と１０のウソ 
- 著者：ロバート・L・グラス 
- 出版社：日経BP社
- ISBN：4-8222-8190-6

## 参考
-
【Tomcat】404エラーが起きた際に確認すること

JavaプログラムをTomcatで実行した際に404エラーが発生する事象に合ったため、備忘目的で記事に残します。

(私自身がJava初心者のため)基礎的な内容となります。

## やりたいこと
JavaプログラムをTomcatで実行した際の404エラーを解消する。

## 原因
web.xmlの設置忘れ。

Eclipseで動的webプロジェクトを作成した際にweb.xmlが自動生成されておらず見落としていました。

web.xmlはURLマッピング含め、「Javaアプリのデプロイ関連の情報を記述するファイル」(デプロイメント記述子)であり、プロジェクトごとにカスタマイズが必要とのこと。

## 解決策
/src/main/webapp/WEB-INF配下にweb.xmlを作成し、
サーブレットのパスを適切に設定することで解決。
`<servlet-class>[所属パッケージ].[サーブレット]</servlet-class>`

なお、web.xmlはサーブレット作成時に自動更新される仕様。

## 参考
https://media.zenet-web.co.jp/entry/2022/08/09/104606
デプロイ・リリース方法について

# 0. はじめに
この記事では、デプロイ・リリースの手順について説明しています。

## 1. デプロイとは
エンジニアなら誰でも必ず経験する作業の一つとして、「**デプロイ**」が挙げられます。

デプロイとは、**ソフトウェア開発の工程のうち、開発した機能やサービスを利用できる状態にする作業**です。

参考: https://www.weblio.jp/content/%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4

デプロイの一般的な流れは、以下の通りです。

**ローカル** => **開発環境** => **検証環境** => **本番環境**

---

次に、デプロイとリリースの違いについて説明してきます。

---

### 1-1. デプロイとリリースの違い
デプロイ -> 目的のアプリケーションを特定の環境で「利用できる状態」にすること
リリース -> 目的のアプリケーションを一部もしくは全部の人から使えるようにすること
参考: https://zenn.dev/bun913/articles/fa6179472f8f82

---

## 2. デプロイの種類

主要なデプロイの種類を3つ紹介します。
また、それぞれの特徴を説明していきます。

### 2-1. ブルーグリーン
 **以前のバージョンから、ほぼ同一の新しいリリースに徐々に転送するアプリケーション・リリースモデル**
 * 両バージョンが稼働中で実施するもの
 * 稼働停止時間なしに公開できる
 * ただし、テストの工程が含まれていない

### 2-2. カナリア
**新バージョンのアプリケーションをリリースする際、最初から全てのユーザーに公開するのではなく、まずは一部のユーザー(全体の1%など)に限定公開してテストを行い、所定の基準をクリアすることができれば、一般に向けて公開する手法**
 * 最大のメリットは、本番環境でのテストが実施できること
 * 問題があればすぐに戻せる、稼働停止時間がない
 * コストや時間、労力がかかるといったデメリットがある

### 2-3. ローリング
**古いバージョンのアプリケーションをシステムを稼働させたまま新しいバージョンに順次置き換えることでデプロイを行う手法**
 * 高速に実行可能というメリット
 * 一時的に、既存環境と新規環境が混在してしまうというデメリット
 * うまくデプロイできなかった際に、元に戻す作業が複雑になる

## 3. まとめ
デプロイは主に3種類あり、**速さを求めると安全性が損なわれるし、安全性を重視すると時間がかかる**ということがわかりました！

問題は**必ず**といっていい程起こるため、**臆せずに挑戦してみること**、そして、**開発体制に適したデプロイ方法を選択すること**が大切ですね！

何か不明点や質問等ありましたら、お気軽にコメントしていただけますと幸いです！

参考
* https://www.weblio.jp/content/%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4
* https://zenn.dev/bun913/articles/fa6179472f8f82
デプロイを通じて学習したサーバーの仕組み

# サーバーの仕組み

## 1. サーバーとは？

サーバーとは、ネットワークを介して他のコンピューター（クライアント）にサービスを提供するコンピューターです。  
一般的に「サーバー」と呼ばれる場合、以下の2つの意味が含まれます。

- **物理サーバー**: 実際のハードウェアそのもの。
- **サーバーソフトウェア**: サーバー上で動作するプログラム（例: Webサーバーやアプリケーションサーバー）。

サーバーは、ユーザーがいつでもアクセスできるよう24時間稼働するよう設計されています。

---

## 2. サーバーの種類と役割

サーバーはその役割によっていくつかの種類に分けられます。

- **物理サーバー**: 実際にデータセンターなどに設置されているハードウェア。
- **仮想サーバー**: 物理サーバーの上で仮想化技術を使って作られたサーバー環境。
- **Webサーバー**: 静的なファイル（HTML, CSS, JavaScript, 画像など）を提供します。
  - 主なソフトウェア例: Apache, Nginx。
- **アプリケーションサーバー**: プログラムを実行して動的なコンテンツを生成します。
  - 主なソフトウェア例: Puma、Unicorn。

---

## 3. Webサーバーとアプリケーションサーバーの違い

### Webサーバー

- **役割**: 静的ファイルを提供し、ブラウザにそのまま表示されるコンテンツを返します。
- **主な使用例**: ウェブサイトのHTMLや画像、CSSを提供。
- **代表的なソフトウェア**: Nginx、Apache。

### アプリケーションサーバー

- **役割**: データベースと連携してプログラムを実行し、動的なコンテンツを生成して返します。
- **主な使用例**: ユーザー認証や動的なデータ表示が必要なWebアプリケーション。
- **代表的なソフトウェア**: Puma、Unicorn（Rails用）。

---

## 4. 仮想サーバー（AWS EC2）の仕組み

AWSのEC2（Elastic Compute Cloud）は、仮想サーバーを簡単に利用できるクラウドサービスです。

### 仮想サーバーの特徴

- 物理サーバーを仮想化し、複数の仮想サーバーを1台の物理サーバー上で運用。
- 必要に応じてリソース（CPUやメモリ）を柔軟に増減可能。

### メリット

- 自分で物理サーバーを用意する必要がなく、コストを削減できる。
- 必要なリソースをオンデマンドで利用でき、スケールアウトも容易。

---

## 5. デプロイの仕組み

デプロイとは、ローカル環境で作成したアプリケーションを本番サーバーに配置し、公開するプロセスです。

### デプロイの流れ

1. **ローカル環境**:
   - 開発したコードをGitで管理。
   - 必要な設定ファイル（例: CapistranoやDockerfile）を準備。

2. **リモートリポジトリの利用**:
   - GitHubやGitLabのリモートリポジトリにコードをプッシュ。
   - 本番サーバーがリモートリポジトリからコードを取得。

3. **サーバーでのセットアップ**:
   - 必要なライブラリやGemをインストール。
   - データベースのマイグレーションを実行。

4. **本番サーバーの起動**:
   - Webサーバー（Nginx）やアプリケーションサーバー（Puma）を起動してアプリケーションを公開。

---

## 6. サーバーの仕組みのまとめ

サーバーについて理解することは、デプロイやアプリケーション開発において重要です。

- サーバーは**物理**または**仮想**の形で提供される。
- Webサーバーとアプリケーションサーバーは役割が異なり、それぞれが連携して動作。
- AWS EC2のような仮想サーバーは、柔軟でスケーラブルな開発環境を提供。
- デプロイでは、ローカルのコードを本番サーバーに配置する仕組みを理解する必要がある。
テストケースとテストシナリオの管理方法の悩み

# テストケースとテストシナリオの管理方法の悩み

## 01.はじめに
Advent Calendar 2024の「テスト自動化あるある言いたい by T-DASH」、21日目の記事です。
https://qiita.com/advent-calendar/2024/t-dash03

2024年では、仕事以外でもアウトプットをすると思いつつ年末まで来てしまいました。
アドベントカレンダーの季節となりましたので、これを機会に、投稿いたします。
初投稿なので、よろしくお願いします。

## 02.背景
タイトルの「テストケースとテストシナリオの管理方法」ですが、第三者検証としてのシステムテストにフォーカスした話となります。

システムテストのテスト自動化を導入は、今まで手動で実施していたテストケースを、様々なツールを使用して自動化しています。
この時、テストケースとテストシナリオが1対1で紐づくわけですが、テストケースは往々にして、テスト実施中や仕様変更によって変更されます。

皆様は、どのように管理されていますでしょうか？
手動テストの経験はありますが、自動化については知見がない人間の試行錯誤の話として、読んでいいただければと思います。

## 03.試行錯誤の内容

私のPJで試行錯誤した結果の取り組みを記載します。

今回の状況としては、
　・　テスト仕様書は、エクセルなどで管理
　・　自動化テストのシナリオは、1ファイル＝1テストケースのようなイメージ
　・　自動化困難なテストケースもあり、手動テストも入り混じっている
　・　自動化シナリオの作成が間に合っていないテストケースもある
で考えていただければと思います。

この時、テストシナリオとテストケースのトレーサビリティをとるにはどうすればよいのでしょうか？

### 1回目の取り組み
単純に、テストケースの項番をテストシナリオを格納しているフォルダ名やファイル名にしました。
しかしながら、この項番は、新規にテストケースを追加した際に、実施のしやすさなどから順序を変更することがありました。
過去のテスト仕様書と現在のテスト仕様書を参照して、テストシナリオを探して実行するという手間が発生してしまいました。今後のことを考えると毎回この手間がかかるのはいただけません。

### 2回目の取り組み
テスト項番が変わる可能性があるため、テスト項番とは別にユニークなテストIDを付与し、テストIDとテストシナリオを紐づけるようにいたしました。テスト項番とユニークなテストIDの二重管理となり、二度手間な気がしないでもないですが、不具合チケットの関連付けやテストメンバーへの実施依頼をした際に、視認性がよく使いやすいため、維持することとなりました。
これで、テストケースと自動化シナリオのトレーサビリティはとれるようになりました。
テストケースが追加され、テスト項番などの並び順が変わっても、自動化シナリオにアクセスできます。

しかしながら、仕様変更により、テストケースの手順や期待値の変更が発生しました。
この変更にテストシナリオが、追従しているのかを中身を確認しなければ、ならなくなりました。

### 3回目の取り組み
テストケースを変更した際に、テストシナリオを変更すれば、よいのですが、工数の都合上などで、いったん手動でテストして、後でシナリオを修正するなどで、後回しになることがありました。

後から見たときに、変更したテストケースに対して、どのテストシナリオが対応済みで、どのシナリオが未対応なのかを明確にする必要があります。
テストケースを修正した際には、テスト仕様書のバージョンをインクリメントしていますので、テストシナリオにはテストID以外にも、テスト仕様書のバージョンも記載するようにしました。

## 04.まとめ
これらにより、テストケースとテストシナリオの管理ができるようになりました。
ただ、テストケースの変更した際の手間が増えてきましたので、管理が大変になってきました。

テスト項番くらいだったテストケースに、
　・ユニークなテストID
　・バージョン
 を管理していかなければなりません。

過去のソフトでの再評価や、再利用性を考慮すると利点もありますが、今後の運用の中で、よりよい方法を検討していきます。