OmniAICreator/Qiita-1.07M huggingface dataset:
nodenvとnodeのバージョンが違う時に試したこと

# はじめに
Reactの環境構築を行いサーバーを立ち上げようとしたところ、エラーが起きてしまったので、その際に行ったことをまとめました。
# 問題
以下のように`nodenv`がグローバルバージョンを`18.16.0`に設定しているにもかかわらず、実際に使用されているバージョンが`15.14.0`のままになってしまっています
```bash
MacBook-Air-4:sample-vite user$ nodenv versions
  system
  15.14.0
  16.2.0
* 18.16.0 (set by /Users/user/.node-version)

MacBook-Air-4:sample-vite user$ node --version
v15.14.0
```

# 解決方法
まず、現在のディレクトリで`Node.js`のバージョンを確認します
```bash
nodenv local
```
もし出力がない場合や、`18.16.0`以外のバージョンが表示される場合は、以下のコマンドを実行してプロジェクトの`Node.js`バージョンを`18.16.0`に設定します：
```
nodenv local 18.16.0
```

次に、`nodenv`の設定を再読み込みします
```
nodenv rehash
```
 シェルを再起動するか、以下のコマンドを実行して`nodenv`の設定を現在のシェルに適用します
 ```
eval "$(nodenv init -)"
```

`Node.js`のバージョンが正しく設定されたか確認します
```
node --version
```

これで`v18.16.0`が表示されるはずです。正しいバージョンが表示されたら、依存関係を再インストールします
```
rm -rf node_modules
npm install
```
最後に、開発サーバーを起動してみてください
```
npm run dev
```

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからお願いします👇

https://projisou.jp
Railsでto_paramメソッドが呼び出せない

## 概要
SEO対策の一環として、RailsアプリケーションのURLに含まれる<font color="blue">`id`を固有名詞に置き換える実装</font>を行いました。
例えば、以下のようなケースです。

```ruby
# これを
https://spocale.com/fruit/1
# 以下の形式にしたい。
https://spocale.com/fruit/apple
```
フルーツに関する一覧ページがあり、そこから「りんご」を選択して詳細ページに飛ぶ場合を想定します。このとき、URLの`id`部分を`apple`という固有の文字列に変えたいとします。

ただし、<font color="red">既存のURLを突然変更すると、ブックマークなどで保存されている従来のURLが使えなくなる可能性があります。</font>そこで、id付きの従来のURLも維持しつつ、新しい形式のURLも利用できるように実装しました。この記事では、その過程で直面した課題と解決方法についてまとめます。

## 対象読者
- Railsアプリケーションでid付きのURLを固有名詞で表示する方法を知りたい方
- 既存のURL形式を維持しつつ、新しいURL形式を導入したいと考えている方

## 実装内容
### `to_param`メソッドの定義
まず、モデル内で`to_param`メソッドをオーバーライドし、URL生成時に`id`以外の値を使うように定義します。今回は、`Fruit`モデルに`type_string`というURLで使用する文字列を保存するカラムがあるとします。
```ruby
# app/models/fruit.rb

class Fruit < ActiveRecord::Base
  # to_paramをオーバーライドしてtype_stringを返すようにする
  def to_param
    type_string.present? ? type_string : id.to_s
  end
end
```

ポイントは<font color="blue">三項演算子で条件分岐をしている部分です。</font>
```ruby
type_string.present? ? type_string : id.to_s
```
このように書くことで、`type_string`が存在する場合にはその値を、存在しない場合には従来の`id`を使ったURLを生成することができます。これによって、新しい形式のURLと既存の`id`形式のURLの両方に対応が可能となります。

### コントローラーの修正
従来はパラメーターで`id`が渡ってきていましたが、今回の変更により、URLの一部が文字列に変わるため、パラメーターの取得ロジックを修正する必要があります。このとき、文字列でパラメーターが渡ってくる場合に、それを`id`に変換する処理を`before_action`で定義することで、既存のコントローラーのロジックを大きく変更せずに対応できます。
```ruby
class FruitsController < ApplicationController

  # 追加
  before_action :set_params_fruit_id, only: [:show]

  # 既存のコード
  def show
    @fruit = Fruit.find_by(id: params[:fruit_id])
  end

  private

  # 追加
  def set_params_fruit_id
    return true if params[:fruit_id].to_i.to_s == params[:fruit_id]
    params[:fruit_id] = Sport.find_by(name: params[:fruit_id])&.id
  end
end
```
従来通り、パラメーターで`id`が渡ってきた場合は`return`で処理を終了し、`type_string`の文字列が渡ってきた場合には、それを`id`に変換しています。
## 詰まった部分
ここまでの修正を行い、URLが変わるか試してみましたが、従来通り`id`付きの`URL`しか生成されず、そこで詰まってしまいました。特にエラーも表示されないため悩んでいましたが、URL生成部分に問題があることに気づきました。
```ruby
<%= link_to "詳細", fruit_path(@fruit.id) %>
```
このように、`link_to`や`redirect_to`の中で手動で`id`を指定してURLを生成している場合、`to_param`は呼び出されず、`to_param`が適用されるのは、Railsのパスヘルパー（例: `fruit_path(@fruit)`）を使ってURLを生成する場面のようです。
そのため、以下のように`_pathヘルパー`を適切に使うように修正しました。
```ruby
<%= link_to "詳細", fruit_path(@fruit) %>
```
## 終わりに
今回は、Railsアプリケーションで`id`を固有の文字列に置き換える実装の方法をまとめました。`to_param`メソッドを活用することで、既存の`id`形式のURLを維持しつつ、新しいURL形式にも対応できるような実装が可能です。この記事がお役に立てば幸いです。

## 参考
https://qiita.com/kamohicokamo/items/a5f9c0dd98f18a1542ee

https://blog.shitake4.tech/entry/2018/01/18/Rails%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E8%AA%AD%E3%82%93%E3%81%A7%E3%81%BF%E3%82%8B_%7C_Active_Support_to_param%E7%B7%A8
FastAPI pytestを使用してDBアクセスも含むテストを実装する時のメモ

## Pythonのpytestを使用してデータベースアクセスも含むテストを書く時の実装メモ
\
例えば下記の様なメソッドをテストしたい場合
```python
from sqlalchemy.ext.asyncio import AsyncSession
from {user_crudのインポート} import user_crud

async def get_user_list(db: AsyncSession):
    type = 1
    # 指定したユーザーのタイプでDBからリストを取得
    user_list = await user_crud.get_list(type, db)

    return user_list

```

\
テストコード
```python
import pytest
import pytest_asyncio
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool


# 使用するデータベースURL設定
TEST_DATABASE_URL ="postgresql+asyncpg://postgres:{パスワード}@db:5432/{DB名}"

# エンジン設定
engine_test = create_async_engine(
    TEST_DATABASE_URL, poolclass=NullPool, echo=True
)
# セッションの作成
TestingSessionLocal = sessionmaker(
    autocommit=False, autoflush=False, bind=engine_test, class_=AsyncSession
)  # type: ignore

@pytest_asyncio.fixture
async def db():
    async with TestingSessionLocal() as session:
        yield session

@pytest.mark.asyncio
async def test_get_user_list(
    db
) -> None:
    """テストユーザー数を取得テスト"""

    # ここで、対象となる関数を呼び出す
    result = await get_user_list(db)

    # 結果の検証
    assert len(result) = 1
```

細かい説明は省きますが、テスト用のDBのセッションを作成して渡すという感じになります。
今回は非同期処理させる為に「pytest_asyncio」を使っています。
「人生を変えるモーニングメソッド」を読んで、人生はどう変わったのか

# はじめに
こんにちは。僕は情報系の学部に通う大学生です。
小さい頃から朝起きることができず、学校には遅刻ギリギリな生活を送っていました。
「朝の時間を活用した方がいい」と考えていても、大学生活でもそれが変わることは無かったです。
そんな中、「[人生を変えるモーニングメソッド](https://www.amazon.co.jp/%E6%9C%9D%E6%99%82%E9%96%93%E3%81%8C%E8%87%AA%E5%88%86%E3%81%AB%E9%9D%A9%E5%91%BD%E3%82%92%E3%81%8A%E3%81%93%E3%81%99-%E4%BA%BA%E7%94%9F%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B%E3%83%A2%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89-%E3%83%8F%E3%83%AB%E3%83%BB%E3%82%A8%E3%83%AB%E3%83%AD%E3%83%83%E3%83%89/dp/4479795723/ref=sr_1_1?crid=JQIXVSLCY8JV&dib=eyJ2IjoiMSJ9.WwNMaWR08Mfv1n8oWDubsLL0CY4UPLk96B2bIYCERD4IlnoXbTS15J3O5VLVTOpxHBcnBrPmf2pIWlbkFnAaDuCF71fDm8APz_QIq30Izp-X6l-IWQZkvsBHvxTMUJJxRVy_MYraoY2i9la44ARtKgTTs_AJsCGahJhj1ywv73V0WOeV3nke4QzVlUUDBfKUtEXudr-6pLpfCSYE0w_UKO_4aY72Msf-ESxKTcq4AjVrMGcOXzdKiUx-0q7QVOaiujb8VicbxwpyBC6zFAw74DkLHJzvZvUuA8Bs0hRyvYI.YibrDG9qfNYGBC15WQ7bsbwG4EtZo8BsBoFtfPwE1uQ&dib_tag=se&keywords=%E4%BA%BA%E7%94%9F%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B%E3%83%A2%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89&qid=1727535037&sprefix=%E4%BA%BA%E7%94%9F%E3%82%92%2Caps%2C194&sr=8-1)」という本を読み、人生がちょっと上向きになったのでこの本を紹介したいと思います。

https://www.kinokuniya.co.jp/f/dsg-01-9784479795728

# 内容について
著者ハル・エルロッドは、20歳のときに飲酒運転のトラックと正面衝突し、6分間心肺停止に陥り、11箇所の骨折と脳に修復不可能な損傷を負い、二度と歩けないと診断されました。しかし、懸命なリハビリを続けた結果、最終的にはウルトラマラソンを完走するまでに回復した人物です。
この本はそんな彼が行った朝の過ごし方が書かれています。

# 人生を変える6つの習慣
## 1.サイレンス（瞑想）
現代社会には日々スピードの速い忙しいライフスタイルを送っている人が多くいると思います。
本書では、「目的のある瞑想」の効果について触れており、「**1時間の沈黙は、1年分の読書よりも多くのことを教えてくれる**」と言及しています。
そして定期的に瞑想を行うことで、代謝、血圧、脳の活動、身体機能の向上が認められています。

## 2.アファメーション
アファメーションとは、なりたい自分になるための宣言のことです。
元プロボクサーのモハメド・アリも「私は世界一だ！」とアファメーションを繰り返し使い、それを実現させました。
アファメーションを上手に活用するには、自分が達成したい目標に合わせたアファメーションを作成して書き出し、**毎日唱える必要があります**。

## 3.イメージング
イメージングとは、想像力を使って具体的な行動や結果を心の中で描くことです。
アファメーションとイメージングは最初同じようなものに思いましたが、読んでいくうちにイメージングは頭の中でプレイヤーを動かし脳に擬似体験させることだと感じました。
イメージが具体的であればあるほど、その効果はより強く発揮されます。

## 4.エクササイズ
**毎日数分だけでも運動を行うと、エネルギーが上がり、健康が増進し、自信が出てきて、感情が安定し、思考力と集中力が増します。**
多くの人が運動を行わない理由は「忙しい」や「疲れている」などですが、朝の時間にはそれがなく、運動に最適です。

## 5.リーディング
**望みを亭に入れる最速の道は、すでにそれを手に入れた成功者の真似をすること**と言及していて、自分もその通りに感じました。
1日最低10ページを読むことで年間1冊200ページの本を18冊も読むことができます。
読書を始める前に「なぜこの本を読むのか」「この本から何を得たいのか」を自問することで、本への向き合い方が変わりより効率的にインプットできます。

## 6.ライティング
筆者のお気に入りの「ライティング」は日記をつけることと紹介されています。
日記を寝る前に書こうと決めても、結局日記帳は白紙のページがほとんどということはよくあると思います。
しかし日記を書く時間を朝に変更するだけで、ひらめきやアイディア、気づき、目標達成度などを継続して記録ができます。
1冊の日記を書き終わった時、日記の初めのページと終わりのページを比較してみると自分の成長を大きく感じられるのではないでしょうか。

# モーニングメソッドを3週間行ってみた結果
この3週間のうち自分は15日間モーニングメソッドを行うことができました。（6つ全てではないが。）朝起きてモーニングメソッドを行った日は、朝から達成感があり、気持ち的にすごく充実した日を送れるように感じました。また現在インターンを行っているが、業務開始時間よりも早い時間に出社することで、その時間を安定して有効活用できるようになったのも個人的にはとても大きかったです。そのような体験が「明日も起きよう」という気持ちに繋がり良い循環を生んでいると実感しています。一方モーニングメソッドを行うことができなかった日は、前日に深夜まで開発を行っていたり普段とは異なる環境で眠っていた時が多く、そのような状況でも実践できるよう、習慣化や対策を考えていきたいです。

# まとめ
今回は「人生を変えるモーニングメソッド」のモーニングメソッドとそれを行った結果について紹介しました。個人的には大きく影響を受けた本で本当に読んで良かったと思います。
本書には、この内容だけでなく1つ1つのモーニングメソッドの重要性や行方、時間がない人向けの簡易版モーニングメソッドの行い方など書かれています。ぜひ読んでみてください。
AndroidStudioが重い時にやること


# はじめにやって欲しいこと

* **Invalidate Caches...**
AndroidStudio上部にカーソルを合わせた時に表示される**File**から選択

* **Clean Project**
同じく上部の**Build**から選択

# メモリ関係
「gradle.properties」ファイルの最後に
```
org.gradle.jvmargs=-Xmx1024m
```
を追加。

PCのメモリサイズによって異なるので、

https://qiita.com/shirahon/items/f5d145689c0ea4230257

詳しくはこちらを参照。

# エミュレータ
* Instant Runを使用する
修正した内容をビルドしなくても反映させる　簡単な内容だったらこれを使うといいかも

* エミュレータの不要な設定をオフにする
必要な動作確認に音声やGPS機能などの機能が使われない場合、それをオフにすることでエミュレータの動作が軽くなる可能性があります。
configファイルに以下を追記します。
```
hw.audioInput = no    // 音声入力off
hw.audioOutput = no  // 音声出力off
hw.GPS = no         // GPSoff
```
こちらも詳しくは以下を参照。

https://stackoverflow.com/questions/37063267/high-cpu-usage-with-android-emulator-qemu-system-i386-exe


https://pg.akihiro-takeda.com/android-avd-chgini/
GCSのライフサイクル管理とは？

# はじめに
Google Cloud Storage（GCS）は、大量のデータを柔軟に管理できる優れたストレージサービスですが、効率的に利用するためには「ライフサイクル管理」を活用することが重要

# 1. GCSのライフサイクル管理とは？
GCSのライフサイクル管理とは、バケット内に保存されたオブジェクト（ファイル）の状態やルールに基づいて、自動的にデータを移行・削除する仕組みです。これにより、データの保存場所や利用頻度に応じて最適なストレージクラスを選び、無駄なコストを削減できます。

### ライフサイクル管理でできること
自動データ削除: 一定期間が経過したファイルを自動的に削除。

ストレージクラスの自動移行: アクセス頻度が低いデータを安価なストレージクラスに移行。

データのアーカイブ: 長期間利用されないデータをColdlineやArchiveクラスに移動。

# 2. GCSのストレージクラスの種類と役割
GCSにはいくつかのストレージクラスがあり、データのライフサイクルに応じて使い分けることが推奨されています。ライフサイクル管理では、これらのクラスを自動的に切り替えることができます。

### 主なストレージクラス
+ Standard: 頻繁にアクセスされるデータ向け。高い可用性とパフォーマンス。
+ Nearline: 30日以上アクセスされないデータ向け。コストがStandardに比べて安価。
+ Coldline: 90日以上アクセスされないデータ向け。長期保存に最適でさらにコストが低い。
+ Archive: 365日以上アクセスされないデータ向け。最も安価で長期保管に適しているが、リカバリには時間がかかる。
# 3. ライフサイクル管理の活用方法
### コスト削減のためのデータ管理
ストレージコストを抑えるには、頻繁にアクセスされないデータを低コストのストレージクラスに移行し、不要になったデータを削除することが重要です。GCSのライフサイクル管理を利用すれば、これを自動化することができます。

### データ保持ポリシーの遵守
多くの企業や組織には、特定の期間データを保持し、その後削除する必要があります。ライフサイクル管理は、データの自動削除を設定することで、ポリシーの遵守をサポートします。

### データアーカイブの効率化
長期間アクセスされないデータでも、法律や業界規制により一定期間保存する必要がある場合、ライフサイクルルールを使ってArchiveストレージクラスに自動移行することで、コストを大幅に削減しながら保管することができます。

# まとめ
GCSのライフサイクル管理は、データの保管コストを削減し、効率的なデータ管理を実現するための強力なツールです。適切なルールを設定することで、手動での管理作業を大幅に減らし、データの使用状況に応じた柔軟な運用が可能になります。特に大規模なデータを扱う環境では、ライフサイクル管理の導入が重要な要素となります。

日時で動くFunctionsもあれば、月次で動くFunctionsがある その結果をGCSに格納しているが、見に行く頻度が全然違うのでライフサイクル管理する必要がある
Python ログローテーションの時間経過による設定方法

# はじめに
プログラムの実行中に発生するログを、時間経過で自動的にローテーションする方法を紹介します。ログファイルが大きくなりすぎないように、定期的に新しいファイルに切り替えることは、ログ管理において非常に重要です。今回は Python の logging モジュールを使い、時間経過に基づいたログローテーションの実装方法を解説します。

# ログローテーションとは？
ログローテーションは、プログラムの実行中に記録されるログを、一定の基準で新しいファイルに切り替える技術です。時間経過（例：毎日、毎時）やファイルサイズの上限などでログを分割することができます。

# ログローテーションの種類
ファイルサイズによるローテーション：指定されたファイルサイズを超えると、新しいログファイルを生成。 時間経過によるローテーション：指定された時間ごとに新しいログファイルを生成。 今回は、時間経過によるローテーションに焦点を当てて説明します。

# 必要なモジュール
Python 標準の logging モジュールに加え、TimedRotatingFileHandler を使用します。

```
import logging
from logging.handlers import TimedRotatingFileHandler
```

# ログローテーションの設定
以下のコードは、1日ごとにログファイルがローテーションされる例です。

詳細は割愛しますが

```
# ロガーの設定
logger = logutil.setup_logging(log_dir)

def setup_logging(log_dir):
# 既存のハンドラーをクリア
logger = logging.getLogger(__name__)
logger.handlers.clear()

log_level_file = 'DEBUG'
detail_formatting = '%(asctime)s %(levelname)-8s [%(module)s# %(lineno)d] %(message)s'

# ログレベル設定
logger.setLevel(getattr(logging, log_level_file))

# ファイルローテーションハンドラー設定
file_handler = TimedRotatingFileHandler(
    log_dir,
    when='D',
    interval=1,
    backupCount=5,
    encoding='utf-8'
)
file_formatter = logging.Formatter(detail_formatting)
file_handler.setFormatter(file_formatter)

logger.addHandler(file_handler)

return logger
	
```

# TimedRotatingFileHandler の引数
filename：ログファイルの名前。例：my_log.log

when：ローテーションの時間単位。midnight（深夜）、H（毎時）など。

interval：指定した時間単位の間隔。例：interval=1 と when="midnight" は1日ごと。

backupCount：古いログファイルを保持する数。

例：
backupCount=7 とすると過去7日分のログファイルが保存されます。

# ローテーションのタイミング

when="midnight" を指定した場合、毎日深夜0時に新しいログファイルが作成されます。

ログファイルの命名ルール TimedRotatingFileHandler は、ローテーションしたファイルにタイムスタンプを追加します。例えば、my_log.log はローテーション時に

my_log.log.2023-09-06

という形式になります。

# 苦戦した箇所
もし誤って拡張子をつけてしまった場合、ログローテーションでファイル名に二重に拡張子が付いてしまうことがあります

（例：my_log.log.2023-09-06.log）。

拡張子をつけるとローテンションで削除されないことが発覚

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639495/75a7f050-06af-862c-2ccb-c43db6abcfe0.png)


ですので、ログのfile_nameは拡張子付けずに！！！
ハッカソンに初参加！完成品と学びについて

# はじめに
こんにちは。<a href="https://x.com/Kei_dev_1213">Kei_dev_1213</a>と申します！
先日、参加しているコミュニティのハッカソンに参加しました。
「AIで日常を魔法に」というテーマで、2日間でアプリを開発しました。

本記事では、アプリのご紹介と、初めてハッカソンに参加してみた学びを共有していきたいと思います！

# テーマ：「AIで日常を魔法に」
ハッカソンのテーマは「AIで日常を魔法に」というものでした。
パッと聞いた感じ、色々考えられそうだなと思いながら、いざ考えてみると割と難しく、悩みながら作成しました。
また、AIと言っても画像生成や音声認識など様々なAIがありますが、
今回は、以前も使ったことのある文章生成のGemini AIを使ってアプリを作成することを考えました。

# 完成品：「Mind AI」
では完成品のご紹介となります。
- **概要**
  - アプリ名：「Mind AI」
  - 概要：
    AIとのやり取りをすることが出来るアプリ。
    日記の感想や、リアルタイムチャット機能を通じて孤独感を感じにくくする機能を提供する。
  - 技術：React、supabase、Gemini API

<br>

- リアルタイムチャット機能
![after1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832049/d461ddbb-61a1-993c-3c40-05ec89b05ce0.gif)
　AIとのリアルタイムチャット機能。AIと対話している感じを演出したかったため、UIはLINEのインターフェースに似せています。また、やり取りはsupabaseに保存されており、チャットの内容もこれまでのやり取りを踏まえた回答をしてくれるため、人間とやり取りしているような感覚でやり取りすることが出来ます。

<br>

- 日記機能
![after1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832049/656285bb-eb75-c59b-38b4-f4da71ba56d4.gif)
日記機能。一覧画面から遷移し、その日の気分の状態とジャーナルをつけて登録することで、AIからの一日のねぎらいのメッセージが生成される。

# このアプリを作った動機
一言で言うと、「AIとやり取りが出来て孤独感を紛らわせることができるって魔法感あるよね」と思ったからです（安直）。特に、チャット機能の部分はLINEのUIに似せることでまさに誰かとチャットしている感じを演出したかったため、そのようにしました。

# 反省点と学び
以下、今回のハッカソンに参加してみた反省点と学びです。
- **発想が安直すぎた**
  今回の最大の反省点はここだと思います。ハッカソンの最後で、参加者みんなで発表会をしたのですが、そこでの他の参加者は様々な発想からユニークなアプリを作成されていました。ただ、私の場合は時間制限に焦ってしまい、最初にじっくり考えることをせず、とりあえずAIとチャットできたらいいよね、あとは作りながら考えるか、と思いながら出発してしまったため、完成してから「あれ？これアイディアつまんなくね？」と気付く形となってしまいました。。きちんと最初にプロットを考えてから作りはじめた方がもっと面白かったんじゃないかな、と反省しました。

- **技術力がある程度あることは分かった**
  ハッカソンは2日間で行われたのですが、私は一人で参加したため、時間制限が結構きついなと思っていました。
  しかも、1日目はほぼ作業時間を確保出来ていなかったため、実質このアプリは1日（4時間ぐらい）で作成したのですが、完成形のイメージを考えてから最終的な形にすることが出来たのは良かったと思います。
  特につまる所もなく、割とサクサク作ることが出来たので、「とりあえずこのアプリを作れる程度には技術力があるんだな」という実感を得られたのは大きかったなと思いました。

- **他の人の発表が面白かった**
  ハッカソンの最後の発表会では、他の人の発表が勉強になり、発想力やプレゼン能力の違いを見せつけられました。ハッカソン参加者はエンジニアのみではなかったため、異なる分野の人々の考えに触れることができ、学ぶことも多かったです（他の方のハッカソンの記事は↓を参照）。

https://qiita.com/organizations/jisou/items

# おわりに
いかがだったでしょうか。
ハッカソンに参加する前は自分の実力でどこまでいけるか非常に不安だったのですが、やってみると意外と何とかなりました。あとは発想力やプレゼン能力など、自分に弱いところも見つけることが出来たので、今後もコミュニティ活動を通じて、技術力の向上と新しい発想の育成に努めていきたいと思います。
最後に、ハッカソンに参加してくれた皆さん、そしてこの記事を読んでくれた皆さんに感謝いたします。

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
【MacOS Sequoia】 MultipassインスタンスがUnknownとなる原因と解決策

# はじめに

:::note warn
本記事は2024/09/29時点の情報です。今後のリリースで問題が解決される可能性があるため、最新版の情報も確認してください。
:::
MacOSをSequoiaにバージョンアップ後、`multipass launch`や`multipass start`でインスタンスを起動しても、STATEが`Unknown`となる現象が発生しました。

バージョンアップ前まで普通に利用できていたので、OSのバージョンアップが原因だと考えられました。

GitHubのIssue #3661にて解決策が提示されているため、ここでまとめます。

https://github.com/canonical/multipass/issues/3661

# 環境

```:OS Version
$ sw_vers
ProductName:		macOS
ProductVersion:		15.0
BuildVersion:		24A335
```

```:Multipass Version
$ multipass version
multipass 1.14.0+mac
multipassd 1.14.0+mac
```

# 原因

上記のIssueによると、OSのバージョンアップにより`/var/db/dhcpd_leases`のフォーマットが変更され、MultipassがインスタンスのIPアドレスを正しく取得できなくなったため、インスタンスがUnknown状態になると考えられます。

# 解決策

MultipassのCollaboratorであるricabさんが上記Issue内で提供しているパッケージを適用します。手順は以下の通りです。

1. GitHub Issueの[コメント](https://github.com/canonical/multipass/issues/3661#issuecomment-2363403467)のリンクからパッケージをダウンロード
2. `.pkg`ファイルをダブルクリックしてインストール
3. セキュリティ設定で許可が必要な場合は、システム設定 > プライバシーとセキュリティから「許可する」を選択

なお、2024/09/25時点でricabさんがRCを近いうちにリリースすると発言されているため、記事作成から時間が経っている場合この問題は解決している可能性が高いです。
>Hi @HansS1964, I am glad it worked for you. If we have no further surprises, we're aiming to have a release candidate (RC) ready in approximately a couple of weeks. After that, if all is well with the RC it still takes a few days to sign and finally release.

# おわりに

上記手順で問題が解決しない場合は、公式の[トラブルシューティングガイド](https://multipass.run/docs/troubleshoot-networking)を確認するか、リリース候補版（RC）のアップデートが公開されているか確認してください。

記事を閲覧いただきありがとうございました。同じ事象が発生していた方への良い情報提供になれば幸いです。
Reactについて勉強中。。。

## はじめに

初学者でReactのドキュメントを読みながら勉強中です。
初学者だからこそ、わかりづらいところなどを初学者目線で書けている気が、、、します。

間違って解釈していたら直したいのでぜひぜひ指摘ください！

#### ※Reactについてどんなものか知りたい人向け①から見てくださいね！

　
## イミュータリビティとは

イミュータリビティ・・・不変性
つまりデータやオブジェクトの状態が一度作成されたら変更できないという性質のこと

もし変更しようとする場合は、新しいコピーを作成する必要がある。
『slice()』や『...（スプレット構文）』を使用する。

　
#### データを変更するには基本的に２つ
①データの値を直接ミューテート(書き換え)する方法
```diff_jsx
const squares = [null, null, null, null, null, null, null, null, null];
squares[0] = 'X';
// Now `squares` is ["X", null, null, null, null, null, null, null, null];
```
②望ましい変更が施された新しいコピーで元のデータを置換する方法
```diff_jsx
const squares = [null, null, null, null, null, null, null, null, null];
const nextSquares = ['X', null, null, null, null, null, null, null, null];
// Now `squares` is unchanged, but `nextSquares` first element is 'X' rather than `null`
```

②がイミュータリビティだが、こうすることでメリットがいくつかある


## イミュータリビティを使うメリット

データを変更しないということにメリットがある。
今回のReactのチュートリアル、三目並べでは「巻き戻し機能」が存在する。
これを実装するとき、元のデータを変更していないので戻るのが容易だが、
コピーなしで実装となるとかなり難しくなる。（てかコピーしないでできるのか？）

 　
また、再レンダーの回避も可能になる。
　＝＞親コンポーネントのStateが変更されるとすべての子コンポーネントも再レンダーされるがこれを回避することができる。

  　
イミュータリビティによってコンポーネントのデータが変更されたかどうかを容易に比較できるためだ。
　＝＞ここの理解がまだできていない。

## スプレット構文・スプレット演算子について ...

```diff_jsx
setHistory([...history, nextSquares]);
```
[...history, nextSquares] というコードは、history のすべての要素の後に nextSquares が繋がった新しい配列を作成します。（この ...history はスプレッド構文であり、「history のすべての項目をここに列挙せよ」のように読みます。）

例えば、history が [[null,null,null], ["X",null,null]] で nextSquares が ["X",null,"O"] の場合、新しい [...history, nextSquares] 配列は [[null,null,null], ["X",null,null], ["X",null,"O"]] になります。

 
ーーーー　ドキュメント参照（コピペ）↑　ーーーーー


 　
なかなか初めて勉強する人によってはよくわからな過ぎました、、、、。
けどchatGDPと確認しながら理解できました。

スプレット構文は
①第一引数のコピーを作成して、
②そのコピーしたデータに第二引数を結合。
③結合したデータを「set第一引数」にセットする。

#### 要はhistoryの配列にnextSquaresの配列を追加してhistoryではなく、setHistoryに保存されるということ。（historyは変わらない、不変である。)

　

 コピーされ、、、
 結合して
 set側に保存される。。。

 わかりづらい、、、useStateといい、慣れないなぁ、、、
 けど楽しい！ｗ
BigQuery のストリーミングバッファとは?

# はじめに
データ分析やビジネスインテリジェンス(BI)の分野では、随時でデータを活用することが重要になっています。

Google Cloud の BigQuery とその後の処理機能は、この機能センターにあるのが「ストリーミングバッファ」によって提供されています。

### 1. BigQuery とは何ですか?
BigQuery のストリーミングバッファは、ストリーミング挿入されたデータが一時的に保存されるドメインです。通常、のバッチとは異なり、ストリーミングデータは突然に近い形で上にBigQueryに反映されますが、 すぐにテーブルに书き手続きではなく、ストリーミングバッファにまずSAVEが行われます。ます。 このバッファの存在により、ラケットのデータ処理効率が、安定して行われています。

### 2.ストリーミングバッファの必要性とメリット
### パフォーマンスのメンテナンス
BigQuery は大量のデータを迅速かつ効率的に処理できますが、そこに挿入される大量のデータの影響を受ける可能性もあります。ストリーミングバッファは、これを防御するために一時的にデータを蓄積し、効率的にテーブルに取り込むことで、パフォーマンスを最適化します。

### データの統合の確保
大量のデータが同時にされる現実の状況に挿入され、させると書ける結果が直接、させると許される結果と、じズレが生じる可能性があります。ストリーミングバッファはその調整を行い、データがテーブルに书き勝つことで、結果の統合と保護を行います。

### 3. 構造器具の制限・制限に関する注意事項
データのリアルタイム反映に時間がかかることも
ストリーミングバッファ内のデータは、すぐに使えるもの、バッファからテーブルに书き投票には credleglegâ€”そのため、定期的に処理するデータと比較して、データの更新に遅れ延長が発生する可能性があります。

### テーブル更新の制限事項
ストリーミングデータは、一度バッファに保存された後、最終的にテーブルに取り込まれますが、このプロセスには制限があり、ストリーミングデータが一定の条件を満たすまでバッファ内に残ります。

### まとめ
ストリーミングバッファにデータがある间は、書いてそのデータを参照できますが、テーブルに以前の更新 (例: UPDATE DELETE) を完全に反映します。

ですので、ストリーミングバッファの特性を理解し、適切に使用することで、より効率的な処理や解析を行う必要があります。
😔 マスター系データの置き場所の分散にまつわる考察 💭

# これは何か
いわゆるマスター系データには「置き場所の分断」という問題がありがちと思っていて、それに対する考察をまとめたものです。
ただ独自考察なので、正しいかどうかは何とも言えず、書籍とかネット上の発表でこのあたりの話まとめてるのあったら教えてほしいです。
とはいえDB-アプリ横断の話になるし、「Webアプリケーションの作り方」的な本だと触れてる暇が無いと思うので、存在してない気も……。ネットの記事でも見たことがない……泥臭い現場の知恵系の話ですからね。

# マスター系データとは何か
> マスタデータの主な特徴
> - 変更が少ない静的な情報で、安定性が求められる
> - 企業全体で共有され、多くの部署にわたり一貫したデータ
> - ビジネスプロセスの効率化を実現する基盤となる情報

引用元:

https://www.srush.co.jp/blog/1108150667
 
# 話の発端
これまで

1. 零細レガシー企業（自社サー）
2. 零細ベンチャー（自社サー/受託両方やってたけど受託メイン）
3. 零細レガシーではないけどなりそうな気配のある現職（受託メイン）

と3社経験して、どの会社でも、**「中途半端にマスター系データがDBとアプリ側に分散していて処理追うのがきつい！バグの温床になっている！」** という問題と遭遇しました。
（自分はPHPerなので）PHPファイル内で巨大連想配列で直書きされているならまだ可愛い方で、**大元はCSV,JSONファイル**なんて例も珍しくはなく、**他社からファイル連携（という名の他社からのサーバー接続からの自動/手動のアップロード作業）** であったりとか、**非エンジニアが元データ作って渡してくる** とかが絡んでて、フローごと変えるコストが滅茶苦茶高いケースもありますね。
独立した小データならまだいいんですが、リレーションがあって本来DBのテーブルとして切り出さない内容なのにアプリ側で持っているもんだから、**"●●●Id"プロパティがデータに埋め込まれている** なんてのもよくある話。別タブやウィンドウでコードとDBの値見て**脳内JOIN**……うーん！😑😑😑😑😑


# 結論
- **理想としてはDBに全部あった方がいい（大前提）**
- **諸々の技術革新で昔に比べれば改善したものの、未だDBの変更よりアプリの変更の方がコストが安い／難易度が低いという現実** があり、そこが運用面に重くのしかかっていて発生している。
- とことん運用都合（主導）であり、純粋なエンジニアリング理論とはほど遠いところの話である。現場の知恵的な。
- 肌感としては「仕様として枯れている」、「そのアプリケーションの中でコア」、「管理画面やAPIを通して動的に変更する必要がある」ものはDBに置くのがいいと思います。（というか置かざるを得ない）
- **開発や運用初期で仕様自体が全く安定せず、変更はデプロイ時のみでOK**という場合はあえてアプリ側に留めて頑張ってカバーするというのも正直言ってアリ。（なお移行する暇なくて割れ窓になる模様😩）
- 他社や非エンジニアからファイルを貰わずに済むよう、管理画面や入力フォーム等を整備したり、ファイルからDBに取り込む処理を書く等、泥臭く整備するしかない。そもそもそんな自社orクライアントにお金がないからこんなことになっているし、改善したくてもお金の問題で手をつけられないことが多いのだが……
ファイルアップロードと共有資源やキャッシュ、JSに関する問題

## ファイルアップロードにまつわる問題

- アップロード機能に対するDoS攻撃
- アップロードされたファイルをサーバー上のスクリプトとして実行する攻撃
- 仕掛けを含むファイルを利用者にダウンロードさせる攻撃
- 閲覧権限のないファイルのダウンロード

がある。

## 共有資源やキャッシュに関する問題

### 競合状態の脆弱性

複数のプロセスやスレッドから同時に利用している変数、共有メモリ、ファイル、データべースのことを共有資源と呼ぶ。
共有資源に対する排他制御ができていないと、競合状態の脆弱性になる可能性がある。

対策としては、
- 可能であれば共有資源を使用しない
- 共有資源に対して排他制御を行う

### キャッシュからの情報漏洩

- アプリケーション側のキャッシュ制御不備
- キャッシュサーバーの設定不備
- によって、キャッシュから情報が漏洩することがある

対策は、
- 正しくキャッシュ制御やサーバの設定を行うこと
- そもそも、情報漏洩になるような情報をキャッシュしないこと

## JavaScriptの問題

### DOM Based XSS

JavaScriptによる処理の不備が原因でXSSとなること。

原因は
- DOM操作の際に外部から指定されたHTMLタグなどが有効になってしまう機能を用いている
- 外部から指定されたJSが動作する`eval`などを使用している
- XMLHttpRequestのURLが未検証
- `location.href`やsrc属性、href属性のURLが未検証

対策は
- 適切なDOM操作、記号のエスケープをする
- evalなどの引数に文字列形式で外部から値を渡さない
- URLのスキームをhttpかhttpsに限定する
- JQueryのセレクタは動的生成しない
- 最新のライブラリを使用する
- XMLThhpRequestのURLを検証する

### Webストレージの不適切な利用

Webストレージは、JavaScriptから読み書きできるストレージであるため、重要な情報は保存してはいけない。


## 終わり

Webセキュリティは学習することがたくさんあって、全然覚えることができていません。
また、いつかセキュリティの資格に挑戦したいので、その時に改めて勉強しなおそうと思ってます。
【IT業界未経験】AWS認定ソリューションアーキテクト(SAA)合格への記録

# はじめに

IT業界未経験からインフラエンジニアへの転職を目指すmmと申します。<br>
2024年春、AWS SAAに合格できたので勉強方法を記事に残します。

# 記事の目的
この記事は効率的な受験勉強の方法や早く合格するためのテクニックを紹介するものではありません。<br>
私が受験にあたって、受験当時意識した事や反省した事、受験を終えて感じた事などの記録となります。ご留意ください。<br>
また本記事では、AWS SAA試験の概要は省略しております。

# 経歴
- 文系４大卒。IT業界未経験
- プログラミング経験はVBAのみ
- オンラインスクールでAWSコースを完走済み
- 所持資格はなし

# 受験の動機

- AWSの基本サービスについて体系的に学ぶことができるため
- お世話になっているスクールでも取得が推奨されており、AWS案件への参画条件となっている事も多く、転職にあたって取得した方がいいと思ったため

# 学習期間
1ヶ月（毎日2時間以上）

# 目標とした事
学習にあたって合格以外に目標とした事です😀

- 暗記ではなく理解をすることに努める（どの資格学習でも共通！！）
- 触れた事のないサービスについては可能な限りハンズオンを行う

# スコア
- 836点（1000点満点中）<br>
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837659/487e2fe2-637e-36a9-ef1e-249ba0b0199d.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837659/f8ad6250-7ba6-dc48-9315-c8a715bec2f4.png)


# 使用した教材・サイト
## 参考書
- [AWS Black Belt](https://aws.amazon.com/jp/events/aws-event-resource/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc)
- 一夜漬けAWS認定ソリューションアーキテクトアソシエイト［C03対応］直前対策テキスト

## 演習問題
- [CloudTech](https://kws-cloud-tech.com/)のAWS資格演習対策コース
- 公式の無料問題20問
- Udemy【SAA-C03版】AWS認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）

# 教材の使用回数
- CloudTech演習問題230問×4周程（覚えてないが恐らくこれくらい）
- 分からない部分については[AWS Black Belt](https://aws.amazon.com/jp/events/aws-event-resource/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc)を確認
- 公式の無料問題20問×1回
- Udemyの模擬問題×1周
- 一夜漬けテキストは受験一週間前に購入し、サービスを頭の中で整理するために適宜使用

# 勉強方法
- CloudTechの演習問題230問を繰り返す
- CloudTechの解答下部の関連動画、解説を見て理解を深める。同時に公式ドキュメントを確認する
- 全ての選択肢について正解、不正解に関わらずの理由を説明できるようにする
- CloudTechの正解率が8〜9割になった時点で正解を覚えてしまいつつある事に気づき、時間を置くためにUdemyの模擬問題を挟む

# 試験結果の通知方法
試験終了時に合否は出ませんでした。私の場合は16時に試験が終了し、19時過ぎに受験履歴を確認したら結果が表示されました。

# 反省点

- ハンズオンできていないサービスがある
- 合格したとはいえネットワークについての基礎知識など、広い部分でIT業界に関する基礎知識の不足を感じた

# よかった点

- AWSのメインサービスについて基礎知識を身に付ける事ができた
- AWSのサービスとは直接関係ないIT用語（例：オーバーヘッド、レイテンシーなど）も覚えることができた

# 終わりに
始めて受けたIT試験と言うこともあり非常に緊張しました。あと、正直落ちたと思いました😂<br>
見直したい問題にチェックを付けて最後に見直しできるのですが、自信がない問題が35問もありました。試験時間をフルに使い見直しましたが最後まで自信はないままでした。<br>
また、反省点に記載の通り、ネットワークやサーバーについての基礎知識など、広い部分でIT業界に関する基礎知識の不足を感じました。一度、基礎知識の習得のために時間を作ろうと思います。
アジャイルと品質

![](https://storage.googleapis.com/zenn-user-upload/909641d1aed4-20240929.jpg)

アジャイル開発の中で、品質はどのように担保されるべきか、というお話です。

![](https://storage.googleapis.com/zenn-user-upload/4c68132e3896-20240929.jpg)

品質を確保する目的は何でしょうか？それは、プロジェクト全体のスピードを落とさないためです。

![](https://storage.googleapis.com/zenn-user-upload/827c20e480a0-20240929.jpg)

ウォーターフォールの時代から、品質を担保する理由は一貫しています。バグを早期に見つけて修正しないと、後のフェーズで問題が発覚してから修正に余計なコストがかかるからです。後から修正が必要になると、開発スピードがガクンと落ちます。

![](https://storage.googleapis.com/zenn-user-upload/0b4f57d25d7c-20240929.jpg)

アジャイル開発でも、品質を担保する理由は全く変わりません。バグが見つかるタイミングが遅れれば遅れるほど、その修正には多くの時間がかかり、結果としてプロジェクト全体の進行が遅くなってしまいます。デバッグは非常に工数を消費しますからね。

納期と品質のバランスというのは、よく聞く話ですが、実際には「品質が低ければ納期は遅れる」のが現実です。製造業からの影響かもしれませんが、ITプロジェクトにおいては、品質が悪いと納期が守れないというのは多くの経験からも明らかです。

![](https://storage.googleapis.com/zenn-user-upload/0af7ee30570b-20240929.jpg)

品質が低いアジャイル開発なんて存在しません。品質を無視すれば、アジャイル開発自体が成立しなくなります。

![](https://storage.googleapis.com/zenn-user-upload/ceae02372c0a-20240929.jpg)

アジャイルの品質が低いと言っている人は、おそらくカウボーイコーディングと混同しているのでしょう。アジャイルでもなく、ウォーターフォールでもない、ただプログラマーの直感や経験だけで進めるやり方です。これでは本当のアジャイルとは言えません。

![](https://storage.googleapis.com/zenn-user-upload/16be0bb54e08-20240929.jpg)

アジャイル開発においては、顧客に頻繁に動作を見せることが求められるため、機能追加が常に前提にあります。ですから、品質が悪いとこのサイクルが成立しません。

![](https://storage.googleapis.com/zenn-user-upload/b39ae328e117-20240929.jpg)

そこで登場するのがTDD（テスト駆動開発）やペアプログラミングです。

![](https://storage.googleapis.com/zenn-user-upload/c973d31d633a-20240929.jpg)

TDDは、最初にテストを書くので、手を抜かなければほぼ100%のテストカバレッジが実現できます。また、コードの可読性もリファクタリングによって保たれます。

![](https://storage.googleapis.com/zenn-user-upload/d9b4f6f7da5e-20240929.jpg)

ペアプログラミングは、教育面での利点もありますが、品質の観点から見ると、リアルタイムでのレビューと同じ効果があります。レビューを繰り返すことでバグを早期に発見し、結果として開発速度が上がるのです。

ただ、ペアプログラミングは普及度が今ひとつ。理由の一つとして、プログラマーが一日中会話しながら作業するのが苦手な人が多いという点が挙げられます。その場合は、レビューを強化するなど、他の方法で対応することが必要です。

![](https://storage.googleapis.com/zenn-user-upload/ca7a7a4e23e3-20240929.jpg)

アジャイル開発において、品質が低いということはあり得ません。高品質でなければ、アジャイルは成り立たないのです。

![](https://storage.googleapis.com/zenn-user-upload/63db1f5decc4-20240929.jpg)

品質が高いからこそ、デバッグに時間を取られず、機能追加がスムーズに行えます。これこそ、良いサイクルが回っている証です。

![](https://storage.googleapis.com/zenn-user-upload/d00192de0391-20240929.jpg)

アーキテクチャ選定にも品質は大きく影響します。マイクロサービスなどの複雑な構成では、高品質なアジャイルが前提でないと実現は困難です。複雑なシステムほど、アジャイルの品質管理が重要になります。

![](https://storage.googleapis.com/zenn-user-upload/7015ed00af03-20240929.jpg)

高品質なアジャイルを実現することで、以下のような新たな世界が広がります。
* 影響範囲の調査不要
* どのコードでも安心して書き直せる
* 機能追加がスムーズ
* ライブラリのアップデートも安心
* 変更をすぐに本番に反映
* 言語変更以外は慌てず対応可能

このような未来を目指して、高品質なアジャイル開発を実現していきましょう。

(編集協力：ChatGPT 4o様)  
(当記事はZennにもマルチポストされます)
[Zenn](https://zenn.dev/hrmstrsmgs/articles/edcc2f08109224)
(スライド全体はこちら)  
[speakerdeck](https://speakerdeck.com/player/f7beb0ad0d2b4214b69627c4432b13e3)
Dockerfile の COPY の挙動

# 目的
Dockerfile の `COPY` の挙動を理解する。

# 説明
## ファイルのコピー

[公式ドキュメント](https://docs.docker.com/reference/dockerfile/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508161/cd22224a-9eef-f4c0-f02e-17f214f4b271.png)

ファイルを特定のディレクトリの中にコピーするときは、ディレクトリの終わりに `/` (スラッシュ)をつける必要がある。
つまり、ファイルのコピーには、下記の2パターンの方法がある。

### (1) コピー先にディレクトリを指定する方法
```
# Dockerfile

# create /abs/test.txt
COPY test.txt /abs/
```
(2) の方法と違って、こっちの方法は、下記のようにまとめて複数のファイルをコピーできる。
```
# Dockerfile

# create /usr/src/things/file1.txt
# create /usr/src/things/file2.txt
COPY file1.txt file2.txt /usr/src/things/
```

### (2) コピー先にファイルを指定する方法
```
# Dockerfile

# create /abs/test.txt
COPY test.txt /abs/test.txt
```


## ディレクトリのコピー

[公式ドキュメント](https://docs.docker.com/reference/dockerfile/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508161/1253271d-a3ef-258c-8a1d-4104ab1d7e19.png)

コピー元がディレクトリの時は、そのディレクトリの**中身**が、コピー先のディレクトリの中に展開される。
下記のように書くことで、ホストマシンの`./web/`ディレクトリの**中身**が、コンテナの`/MyApp/web/`ディレクトリの中に展開される。
```
# Dockerfile
COPY ./web/ /MyApp/web/
```

# おまけ
`docker cp` コマンド(リンクは[こちら](https://qiita.com/ShiroatoHiro/items/4d30a7ebdd11ff51c89a))とは挙動が異なるので注意。
MongoDB compassで"getaddrinfo ENOTFOUND mongo"と出て接続できないとき

## したかったこと
Docker上でMongoDBを立ち上げて、ホストマシン上のMongoDB compassからアクセスしたかった。
## 症状
```
mongodb://localhost:27017/
```
にcompassから接続を試みたが、
```
getaddrinfo ENOTFOUND mongo
```
というエラーが発生して接続できない。

一方で、mongoshを使ってターミナルからアクセスするとアクセス可能であった
```
% mongosh "mongodb://localhost:27017"
Current Mongosh Log ID:	66f8d4b7c208d9e36d035dda
Connecting to:		mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.3.1
Using MongoDB:		6.0.17
Using Mongosh:		2.3.1

hogehoge [direct: primary] test>
```
## 解決
Advanced Connection OptionsのDirect Connectionにチェックを入れるだけで解決した（チェックを入れると、URIに```?directConnection=true```が追加される）。
よく見たらmongoshでの接続ではこの設定が有効になっているので接続できたのだと思われる。
![スクリーンショット 2024-09-29 16.18.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661623/dc9f092a-741a-af49-a307-b17e27951463.png)

## おわりに
インターネット上で情報を探しても、特に細かい設定無しで簡単に接続できる！という記事ばかりで接続できない場合に関する情報が少なく、解決に非常に時間がかかってしまった。特にmongoshからは接続できるのが謎で、探しても見つからない症状だったが、偶然この方法に言及している方がいて助かった。
ただ、今になって思えばmongoshの```Connecting to:```以下を真似ればすぐに解決したのだった。

一方で、なぜ今回このオプションが必要となったのかは不明で、かつこの設定によって具体的に何が変わって解決したかも不明なので、有識者の方教えてください。



## 参考リンク
https://stackoverflow.com/questions/73836909/getting-getaddrinfo-enotfound-mongo-when-trying-to-connect-to-mongodb
https://github.com/mongodb/mongodb-kubernetes-operator/issues/946
【AWS】S3のPDFファイルにカスタムドメインでアクセスする

# 概要

S3 バケットのパブリックアクセスを許可することで、オブジェクト URL により PDF ファイルにアクセスすることができる。

![s3-pdf-custom-domein-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/58e06e58-f861-4c70-15c5-ac7866e415f5.png)

本記事では CloudFront のカスタムドメインを使用して、この PDF ファイルにカスタムドメインでアクセスする手順を記載する。

![s3-pdf-custom-domein-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/ba21d615-e3be-daa7-b722-90de150adca3.png)

# 前提条件

- Route53 にパブリックホストゾーンが存在すること
  - 本記事ではパブリックホストゾーン名は `oizumi-yuta.com` とする
- S3 バケットのパブリックアクセスが許可されていること

# 手順

## 1. CloudFront ディストリビューションを作成する

オリジンに対象の S3 バケットを選択する。

![s3-pdf-custom-domein-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7d8b76f4-2260-69db-b8d5-ff8127596da7.png)

その他はデフォルトで作成する。

## 2. ACM でパブリック証明書をリクエストする

バージニア北部リージョンで証明書をリクエストする。完全修飾ドメイン名にカスタムドメイン名を入力する。

![s3-pdf-custom-domein-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/20e37d24-c990-bf61-dc9a-698b9935f062.png)

## 3. Route 53 でレコードを作成する

ホストゾーン `oizumi-yuta.com` に CloudFront 向けエイリアスレコード `docs.oizumi-yuta.com` を作成する。
レコード名はカスタムドメイン名を入力する。

![s3-pdf-custom-domein-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7ce292e6-07c7-14be-b3d9-7a49cfa61ba1.png)

## 4. カスタムドメインをディストリビューションに設定する

![s3-pdf-custom-domein-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/fa9ef51a-fc4e-7309-bd5b-efd5779ca46f.png)

# 動作確認

![s3-pdf-custom-domein-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/ee4ac945-0c84-89e3-c203-8c70921d0065.png)

# 参考

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-requirements
foreach文のkeyとvalueの取得方法

## コードの説明

- dictionaryを宣言し、keyに"1"、Valueに"りんご"等を加えます。

- dictionaryをforeachでループします。

- foeachのスコープ内でfluit.Key、fluit.Valueで値を取得することができます。
```ruby:test.cs
static void Main(string[] args)
{
    var fruitsDic = new Dictionary<string, string>();
    fruitsDic.Add("1", "りんご");
    fruitsDic.Add("2", "いちご");
    fruitsDic.Add("3", "めろん");
    
    foreach(var fluit in fruitsDic)
    {
        Console.WriteLine("{0}番目は{1}です。", fluit.Key, fluit.Value);
    }
    Console.ReadLine();
}

```
出力結果は以下のようになります。
1番目はりんごです。
2番目はいちごです。
3番目はめろんです。
docker cp コマンドのコピー元ディレクトリは常に  /.  (スラッシュ と ドット)で終われ

# 目的
`docker cp` コマンドの挙動について理解する。

# 結論
## ディレクトリのコピー
例えば、コンテナ内の Go 環境をホストマシンにコピーしたいときを考える。
※ `MyApp-web-1` はコンテナ名です。
### (1) 推奨されるコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/. ~/usr/local/go/
```
### (2) 少し危険なコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/
```
### (3) 非常に危険なコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/go/
```

## ファイルのコピー
ファイルのコピーは単純。
```
$ sudo docker cp MyApp-web-1:/MyApp/web/go.sum web/go.sum
```

# 説明
## ディレクトリのコピー
### 公式ドキュメントを確認
公式ドキュメントは[こちら](https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/cp/)
```
$ docker cp [オプション] CONTAINER:SRC_PATH DEST_PATH
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508161/2a41d794-9d97-5df1-6704-098be8c00762.png)

### 具体例
#### (1) 推奨されるコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/. ~/usr/local/go/
```
公式ドキュメントを見ると、この方法であれば、常に、コピー元ディレクトリ(`MyApp-web-1:/usr/local/go/`)の**中身**が、コピー先のディレクトリの中に展開される。
前提として、コピー先の親ディレクトリ(`~/usr/local/`)が存在しなければエラーを吐いてくれる。

#### (2) 少し危険なコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/
```
公式ドキュメントを見ると、この方法を使うと、コピー先のディレクトリ(`~/usr/local/`)が存在する場合に限り、意図通りのコピーが実施される。
このコマンドが少し危険な理由は、コピー先のディレクトリ(`~/usr/local/`)が存在しないで、コピー先の親ディレクトリ(`~/usr/`)のみが存在する場合、コピー先のディレクトリ(`~/usr/local/`)の中に、コピー元ディレクトリ(`MyApp-web-1:/usr/local/go/`)の**中身**が展開されてしまうからである。
このコマンドの前に、常に、`$ mkdir -p ~/usr/local/` を実行するようにすれば問題ない。

#### (3) 非常に危険なコマンド
```
$ sudo docker cp MyApp-web-1:/usr/local/go/ ~/usr/local/go/
```
コピー先のディレクトリ(`~/usr/local/go/`)が存在せずに、コピー先の親ディレクトリ(`~/usr/local/`)が存在する場合は、意図通りの挙動となる。
しかし、コピー先のディレクトリ(`~/usr/local/go/`)が存在する場合は、コピー元のディレクトリ(`MyApp-web-1:/usr/local/go/`)が、コピー先のディレクトリ(`~/usr/local/go/`)にコピーされてしまう。
コピー先のディレクトリ(`~/usr/local/go/`)が存在せず、コピー先の親ディレクトリ(`~/usr/local/`)のみが存在する状態で、上記のコマンドを二回実行したら、一回目は意図通りの挙動だが、二回目は`~/usr/local/go/go/`ディレクトリを作成してしまう。

# おまけ
Dockerfile の `COPY` の挙動(リンクは[こちら](https://qiita.com/ShiroatoHiro/items/d079cee47999b07522e8))とは異なるので注意。


# 参考
https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/commandline/cp/
TNCコマンドに関して

# 背景
今回、Azure上に仮想の制御サーバを立てて、プリンタと仮想サーバの通信を行おうとしていました。
ただ、プリンタで制御サーバの設定をしようとしてもうまく設定できなかったため、ポートの穴あけを行い、その際の疎通確認をするためにTNCコマンドを初めて使用しました。どのポートが開いているのかを確認するのにとても便利です！
## TNCコマンドとは
TNCコマンドは、Test-NetConnectionコマンドのことで、PowerShellを使用してポートの疎通確認を行います。
コマンドの表記は以下のようになります。
** Test-NetConnection <接続先の端末> -Port <ポート番号> **

例えば、Googleの443のポートが開いているかを確認したいときは以下のようにします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765220/01ba9b92-6007-c1a3-fc8a-ce801e264d2a.png)
上記の画像の最後の行である「TcpTestSucceeded」がTrueとなっている場合は疎通が出来ていることになります。

みなさんもぜひ使ってみてください！！
【初心者向け】辞書攻撃、パスワードスプレー攻撃、パスワードリスト攻撃、ブルートフォース攻撃の違いと対策

# はじめに
現代のサイバーセキュリティの脅威の中で、特にアカウントの侵害に繋がる攻撃手法は多様です。その中でも「辞書攻撃」「パスワードスプレー攻撃」「パスワードリスト攻撃」「ブルートフォース攻撃」は特に一般的な手法として知られています。本記事では、それぞれの攻撃方法の特徴や違いを解説し、対策方法も紹介します。

## 1. 辞書攻撃（Dictionary Attack）
### 概要
辞書攻撃とは、一般的に使われている単語やフレーズをまとめたリスト（「辞書」）を利用して、順番に試行することでパスワードを割り出そうとする手法です。多くのユーザーが単純なパスワード（例: "password123", "welcome2023" など）を使っているため、これらを短時間で試すことができます。

### 特徴
辞書リストを利用するため、単語ベースのパスワードに対して効果的。比較的早い段階で成功することが多いが、複雑なパスワードには弱い。
### 対策
簡単な単語や一般的なフレーズをパスワードに使用しない。パスワードマネージャーを利用し、ランダムで複雑なパスワードを生成・管理する。

## 2. パスワードスプレー攻撃（Password Spraying Attack）
### 概要
パスワードスプレー攻撃では、多数のアカウントに対して少数の一般的なパスワード（例: "password", "123456"）を試す手法です。具体的には、攻撃の時刻と攻撃元IPアドレスを変え、アカウントロックを回避しながら、よく用いられるパスワードを複数の利用者IDに試し、ログインを試行します。
この手法は、同じアカウントに対して短時間に多くのパスワードを試すのではなく、広範囲のアカウントに対して少量のパスワードを試すことで、アカウントロックを避けることが目的です。

### 特徴
多数のアカウントに対して一斉に攻撃を行う。単純なパスワードを使用しているアカウントがターゲットになる。ロックアウトメカニズムを回避するため、比較的ゆっくりとした速度で行われる。

### 対策
アカウントに対する多重認証（MFA）を有効にする。簡単なパスワードの使用を避けるようにユーザーに啓蒙する。一定回数のログイン失敗後、アカウントロックを設定する。

## 3. パスワードリスト攻撃（Credential Stuffing Attack）
### 概要
パスワードリスト攻撃は、他のサービスやサイトで漏洩したユーザー名とパスワードの組み合わせ（「クレデンシャルリスト」）を利用し、他のサービスに不正ログインを試みる攻撃です。ユーザーが複数のサービスで同じパスワードを使い回している場合に、成功率が高くなります。

### 特徴
既に漏洩したユーザー名・パスワードを利用する。ユーザーが異なるサービスで同じパスワードを使っている場合、効果的に攻撃が行える。成功率は漏洩データの品質に依存する。

### 対策
各サービスで異なるパスワードを使用する。パスワードマネージャーを使用して複雑かつユニークなパスワードを生成する。多重認証（MFA）を導入し、パスワードのみではログインできないようにする。

## 4. ブルートフォース攻撃（Brute Force Attack）
### 概要
ブルートフォース攻撃は、可能なパスワードのすべての組み合わせを順番に試す方法です。コンピュータの処理能力に依存し、大量の試行が行われます。複雑なパスワードでも、時間さえかければ破られる可能性がありますが、組み合わせの多さが成功率に影響します。

### 特徴
すべてのパスワードの組み合わせを試すため、非常に時間がかかることがある。パスワードが長く複雑であればあるほど、成功するまでにかかる時間が増える。処理速度の向上に伴い、短いパスワードは破られるリスクが高まっている。

### 対策
長く複雑なパスワードを使用する（推奨：12文字以上）。一定回数のログイン失敗でアカウントを一時的にロックする。キャプチャ（CAPTCHA）や他のボット対策を導入する。

# まとめ
本記事では、辞書攻撃、パスワードスプレー攻撃、パスワードリスト攻撃、ブルートフォース攻撃の違いと、それぞれの対策について解説しました。パスワードの強度を高めることや、多重認証を導入することが、これらの攻撃に対する強力な防御策となります。インターネットの世界では、自分のセキュリティを守るために、少しの注意が大きな差を生むことを忘れないようにしましょう。
ネットワーク知識入門〜重要そうな点〜

# 概要
ネットワークについて、重要そうなものを浅くではあるが、学んだので、改めてアウトプットします。

重複もありますが、ここでもまとめてます。
[ネットワーク知識入門1](https://qiita.com/saburo555/items/e14c2524a12d9b8d061f)
[ネットワーク知識入門2](https://qiita.com/saburo555/items/b7fee560e091e7d8c009)
[ネットワーク知識入門3](https://qiita.com/saburo555/items/7a0972ed39a06c2d6175)

# TCP/IP
TCP/IPモデルの階層は、以下の4つ。
* アプリケーション層（L5~7）
* トランスポート層（L4）
* インターネット層（L3）
* リンク層（L2）
TCPはトランスポート層のプロトコルで、IPはインターネット層で使用されるプロトコル。

インターネット層とは、エンドツーエンド（送信元と宛先を結ぶ通信経路）の通信に関するプロトコル群。
トランスポート層とは、通信における信頼性に関するプロトコル群。

### IP
IPはコネクションレス型で、ベストエフォート型（送りっぱなし、届いたかどうか、感知しない。また、保証はしないけど、全力は尽くす。）。そのため。エラー情報の転送するためのプロトコルのICMPをIPとセットで用いる。

### ARP
ARPとは、IPアドレスに基づく、MACアドレスを調べるためのプロトコル。
このMACアドレスを調べる行為をアドレス解決という。

### TCP
TCPはコネクション型（確認しあって、情報を送りあう）。

# IPアドレス
現在はIPv4（32ビット）とIPv6（128ビット）が使用されている。
IPアドレスは住所のようなもの。
MACアドレスと違い、個々のノードに付与されるIPアドレスは状況によって変化する。

# ポート番号
どのアプリケーションにデータを送信するのかを判断するためのもの。

# DNS（ドメイン　ネーム　システム）
人が覚えやすい名前（ドメイン名）とIPアドレスを関連付けて、アクセスを容易にしようという仕組み。
ここでいうドメイン名は、ホスト名 + ドメイン名。
上記の関連付けをすることで、IPが変わったとしても、サイト等にアクセスできる。

関連付けを実現する方法として、「hosts」という仕組みがある。
各コンピューターの「hosts」ファイルにドメイン名とIPアドレスの対応表を記載し、通信時に参照する。
上記の方法では管理が難しくなったため、ユーザーがアクセスする際に、ドメイン名を問い合わせてIP名を教える方法をとり、それを実施するのがDNSサーバー。

# NAT/NAPTの理解
NAT/NAPTはIPアドレス（例：プライベートをグローバルになど）の変換技術。
グローバルIPアドレスが枯渇しているため、プライベートIPアドレスを個々の端末に持っている。
そのプライベートIPからインターネットに接続する際に、グローバルIPに変換するため、NATやNAPTを使用する。

### NAT
1対1の変換を行う。
プライベートIPを隠蔽したい時に使用。

### NAPT
他対1の返還を行う。
複数のプラベートIPを1つのプライベートIPに紐付けできる。
ポート番号も組み合わせて使用する。

# サブネット化
ネットワークをさらに分割することをサブネット化という。

### サブネットマスク
IPアドレスのネットワーク部とホスト部がどこで区切れているかを表す。
ホスト部は具体的なコンピュータを表す。

表記方法
* IPアドレス　＋ サブネットマスクそのまま表記
* プレフィックスを使用（先頭から何ビット目までネットワーク部かを記載）
string.Emptyと""の違いについて

## 結論
可読性向上のため、""よりもstring.emptyが多く使われている。
## string.Emptyの使い方

```ruby:test.cs

var test =  string.Empty

```
### ""の使い方


```ruby:test.cs

var test =  ""
```
[String.Empty フィールドについて](https://learn.microsoft.com/ja-jp/dotnet/api/system.string.empty?view=net-8.0)
【SpringBoot］@Transactionalについて

## Transactionalアノテーションとは
「トランザクション」を利用するために必要なアノテーション。
「トランザクション」とは、データベースを利用する一連の処理を一括で実行する機能であり、処理中に例外が起こった場合は、自動でロールバックしてくれる。

## トランザクションを利用しなかった場合
データアクセス処理中に、途中で外部からデータベースにアクセスされ、データが変更されたりすると、データの整合性に問題が発生してしまう。そうしたトラブルを防ぐためにトランザクションは必要となる。


## 使い方
サービスクラスに「@Transactional」を付与することで、そのクラス内の全てのメソッドにトランザクションが適用される。
※特定のメソッドにのみ適用したい場合は、該当メソッドにのみアノテーションを付与する。

### 例：Controllerクラス
```java:TestController.java
public class TestController {

    @Autowired
    TestService testService;

    @PostMapping("/post")
    public void postTest() {
        testService.insertA();
    }
}
```

### 例：Serviceクラス
```java:TestService.java
@Service
@Transactional
public class TestService {

    @Autowired
    TestDao testDao;

    public void insertA() {
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);

        // 例外発生
        throw new RuntimeException();
    }
}
```

### 実行結果
正常にロールバックされている。
```mysql:
mysql> select * from fruit;
Empty set (0.00 sec)
```


### ※注意点
トランザクションが機能するのは、このサービスクラスをDIしたクラスから直接呼び出されているメソッドのみということ。以下のような場合、ロールバックされません。
```java:TestService.java
@Service
public class TestService {

    @Autowired
    TestDao testDao;

    // これがControllerから直接呼び出されているメソッド
    public void insertA() {
        insertB();
    }

    // Controllerから直接呼び出されていないメソッドに付与
    @Transactional
    public void insertB() {
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);

        // 例外発生
        throw new RuntimeException();
    }
}
```

### 実行結果
ロールバックされず、データは挿入される。
```mysql:
mysql> select * from item;
+----+-------+-------+
| ID | NAME  | PRICE |
+----+-------+-------+
| 1  | apple | 100   |
+----+-------+-------+
```


## 属性値について
指定可能なプロパティは９種類ほどある模様
詳しい内容は<a href="https://qiita.com/NagaokaKenichi/items/a279857cc2d22a35d0dd">こちらの記事</a>を参照


本稿では、その中でも、開発時によく利用しているreadOnly属性について解説する。

### 【readOnly属性】
・readOnly属性（デフォルトは``false``）を ``true`` に設定すると、読み取り専用のトランザクションと見なし、レコードへの書き込みや変更を伴う操作が走った際に例外を投げてくれる。


```java:java
@Service
public class UserService {

    /** 更新系 **/
    @Transactional(readOnly = true)
    public User insertFruit() {
    
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);
    }
}
```
### 実行結果
更新処理は許可されていないため、以下のようなエラーが出力される。
```
java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
```
CSMのSEUが加算されるタイミングまとめ

# はじめに
先週CSM試験の合格までの流れについて、記事にまとめました。

https://qiita.com/YuukiYoshida/items/0db6b0fdbb66f94ddbac

今回はCSMの資格の更新時などに必要なSEUを貯めていく為の方法を備忘録的にまとめておきたいと思います。

# SEUとは？
SEUはScrum Education Unitsの略で、アジャイルやScrumに関連した活動や学習を通じて得られるポイントになります。
CSMの資格更新にも必要とされるポイントで、上位のA-CSMやCSP-SMを取得する際にも必要となります。

# SEUが加算される行動
SEUの詳細がわかったところで、このポイントが加算される行動や活動についてまとめていきたいと思います。

### カテゴリ A: Scrum Allianceが主催する活動
内容: Scrum Allianceが直接主催するイベントやトレーニングコースに参加すること。
SEUの獲得量: 以下1時間の参加につき1 SEU
   - Scrum Gatherings: Scrum Allianceが年に数回開催する国際会議。アジャイルの最新トレンドやベストプラクティスについて学べる場。
   - Regional Scrum Gatherings: 地域ごとのScrum Gatheringイベントでの参加。
   - Scrum Allianceトレーニング: Scrum Alliance認定のトレーナーが実施する公式トレーニング（例：Advanced CSM、CSP-SMなどのトレーニングコース）。


### カテゴリ B: その他の外部トレーニングやイベントへの参加
内容: 外部のトレーニングやアジャイル関連イベントに参加することでSEUを獲得できます。
SEUの獲得量: 以下1時間の参加につき1 SEU。

   - アジャイルカンファレンスやセミナー: Scrumやアジャイル関連の国際会議、ワークショップに参加（例：Agile Japan、Lean Agile USなど）。
   - 外部トレーニング: Scrum Alliance以外の組織やトレーナーが実施するScrumやアジャイルのトレーニングコース。
   - コミュニティイベント: Scrumユーザーグループやローカルアジャイルコミュニティが開催するミートアップ、ハッカソンなどに参加。

### カテゴリ C: 独学による学習活動
内容: 本や記事を読んだり、ビデオやウェビナーを視聴することでもSEUを取得できます。
SEUの獲得量: 以下1時間の学習につき1 SEU。

- アジャイルやScrum関連の書籍を読む: Ken SchwaberやJeff SutherlandによるScrumの基本書、Mike Cohnのアジャイル開発関連書籍などを読む。
- ブログや論文を読む: Scrum Allianceや他の信頼できるアジャイルリソースが発行するブログや記事を読むこと。
- ウェビナーを視聴: Scrumやアジャイルに関するオンラインウェビナーや動画を視聴する（例：Scrum Allianceが提供するウェビナー）。

### カテゴリ D: 公開されたコンテンツの制作
内容: Scrumやアジャイルに関するコンテンツを公開することでSEUを取得できます。
SEUの獲得量: 公開された内容に応じて、Scrum Allianceが認定するSEUを取得。

- ブログ記事を書く: Scrumやアジャイルの実践に基づいた記事を執筆して公開。
- プレゼンテーションの実施: アジャイルカンファレンスやコミュニティイベントでの発表や講演。
- 書籍や論文を執筆: Scrumやアジャイルに関する書籍、ホワイトペーパー、技術論文を執筆し公開。

### カテゴリ E: Scrum実務への参加
内容: Scrumの実務に関与することでSEUを取得できます。これは主に、仕事の中でScrumマスター、プロダクトオーナー、あるいはScrumチームのメンバーとして活動することを指します。
SEUの獲得量: 2年間の実務経験につき最大で15 SEUを取得可能（1年間で最大7.5 SEU）。

- Scrumチームでの活動: プロジェクトにおけるScrumイベントのファシリテーションや日々のScrum活動。
- アジャイル導入のリード: チームや組織にScrumやアジャイルを導入し、その実行を支援する活動。

### カテゴリ F: コーチングやメンタリング
内容: 他のScrumマスターやチームに対してコーチングやメンタリングを行うことでSEUを取得できます。
SEUの獲得量: 以下1時間のコーチング・メンタリングにつき1 SEU。

- Scrumチームに対するコーチング: 経験が浅いScrumチームに対して、プロセス改善や自己組織化の支援を行う。
- アジャイルコーチとしての活動: 企業や組織にアジャイルの導入や改善を支援する活動。

# おまけ：各資格に必要なSEUの必要量
各資格の更新に必要なSEUの数は以下の通りです。

- Certified ScrumMaster (CSM): 20 SEU（2年間で）
- Advanced Certified ScrumMaster (A-CSM): 30 SEU（2年間で）
- Certified Scrum Professional - ScrumMaster (CSP-SM): 40 SEU（2年間で）

# さいごに
CSMはあくまで一つのきっかけでしかないので、取得してからどれだけ行動したかが重要になります。
この行動に対してポイントがつくのは実際の活動が目に見えて個人的には嬉しいですが、更新時に慌てることがないようにきちんと管理していきたいところです。
paizaラーニング問題集「最長部分増加列」を解いてみた

https://paiza.jp/works/mondai/dp_primer/dp_primer_lis_step0

▼感想

自分で色々考えて実装したものの、
なかなかスコアが100にならなかったため、
ヒントを見て理解し実装しました。
本記事の下部に理解した内容をメモとしてまとめました。

▼コード
```py
########## 処理0(準備) インプット,リスト定義など ###########

n = int(input())

a = [0]*n

########## 処理1 漸化式の定義、計算、出力 ##########

dp = [0]*n

dp[0] = 1

for i in range(n):
    a[i] = int(input())

for i in range(1,n):
    dp[i] = 1
    for j in range(i):
        if a[j] < a[i]:
            dp[i] = max(dp[i],dp[j]+1)

print(max(dp))
```

▼変数に関するメモ

・a=[3,1,4,1,5,9,2,6] 
木が8本横並びで存在し、aはそれぞれの木の高さ(cm)を表すリスト。
a[0]は左端から1番目に存在する木の高さ。
　
・dp=[0,0,0,0,0,0,0,0]
木の高さが左端から単調増加しているか？を考える。
その木が単調増加の末尾にあると仮定したとき、(その木を含め)単調増加に含めることができる木の本数の最大値を格納するリスト。

初期値はすべて0だが、処理後は以下のようになる。
dp=[1,1,2,1,3,4,2,4]

・i=1～7
(外側のloopのi)dpを先頭から末尾まで走査する変数。
(内側のloopのi)単調増加の末尾に存在する木の番目を示す変数。

・j=0～i
(内側のloop)単調増加の末尾に存在する木と比較する木の番目を示す変数。

▼i=4のときの処理に関するメモ

i=4(to8)

dp[4]=1

　j=0(to4)
　　a[0] ? a[4] (3<5につきTrue)
　　dp[4]=max(dp[4],dp[0]+1)=max(1,2)=2

　j=1(to4)
　　a[1] ? a[4] (1<5につきTrue)
　　dp[4]=max(dp[4],dp[1]+1)=max(2,2)=2

　j=2(to4)
　　a[2] ? a[4] (4<5につきTrue)
　　dp[4]=max(dp[4],dp[2]+1)=max(2,3)=3

　j=3(to4)
　　a[3] ? a[4] (1<5につきTrue)
　　dp[4]=max(dp[4],dp[3]+1)=max(3,2)=3

　j=4(to4) Inner loop finished.

▼ dp[i]=max(dp[i],dp[j]+1) の処理に関するメモ

max関数の2項目 dp[j]+1
j番目の木がi番目の木より小さいならば、
j番目の木までの単調増加に1つ木を加えることができる。
dp[i]の初期値は1なので、
max関数を用いることで2項目(dp[j]+1)の値でdp[i]を更新できる。
歯科用 3D スキャナーの価格はいくらですか?

技術の発展に伴い、歯科の分野も発展していきます。歯科用 3D スキャナは、多くの歯科医院で標準装備となりつつある重要なツールです。生産性が向上するだけでなく、治療の精度と患者エクスペリエンスも向上します。この記事では、歯科用 3D スキャナの価格帯と、歯科におけるその用途について説明します。

歯科用3Dスキャナーの価格
歯科用 3D スキャナーの価格は、多くの場合、デバイスのブランド、技術仕様、機能によって異なります。一般的に、歯科用3Dスキャナのエントリーモデルの価格は15万～75万円程度です。これらの装置は通常、小規模な歯科医院や個人の歯科医に適しています。

![756366329beb068628631046ea324ec0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/d03af425-071a-2bcc-d2c1-938167439312.png)
中高級の歯科用3Dスキャナの価格は75万～300万円程度で、より高精度で複雑な機能が求められる診療所に適しています。たとえば、一部の高度なデバイスには、歯や口腔構造のより詳細な画像を提供するために、リアルタイム イメージング、高速スキャン、および高解像度が装備されています。

また、大病院や研究機関向けの300万円以上の業務用3Dスキャナーもあります。これらのデバイスは通常、より高度なテクノロジーを備えており、より複雑な症例を処理でき、他の医療機器とシームレスに接続できます。

歯科における 3D スキャナー

1. 歯と口腔の模型の作成: スキャナーは患者の歯と口腔の構造データを迅速に取得できるため、歯科医は正確な歯の模型を作成し、修復物の適合性を向上させることができます。

![33542d5358b546157aad6b8353209f0e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/6538df14-6f92-50ca-51f5-3849e75a6b2d.png)
MINI2 3D スキャナーからのモデル
https://www.revopoint3d.jp/products/industry-3d-scanner-mini

2. デジタル歯科記録: 歯科医は 3D スキャナーを使用して、患者の歯科データを簡単にデジタル化し、その後の追跡と比較を行うことができます。

3. 治療計画と評価: 高精度の 3 次元画像により、歯科医は個別の治療計画をより適切に策定し、手術の成功率と患者満足度を向上させることができます。

4. 教育とトレーニング: スキャナーは、学生が複雑な解剖学を学び、理解するのに役立つ歯科教育でも広く使用されています。

歯科用 3D スキャナには幅広い価格帯があり、さまざまな規模やニーズの歯科診療に適したさまざまなデバイスが用意されています。テクノロジーの進歩に伴い、これらの効率的で正確なツールは、歯科医が患者の治療体験を向上させるのに役立っています。市場が発展し続けるにつれて、歯科用 3D スキャナの応用の可能性も広がり、歯科業界に新たな機会がもたらされるでしょう。
線形判別関数で使用する線形代数の知識

2変数線形判別分析では, 群間変動$w^{T}S_Bw$を大きく, 群内変動$w^{T}S_Ww$を小さくしたい. つまり以下の$\lambda$の最大化を目指す.

```math
\lambda = \frac{w^{T}S_{B}w}{w^{T}S_ww}
```
ここで, $S_B$は半正定値行列, $S_W$は正定値行列より, $\lambda \ge 0$.

$w^{T}S_ww=1$のもと, ラグランジュの未定乗数法を用いると, 
```math
S_W^{-1}S_Bw = \lambda w
```
となり, $S_W^{-1}S_B$の最大固有値を求めればよいことがわかる.
ここで, $S_B$のランクは1より, $S_W^{-1}S_B$のランクも1となる.
行列のランク$\ge$非ゼロ固有値の数　より, $S_W^{-1}S_B$は最大で1つの非ゼロ固有値$(>0)$を持つ. よって, $S_W^{-1}S_B$における非ゼロ固有値に対応する固有ベクトル$\hat{w}$を求めればよい.

行列のランク$\ge$非ゼロ固有値の数　は, 任意の正方行列Aが正則行列Pを用いて三角化できることから確認できる（$\Sigma$：上三角行列）.

```math
P^{-1}AP = \Sigma
```

$rank(左辺) = rank(P^{-1}AP)=rank(A) =rank(\Sigma) =  rank(右辺)$ .
Firefoxアドオン版BitwardenでPassKeyを使う


パスキー(PassKey)のおかげで、より安心してログインができるようになるわけですが、使い方が煩雑だと、億劫になってしまいます。より簡単に扱えるようにしたいものですね。
LinuxのFireFox系ブラウザでアドオンとしてパスワードマネージャーのBitwardenを用いています。それを少し便利にするTipsです。
EdgeやChromeのアドオンのBitwardenでは、標準設定でパスキー(PassKey)も扱ってくれます。Firefoxの場合でも、少しだけ設定を変更して権限を与えることで、同じ操作感になりました。
次の設定をしていない場合、パスキーでのログインの場合、ポップアップでセキュリティキーのある端末の操作などを求められます。次の変更をしておくと、Bitwardenがパスキーも扱ってくれるので、そのままブラウザ内で操作が完結できます。

- 設定項目は、アドオンの標準設定に加えて、権限の設定で`Firefox とは別のプログラムとのメッセージ交換`を有効にするだけです。

これで、ポップアップでブラウザ以外の操作を求められることなく、代わりにBitwardenの画面でパスキーを選択してログインできるようになります。パスワードもパスキーもBitwardenにお任せする感じです。

またLinux以外のOSでのブラウザの動作は、また異なるかもしれませんが、パスキーをブラウザで完結出来ていない場合、類似の設定がないか確認してみてください。

ちなみにパスワード管理はBitwarden、2段階認証はAuthyを用いていますが、別環境で同じ環境を構築するのが、比較的簡単なので気に入っている組み合わせです。