OmniAICreator/Qiita-1.07M huggingface dataset:
生成AIエージェントsattoとNode-REDを組み合わせた話

# はじめに

こちらの投稿内容に関する備忘録メモです。

https://x.com/Zakkiea/status/1847525486181961780

# 生成AIエージェントsattoとは

ソフトバンク株式会社が開発した生成AIエージェントサービスで、2024年8月23日にベータ版の提供が開始されました。ウェイトリストへ登録し、先行ユーザーになる必要があります。

https://x.com/Zakkiea/status/1834456543808323785

# 課題

sattoはショートカットキーで呼び出して生成AIエージェントのスキルを実行します。
使い方の一例です。

- 文字列を選択してショートカットキーで呼び出す
- ショートカットキーで呼び出してスクリーンキャプチャー(画面の画像を取得)する
- ショートカットキーで呼び出して、文字列、または、画像を入力する

サッと呼び出してすぐに実行できるのがメリットですが、入力データと実行結果がログとして残らないため、あとで見直したり、一部を変更して再度実行するのが面倒(入力データと実行結果を手動でメモ帳へ貼り付けて残しておく必要がある)という課題があります。

いわゆるロガーの機能をスキルに組み込むという話です。

# Node-REDとの連携

sattoとNode-REDを組み合わせて、Googleスプレッドシートに入力データと実行結果を記録する方法を説明します。

## satto側の対応

スキル作成機能でアプリノード(REST API)を使用します。
(当初は限定されたユーザーのみがiPaaSビルダーの機能を利用できましたが、その後のバージョンアップで機能制限が解除されました。)

スキル作成画面を開き、「＋」をクリックします。

![スクリーンショット 2024-12-16 16.44.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/2f506779-8e6d-5634-f5b2-9252b2e357be.png)

「アプリノード」を選択します。

![スクリーンショット 2024-12-16 16.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/01892a5f-41cf-3178-33c2-6773194793eb.png)

![スクリーンショット 2024-12-16 16.46.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/4a02810e-00a7-9f49-957f-5381817dfe2f.png)

「アプリ選択」で「カスタム」を選択します。

![スクリーンショット 2024-12-16 16.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/c41ec0dc-eb30-b799-f98d-919d949d419a.png)

「メソッド」→POST
「リクエストURL」→Node-REDのURL
「Header」→任意(トークンで認証させるなど)
「Body」→コンテキスト、出力結果

## Node-RED側の対応

Node-REDフローの全体像です。

![スクリーンショット 2024-12-16 18.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b795aca6-724f-719d-b4c8-590e5dfa8a27.png)

「injectノード」と「debugノード」はデバッグの目的で、ロガーの機能としては不要です。
事前に「パレットの管理」→「ノードを追加」で以下のサードパーティノードを追加します。
- node-red-contrib-google-sheets

使用するノードは以下です。

- 「http inノード」
- 「http responseノード」
- 「changeノード」
- 「GSheetノード」

![スクリーンショット 2024-12-16 18.41.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8dba4e6b-c548-f0a0-14db-6fcf0dd42dd5.png)

![スクリーンショット 2024-12-16 18.41.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a6745710-fb5a-b6c8-1a59-2c2f7f6802ea.png)

![1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a8d02baf-424c-2ea0-0eb5-903313c053dd.png)

# 実行結果

![GaO6DzGbUAICA7o.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/50877f0d-3aa3-16bf-cfe9-5cb345a16749.png)

![GaO6FXfbUAEGvUB.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f46725fa-bf9b-714a-76e8-511b80c123c5.jpeg)

# さいごに

GoogleスプレッドシートをAPIとして利用できる<A HREF="https://steinhq.com/">Stein</A>というサービスがありますが、無料アカウントだとAPIの利用回数に制限がありますので、Node-REDを使用すれば無料で制限なく利用できます。

API経由でロガーの機能は汎用的に使えるので、別のツールと連携させても良いと思います。
pythonライブラリから見る機能と処理

生成AI、MMLなどでよく使うpython ライブラリを一覧し、
どういう機能があり、そういう処理をしているのか調べる出発点としたい。

# transformers
transformers(ライブラリ)
https://qiita.com/niship2/items/f84751aed893da869cec

[python / transformers] Rust が原因で pip install transformers できない問題の対策
https://qiita.com/siruku6/items/a133f79ff4c80e73cea3

transformersのモデルのダウンロードについて
https://qiita.com/SoseSose/items/00185f49f245c4d8df16

Huggingface Transformerがエラーを吐かない実行環境は、Python3.6.3 & TensorFlow2.2だと確認した件
https://qiita.com/Afo_guard_enthusiast/items/9fcde2e06588c01a40db

Huggingface Transformer version.3.5.1で、東北大学が作った日本語用の学習済みモデル 'cl-tohoku/bert-base-japanese-char-whole-word-masking'を使って成功した件
https://qiita.com/Afo_guard_enthusiast/items/88ce7d9610073ac1eca2

transformersのTrainerでもにょった
https://qiita.com/payanotty/items/a012a5607279ff7f4056

富岳のspack0.19版python3.10にはtransformersが乗らないのか
https://qiita.com/KoichiYasuoka/items/521087a76186b4432145

transformers,gpt2-large-japaneseをローカル環境で利用する
https://qiita.com/dot-info/items/6d6745d66b7460a16fd5

# bitsandbytes
Windows10でのPEFTの実行方法 (bitsandbytes-windows-webui使用)
https://qiita.com/selllous/items/c4880767da45173227c1

PEFTを使用したLoRA (Windows10（WSL2不使用） bitsandbytes==0.37.0使用)
https://qiita.com/selllous/items/fbaa2c3d2d504e436b17

無料版GoogleColabで13BのLLMを動かす方法（OOMにならない！/Fugaku-LLM-13Bも動いたぞォ！）
https://qiita.com/HawkClaws/items/f13c6a4168a6529b06ae

peft環境作成（cudaサポートbitsandbytes 0.41.1）
https://qiita.com/kik0220@github/items/9d67b9458ac42b362431

8-bit最適化アルゴリズム公開した
https://qiita.com/terry_chan/items/28d900f1a62639227e2a

GCPのGPU搭載インスタンスで [Errno 13] Permission denied: '/root/google_vm_config.lock'
https://qiita.com/munaita_/items/88b1a3ffba9efbfd6612

layerdiffusion
https://qiita.com/ma7ma7pipipi/items/8d00a7fa8addb1b9a8d0

# accelerate
Google ColabでLoRAを実行する
https://qiita.com/nR9h3kLy/items/a2d2be4c48f253a8e331

huggingfaceのaccelerateを使って訓練時のCUDA out of memoryを回避する
https://qiita.com/m__k/items/518ac10399c6c8753763

限られたリソースの中でLLMを使う
https://qiita.com/Miki7/items/26aab2cb1323ccf9a753

M1 Macでwaifu-diffusion
https://qiita.com/DR623G/items/99c3c784e594c7b21913

[翻訳] Hugging Face transformersの推論パイプライン
https://qiita.com/taka_yayoi/items/fe841afc78c27b153b44

01-ai/Yi-6B-ChatをGoogle Colabで動かしてみた
https://qiita.com/Maki-HamarukiLab/items/df4c70d5300681b9af49

ヅカの芸名を自動生成するAIを作る(6)：GPT-2編(2)
https://qiita.com/muto-jo/items/460ffb50924fd24010d6


# datasets
# peft
# trl
#　wandb
# ipywidgets
学習日記アプリ作成（API設計）

## １．機能要件
+ ユーザー管理
  + ユーザー登録
    + POST /api/user : 新しいユーザーを作成 
  + ログイン/ログアウト (セッション管理)
    + PUT /api/user/{id}:特定のユーザーのセッション情報を更新 
  + ユーザープロフィールの編集
  　+ PUT /api/user/{id}:特定のユーザー情報を更新

* 学習日記管理
  * 学習内容の登録 (タイトル、日付、内容)
    + POST /api/records : 新しい学習記録を作成
  * 登録した日記の閲覧 (一覧、詳細)
    * GET /api/records : 全ての学習記録を取得
    * GET /api/record : 特定の学習記録を取得

+ 日記の編集・削除
  + 編集
    + PUT /api/records/{id} : 特定の学習記録を更新 
  + 削除
    + DELETE /api/records/{id} : 特定の学習記録を削除

* 学習履歴機能
  + 過去の日記の検索・フィルタリング (日付やキーワードで検索)
    + GET /api/records? :指定した条件で学習記録を取得
個人の目標管理で使えそうなWOOPの法則とやる気スイッチの押し方


## まとめ

- 自分の思考タイプを認識し、やる気スイッチの押し方を知る
- WOOPの法則を使ってやる気を維持する


この記事は以下の内容を聞いて自分なりにまとめたものです。

https://schoo.jp/class/8515

## WOOPの法則とは

WOOP法則は、Wish（願い）、Outcome（結果）、Obstacle（障害）、Plan（計画）の頭文字をとった手法で、目標達成や問題解決を図るための心理学的手法です。

目標設定で利用するときは短期的な目標をWishに定義し、ほかを埋めます。
自分で考えるのが面倒なのでChatGPTにどのようにそれぞれを定義すればよいか聞いてみました。

```
1. あなたが達成したいと思う具体的な目標（Wish）は何ですか？
2. その目標が達成されたときに得られる最善の結果（Outcome）は何ですか？
3. その目標を達成するための障害（Obstacle）は何ですか？また、それらの障害が発生する可能性は何によると思いますか？
4. その障害を乗り越えるための具体的な計画（Plan）は何ですか？
```

わかりやすいですね！
このテンプレートを使って色々書いて1ヶ月後あたりに見返して再設定するという流れを繰り返せばよいのですが、なかなか目標達成できない、やる気が起きない……というパターンもあるでしょう。

そういうときは「やる気スイッチ」の出番です。

## やる気スイッチは人によって違う

某バスケット漫画でも、褒めて伸びるタイプの選手と叱って伸びるタイプの選手がいることが明記されていたとおり、人によってやる気の出るシチュエーションや環境は異なります。

### 2つの軸「心理」「思考」

やる気スイッチを見つけるための指標として、「心理」と「思考」という2つの軸があります。それぞれに2つのタイプがあるため、大きく分けて4つのタイプに分類できます。

軸を知るには自分のWish（願望）に対する思考を知ることが重要らしいです。
先ほど立てた目標（Wish）を材料に、なぜそれを達成したいのかを考えてみましょう。

### 心理の2タイプ「証明型」「習得型」
#### 証明型
他者からの評価や結果を重視します。「この成果を出すことで自分の価値を証明したい」という動機が強いタイプです。

####  習得型
自分自身の成長や学びを重視します。「この経験を通じてスキルを磨きたい」という動機が強いタイプです。

### 思考の2タイプ「獲得型」「防御型」
#### 獲得型
自分が得たい成果や利益を追求するタイプです。例えば、アスリートが大会で優勝することを目指す場合が該当します。ポジティブなフィードバックが有効です。

####  防御型
自分が守りたい価値や理念を動機とするタイプです。例えば、優勝してスポーツの良さを世間に広めたいと考える場合が該当します。ネガティブなフィードバックが有効です。

ちなみにこれら軸についての心理学の内容は以下の書籍で詳しく取り上げられています。

https://www.amazon.co.jp/dp/4479794123

## やる気を継続させるには社会との接点を持つ

やる気を保つ対策として、社会的に孤立していない状態を作ることが有効です。
InstagramやX（ツイキャス）で自分が勉強している姿を配信する人が一定数いますが、あれは他人からの監視とつながりという点で有効ということになります。カフェで作業している人も、もしかしたら同様の理由かもしれません。

あと、やる気を起こすには行動しかないというのも最近よく言われます。
最初の4分だけ我慢して行動すればOKという法則です。

https://note.com/online_hirok/n/n404232958019

まとめると、毎日もくもく配信を5分だけすることを継続すれば、一定のやる気は確保できるということです！

## 自分の思考タイプを知る

以下は、心理と思考タイプを判別するための質問例です。これを参考に、自分の特性を把握してみてください。(ChatGPTに考えてもらいました）

### 心理タイプを判別する質問

1. 他人から認められることが、自分のモチベーションにどの程度影響しますか？
2. 新しいことを学ぶ過程で得られる満足感を重視しますか？
3. 成果を出すことで自分の能力を証明したいと感じますか？
4. 結果よりも、挑戦そのものを楽しみたいと考えますか？

### 思考タイプを判別する質問

1. 目標を達成することで、どのような利益を得たいと考えますか？
2. 自分の行動が他人や社会に与える影響を意識することが多いですか？
3. リスクを取ってでも新しい挑戦に取り組むことに魅力を感じますか？
4. 現状を守るために、自分ができることを優先して考えますか？

これらの質問に答えることで、自分がどのタイプに当てはまるかを分析し、適切な目標設定ややる気スイッチの活用につなげることができます。

自分に合ったやる気スイッチを理解し、WOOPの法則と組み合わせることで、目標達成に向けた具体的なアクションが取れるようになります。ぜひ日々の生活に取り入れてみてください！
rootで"/"によるルーティングを指定

3.15 rootを使う
>rootメソッドを使うことで、`'/'によるルーティング先を指定`できます。
```rb
root to: "pages#main"
root "pages#main" # 上の省略形
```
```
 Prefix Verb   URI Pattern                                                                                       Controller#Action
                                    root GET    /                                                                                                 pages#main
````
>rootルーティングは、ルーティングファイルの冒頭に記述するのが一般的です（最初にマッチする必要があるため）。

>rootルーティングがデフォルトで処理するのはGETリクエストですが、それ以外のHTTP verbを指定することも一応可能です（例: root "posts#index", via: :post）。

>rootルーティングは、以下のように名前空間やスコープの内側でも指定できます。
```rb
root to: "home#index"

namespace :admin do
  root to: "admin#index"
end
```
>上は、/adminがAdminControllerのindexアクションにマッチし、/はHomeControllerのindexアクションにマッチします。

https://railsguides.jp/routing.html#rack%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B:~:text=3.15%20root%E3%82%92,%E3%83%9E%E3%83%83%E3%83%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

```
Prefix Verb   URI Pattern                                                                                       Controller#Action
                              admin_root GET    /admin(.:format)                                                                                  admin/admin#index
```
Biopythonを用いたgbkフィルの解析

# Biopython
近年、データサイエンスの世界で扱われているプログラミング言語Pythonですが、Bioinfomaticsにおいても、解析を容易にできるライブラリとしてBiopythonと呼ばれるものがあります。本記事では、インストールからgbkファイルを用いた具体的な解析方法を紹介します。

# Biopythonインストール
pythonのパッケージ管理システムである**pip**を用いてインストールできる。

```
pip install Biopython
```
または
```
python -m pip install BioPython
```

# SeqIOクラス
```
from Bio import SeqIO
```
SeqIOは、BioPythonライブラリに含まれるモジュールで、様々な形式（フォーマット）のファイルを取り扱うことができる。読み込みと書き込みの両方をサポートしているため、SeqIOを利用することで、ファイルのフォーマットの変換も簡単に行えるようになる。

詳細は[BioPython wiki](https://biopython.org/wiki/SeqIO)

## 配列操作
塩基配列、アミノ酸配列についての文字列操作を行うには、`from Bio.Seq import Seq`を使う。これによりSeq()の関数を使うことができ、塩基配列またはアミノ酸配列を定義することができる。
以下に `Bio.Seq.Seq` の基本的な使い方と具体例を示します。
|メソッド名|機能|
|--------------------------------------|---------------------------|
|`reverse_complement()`|配列の逆相補鎖を取得（DNA の A ↔ T, G ↔ C を変換して逆順にする）|
|`complement()`|配列の相補鎖を取得（逆順にはしない）|
|`transcribe()`|DNA 配列を RNA 配列に転写（T を U に変換）|
|`back_transcribe()`| RNA 配列を DNA 配列に逆転写（U を T に変換）|
|`translate()`|DNA または RNA 配列をタンパク質配列に翻訳（コドン → アミノ酸）<br>-主な引数　<br>`to_stop` 翻訳をストップコドンで終了するかどうか（デフォルトは False）<br> `table`コドン表を指定（デフォルトは標準遺伝暗号）|
```
>>> from Bio.Seq import Seq
>>> dna_seq = Seq("ATGCGTACGTTAGC")
>>> print(dna_seq)
ATGCGTACGTTAGC
# 相補鎖
>>> print(dna_seq.complement())
TACGCATGCAATCG
# 逆相補鎖
>>> print(dna_seq.reverse_complement())
GCTAACGTACGCAT
# 転写
>>> print(dna_seq.transcribe())
AUGCGUACGUUAGC
# 翻訳
>>> print(dna_seq.translate(to_stop=True))
MRTL
```

## データの読み込み(gbk)

```
records = SeqIO.parse("hoge.gbk", "genbank")
```
返り値はイテレーターオブジェクトになる

基本的なメソッド
- seq(DNA配列の取得)
- feature(配列の詳細な情報)

## featrueメソッド
先程のfeatureに関して内包されているメソッド一覧
- location(配列のスタート位置と終了位置)
    - start
    - end
    - strand(鎖の情報)
        - -1 対の鎖
        - 1  記載されている鎖
- type：geneかRNAかなど
- qualifiers：詳細な情報

#### 具体的なコード
gbkファイルを読み込んで、出現するtRNAとその長さを出力するプログラム

```
from Bio import SeqIO


# GenBankファイルのパスを指定 
file_path = "NC_012346.gbk"
# GenBankファイルを読み込む
records = SeqIO.parse(file_path, "genbank")

trna_list = []

for record in records:
    for feature in record.features:
        if (feature.type == "tRNA"):
            start = int(feature.location.start)
            end = int(feature.location.end)
            product_type = feature.qualifiers["product"][0]
            trna_list.append((product_type,end-start))

print(trna_list)
```
出力
```
[('tRNA-Phe', 67), ('tRNA-Val', 67), ('tRNA-Leu', 75), ('tRNA-Ile', 69), ('tRNA-Gln', 72), ('tRNA-Met', 69), ('tRNA-Trp', 67), ('tRNA-Ala', 69), ('tRNA-Asn', 74), ('tRNA-Cys', 67), ('tRNA-Tyr', 68), ('tRNA-Ser', 73), ('tRNA-Asp', 69), ('tRNA-Lys', 67), ('tRNA-Gly', 69), ('tRNA-Arg', 69), ('tRNA-His', 70), ('tRNA-Ser', 60), ('tRNA-Leu', 70), ('tRNA-Glu', 69), ('tRNA-Thr', 69), ('tRNA-Pro', 66)]
```
# 参考
・https://qiita.com/Ag_smith/items/94c4b97729b043fae0cb
アプリのマーケティング結果と分析　#1

## このシリーズの方針
多くの個人開発者さんがX,Insta,Youtubeのアカウントのフォロワーさんが少ないもしくはそもそもアカウントを持っていない人ではないのでしょうか？(自分はそうでした)

そこで、今回0から始めるマーケティングと題してこれまで私がしてきたことやこれからどうしていくのかを逐一ここで記録できたらなと思います。

自分もフォロワーがいないからどうしていけばわからないという個人開発者さんはぜひ読んでみてください。

## そもそも
そもそもどのようなアプリを私が出したかを説明しないとつまらないと思うので軽く説明させてもらいます。

まず名前は{.Avenue}といいます。
このアプリは一言で言えばチャットアプリです、他のチャットアプリとの違いと大きな違いとしてあるのは友達の友達と話せる所です。

ここからは実際にやってみて欲しいのですが、簡単にいうと友達全員が同じチャット画面で会話をするようになっています、これによって友達だけではなくその友達とも喋れることができます。

## 現状
ここまでざっくりアプリの紹介をしましたが、ここで現在のダウンロード数また他SNSの再生回数、フォロワー数などの紹介をしていきます。

まず、ダウンロード数において10/26-12/14までで98回となっています。
これはどうなんでしょうか、ぜひ自分のアプリと比較してみてください。

続いて、他SNSのフォロワーにおいてはX,Insta,Youtubeを開始していますがフォロワーは全部自分の他のアカウントですね。
しかし、一個一個の投稿の反応で見てみるとInstaは高いやつでは129回の視聴回数ですね。これはまあまあ良いのではないでしょうか？
さらに、Youtubeの動画では47回ですね。これはInstaに比べると少ないですがひとまず頑張ってるとしましょう。
Xにおいてはあまり活動できていないと言うのも文字で伝えることがあまりなく投稿頻度で言うと他二つに比べかなり劣りますね。

そして、実はYoutubeアカウントが二個ありもう一つの方ではずんだもんさんに喋ってもらい、このブログを映像化しています、つまりこれは動画の台本？も兼ねていけたらいいなと思います。

## これからの取り組み
ひとまずは今までやっていたのは、毎日一本Insta,Youtubeに動画投稿、そしてアップデートの回数を週3~4してそれをXにアップデート内容としての記述、最後に週末ずんだもんさんの動画投稿をしています。
ひとまずはこの形で年末までやっていこうと思います。

さらに、それらに加えてQiitaでブログの投稿も週一を目指していこうと思います。

応援よろしくお願いします。

## リンク先
以下に先述したアカウントのリンクを貼っておきますので、気になるのがあれば飛んでみてください。

https://apps.apple.com/jp/app/avenue/id6732322396

https://x.com/camble0128

https://youtube.com/@avenueapp?si=rFmaoMnoTY4z7_Ic

https://youtube.com/channel/UCZ7GAitJpMQD31PhrzBrqkw?si=TLVMC2BC6O6DCuQb

Instaのリンクを貼ったら表示がおかしかったので、一旦やめときます。
Qiitaのブログ何か助言があればコメントお願いします。
では、また来週お会いしましょう！
証明書の拡張子はcrtにしましょう、という話

# サマリ

- 会社の独自プロキシ証明書がcer拡張子で配布されていた
- debian系のdocker imageをbuildするのにupdate-ca-certificatesコマンドがうまく動かなかった
- `mv sample.cer sample.crt` したら動いた

# 環境

node:16を使っていた。debianのbusterがベース。

```
$ docker run --rm -it node:16 sh
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```

# 背景

[さまざまな情報源](https://www.baeldung.com/linux/ca-certificate-management#1-debian-distributions)に、debianに独自証明書を追加する場合は、以下のどちらかのパスに証明書をおいて `update-ca-certificates` コマンドを叩きましょうと書いてある。

- `/usr/share/ca-certificates`
- `/usr/local/share/ca-certificates`

Dockerfile上で以下のようにどちらにも置いてみたが、curlが失敗した。

```
COPY sample.cer /usr/local/share/ca-certificates/
COPY sample.cer /usr/share/ca-certificates/
RUN update-ca-certificates
```

# 暫定対応1

今回はcurlで外部通信を行いたかったので、以下のように `.curlrc` に記載することでうまく動いた。

```
COPY sample.cer /usr/local/share/ca-certificates/
RUN echo "cacert=/usr/local/share/ca-certificates/sample.cer" > ~/.curlrc
```

# 暫定対応2

`update-ca-certificates` の実行結果としてファイルが移動されるらしいので、移動先に直接置いてみたうえで `fresh` オプションを付けることでも、動いた。

```
COPY sample.cer /etc/ssl/certs/
RUN update-ca-certificates --fresh
```

# 恒久対応

`node:16` コンテナではmanコマンドが使えなかったため、直接 `update-ca-certificates` コマンドの中身を確認することにした。

```
$ docker run --rm -it node:16 sh
# command -v update-ca-certificates
/usr/sbin/update-ca-certificates
# cat /usr/sbin/update-ca-certificates
```

以下はコマンドの中身の抜粋だが、 `"*.crt"` を探しており、用意していた証明書 `"*.cer"` は対象外となっていることがわかる。

```
CERTSDIR=/usr/share/ca-certificates
LOCALCERTSDIR=/usr/local/share/ca-certificates

find -L "$CERTSDIR" -type f -name '*.crt' | sort | while read crt
find -L "$LOCALCERTSDIR" -type f -name '*.crt' | sort | while read crt
```

cerもcrtも中身は一緒らしいので、以下のように記載することでうまくいった。

```
COPY sample.cer /usr/local/share/ca-certificates/
RUN mv /usr/local/share/ca-certificates/sample.cer /usr/local/share/ca-certificates/sample.crt
RUN update-ca-certificates
```

# 感想

証明書の種別については以下を参考にさせていただいた。
https://qiita.com/kunichiko/items/12cbccaadcbf41c72735

`"*.cer"` はMicrosoftが定めた形式とのこと。より広く使われているcrtを使うべきだということがよくわかった。
なぜSvelteKitのルーティングファイルには+がついているのか？

# はじめに
Next.jsやNuxtなど多くフレームワークがファイルベースルーティングを採用しています。SvelteKitもファイルベースルーティングを採用していますが、独自のアプローチとして、`+page.svelte`や`+layout.svelte`のように、ルーティング関連のファイルには必ず+のプレフィックスを付けるというルールを持っています。この命名規則は、初めてSvelteKitを利用する人にとっては少し違和感を持たれるかもしれません。この記事では、なぜSvelteKitがこの形式を採用しているのかについて説明していきます。

# `+`プレフィックスを採用する前のファイルベースルーティングの弱点

## ルーティングの設定に複数の方法が存在していた
`+`プレフィックスを採用する前は`src/routes/foo.svelte`または`src/routes/foo/index.svelte`とルーティングファイルを定義する方法が2つありました。
Svelteの設計思想の「1つのことを実現できる方法は1つであるべきである」という考えに反していましたので1つの方法になりました。
これはとてもいい変更で２つの方法があることで混在してしまう可能性がありますし、特にチーム開発では混乱が生じます。

## 回避策を講じないと関連するファイルを同じ場所に配置することができなかった
`foo.svelte`に関連するファイルを同じ場所に配置したい場合があると思いますが、その場合に少し面倒でした。
`_item.svelte`や`_components/item.svelte`など回避策を講じた命名にしないといけません。
`+`プレフィックスを採用したことで`src/routes/foo/+page.svelte`、`src/routes/foo/components/item.svelte`または`src/routes/foo/item.svelte`のように関連するファイルを同じ場所に配置することができます。

## エディタ上でルートファイルを探しづらかった
エディタではアルファベット順にグループ化されています。
`src/routes/foo.svelte`や`src/routes/foo/index.svelte`がルーティングの場合はどれがルーティングファイルなのかぱっと見ではわかりづらいです。しかし、`+`プレフィックスを採用したことで子ディレクトリ、ルーティングファイル、通常のファイルの順序で見られるようになりました。

```
src/
└─── routes/
    ├── about/
    │   ├── +page.svelte
    │   └── item.svelte
    ├── contact/
    │   └── +page.svelte
    ├── +layout.svelte
    └── +page.svelte
```

また、コマンドパレットに`+page`を入力するだけですべてのルートのリストを表示でき、`blog+`などを入力すると該当ルーティングのファイルをすぐに探すことができます。

![181781428-8a5c4fde-aecc-488c-91b0-465fbba935f0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217487/f5d09055-a57b-64fe-f902-7ba961fefd2e.gif)

## 将来の拡張性が悪かった
SvelteKitが今後成長していく中で新しい機能を追加することがあると思いますが、互換性を保ったまま追加するのが難しかったです。しかし、`+`プレフィックスを採用したことで予約済みのプレフィックスができましたので例えば`+loading.svelte`のような機能が追加された場合も破壊的変更を少なく導入することができます。

# おわりに
SvelteKitの`+`プレフィックスは、最初は違和感を持たれるかもしれません。しかし、このルールはファイルの管理をスムーズにしてくれて、エディタでファイルを見つけやすくしてくれます。さらに、新しい機能の追加もやりやすくなるので将来の破壊的変更を最小限に抑えることができます。

他のフレームワークでは採用していないものなので違和感を持った方々の疑問に少しでもこの記事が答えられていると嬉しいです。

僕も最初はとても違和感がありましたが、今はすごく合理的でいいルーティングシステムだと感じています。

# 参考

https://github.com/sveltejs/kit/discussions/5748
Simulink_DFF

```
function [Q, Q_bar] = DFF(D, CLK, ICLR)
% D Flip-Flop 動作のSimulink用関数
% 入力: D - データ, CLK - クロック, ICLR - 非同期クリア
% 出力: Q - 主出力, Q_bar - 反転出力

% 初期化状態
persistent Q_reg prev_CLK

% 初回実行時の初期化
if isempty(Q_reg)
    Q_reg = 0;      % 初回実行時にレジスタを0で初期化
    prev_CLK = 0;   % 初回実行時のクロック値
end

% 離散動作: ICLR が 1 の場合はリセット
if ICLR
    Q_reg = 0;
else
    % クロックの立ち上がりエッジで D を Q に反映
    if CLK && ~prev_CLK  % クロックが立ち上がるタイミング
        Q_reg = D;
    end
end

% クロック値を更新
prev_CLK = CLK;

% 出力
Q = Q_reg;        % 主出力
Q_bar = ~Q_reg;   % 反転出力
end
```

```
function [Q, Q_bar] = DFF(D, CLK, ICLR)
% D Flip-Flop 動作のSimulink用関数
% 入力: D - データ, CLK - クロック, ICLR - 非同期クリア
% 出力: Q - 主出力, Q_bar - 反転出力

% 初期化状態
Q = 0;

% 離散動作: ICLR が 1 の場合はリセット
if ICLR
    Q = 0;
else
    % クロックの立ち上がりエッジで D を Q に反映
    if CLK
        Q = D;
    end
end

% 反転出力
Q_bar = ~Q;
end



```
```
function [Q, Q_bar] = DFF(D, CLK, ICLR)
% D Flip-Flopの動作をシミュレートする関数
% 入力:
%   D    - データ入力
%   CLK  - クロック入力
%   ICLR - 非同期クリア入力 (1でリセット)
% 出力:
%   Q     - メイン出力
%   Q_bar - Qの反転出力

% 静的変数の定義 (前回のQを保持するため)
persistent Q_prev

% 初期化 (シミュレーションの最初にQ_prevを0に設定)
if isempty(Q_prev)
    Q_prev = 0;
end

% 非同期クリア (ICLR) が1の場合、Qをリセット
if ICLR == 1
    Q = 0;
else
    % クロックの立ち上がりエッジでDの値をQに反映
    if rising_edge(CLK)
        Q = D;
    else
        % 変化しない場合は前回の値を保持
        Q = Q_prev;
    end
end

% Qの反転出力を生成
Q_bar = ~Q;

% Q_prevを更新
Q_prev = Q;
end

% 補助関数: クロックの立ち上がりエッジ検出
function result = rising_edge(CLK)
    persistent CLK_prev
    if isempty(CLK_prev)
        CLK_prev = 0;
    end
    result = (CLK_prev == 0) && (CLK == 1);
    CLK_prev = CLK;
end

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/84934afb-b3ad-40f7-3472-04cc5d3f6638.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/8cf90a37-3b60-94ea-1dd5-7a4f0a8234b4.png)
[小ネタ] シェルスクリプトで日報作成スクリプトを作ってみた

# きっかけ
日報書くためのフォーマットをなんか作りたいなあと思ったので作りました。
日付で管理できるのであとあとの振り返りに便利だと思うので是非ご活用ください

# スクリプト本体
```sh:create_journal.sh
#!/bin/bash

# 環境変数から本名を取得

if [ -f .env ]; then
  export $(cat .env | xargs)
else
  echo ".envファイルが見つかりません。"
  exit 1
fi


FULL_NAME=${FULL_NAME}

# 現在の日付を取得
TODAY=$(date +"%Y/%m/%d")
YYYY=$(date +"%Y")
MM=$(date +"%m")
DD=$(date +"%d")
WEEKDAY=$(date +"(%a)")  # 曜日を短縮形で取得

# フォルダパスとファイル名を定義
FOLDER="${YYYY}/${MM}"
FILENAME="${YYYY}${MM}${DD}.md"
FILEPATH="${FOLDER}/${FILENAME}"

# フォルダが存在しない場合は作成
if [ ! -d "$FOLDER" ]; then
  mkdir -p "$FOLDER"
fi

# ファイルが既に存在するか確認
if [ -f "$FILEPATH" ]; then
  read -p "ファイル $FILEPATH は既に存在します。上書きしますか？ (y/n): " CONFIRM
  if [ "$CONFIRM" != "y" ]; then
    echo "ファイルの作成をキャンセルしました。"
    exit 0
  fi
fi

# ファイルを作成し、内容を書き込む
cat <<EOL > "$FILEPATH"
${YYYY}/${MM}/${DD}${WEEKDAY} ${FULL_NAME}
#作成したいフォーマットを記述
EOL

echo "ファイルが作成されました: $FILEPATH"

read -p "このままそのファイルを開きますか？ (y/n): " CONFIRM
  if [ "$CONFIRM" == "y" ]; then
    # 開きたいエディタのコマンドを設定
    # 自分はvscodeで開きたいので code .を設定
    code . $FILEPATH
  fi
```

# 使い方
スクリプトに権限を与えてを実行するだけ。
自分の名前だけ`.env`に設定してください
```bash
$ chmod 775 create_journal.sh
$ ./create_journal.sh
```

```txt:.env
FULL_NAME="フル・ネイム"
```
# いいところ
日付に応じたファイルパスに日報のフォーマットが吐き出されます。
スクリプトを実行した日時をそのままファイルパスにしてくれます

```bash:日報を生成した際のフォルダ構造
├── 2024
│   ├── 05
│   │   ├── 20240510.md
│   │   ├── 20240516.md
│   │   ├── 20240517.md
│   │   ├── 20240522.md
│   │   ├── 20240523.md
│   │   ├── 20240524.md
│   │   ├── 20240527.md
│   │   ├── 20240528.md
│   │   ├── 20240529.md
│   │   ├── 20240530.md
│   │   └── 20240531.md
│   ├── 06
│   │   ├── 20240603.md
│   │   ├── 20240604.md
│   │   ├── 20240605.md
│   │   ├── 20240606.md
│   │   ├── 20240607.md
│   │   ├── 20240610.md
│   │   ├── 20240611.md
│   │   ├── 20240612.md
│   │   ├── 20240613.md
```

また、スクリプトを実行するとそのままファイルをいじれます
```bash
$ ./create_journal.sh 
ファイルが作成されました: 2024/12/20241216.md
このままそのファイルを開きますか？ (y/n): 
```

# まとめ
それなりに便利なのでよければ使ってやってください。
Wallpaper EngineをPythonで再現？Pygameで作るアニメーション壁紙

# はじめに
Wallpaper Engineの自作について記事を書きます。

現状同じようなことが書かれた記事はないため、後輩のために書きます。
自分は2024年に入学をした大学1年生です。
今回が初めての記事のため、至らない点があると思いますがご了承ください。

## 言語
- ### Python

## 仕様技術
- ### Pygame
    アニメーションフレームや動く画像を簡単に描画できるPygameを利用

- ### Ctypes
    WindowsAPIをpython側で利用するためのもの

## Windowsのデスクトップウィンドウの仕組み
- #### デスクトップの構造

    - ##### Taskbarウィンドウ
        - 最上層のウィンドウであり、下に表示されているタスクバーを管理している
    <br> <!-- 空行を追加 -->
    - ##### Progmanウィンドウ
        - Taskbarの一つ下の層であり、デスクトップのアイコンを管理している
    <br> <!-- 空行を追加 -->
    - ##### WorkerWウィンドウ
        - Progmanの一つ下の層であり、普段は存在していないウィンドウ
        - Progmanを再構築を行うと、WorkerWが作成される
    <br> <!-- 空行を追加 -->
    - ##### Desktopウィンドウ
        - デスクトップのファイル、ショートカットなどを管理している

    Windowsのデスクトップはこれらの複数のレイヤーで構成されています。
    主にWorkerWウィンドウを利用し、動的背景を実現していきます。

## STEP1 - Pygameで動的背景ウィンドウの作成
- ##### 画像の表示
    左側で画像のpathを指定し、右側で画像の座標を指定する
    `screen.blit(image-path,(0,0))`
<br> <!-- 空行を追加 -->
- ##### ウィンドウの更新
    ウィンドウを更新する
    `pygame.display.update()`
<br> <!-- 空行を追加 -->
- ##### ウィンドウの更新
    FPSを指定する
    `clock.tick(60)`

    ```python
    while True:
    
        screen.blit(back,(0,0))
    
        pygame.display.update()
        clock.tick(60)
    ```

## STEP2 - CtypesでWorkerWウィンドウの作成
- ##### Progmanのハンドルを取得
    `progman = ctypes.windll.user32.FindWindowW( "Progman" , None)`
<br> <!-- 空行を追加 -->
- ##### ウィンドウの更新
    Progmanに再構築の命令を送る(0x052Cが再構築)
    `ctypes.windll.user32.SendMessageTimeoutW (progman,0x052C,0,0,0x0,1000,None)`
<br> <!-- 空行を追加 -->
- ##### ウィンドウの更新
    生成されたWorkerWのハンドルを取得
    `workerw = ctypes.windll.user32.FindWindowExW(None,None,”WorkerW”,None)`

    ```python
    progman = ctypes.windll.user32.FindWindowW( "Progman" , None)
    ctypes.windll.user32.SendMessageTimeoutW (
        progman,0x052C,0,0,0x0,1000,None
    )
    workerw = ctypes.windll.user32.FindWindowExW(None,None,”WorkerW”,None)
    return workerw
    ```

## STEP3 - PygameウィンドウとWorkerWを繋げる
- ##### Pygameのハンドルを取得
    `window_info = pygame.display.get_wm_info()`
<br> <!-- 空行を追加 -->
- ##### その中のwindowハンドルを取得
    `hwnd = window_info["window"]`
<br> <!-- 空行を追加 -->
- ##### 親子関係を設定
    workerwを親、pygameを子として設定する
    `ctypes.windll.user32.SetParent( hwnd , workerw )`

    ```python
    window_info = pygame.display.get_wm_info()
    
    hwnd = window_info["window"]
    ctypes.windll.user32.SetParent( hwnd , workerw ) 
    ```

## まとめ

WallpaperEngineの自作方法をまとめました。
今回は、画像を表示する方法を中心にまとめましたが、以下のようなことも試したため、コメントがあれば記事にします。
- デスクトップでの3Dオブジェクトの操作
- 画像を高速更新することで、リアルタイムにアニメーションを反映させる
- 動画の表示
Firefoxで使えるショートカットキー+αまとめ


業務でFirefoxを使うことが多いので、頻繁に使うFirefoxの便利機能をまとめてみました。紹介しているショートカットキーはmac OS対応のものです。
※他ブラウザと共通の機能も含みます。


* * *
### 1.スクロールキャプチャ

表示しているページの一部、または全体をスクリーンショットで保存できる機能。

>ページ上で右クリック → 「スクリーンショットを撮る」を選択。
>>スクリーンショットツールを起動
command⌘ + Shift + S


### 2.動画の再生/音量調節

動画プレイヤーがフォーカスされている状態で使えるショートカットキー。

>再生/停止: space 
音量調整: ↑ / ↓ 


* * *
### 3.検索エンジンの変更

簡単な操作で検索エンジンを好きなものに変更することができる。

>検索バーにフォーカスした状態で 
command⌘ + K

>検索エンジンを選択
command⌘ + ↓ / ↑ 

* * *
### 4.開発者ツール
開発者ツールを使用する際に役立つショートカットキー３選。

>開発者ツールを開く
command⌘ + Option + I

>レスポンシブデザインモード
command⌘ + Shift + M

>要素選択ツールの起動
command⌘ + Shift + C

* * *
### 5.タブの切り替え
タブが増えてきた際に役立つショートカットキー

>タブの切り替え
command⌘ + 1(左端のタブに移動)
command⌘ + 9(右端のタブに移動)

>最後に閉じたタブを復元
command⌘ + Shift + T

>>おまけ
右クリック→[タブをピン留め]
タブを固定することができる。


* * *


慣れるまでは難しいですが、ショートカットキーを覚えてから作業効率がぐっと上がったように思います。
日常的にFirefoxを使っている方は覚えてみてはいかがでしょうか。
Gitコマンド：`git checkout`から`git switch`と`git restore`へ

# はじめに
Gitは開発者にとって欠かせないバージョン管理ツールですが、その操作コマンドには多くの機能が詰まっています。特に`git checkout`はブランチの切り替えやファイルの復元など、多目的に使用されてきました。しかし、その多機能さゆえに動作が曖昧になりやすく、誤った操作を招く原因にもなっていました。

Git 2.23（2019年8月）以降、新しいコマンドである`git switch`と`git restore`が導入されました。これらのコマンドはそれぞれ特定の操作に特化しており、より直感的で安全なGit操作を実現します。本記事では、`git checkout`の問題点や新しいコマンドの使い方、そして`git checkout`を使わないべき理由について解説します。

## **`git checkout`：古い多目的コマンド**

`git checkout`は以下のような複数の機能を持つコマンドです。

- **ブランチの切り替え**
- **新規ブランチの作成**
- **ファイルの復元**
- **コミットのチェックアウト**

一つのコマンドで様々な操作が可能ですが、その反面、どの操作が実行されるのかがコマンドの書き方によって変わるため、動作が曖昧になりやすいという問題があります。特に初心者にとっては学習コストが高く、誤った操作によるトラブルも起きやすいです。

### **新しいコマンドの導入：`git switch`と`git restore`**

Git開発チームはこれらの問題を解決するため、操作を明確に分離した新しいコマンドを導入しました。

#### **`git switch`：ブランチ操作に特化**

`git switch`はブランチの切り替えや新規ブランチの作成に特化したコマンドです。

- **ブランチの切り替え**

  ```bash
  git switch ブランチ名
  ```
  
- **新規ブランチの作成と切り替え**

  ```bash
  git switch -c 新しいブランチ名
  ```

#### **`git restore`：ファイル操作に特化**

`git restore`はファイルの復元やステージングの解除に特化しています。

- **作業ディレクトリのファイル復元（変更内容を削除）**

  ```bash
  git restore ファイル名
  ```

  :::note
  Gitで追跡していないファイルを削除する場合
  **clean**コマンドを使う
    1. 削除されるファイルを確認
        ```bash
        git clean -n
        ```
    2. ファイルを削除する
        ```bash
        git clean -f
        ```
    3. ディレクトリを削除する
        ```bash
        git clean -d
    4. ファイルとディレクトリを削除する場合
        ```bash
        git clean -fd
        ```

bash

コピー
git clean -fd
  :::
  
- **ステージングの解除**

  ```bash
  git restore --staged ファイル名
  ```

### **具体的な使用例**

以下に`git checkout`と新しいコマンドの対応する使用例を示します。

#### **ブランチの切り替え**

```bash
# 従来の方法
git checkout develop

# 新しい方法
git switch develop
```

#### **新規ブランチの作成と切り替え**

```bash
# 従来の方法
git checkout -b feature

# 新しい方法
git switch -c feature
```

#### **ファイルの復元**

```bash
# 従来の方法
git checkout -- file.txt

# 新しい方法
git restore file.txt
```

### **`git checkout`を使わない理由**

#### **1. 動作の曖昧さを排除**

`git checkout`は一つのコマンドで複数の異なる操作を行うため、コマンドの意図が不明瞭になりやすいです。例えば、ブランチ名とファイル名が重複している場合、どちらを指しているのか混乱を招く可能性があります。`git switch`と`git restore`を使用することで、その操作がブランチに関するものかファイルに関するものかが明確になります。

#### **2. 学習コストの低減**

新しいコマンドはその名前から機能が直感的に理解できるため、Gitの学習コストを下げることができます。特に初心者にとって、操作を誤るリスクを減らし、安心してGitを活用できるようになります。

#### **4. 将来的なベストプラクティスへの適応**

Gitの開発者は、`git switch`と`git restore`の使用を推奨しています。これらのコマンドは今後も維持・改善が行われると考えられ、最新のベストプラクティスに従うことで、将来的な互換性やサポートを得やすくなります。

### **まとめ**
`git checkout`は長らくGitユーザーに利用されてきた多目的コマンドですが、その曖昧さや誤用のリスクから、`git switch`と`git restore`への移行が推奨されます。これらの新しいコマンドを使用することで、操作の意図が明確になり、誤った操作を防ぐことができます。Git 2.23以降を利用している場合は、ぜひ`git switch`と`git restore`を積極的に活用して、より効率的で安全なGit操作を実現しましょう。
ITアレルギーの私が、パソコンと友達になった話

この記事は[Schoo Advent Calendar2024](https://qiita.com/advent-calendar/2024/schoo)の23日目の記事です！
# はじめに
こんにちは、株式会社Schooの江川@saki_egawaです。
Schooの学習動画コンテンツの企画制作ディレクターを担当しています。
このページでは、自称「ITアレルギー」の私が、あるコンテンツ制作を通じて「パソコンと友達になった」エピソードをシェアしたいと思います。
# なぜコンピューターを学ぶ授業を企画したのか？
## 「ITアレルギー」
冒頭に「ITアレルギー」と記しましたが、私は幼い頃から今に至るまで、「IT」「コンピューター」「プログラミング」のような「機械っぽいこと」に漠然とした苦手意識を抱いていました。
就職するまでブラインドタッチもできなかった私ですが、そもそもなぜ「ITアレルギー」になってしまったのかを振り返ると、いくつか思い当たる節があります。
- 「パソコンは大人になってから触るもの」だと思っていた
- 子どもの頃、ブラインドタッチの速さを競うゲームで、クラス最下位になった
- 上記の影響で、なかなか興味を持つ機会がないまま、気づいたら大人になっていた

社会人になり、さすがにブラインドタッチは習得しましたが、IT全般への苦手意識はゼロではありませんでした。
## コンピューターをもっと知りたい
### 企画のきっかけ
そんな私の意識を変えたのが、Schoo授業[「コンピュータのひみつ -分解でわかる仕組みと構造」](https://schoo.jp/course/8173)の企画制作でした。
自身の担当する学習テーマとして「ITリテラシー」「コンピューター」が決定し、必要なテーマだなと感じつつも企画に苦戦していました。
観点として、
 - ITパスポートの受験に役立つ知識
 - 若手のうちに身に付けたいITリテラシーの一環としてのコンピューター知識
 - DXの波に乗り遅れないための基礎知識

といった項目をインプットできるのが「価値」のあるコンテンツだと考え、ITパスポートの過去問題を読んだり、学習動画を視聴したりして、考えを巡らせていました。その時に初めて、『私は「学ばねばならない」と思いすぎて、全然「学びたい」と思っていない』ということに気づきました。
### 「学びたい」という気持ち
そんな時に出演をご快諾してくださったのが、日出学園中学校・高等学校情報科教諭の[武善紀之先生](https://schoo.jp/teacher/3853)でした。
スキルや知識よりも、まず大切なのは「コンピューターと友達になる」気持ちだとおっしゃっているのを聞き、まさに自分に足りなかったのはこの姿勢だと痛感したことを鮮明に覚えています。
そこからの企画プロセスでは、『どんな動画なら、私のような「ITアレルギー」の人を楽しませられるか』を第一に考え、とにかく身近さと面白さを追求しました。
例えば、
- 実際のパソコンを分解した動画を映し、視覚的に学ぶ
- ミニ劇で各装置の役割を再現する
- 先生が愛用しているコンピューター製品と一緒に登壇する
のような構成・演出により「未知の存在」だったコンピューターを少しでも身近に感じてもらう工夫を凝らしました。
この制作プロセスを通して、当初抱いていた「ITアレルギー」の感覚は、いつの間にか消えつつありました。
![2024-12-16 17.51の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940314/40fca12f-d2e0-7c80-f8c5-4db7c397e4c3.jpeg)
参考：分解したコンピューター内部

# 制作を経て得た学び
## コンピューターって「かわいい」かも
では、「ITアレルギー」の気持ちは、どのように変化したのか。
ここからは、2つの大きな変化を共有します。
1つ目は、「コンピューターをもっと知ってみたい」と思えたことです。
今まで「五大装置」すら名称を覚えられなかったのは、姿を見たことがなく、得体の知れないものだと思い込んでいたからだと気づきました。
実際にコンピューターを分解してみると、「CPUやメモリーってこんな形だったの？」と知り、例えるなら「今までずっとメールでやり取りしていた人と、初めて会った時の感覚」が呼び起こされました。
また、授業内の「ミニ劇」では、各装置の働きをペンギンのミニフィギュアで再現しているのですが、人間の指示に従って頑張って働いている装置たちが可愛らしく思えてきて、親近感が湧きました。
今までは「よくわからないもの」だったのが「頑張っている可愛らしい子たち」に変わったことに気がつきました。
また、普段仕事で使っているパソコンに対しても愛着が湧いてきてどんどん触るのが楽しくなってきました。

![スクリーンショット 2024-12-13 12.36.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940314/e8cb9083-9126-8fe5-2ca8-cfdd69be19d4.png)
参考：ペンギンのフィギュアを使ったミニ劇
## 姿勢の変化
2つ目は、自力でITの未知の領域を開拓できるようになったことです。
正直、授業制作後にIT知識が見違えるほどついたわけではありません。初心者レベルのことでも、いまだにわからないことばかりです。
それでも、「未知のIT」と出会ったときに、怖がらずに歩み寄ってみる姿勢は身につきました。
例えば、普段からコンテンツのタイトルをAIに壁打ちしてみたり、趣味で画像や動画の編集をする時にも、今まで使ったことがなかった機能やツールを使ってみたりしています。
このように、未知と遭遇した時に「自分から歩み寄って友達になってみる」姿勢が、学びの可能性を広げるきっかけになると実感しました。
エンジニアのみなさんが、コンピューターやITについて構造的に分かりやすく説明してくれることが本当にありがたいと感じました。
今後も、Schooを通じて 特定分野に苦手意識を持っている多くの方々が勇気づけられるようなコンテンツを制作していきたいと思います。

# 最後に
最後まで読んでいただきありがとうございました！
この記事を読んで「パソコンと友達になってみたい」と思った方は、ぜひ[こちらの授業](https://schoo.jp/course/8173)をチェックしてみてください。

---
Schooでは一緒に働く仲間を募集しています！

https://corp.schoo.jp/careers/graduates

https://corp.schoo.jp/careers
TCP輻輳制御

## TCPはトラフィックレートを調整する
>ネットワーク層から輻輳のフィードバックを受け取り、ネットワークに送信するトラフィック・レートを低くするかどうかはトランスポート層次第である。インターネットにおいて、TCPは信頼性の高い転送の主な担い手であると同時に、輻輳制御においても主要な役割を果たす。TCPが特別なプロトコルであるのはそういう理由である。

### サイズを輻輳ウィンドウにより管理する
>TCPは輻輳ウインドウ(congestion window)を管理する。輻輳ウインドウのサイズは、送信側がネットワーク上に滞留させることができるバイト数の上限を意味する。輻輳ウインドウに対応する送信レートは、ウインドウの・サイズを各コネクションの往復時間で割ったものである。TCPはAIMDに従ってウインドウ・サイズを調節する。
　フロー制御ウインドウに加えて、輻輳ウインドウがあることを思い出そう。フロー制御ウインドウは受信側がバッファできるバイト数を示している。両ウインドウは並行して片越される。送信側が許されるバイト数は二つのウインドウの小さいほうである。それゆえ実際に効果を持つウインドウ・サイズは、送信側はこれで良いと思うウインドウ(つまり輻輳ウインドウ)と、受信側がこれで良いと思うウインドウ(つまりフロー制御ウインドウ)の小さいほうである。

## 輻輳崩壊
>輻輳崩壊(congestion collapse)と呼ばれる最初の現象が起こっていた。ネットワーク内の輻輳のため、かなり長期的の間グッとプットが急激に落ち込んだのである。(100倍以上）。
### パケットロスで輻輳を判断する
>パケット・ロスが輻輳信号として適切であることに気づいた。この信号は少し遅れてくる（ネットワークがすでに混雑してるため)が、それはかなり信頼できるものである。結局のところ、過負荷がかかっている時、パケットを落とさないルーターを作り上げることは困難である。この事実が変わる可能性は低い。

>しかしながら、輻輳信号としてパケットロスを利用することは、送信誤りが比較的まれに発生する場合でなければうまくいかない。

### 再送信タイマーでネットワークにかかる負荷を知る
>インターネットのあらゆるTCPアルゴリズムはパケット・ロスを輻輳に起因するとみなし、タイムアウトを監視し、トラブルの徴候を探している。パケット・ロスを正確にかつ迅速に見つけるためには良い再送タイマーが必要である。TCPの再送信タイマーが往復時間の平均や変動をどのように評価するかはすでに学んだ。

>再送信タイマーの機能が良ければ、TCPの送信者は確認通知の戻ってこないパケットのバイト数を把握できる。すなわち、ネットワークにかかっている負荷がわかるということである。送信済みの順序番号と確認通知が返ってきた順序番号の違いを調べることは簡単である。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
スクラム開発の基本から実践まで：チーム力を引き出すフレームワーク

# はじめに

スクラム開発は、アジャイルソフトウェア開発のフレームワークの一つで、迅速かつ柔軟に製品やプロジェクトを進める手法です。ソフトウェア開発において複雑な課題を解決し、変化に対応するためのチームワークを重視した方法論として広く利用されています。

---

## 基本的な要素

### 1. スクラムチーム
スクラムチームは以下の3つの役割で構成されます。

- **プロダクトオーナー (Product Owner):**
  プロダクトの価値を最大化する責任を持つ人物。市場や顧客のニーズを反映し、プロダクトバックログを常に更新します。また、ステークホルダーとの調整役としても重要な役割を果たします。

- **スクラムマスター (Scrum Master):**
  チームがスクラムのルールを守り、スムーズに運用できるよう支援する役割です。障害の除去や効率化のためのコーチングを行い、時には組織全体のプロセス改善にも関与します。

- **開発チーム (Development Team):**
  高度な専門性を持ち、自律的に動けるメンバーで構成されます。設計やコーディングだけでなく、テストやリリースまで一貫して対応します。小規模でありながらクロスファンクショナルな構成が求められます。

### 2. スプリント (Sprint)
スプリントは1〜4週間の短期間で計画される反復的な作業サイクルです。スプリント中は計画を変更しないことが原則で、終了時にはリリース可能な状態のインクリメントを目指します。短期間で成果物を作成することで、フィードバックを迅速に得ることが可能です。

### 3. プロダクトバックログ (Product Backlog)
プロダクトバックログは、開発に必要なすべての要件をリストアップしたもので、優先順位が常に見直されます。新たなアイデアや要求が追加されることで、柔軟性を持ってプロダクトを成長させることができます。

### 4. スプリントバックログ (Sprint Backlog)
スプリントバックログは、スプリント中に取り組むタスクの一覧で、具体的かつ達成可能な粒度に分解されています。タスクの進捗状況は、カンバンボードやバーンダウンチャートで可視化されることが一般的です。

### 5. デイリースクラム (Daily Scrum)
デイリースクラムは、毎日15分程度の短いミーティングです。進捗の共有、目標の再確認、障害の特定を目的とし、チームの一体感を高めます。また、継続的な改善につなげる重要な場でもあります。

### 6. スプリントレビュー (Sprint Review)
スプリントレビューでは、プロダクトオーナーやステークホルダーに対して成果を発表し、フィードバックを得る場です。これにより、次のスプリントの方向性が明確になります。

### 7. スプリントレトロスペクティブ (Sprint Retrospective)
スプリント終了後に、チームの作業プロセスやコミュニケーションを振り返る場です。成功例や課題を洗い出し、改善策を具体化することで、次回のスプリントの効率を向上させます。

---

## スクラム開発のメリット

1. **スキル向上の場を提供する:**
   チーム全体で問題解決に取り組むことで、各メンバーの専門スキルだけでなく、リーダーシップやコミュニケーション能力といったソフトスキルも向上します。
2. **迅速な成果の提供:**
   短いスプリントで進捗を確認しながら開発を進めるため、顧客に価値を迅速に提供することが可能です。市場の変化にも柔軟に対応できます。
3. **チームワークの向上:**
   共通の目標に向かって協力し合うことで、チーム内に信頼関係が生まれ、一体感が強まります。これにより、プロジェクトの達成感が高まります。

---

## スクラム開発のデメリット

1. **厳格な納期への対応が難しい:**
   スクラムでは柔軟性を重視するため、納期が厳密に決まっているプロジェクトには不向きな場合があります。そのため、納期を重視する環境では別の手法との併用が必要になることがあります。
2. **チームの維持が難しい:**
   長期的に同じメンバーでチームを維持することが難しい場合、スクラムの効果が薄れる可能性があります。特に人員の入れ替えが頻繁な環境では課題となります。
3. **ステークホルダーとの関係が疎かになりやすい:**
   チーム内の作業に集中しすぎると、外部との調整やフィードバックの取り込みが不足し、全体の方向性がぶれるリスクがあります。
4. **適した環境が限られる:**
   自律性やチームワークを重視するスクラムは、特定の文化や体制が整った組織でこそ最大の効果を発揮します。そのため、トップダウン型の組織や明確な役割分担が求められる場合には適さないことがあります。

---

## 実際の導入例

スクラム開発は、さまざまな業界やプロジェクトで成功を収めています。特に、変化が激しいIT業界やスタートアップ企業で広く活用されています。導入時には、以下のステップを考慮することが重要です。

1. チームの教育とトレーニング
   - スクラムの基本概念や役割について理解を深めるセッションを行います。

2. スクラムマスターの配置
   - スクラムの運用をリードし、初期段階の障害を取り除く役割を担います。

3. スモールスタートによる試験的導入
   - 小規模なプロジェクトや一部のチームで試験的に導入し、効果を検証します。

---

## まとめ

スクラム開発は、アジャイルなアプローチでプロダクト開発を進めるための強力なフレームワークです。チームワーク、透明性、柔軟性を活かして、複雑なプロジェクトを成功に導くことができます。ただし、導入には適切な準備とサポートが必要です。
リーダーになるのが不安なTE（テクニカルエンジニア）のあなたへ

# リーダーになるのが不安なTEのあなたへ

## はじめに
### この文章について
5分ぐらいで読めるようにしています。  
  
この文章はTEでリーダーシップを執らなければならない立場を迎える方に送ります。  

> 2024/12/17 追記＆補足：TEは「テクニカルエンジニア」を指します
  
さらに想定読者を絞ると以下になります。
 - TEで技術力が高いが故に「リーダー」や「管理職」になることを期待されている。
 - しかしリーダー経験に乏しくリーダーシップを執ることが「不安」な人。

「不安」がなければここで読むのをやめて、志すままにリーダーの立場をTRY & ERRORしてみましょう。  
  
そして行き詰まったなら、また読みに来てください（この記事を覚えていたら、、ですが）
  
「不安」に思うならこれ以降の4分半が少しお役に立てるかもしれません。

## リーダーになるのが不安なTEのあなたへ（本編）
### あなたの「不安」を解消したい
前提のとおりなのですが、あなたは「不安」なのだと思います。  
  
今までは「リーダー」の責任で守られていたところ、自分でやらなければいけない。  
  
今まで以上に「仕事の結果」「ステークホルダー」「配下のメンバー」への責任が増します。  
  
このあたりが「不安」のポイントだと思います（違っていたらごめんなさい）
  
でも、TEをやっていたのだから、これまでもそういう経験を無自覚にしているのではないでしょうか？    
  
技術的に難しいことや先進的なことは「当事者」か「有識者」でないと有効なレビューをすることはできないと思います。  
  
必ずしも「リーダー」が「有識者」でなかったことがあったのではないでしょうか？ 
  
きっと、これまでも「リーダー」に完全に守られるわけではなく、困難なミッションを乗り越えてきていると思います。  
  
そのことに自信を持ってもいいはずです。  

またリーダーになると「責任」は増しますが「裁量（権限）」も増します。  
  
あなたの「裁量（権限）」で「料理」できる部分が増えるわけです。  
  
以前は裁量がなくて、提案が却下されたことがありませんか？  
  
今後はそのようなことが減ります。腕まくりして厨房に立ちましょう。  


### あなたの生かせる経験  
  
あなたはTEなので以下のようなことをしてきているはずです。  
  
 1. ベストプラクティスを調べる  
 2. 新しいものを試してみる  
  
これらの経験はあなたの執る「リーダーシップ」に必ず役立つはずです。

#### 生かせる経験 ～ 1. ベストプラクティスを調べる ～

何か自身にとって新しいことに取り組むときに世の中の「ベストプラクティス」を調べませんでしたか？  
  
もしくはトレンドを調べたりしたと思います。  
  
これの目的は「妥当性」「客観性」を持たせるためだったと思います。  
  
「ベストプラクティスを求める姿勢」は「リーダーシップ」の世界でも通用します。  
  
  
（とはいえ、一瞬だけ相反することを主張しますが）
筆者の意見ですが「リーダーシップ」について「ベストプラクティスはない」と考えています。    
「いつの時代になっても、リーダーシップに関する書籍が出版され売れている、、」というのがその証跡だと考えています。バイブルはありません。時代背景やトレンドの変遷によっても変わるものだと思うので。  
  
しかしながら「グッドプラクティス」ならいくつもあります。人間の歴史や活字の歴史は2000年以上ありますからね。その中には時代背景やトレンドに問わず、今でも通用するエッセンスはあります。   

> それこそ、古代は孟子からありますね。
  
是非、「リーダーシップ」「チームビルディング」などの本を読んでみてください。もし近くに「腕のいいリーダー」がいるならオススメの本を教えてもらうのもよいです。  
  
その「~~ベスト~~ グッドプラクティスを求め続ける姿勢」そのものが自身の執るリーダーシップに「妥当性」「客観性」をもたらすと思います。

#### 生かせる経験 ～ 2. 新しいものを試してみる ～

あなたは仕事で役立つ技術があったら、実際にちょっと触ってみる、ということをしていませんか？   
  
「人間の成長段階のモデル」というものは世の中にいくつかあると思いますが、おおよそ、以下のようなものだと思います。

| Lv  | 意識／無意識 | できる／できない | 備考        | 例                     |
|-----|-----------|----------|------------|-----------------------|
| Lv0 | 無意識      | できない     | 知らないからできない | プログラミングを知らない          |
| Lv1 | 意識        | できない     | 知っていてもできない | 「プログラミング」を知っているが書けない |
| Lv2 | 意識        | できる      | 意識してできる   | 適宜調べながら書ける         |
| Lv3 | 無意識      | できる      | 無意識でできる  | 無意識で書ける（プログラム脳化） |

これまでの経験から「人間の成長段階のモデル」に共感できるのではないでしょうか。  
  
新しい技術に好奇心があるあなたはLv1（知っていてもできない）に到達するのは早いと思います。    
  
また経験的に「TRY & ERROR」（反復）すればLv2（意識してできる）に到達できることを体感していると思います。  
  
「その技術」が好きになったものならLv3（無意識でできる）にも到達しているかもしれません。  
  
これは技術的なことだけでなく、リーダーシップについても同様のことが言えます。    
 - 自身にとって新しいことを知る事（Lv0→Lv1）
 - 「TRY & ERROR」みること（Lv1→Lv2）

これができるあなたは「我流」でリーダーシップを執る人よりも、より多くの「グッドプラクティス」を得られる素質があると思います。  
  
そしてあなたのリーダーシップで「いい仕事」「いいチーム」ができるかもしれない、と思えたなら、自然とLv2→Lv3への歩みが自然と始まると思います。「できる」ようになると「楽しい」ので継続しやすいんですよね。

### さいごに
まだ不安があるかもしれませんが、あなたがリーダーになると、きっとハッピーになる人がいると思います。  
あなたはTEだから事象や実態をつぶさに捉えて物事を解決してきたと思います。  
だれかに「丸投げ」ではなくて。  
  
そういうあなたは、メンバーが困難を乗り越えてミッションを達成した際に、つぶさに話を聞いて苦労や頑張りに共感した上で「ありがとう」が言えるでしょう。  
ビジネスライクに結果だけみて「ありがとう」と言うよりも人間味があると思います。  
これはあなたのチームビルディングをより良くするでしょう。  
  
「~~ベスト~~ グッドプラクティス」を求めたり「新しいものを試してみる」ということしながら、是非「あなた自身のリーダーシップをエンジニアリング」してください。
個人的にモダンだと思うAWSのWebコンテナ基盤

# はじめに

スタートアップ企業でAWSを使った開発に3~4年ほど携わってきました。スタートアップならではの特徴として、開発の生産性を重視し、よりモダンな構成が選ばれます

これまでの経験から、特に効果的だった構成や選択についてまとめてみました。

# AWS開発者に求められるスキル

- IaCを使って、インフラをコードベースで管理できること
- Dockerfileが書けること
- フロントエンド・バックエンドの基本的な実装ができること（ポートフォリオレベルで可）
- 各言語やフレームワークの基本的な使い方
- セキュリティ監査を実装できること
- CI/CDが使えること

# インフラ構成のポイント

## IaC
インフラはTerraformで管理するのがベスト。コードベースで環境を管理でき、再現性も高いです。

## コンテナ基盤
フロントエンド・バックエンドともにECS Fargateを採用。サーバー管理が不要で、コンテナに集中できます。

## API構成
シンプルにバックエンドのECSだけで十分です。API GatewayやAppSyncは、必要に迫られるまで導入を見送っても問題ありません。

## CI/CD
GitHub Actionsが使いやすいです。AWSのCodeシリーズは機能も十分ですが、GitHubと統合された環境にすることで開発効率が上がります。

## データベース
Aurora Serverlessを採用。
スケールアップなどの運用がほぼほぼ発生せず、非常に管理しやすいです。

## AWSアカウント構成
Control Towerを使って以下の6つのアカウントを作成：
- 開発環境（dev）
- ステージング環境（stg）
- 本番環境（prod）
- 監査用（audit）
- ログ用（log）
- 管理用（management）

# 実装時の選択ポイント

## コンテナイメージの管理
ECRでは`latest`タグは使わず、GitHub Actionsの`${{ github.sha }}`を使ってバージョン管理するのがおすすめです。

https://docs.github.com/ja/actions/use-cases-and-examples/deploying/deploying-to-amazon-elastic-container-service


## 監視設計
まずはCloudWatchからスタート：
- CloudWatch Alarm
- CloudWatch Dashboard
- Performance Insights
- Container Insights

## メディアファイルの配信
S3またはCloudFrontと署名付きURLの組み合わせで対応できます。

# セキュリティ対策

## 脆弱性検知
Amazon Inspectorを導入し、定期的なスキャンを実施。

## WAF設定
最低限以下の対策は必要：
- DDoS対策
- SQLインジェクション対策
- XSS対策
- などなど、WAF側でマネージドに使えるものを利用するのがいいかも

# デプロイ戦略

## デプロイ頻度
理想はトラブルを最小限に抑える・トラブルシューティングやロールバックのしやすさからpushする度にデプロイですが、現実的には週1回程度が多いです。

## デプロイ方式
Blue/Greenデプロイがおすすめ。安全に新バージョンへの切り替えができます。

## データベースマイグレーション
LambdaまたはFargateを使って自動化。
デプロイプロセスの一部としてGitHub Actionsに組み込むのが理想的です。

# さいごに

スタートアップでは、過度に複雑な構成は避け、必要十分な構成からスタートすることが重要です。
事業の成長に応じて、必要な機能を追加していく方針が効果的だと考えています。
「AWS Certified Cloud Practitioner」合格体験記

# はじめに
- 2024年12月、「AWS Certified Cloud Practitioner」に合格することができました
    - 本記事では、私が「AWS Certified Cloud Practitioner」に合格するまでの勉強方法を記載します
- すでに多くの方が同様の記事を書いていますが、この記事を目にするどなたかのお役に立てればと思い、記載していきます

# 「AWS Certified Cloud Practitioner」とは？
- AWSクラウドサービスの基本的な知識が問われる試験と私は認識しています
    - これからクラウドを学ぶ人や実務経験が浅い人向けの試験です
- [AWSの公式ページ](https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)によると、以下のように述べられています
> AWS Certified Cloud Practitioner は、AWS クラウド、サービス、用語の基礎的かつ高度な理解を持っていることを証明します。 これは、IT やクラウドの経験がまったくない個人でクラウドのキャリアに切り替えるか、基礎的なクラウドリテラシーを求めている基幹業務の従業員にとって、AWS 認定ジャーニーの良い出発点となります。

# 学習開始時の知識量
- ネットワークスペシャリスト、応用情報を取得した状態で学習を開始しています
    - ネットワークスペシャリストは2024年春に取得したため、ネットワーク関連の知識は頭に残った状態でした
- クラウドに関しては、知識ほぼゼロでした（実務経験もなし）
    - EC2がサーバで、RDSがデータベースで、VPCがネットワークでくらいの知識しかありませんでした

# 学習期間と総学習時間
## 学習期間
- 2024年10月上旬～2024年12月上旬（2か月間）

## 総学習時間
- 約40時間
    - 平日：30分程度
    - 休日：60分程度
    - 試験前の休日：120分程度

# 学習方法
- 平日と休日とで学習の内容を変えていました

## 平日の学習方法
- 夜寝る前の読書という感覚で、寝る前の30分程度、テキストを読み込んでいました
    - 試験本番までに2周通しで読むことができました
- 私が購入していたテキストは、『[AWS認定資格試験テキスト　AWS認定 クラウドプラクティショナー　改訂第3版 (ＡＷＳ認定資格試験テキスト)](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-%EF%BC%A1%EF%BC%B7%EF%BC%B3%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%B1%B1%E4%B8%8B%E5%85%89%E6%B4%8B/dp/4815625387/ref=sr_1_1_sspa?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3KZ1YNXH3O9TU&dib=eyJ2IjoiMSJ9.AiFOQ7eQOW4NhsuNRuh8FI61CHhwmZRyWCJntf9Vja5HpqnwcH8IF8TwEaPsQ2Xro5gJHYPcS3B1x_gBojkhvbvDmkmqOeRs6YaigxWGs2Sb-lFZ_-dMOE_ux-fhHdyn8kMiW4DuTbU6RHpA2uX3oofoi2yM562Dy2zGRCew8SHubik07BXWyi4UAECxa5KTNgZwawYHAeh7NDcNGAavrjhk4iD9ExyArQ9r4XAtG9Ixd9X78xOZUKS97UvzQvaOFVBXlUoltQCI--7ZWsOHG3rP798mvh03kZSfbXplnBk.-Qzvkdmkya7PoJMeQO1xsEurPIXqVYRDHMFS8d3e2_s&dib_tag=se&keywords=aws+%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC&qid=1734338267&sprefix=aws+%E3%81%8F%E3%82%89%E3%81%86d%2Caps%2C1329&sr=8-1-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1)』です
    - 本屋で探して、練習問題を掲載しているテキストでパッと見つかったものがこちらの書籍でしたので購入しました

# 休日の学習方法
- Udemyで以下の講座を購入して、1日1回分の練習問題を解きました
    - [【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-4260/?couponCode=ST21MT121624)
- 練習問題を解く際は、勘で解いた問題にはフラグを付けて、後で見直すようにしていました
- フラグを付けた問題+間違った問題を見直し、選択肢含め理解があやふやなサービスを書籍で調べ、知識の補填をしました
- 6回分の試験が収録されていますが、試験前までに3, 4周することができました
    - 最初の1周目はどの回も合格点未満でしたが、フラグを付けた問題+間違った問題の見直しで、最終的には9割ほど解けるようになっていました

# 試験本番
- 試験難易度は、上述したUdemyの練習問題と比較して簡単でした
    - 5個の選択肢から2つ、3つ答えさせる問題が少なかった印象です
    - 適切なサービスを選ばせる問題も、Udemyの練習問題よりもシンプルな印象を受けました
- Udemyの練習問題を8～9割解ければクリアできそうな難易度だと思いました

# 最後に
- これから「AWS Certified Cloud Practitioner」を受験する方にこの記事が少しでもお役に立てれば幸いです
- 質問等ありましたら、気軽にコメントに記載いただければと思います
シリアライズとは


## シリアライズ（Serialize）
オブジェクトをバイトストリームに変換すること。

## バイトストリーム
コンピュータが扱いやすい形式である0と1の列（バイナリデータ）に変換したもの。

## なんでバイトストリーム化するの？
オブジェクトを保存したり、通信で送ったり、セッション情報を保持するなど、
ある機能を実装したい時、オブジェクトを直接保存したり送信することはできない場合がある。
バイトストリームに変換して扱えるようにしないと。

## 如何やってシリアライズさせるの？
```
import java.io.Serializable;
import test.他の私のクラス;

public class 私のクラス implements Serializable {

    /** シリアライズするクラスに対して付与するシリアルバージョンUID **/
    private static final long serialVersionUID
    private String 他の私のクラス フィールド名;
    ...
}
```
シリアライズしたいクラスに java.io.Serializable インターフェースを実装する。
シリアルバージョンUIDは、シリアライズしたクラスのバージョンを識別するための一意のID。
これの役割は、シリアライズされたバイトストリームを**デシリアライズ**する際、クラスのバージョンの整合性を確認するために使われる。

## デシリアライズ（Deserialize）
シリアライズされたバイトストリームを元のオブジェクトに復元するプロセス。

## 今まで私、シリアライズを意識したコードを書いた記憶がないけど？

シリアライズは特定の場面で必要になるもので、普段のJava開発では直接意識しないことも多い。
オブジェクトを保存することや通信に使用しない場合、シリアライズは不要。

もしくは、使ってるフレームワークが裏側でシリアライズを処理しているケースかな。
Spring Frameworkもキャッシュ処理とかでシリアライズが必要になる場合に、自動で対応してくれる。

## じゃあ、シリアライズを意識する必要ある？
シリアライズが必要になるのは、主に以下の状況：

1. オブジェクトをファイルやデータベースに保存したい
2. ネットワーク越しにオブジェクトを送信したい
3. セッション管理（JavaのHttpSessionでオブジェクトをセッションに保存する場合）

これらを使っていない場合、シリアライズを意識する機会は少ない。
上でちょっと話したデシリアライズも同じく、保存されたデータの復元、ネットワーク通信のデータ受信、キャッシュからの復元で使われる。

## 上のケースでシリアライズしないとどうなる？
**NotSerializableException** が発生する。

## NotSerializableException?
Serializableを実装していないクラスをシリアライズしようとすると出る例外。

または、クラス自体はSerializableを実装しているが、そのフィールドの一部がシリアライズ不可能なオブジェクトを持っている場合も例外が発生する。
例えばThread, Socket, FileInputStreamがある。

## シリアライズ不可能なオブジェクトがある理由はなんだ
そのオブジェクトの性質や用途がシリアライズに適さないため。
プログラムの実行中にのみ有効な状態や接続を持っており、その状態をバイトストリームとして保存しても、後で復元できないことが多い。


## Thread, Socket, FileInputStreamとかを含むとシリアライズ出来ないの？

この場合解決策として**transient**キーワードを使用。

```
import java.io.Serializable;
import test.他の私のクラス;

public class 私のクラス implements Serializable {

    /** シリアライズするクラスに対して付与するシリアルバージョンUID **/
    private static final long serialVersionUID
    private transient String 他の私のクラス フィールド名;
    ...
}
```


## transient
シリアライズしたくないフィールドを除外。これでシリアライズできない型のフィールドを回避する。
また、不要なフィールドを除外してデータサイズを削減し、パフォーマンスの向上することもできるし、
意味的にパスワードなどの機密情報や一時的な値をシリアライズ対象外にする時も使う。

## 結論
作ったオブジェクトについて、シリアライズが必要か、するとフィールドは含めるかなど、色々考えてみよう。




#### （　・。。・　）🖐
間違っている内容がありましたら、教えて頂ければ喜びます。
Computer Vision tutorial part2

https://www.kaggle.com/code/ryanholbrook/convolution-and-relu

の解説です。
Convolution:畳み込み演算
ReLU:活性化関数

です。
ニューラルネットの理論的支柱を人類はまだわかっていないので、kerasの実装についてのみ書いていきます。

```
keras.Sequential(
```
kerasの層を積み重ねて多層化する


```
tf.image.convert_image_dtype
```

入力画像 image のデータ型を tf.float32 (32ビット浮動小数点数) に変換


```
image = tf.expand_dims(image, axis=0)
```

この行では、image テンソルの先頭 (axis=0) に新しい次元を追加しています。
tf.expand_dims は、テンソルに新しい次元を追加するTensorFlowの関数。
バッチ処理を行う場合、複数の画像をまとめて処理するため、画像データのテンソルは通常、(バッチサイズ, 高さ, 幅, チャネル数) の4次元形状を持ちます。
この行では、元の image が単一の画像データ (例: (高さ, 幅, チャネル数) の3次元形状) であると仮定し、バッチサイズ1のバッチとして扱えるように、先頭に次元を追加しています。


```
reshape（）
```
テンソルの形状を変更する関数。
*kernel.shape は、kernel の現在の形状を展開しています。
バッチ処理および単一出力チャネルの畳み込みに対応できるように、形状を (カーネルの高さ, カーネルの幅, 入力チャネル数, 1) に変更しています。
PowerDNSのAuthorityサーバーのレコードをYAML形式でバックアップする

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

PowerDNSをいろいろセットアップしたりしてきました。

https://qiita.com/ynott/items/27c4f09c1c7f48cc1b0c

https://qiita.com/ynott/items/b128dc7582c4f0b2b44e

https://qiita.com/ynott/items/b1b1d99bcedffa2db571

理由は、Kubernetesクラスターから参照されるDNSサーバーを作りたい。
なぜなら、ExternalDNSで自動的にIngressからレコードを登録させたいから。
なのですが、何だか随分と遠くまで来た気がします(遠い目)。

さて、AnsibleでZoneとレコードを設定できて、バンザーイと思ったのですが意外な伏兵にやられてしまいました。Ansibleの[kpfleming\.powerdns\_auth](https://galaxy.ansible.com/ui/repo/published/kpfleming/powerdns_auth/)は、Zone単位でしか冪等性を保てないということです。

どういうことか？というと、`kpfleming.powerdns_auth`でレコードを登録します。この時に、playbook.ymlに必要なレコードを登録しておけば、問題ありません。

もしレコードが増えても、playbook.ymlに必要なレコードを追加して、Ansibleを実行するだけです。何の問題もありません。

しかし、ここでPowerDNSサーバーにKubernetesクラスターのExternalDNSで自動的に登録されたDNSレコードがあったとしたらどうでしょうか？

「え？別に問題ないでしょ？Playbookファイルに登録されたレコードだけ追加されるんだから」と思うかもしれません。

ここで出てくる問題が、「[kpfleming\.powerdns\_auth](https://galaxy.ansible.com/ui/repo/published/kpfleming/powerdns_auth/)が、Zone単位でしか冪等性を保てない」という部分です。

上記の問題のために、[PowerDNSのZoneとレコードをAnsibleで設定する \#PowerDNS\-Admin \- Qiita](https://qiita.com/ynott/items/b1b1d99bcedffa2db571) では、Playbookファイルのゾーンを更新するために、**以前のZoneファイルを削除**しています。

雑に図示すると以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/cb0b8891-3c16-f14c-570b-d51ee4d8a658.png)

Ansibleでレコードを追加しようとすると、そこで管理されていないレコード(ExternalDNSで自動的に登録されたレコード)が削除されるという鬼畜な状況になります。

じゃあ、どうすればいいかという話になるのですが、どうしようもないのでバックアップする方法をとります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/a03d7694-c96d-a786-d37c-6887c7ce2cd2.png)

# 1. PowerDNSのレコードを取得して、yamlファイルに保存するスクリプト

Ruby言語で作りました。
Gistに保存したので、以下からダウンロードしてください。

https://gist.github.com/ynott/fa33d36f26f0e5c00f69c65564dbb456

実行すると

backup_{zone名}.yaml

ファイルが保存されます。

次工程のAnsibleのタスクに渡したいので必要な情報しか取得しないようになっています。

# 2. まとめ

こちらのRubyスクリプトは生成AIで作ったのですが、ここまで自然言語でスクリプトを組めるのなら、もうローコードツールとか不要じゃね？と思うレベルです。
.htaccessで、.htmlや.phpを付けずにアクセスできるようにする【保存版】

.htaccessの内容に以下を加えてみる。
```sh
# RewriteEngineを有効にする
RewriteEngine On

# .php 拡張子を省略してアクセスできるようにする
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/.]+)$ $1.php [L]

# .html 拡張子を省略してアクセスできるようにする
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/.]+)$ $1.html [L]
```
すると
https://example.com/app.html
でしかアクセスできなかったものが、
https://example.com/app
でアクセスできるようになる！

試す際はバックアップを忘れずに！自己責任で！


## 解説(概要)！
***RewriteEngine On***・・・これは、リダイレクト(書き換え)機能をOn(有効)にするよ～という意味。

***RewriteCond　～　～　（～）***・・・この行は、リダイレクトを、実施するか否かを条件を指定する。ifのような感じ

今回の場合だと、
```sh
%{REQUEST_FILENAME}
```
で、リクエストされたファイル/パスを取得しようとします。
```
!-d
```
で、ディレクトリで***ない***場合（ある場合は -d）、
```
!-f
```
で、ファイルで***ない***場合（ある場合は -f）
これらを組み合わせてここまでの動作がされます。
つまり、リクエストされたものが、 ```「ディレクトリでない」かつ「ファイルでない」場合``` に実行されるのが今回の実装の仕組み＆内容です。

最後に

***RewriteRule***・・・先ほどの条件が満たされた/満たされない場合に、転送する先のURLを示します。今回の場合は、正規化表現ですが、詳しく見ると

少し難しいですが、
.phpと.htmlに分かれているだけで、それ以外の部分は同じです。
正規表現の説明をさせていただきます。(即席のスライドで見づらくて恐縮ですが)
![正規表現解説 Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819700/c2941e48-626d-d83a-c6d6-d82d5d718867.png)
このような形で正規化し、設定します。
```
$1.html(.php) [L]
```
で、$1で、先ほどの正規化部分から取り出し、.htmlや.phpなどの拡張子を付け、リダイレクトをします！


ちなみに、REWRITECONDで、今回は、リクエストされたファイル/パスを取得するために、REQUEST_FILENAMEを使用しましたが、それ以外にもいくつかの変数が使用できます。

https://weblabo.oscasierra.net/apache-rewritecond-base/