OmniAICreator/Qiita-1.07M huggingface dataset:
PDFをWebP形式の画像に変換

# PDFをWebP形式の画像に変換
### GhostScriptを使用した場合

```
> gswin64c -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dPDFSETTINGS=/prepress -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -dMaxStripSize=8192 -sDEVICE=jpeg -r200 -sOutputFile=output.jpg input.pdf
```

一見よさそうだが、PDF内のテキストフォントに問題があると、画像時に文字位置が変な場所にでてきてしまった。

## Pythonを使ってPDFの画像化をする

### pdf2imageを使用するが、popplerが必要とのことで、popplerをダウンロードする
- 最新版のpoppler（poppler-24.06.1.tar.xz）をダウンロードしてきて、展開する
https://github.com/oschwartz10612/poppler-windows/releases
- C:\poppler-24.02.0に配置して、「C:\poppler-24.02.0\Library\bin」にPATHを通す（環境変数のPATHに追加→再起動）

### Pythonにpdf2imageを追加
```
> pip install pdf2image
```

### PDFからJPEGを生成
input.pdfをページごとの0.jpeg,1.jpeg・・・と出力
解像度は、`dpi=300`を指定
`size=(1200, None)`などして、画像サイズでの指定も可能

```pdf2jpg.py
from pdf2image import convert_from_path

def convert_pdf_to_images(pdf_path):
    images = convert_from_path(pdf_path, fmt='jpeg', dpi=300)

    for i, image in enumerate(images):
        image.save(f'{i}.jpeg', 'JPEG')

convert_pdf_to_images('input.pdf')
```

### JPEGからWebPに変換
input.jpegをoutput.webpに変換
```jpeg2webp.py
from PIL import Image

def convert_jpeg_to_webp(jpeg_path, webp_path):
    image = Image.open(jpeg_path)
    image.save(webp_path, 'WEBP')

convert_jpeg_to_webp(f'input.jpeg', f'output.webp')
```

## PDFからWebP形式の画像を生成
input.pdfをページごとの0.webp,1.webp・・・と出力
解像度は、`dpi=300`を指定

```pdf2webp.py
from pdf2image import convert_from_path
from PIL import Image

images = convert_from_path('./input.pdf', dpi=300)

def convert_pdf_to_webp():
    for i, image in enumerate(images):
        image.save(f'{i}.webp', 'WEBP')

convert_pdf_to_webp()
```
【ServiceNow】ユーザーセッション情報を確認できるテーブル

# はじめに
「ServiceNowの使用頻度（ログイン量）を知りたいから調べてくれる？」というお願いをされて、ログインに関するテーブルがないか調べました。

結果、使えそうなテーブルをいくつか見つけたので、備忘としてここにまとめたいと思います。

#### ユーザーセッション[sys_user_session]テーブル
セッションが作成された時間、無効化された時間を確認することができます。
※セッションは、手動でログアウトした場合とタイムアウトした場合に無効化されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335478/3bc8543a-0a04-e0ae-ef45-9f6748809d47.png)

#### ユーザーログイン履歴 [sys_user_login_history]テーブル
ユーザのログイン時刻とログアウト時刻を確認することができます。
ログアウト時刻に値が入っていないレコードは、ログイン中であることを意味します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335478/684ca8e9-a33d-f57d-6c83-4ca68cd227f4.png)

#### ログインユーザー[v_user_session]テーブル
現在ログイン中のユーザーを確認することができます。
:warning:このテーブルは、仮想テーブルです。
:warning:特定のノードのログインしているユーザのみが保存されているため、現在ログインしているすべてのユーザを正確に取得することはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335478/ac6fe064-7d04-60e6-8851-0a3f4b0baf5c.png)

# 補足
#### システムプロパティ[glide.ui.session_timeout]
ユーザーセッションがタイムアウトするまでの時間を設定できます。
デフォルトでは30分となっています。

https://docs.servicenow.com/ja-JP/bundle/washingtondc-platform-administration/page/administer/user-sessions/concept/c_ManageUserSessions.html#title_t_TerminateASpecificUserSession

#### ログイン/ログアウト時にキックされるイベント
ログイン時には以下２つのイベントがキックされます。
・login
・session.established

ログアウト時には、以下１つのイベントがキックされます。
・logout
※セッションタイムアウトのタイミングでは、イベントはキックされません。

# おわりに
本記事では、ユーザーセッション情報を確認できるテーブルについてまとめました。
今誰がログインしているのか、毎日どのくらいの人がログインしているのか、ログイン頻度などを確認するのに使えると思います。

是非ご活用ください。
Sponsored by: LTIMindtree | 7 DBRX Hacks No One Told You About! のまとめ

## 誰にも教えてもらえなかった DBRX の 7 つのハック

### はじめに
* データブリックスが主催するデータとAIのサミットにて、LTI Mindtree のグローバルバイスプレジデント、インディバー・ネイヤー氏が DBRX に関するセッションを実施。
* 顧客実装の視点から、データブリックスおよび MozaicAI 関連の経験について共有。

### LTI Mindtree と生成AI市場
* LTI Mindtree は、データブリックスのエリートコンサルティングパートナーであり、今年の「年間最優秀トランスフォーメーションパートナー」に選出。
* 組織は顧客のビジネス成果を増幅するために、データとAIに注力。
* 生成AI市場は急速に成長しており、今後数年で2000億ドルを超える規模に到達すると予測。

### ユースケース：世界最大のエレベーター会社のフィールドオペレーション
* 世界最大のエレベーター会社における、フィールドオペレーションのテクニカルサポート改善のためのユースケースを紹介。
* プロジェクトを通して得られた7つの重要な観察結果を共有。

#### 7つの観察結果
1. **DBRX の多用途性:** ユースケースの作成だけでなく、ユースケース作成のステップにも活用可能。データパイプライン構築や Kafka コード作成などを DBRX によって自動化できる。
2. **データ理解の重要性:** センサーピングデータなど、メタデータが不足しているデータの理解には課題が存在する。DBRX を使用することで、入力データの理解を深めることができる。
3. **予測メンテナンスを超えて:** 従来の予測メンテナンスに加え、解決時間短縮、修正率向上、設置時間短縮など、フィールドサービス担当者支援のためのソリューション開発にも注力。
4. **生成AI の基盤:** 生成AI ソリューションを効果的に活用するには、スケーラブルで堅牢な基盤が不可欠。
5. **データから意思決定へのライフサイクル:** 生成AI は、ドッグフーディングのように、データプロフェッショナルの作業を加速させるのに役立つ。
6. **多言語サポート:** 複数言語サポートにより、グローバルな組織においても、それぞれの言語で情報にアクセスすることが可能に。
7. **ナレッジグラフの活用:** 機器マニュアルの情報をナレッジグラフとして構造化することで、フィールドサービスチームは問題を迅速にトラブルシューティングすることが可能に。

### DBRX による効果的なソリューション開発
* DBRX を活用することで、短期間（3週間半）でソリューションを実装可能。
* 従来型の RAG ベースの手法だけでなく、DBRX のベースモデルやインストラクトモデルを活用することで、より効率的な開発が可能に。

### DBRX のその他の利点
* データ保護: DBRX を使用することで、機密情報の保護を強化できる。
* 多言語対応: さまざまな言語での質問が可能に。
* 知識グラフの活用: 機器間の関係性を理解し、より効果的なトラブルシューティングを実現。

### まとめ
* DBRX はデータとAIの取り組みを加速させる強力なツール。
* LTI Mindtree は、DBRX と MozaicAI を活用した5つの無料パイロットプログラムを提供。

### Databricks Champion からのコメント
Databricksの Foundation モデル（DBRX、Llama、MPT等）は Foundation Model API を利用することで容易にカスタムモデルを作成することができます！この機能を利用し、社内独自の生成AIの実験へのハードルはかなり下がったのではないでしょうか。

---
2024年6月10日~13日にサンフランシスコおよびオンラインにて開催されるDatabricks社主催の年間最大規模のカンファレンスイベント、「Databricks Data＋AI Summit 2024」が開催中！
ナレッジコミュニケーションではイベント開催に伴い、「生成AIの最新トレンドと業界別ビジネスインパクト」をコンセプトに最新アップデート情報やセッションレポートをお届けする特設サイトを公開しておりますのでぜひチェックしてください！

https://www.knowledgecommunication.jp/product/databricks-data-ai-summit-2024.html
picoMini by redpwn writeup spelling-quiz

## spelling-quiz (Cryptography)

I found the flag, but my brother wrote a program to encrypt all his text files. He has a spelling quiz study guide too, but I don't know if that helps.

添付ファイル
・public.zip

zipファイルの中に暗号化スクリプト、暗号化されたフラグ、ディクショナリが入っていた。
とりあえず、暗号化されたフラグをROT13でデコードするが、意味のある文字列が出てこなかった。
おそらく、ホームズに出てくる、文字やパターンの出現頻度・傾向から解読するタイプの暗号(換字式暗号)であろう。
暗号化スクリプトを見ても換字式暗号で間違いないようだ。
```python
alphabet = list('abcdefghijklmnopqrstuvwxyz')
random.shuffle(shuffled := alphabet[:])
dictionary = dict(zip(alphabet, shuffled))
```
ディクショナリがあるため、文字の出現頻度解析をしてくれるツールを使う。
出現頻度分析から以下のようになった。

|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
|S|P|R|G|W|H|K|J|O|Q|Z|L|D|C|U|V|Y|E|M|N|B|T|I|A|F|X|

表の通りに暗号化されたフラグの文字列を変換すると意味のある文字列が出てきた。
これをフラグの形式になおす。

`picoCTF{perhaps_the_dog_jumped_over_was_just_tired}`
【PostgreSQL】メタコマンド〜\gdesc〜

## 初めに

Qiita Engineer Festa 2024に参加中。完走目指してます。

他のメタコマンドについては以下から読んでください。

[【PostgreSQL】メタコマンドを纏めていく](https://qiita.com/dai_chi/items/04f5339d54130f070671)

## \gdescとは

> 現在の問い合わせバッファの結果の説明（列名とデータ型）を表示します。 問い合わせは実際には実行されませんが、ある種の構文エラーが含まれている場合、そのエラーは通常の方法で報告されます。
> 
> 
> 現在の問い合わせバッファが空の場合、直近に送った問い合わせの説明が代わりに出力されます。
> 

[\gdesc](https://www.postgresql.jp/docs/15/app-psql.html#:~:text=%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,%5Cgdesc,-%E7%8F%BE%E5%9C%A8%E3%81%AE%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B)

## 試してみた

### 事前準備

```sql
-- 顧客テーブルの作成
CREATE TABLE customers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

-- 製品テーブルの作成
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    price NUMERIC(10, 2) NOT NULL
);

-- 注文テーブルの作成
CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_id INT NOT NULL,
    product_id INT NOT NULL,
    order_date DATE NOT NULL,
    quantity INT NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES customers(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
);
```

簡単なデータの投入

```sql
-- 顧客データの挿入
INSERT INTO customers (name) VALUES
('Alice'),
('Bob'),
('Charlie');

-- 製品データの挿入
INSERT INTO products (name, price) VALUES
('Product A', 10.00),
('Product B', 20.00),
('Product C', 30.00);

-- 注文データの挿入
INSERT INTO orders (customer_id, product_id, order_date, quantity) VALUES
(1, 1, '2023-01-01', 2),
(1, 2, '2023-01-01', 1),
(2, 1, '2023-01-02', 1),
(3, 3, '2023-01-03', 3);
```

### \gdescを試す

まずは通常通りにクエリを実行する

```sql
SELECT 
    c.name AS customer_name,
    o.order_date,
    p.name AS product_name,
    p.price,
    o.quantity,
    (p.price * o.quantity) AS total_price
FROM 
    orders o
JOIN 
    customers c ON o.customer_id = c.id
JOIN 
    products p ON o.product_id = p.id;
 customer_name | order_date | product_name | price | quantity | total_price 
---------------+------------+--------------+-------+----------+-------------
 Alice         | 2023-01-01 | Product A    | 10.00 |        2 |       20.00
 Alice         | 2023-01-01 | Product B    | 20.00 |        1 |       20.00
 Bob           | 2023-01-02 | Product A    | 10.00 |        1 |       10.00
 Charlie       | 2023-01-03 | Product C    | 30.00 |        3 |       90.00
(4 rows)
```

\gdescを使う

```sql
SELECT 
    c.name AS customer_name,
    o.order_date,
    p.name AS product_name,
    p.price,
    o.quantity,
    (p.price * o.quantity) AS total_price
FROM 
    orders o
JOIN 
    customers c ON o.customer_id = c.id
JOIN 
    products p ON o.product_id = p.id \gdesc
    Column     |          Type          
---------------+------------------------
 customer_name | character varying(100)
 order_date    | date
 product_name  | character varying(100)
 price         | numeric(10,2)
 quantity      | integer
 total_price   | numeric
(6 rows)
```

使い方としてはクエリの結果として求めたカラムで返ってくるかを見てるのか？

## まとめ

試しに触ってみたけど、いまいち使い勝手がよくわからなかった。

記事を探してみてもこれといった情報がなくて、どんな時に活用されるコマンドなのだろうか。。
iOSアプリでのQR読み取りの記事メモ

# リンク

https://zenn.dev/jollyjoester/articles/a053d4e25523b6

https://qiita.com/KokumaruGarasu/items/e49030098d92f9eba40e

https://qiita.com/Ryu0118/items/4ee5c67558476c22318d
Markdownのリンクを別タブで開くようにする


Markdown で書いたドキュメントのリンクから別タブで開くようにするための処理を書いていきます。


## Markdown を表示する

index.html に JavaScript を使って Markdown を表示します。

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <!-- head -->
  </head>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
    <script>
      const markdown = `
## Markdown ドキュメント

### リンク一覧

[私のQiita](https://qiita.com/diskszk)  
[私のGitHub](https://github.com/diskszk)
`;

      (function () {
        const div = document.createElement("div");
        div.innerHTML = marked(markdown);
        document.body.appendChild(div);
      })();
    </script>
  </body>
</html>
```

index.html ファイルをブラウザで開くと Markdown を表示していることが確認できます。

![screenshot 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639130/f1a00a91-1946-ac21-8cd3-6e2ce71adfea.png)

developer tool で確認すると、当然 href 属性しか設定されていません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639130/d63a175a-d527-71b8-0fcb-324cfc709b68.png)

## aタグに属性を追加する

リンクをクリックした時に別タブで開かせたいので、 a タグに `target="_black"` と `rel="noopener noreferrer` の属性を追加する処理を書いていきます。

``` html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <!-- head -->
  </head>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
    <script>
      const markdown = `
    <!-- markdown の内容 -->
`;

      (function () {
        const div = document.createElement("div");
        div.innerHTML = marked(markdown);
        document.body.appendChild(div);
      })();

+      document.addEventListener("DOMContentLoaded", function () {
+        const links = document.querySelectorAll("a");
+        links.forEach(function (link) {
+          link.setAttribute("target", "blank");
+          link.setAttribute("rel", "noopener noreferrer");
+        });
+      });
    </script>
  </body>
</html>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639130/027ce529-d3dc-ea27-a027-5abc620f6c13.png)

これでリンクをクリックした時に別タブで開くようになりました。

## 参考
https://webitworks.jp/target_blank_noreferrer_noopener/

https://rubirubi.hateblo.jp/entry/how-to-target_new_blank-in-markdown-and-open-a-link-in-a-separate-window
Vue勉強 watch のdeepオプション

(Vue.js 3.1.5を使用)
#### 監視プロパティwatch の deepオプションについて。
deepオプションをtrueにしないと、
監視対象のデータのネストが深い場合には監視されない。
(オプション書かない場合、デフォルトがfalse）

```javascript:javascript
const app = Vue.createApp({
    data: () => ({
        prefs: [
            {name: '青森'},
            {name: '秋田'},
            {name: '岩手'},
            {name: '山形'},
        ]
    }),
    watch: {
        prefs: {
            handler: function(newValue, oldValue){
                console.log('Update!')
            },
            deep: false //prefs.nameはネストが深いため、ここをtrueにしないと、watchのhandlerで検知できない。
        },
    },
    methods: {
        onClick: function(event){
            this.prefs[0].name = '熊本' 
            this.prefs[2].name = '大分' 
        }
    },
})

app.mount('#app')

```

```html:html
    <div id="app">
      <ul>
        <li v-for="pref in prefs">
          {{ pref.name }}
        </li>
      </ul>
      <button v-on:click="onClick">Click!</button>
    </div>
```

## watch のdeepオプションfalseの場合
上記コードのこの行のdeepオプションをfalseにする。(deepオプション書かない場合も、デフォルトでfalseになる。)
```javascript:javascript
            deep: false //prefs.nameはネストが深いため、ここをtrueにしないと、watchのhandlerで検知できない。
```
<b>ボタン押す前</b>
![deep_true_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/5d5c5752-e5f4-46c2-346d-242474112e6f.png)

ボタンをクリックすると、
メソッドでのonClickで、（青森、岩手）が、（熊本、大分）に変わるが、
watchが反応せず、コンソールには何も表示されない。

<b>ボタン押したあと</b>
![deep_false_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/50e9a028-77f3-3dae-3d3f-c3e5096b24a8.png)

## watch のdeepオプションをtrueにする場合
上記コードのこの行のdeepオプションをtrueにする。
```javascript:javascript
            deep: true //prefs.nameはネストが深いため、ここをtrueにしないと、watchのhandlerで検知できない。
```
<b>ボタン押す前</b>
![deep_true_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/5d5c5752-e5f4-46c2-346d-242474112e6f.png)

ボタンをクリックすると、
watchが機能して、コンソールにUpdate!と表示される。

<b>ボタン押したあと</b>
![deep_true_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/14b9bfcd-cdfb-b023-b346-d661e0405577.png)
【2024年6月版】Ubuntu24.04で作る簡単Linuxルーター


# はじめに

Ubuntu24.04でも、Linuxルーター構築したいな

# 環境

- Ubuntu24.04
- インターネット側インターフェイス `ens33`
- 内側インターフェイス `ens36`

# 構築

## ルーターとしての設定を保存するコマンドをインストール

```terminal
$ sudo apt-get install iptables-persistent
```

## パッケットのフォワードができるようにカーネルパラメータを設定

```terminal
$ echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
net.ipv4.ip_forward = 1
```

## ルーターとして動作するように `iptables` を設定

```terminal
# 出口側のインターフェイス名を取得する
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
    altname enp0s33
 :
 :
```

```terminal 
# NAPT(IPマスカレード)の設定
# ens33はでぐちがインターフェイス名なので、環境に合わせる
$ sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
```

## 設定を永続化

これがないと再起動で初期化されてしまう。

```terminal
$ sudo sh -c 'iptables-save > /etc/iptables/rules.v4'
```

# さいごに

かんたんでしたね
Riverpodの再利用備忘録

# pubspec.yaml
```
dependencies:
    riverpod_annotation: ^2.3.5
    freezed_annotation: ^2.2.0
    json_annotation:

dev_dependencies:
    flutter_riverpod: ^2.5.1
    riverpod_generator: ^2.4.0
    riverpod_lint: ^2.3.10
    freezed: ^2.4.7
    json_serializable: 
    build_runner:
    
```

# プロバイダーを定義(image_provider.dart)
上に追加
```
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'image_provider.freezed.dart';
part 'image_provider.g.dart';//json使わなくてもいる
```
保存したいデータのクラス
```
@freezed
abstract class ImageInfo implements _$ImageInfo {
  const ImageInfo._(); //プライベートコンストラクタ freezedで自分のメソッドを追加するために必要
  const factory ImageInfo({
    required int width,
    required int height,
  }) = _ImageInfo;
  factory ImageInfo.fromJson(Map<String, Object?> json) =>
       _$ImageInfoFromJson(json);//JSONから生成を可能にする場合
}

@freezed
abstract class MagimageInfo implements _$MagimageInfo {
  const MagimageInfo._();
  const factory MagimageInfo({
    required List<ImageInfo> imageInfoList,
  }) = _MagimageInfo;

  ImageInfo getImageInfo(int index) {
    return imageInfoList[index];
  }
}
```
RiverPodのNotifier作成
```
@Riverpod(keepAlive: true)
class MagimageInfoNotifier extends _$MagimageInfoNotifier {
  @override
  MagimageInfo build() {
    print("初期化");
    return const MagimageInfo(
      imageInfoList: [],
    );
  }

  void setImageInfoList(List<ImageInfo> infoList) {
    state = state.copyWith(imageInfoList: infoList);
  }

  void setImageInfo(ImageInfo info, int index) {
    List<ImageInfo> list = state.imageInfoList;
    list[index] = info;
    state = state.copyWith(imageInfoList: list);
  }
}

```
main関数にスコープの追加
```
void main() {
  runApp(const ProviderScope(child: MyApp()));
}
```
Beautiful Soupを使ってWebスクレイピング

前回の記事では、PythonのRequestsライブラリを使ってウェブデータを取得する方法を記載しました。
今回は、取得したウェブデータを解析するためのライブラリ「Beautiful Soup」の基本的な使い方について記載します。

#### Beautiful Soupのインストール

まず、Beautiful SoupとRequestsライブラリをインストールします。
以下のコマンドを実行してください。

```bash
pip install beautifulsoup4 requests
```

#### Beautiful Soupの基本的な使い方

##### 1. ウェブページの取得

Beautiful Soupを使うためには、まずウェブページの内容を取得する必要があります。
これには前回紹介したRequestsライブラリを使います。

```python
import requests
from bs4 import BeautifulSoup

# URLの指定
url = 'https://example.com'

# ウェブページの内容を取得
response = requests.get(url)

# ステータスコードが200（成功）の場合のみ解析を実行
if response.status_code == 200:
    html = response.content
else:
    print('Failed to retrieve the webpage')
```

##### 2. HTMLの解析

取得したHTMLをBeautiful Soupを使って解析します。
解析のためにBeautifulSoupオブジェクトを作成します。

```python
# BeautifulSoupオブジェクトの作成
soup = BeautifulSoup(html, 'html.parser')

# HTMLの整形表示
print(soup.prettify())
```

##### 3. 要素の抽出

Beautiful Soupを使うと、特定の要素を簡単に抽出できます。
ここでは、タイトルタグ（`<title>`）の内容を抽出してみます。

```python
# タイトルタグの抽出
title_tag = soup.title

# タイトルの文字列を取得
title = title_tag.string
print(f"ページタイトル: {title}")
```

次に、任意のタグやクラスを持つ要素を抽出する方法を紹介します。
例えば、すべてのリンク（`<a>`タグ）を抽出します。

```python
# すべてのリンクを抽出
links = soup.find_all('a')

# リンクの表示
for link in links:
    href = link.get('href')
    text = link.string
    print(f"リンクのテキスト: {text}, URL: {href}")
```

##### 4. 特定のクラスやIDを持つ要素の抽出

特定のクラスやIDを持つ要素を抽出することも可能です。
例えば、特定のクラスを持つ`<div>`タグを抽出してみます。

```python
# 特定のクラスを持つ<div>タグの抽出
divs = soup.find_all('div', class_='example-class')

# 抽出した要素の表示
for div in divs:
    print(div.prettify())
```

同様に、特定のIDを持つ要素を抽出することもできます。

```python
# 特定のIDを持つ要素の抽出
element = soup.find(id='example-id')

# 抽出した要素の表示
print(element.prettify())
```

##### 5. Beautiful Soupの便利な機能

Beautiful Soupには、他にも便利な機能が多数あります。
例えば、子要素や親要素の取得、隣接要素の取得などです。

```python
# 子要素の取得
children = element.find_all('li')

# 子要素の表示
for child in children:
    print(child.string)

# 親要素の取得
parent = element.parent
print(parent.prettify())

# 次の兄弟要素の取得
next_sibling = element.find_next_sibling()
print(next_sibling.prettify())
```

以上

---

### 前回

https://qiita.com/benjamin1gou/items/2cb051871ce87056d2ab
無料RDBサーバーレスサービスまとめのまとめ

無料RDBサーバーレスサービスまとめのまとめ

https://egashira.dev/blog/free-rdb-services-2023

Citus
https://www.postgresql.jp/sites/default/files/2021-11/PostgreSQL_Conference%202021_B2_pub_20211112-1.pdf


https://qiita.com/tomozilla/items/0edb7a277c80804102cf


Aiven
https://qiita.com/tomozilla/items/0edb7a277c80804102cf

cockroachDB
https://www.cockroachlabs.com/pricing/
[AWS #3] Well-Architected フレームワーク

## はじめに
今回は **「AWS Well-Architected フレームワーク」** について紹介いたします。
:rolling_eyes:うぇーる　あーきてくてっど？

簡単にまとめると
AWSとそのパートナー各社がシステム設計と運用の経験から得た知見を、**6つの柱**に基づいてまとめた<font color=red>**ベストプラクティス集**</font>です。
## ベストプラクティスとは？
ベストプラクティスとは<font color=red> **「問題解決をするための最善の方法」** </font>です。
この「Well-Architected フレームワーク」はAWSを導入した企業のシステム評価のベストプラクティスや、そのシステムがAWsのベストプラクティスにどれだけ準拠しているかを**評価する質問集をまとめたもの**です。

:::note info
自社のシステムがAWSの**最善にどれだけ近いか**判断できます
:::

## AWS Well-Architected Tool
質問に答えるだけでAWSのベストプラクティスと比較してくれるサービスです。

:rolling_eyes:一体**どんな時に使えば良い**んですか？

:upside_down:AWSを**設計・構築する時**や**運用している期間**など**様々なフェーズで活用する**ことができます。
:rolling_eyes:へぇーこのフレームワークは**いつでも使って良い**んですね。

システムの運用を開始してから問題が発生するよりも先に※**顕在化させておくこと**で手戻りが少なく済みます。
※顕在化：潜んでいたことがはっきりと表面にあらわれる、または形としてあらわすこと

:::note info
Well-Architected Toolを使ってこまめにチェックすることは**後々の効率化**にも繋がる
:::

:rolling_eyes:じゃあこれを使ってどんどんベストプラクティスを見つけていけば良さそうですね

:upside_down:と言いたいんだけど、システム的なベストプラクティスは必ずしも**ビジネス的な最善ではない**すな
<br>
コストやスピード、<font color=red>**ビジネス的に優先される方が大切**</font>です。
あくまで **「ビジネス的な判断」をするための一つの材料**ということになります。

:::note warn
システムの最善とビジネスの最善は**異なります**
:::

## 6つの柱
AWS Well-Architected フレームワークを参照する際に、テーマごとに分けられた「６つの柱」を確認します。この6つの柱を意識すれば**安定的・効率的なシステム構築が可能**になります。
### ①オペレーショナルエクセレンス（運用上の優秀性）
「オペレーション」
どうやったら上手に操作できるか？
どうやったら沢山のコンピューターをデプロイ、配備、利用できるのか？
…と言われる観点のことです。

日々の作業の手順ミスが業務処理に大きな影響を与えることもあります。

:::note info
サポートプロセスを継続的に改善し、**問題を回避する能力**を目指します
:::
---

### ②セキュリティ
「配備したコンピュータ群、沢山のコンピュータを便利に使えるようになりました～」
ではそれを **どう安全に使うのか？** という事に関して、ヒントや方法を提供しています。

:::note info
データとシステムの**保護に対する施策が中心**となっています。
:::
---

### ③信頼性の柱
ざっくり言うとそれを **どう確実にずっと安定して使用できるのか？** という方法を提示しているものです。

一例として図を作成してみました。
![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/2b99e11f-669a-4dba-c345-a8590cf27e86.png)
バックアップを沢山取っておくのも一例になるかと思います。

:::note info
期待通りの機能を実行するワークロードと、要求に応えられなかった場合、**迅速に回復する方法が中心**となっています
:::
---

### ④パフォーマンス効率の柱
ITおよびコンピューティングリソースの構造化と、リソースの**合理的な割り当てが中心**となっています。

![AWS_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/bf2cde6f-54b0-1883-4f97-7a5acf11bd75.png)

:::note info
**「長期的に」** **「持続的に」** パフォーマンスを発揮するために**蓄積した知恵を与えてくれる**ものです
:::
---

### ⑤コスト最適化の柱
**不要なコストの回避に重点を置いています。**
継続的にコストを抑えながら最新のアーキテクチャを構築する方法が説明されています。
![AWS_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/c9665e22-5616-8b0d-cd9d-746cf412f6d1.png)

:::note info
ニーズに合わせた**ご利用料の見直しや最適化をご提案**します
:::
---

### ⑥持続可能性の柱
最後は持続可能性です。環境への影響や、エネルギーの消費・効率性に注目して、**リソースへの使用量を低減するアーキテクト**を提示しています。

:::note info
持続可能性を守ることで、お客様のビジネスが環境、経済、社会に与える**長期的な影響を解決**します。
:::

## おわりに
今回紹介した6つの柱は試験にも出る内容とのこと。それぞれの柱がどんなものだったかをイメージできるように理解していきたいと思います。
最後までお読みいただきありがとうございました！

>日頃より活用している参考書です。
>> **「参考書」**
[AWS認定クラウドプラクティショナー改定第3版](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[Well-Architected](https://x.gd/OVLiK)
>
> **「Youtube」**
[【2分で解説！AWS初心者向け】AWSのベストプラクティス AWS Well-Architected フレームワークとは？【クラウドプラクティショナー】](https://x.gd/C1BQE)
マイクラで遊ぶために全力で技術習得した話

## マイクラを始めるきっかけ
今から三年前、新卒で企業に勤め初めてからというもの、友達と交流する機会が減り、「自然と皆が集まる場所」を欲していた。

当初はコロナ禍ということもあり「オンライン飲み会」が世間では流行っていたが、僕らの周りでは全く流行っていなかった。というか、主に自分が苦手だった。（オンライン飲み会って、話題を作るのが難しいよね…。）

オンラインで自然に交流が持てるのはやはり「ゲーム」になる。

ゲーム選定では
- 何人来ても楽しめる
- ゲーム内で他の人が来るまでの待機時間が退屈でない
- みんな持ってる

という感じで皆さんお馴染みの「マインクラフト」をすることに。

## 自分のPCをホストに皆でマイクラしてみた話
マインクラフトを通信で遊ぶのには「自分でサーバーを用意する」か「マルチサーバーを月額契約」する必要がある。

自分でサーバーを用意する場合には何通りか方法があるが、最初は「自分のPCにサーバーを作って、ポート解放で皆がアクセスできるようにする方法」を選んだ。
これはかなり簡単で、色々なサイトでやり方が紹介された。

サクサクと設定して（サーバーの公開とかで何度かつまづきながらも…）遊ぶことができた。

しかし、このやり方にはいくつかデメリットがあった。
- 自分がいない時は皆マイクラが進められない
- 自分の通信環境が悪いと皆のマイクラもラグる
- 自分のPCが重くなる

「自然と皆が集まる場所」を実現させるには特に一つ目が肝心で、誰でも気が向いたタイミングで来てられるところを作りたい気持ちが強かった。

そして後日、別の方法を模索することに。

## クラウドサーバーにマイクラサーバーを建てた話
マルチサーバーの契約は金額が高い上、面白くないなと感じた。
そこで、当初流行りのクラウドサーバーに目をつけるに至った。

「無料で使える」「ネット上にナレッジが沢山ある」ということを聞いて、クラウドサーバーにはAWSを選んだ。

クラウドサーバーはとにかく最初の設定がめんどくさい！

ということで、本来は色々設定しなきゃいけないこと（IAMやCost Managementとか）をすっ飛ばしクラウドサーバーを作成。
（良い子は真似しないでね！）

EC2（仮想サーバー）を新規作成、環境を設定したら、ローカルにあるマイクラサーバーをポン！

## これで完成…？
他にも後から色々と設定して皆で快適に遊べるようにまでした、が
これではクラウドにした意味がない！金がかかりすぎる…。

と言うのも、クラウドサーバーの長所は使っていない時にシャットダウンすれば、お金がかからないところ。
ずっと使っていたら、無料枠からはみ出してしまう！

実際のところ、無料枠ではマイクラのカクツキが酷く、ちょっといい構成で作っていたので、コスト削減は急務だった。

## 誰かがいるタイミングだけ起動する仕組み作り
と言うことで、何かないかと調べてみるといい記事を発見。
それはDiscordを使ってEC2のインスタンスのON/OFFを切り替えられるというもの。

ゲーム友達とはDiscordでやり取りしていた身としては、なんともちょうど良かった。

実装にはかなり苦戦して1週間くらいかけ、マイクラそっちのけで作業していた。これを人は本末転倒という。

DiscordBOTとEC2を何やかんやで連携させ、ついにインスタンスをDiscordから操れるように！

他にもマイクラとDiscordのチャットが双方向へ送られるようにして、マイクラに参加していなくてもマイクラしているメンバーと楽しみを共有できるようにもした。

## オチ
実用的なシステムを作ったのは初めてだったので、全てを完璧に仕上げた達成感は凄まじかった。
賞賛されなくとも、皆が楽しく遊んでくれるなら幸せだなと…。

参加していたのは5人。
2ヶ月後、マイクラに自分以外の姿はなくなっていた…。

↓自分で調べたくない人向け
（おそらく当初見たものとは違うけど、大体同じことやってると思う）
https://zenn.dev/nacal/articles/e7f0d481661ec0
https://riminosu13.hatenablog.com/entry/2020/08/04/005220
爆速で静的WEBをHTTPSホスティングする方法

# はじめに
この記事では、プロトタイプ開発した静的WEBページを爆速でHTTPSホスティングする方法を紹介します。
静的WEBページを第三者に見せたい方や、HTTPS化が必須の機能の動作検証（位置情報の取得、カメラ・マイクアクセスなど）を行いたい方に役立つ情報です。
ホスティング方法としては、GitHub PagesとNetlifyを取り上げます。

# こんな人に読んでほしい
・プロトタイプの静的WEBページを第三者に見せたい方
・HTTPS化が必須の機能の動作検証を行いたい方

# GitHub Pagesを使ったホスティング
GitHub Pagesは、GitHubから提供されている静的サイトのホスティングサービスです。
無料で利用できるため、プログラミング学習や個人プロジェクトの公開に向いています。

1.Githubアカウント作成
GitHubのアカウントを作成します。下記URLから手順に従ってアカウントを作成してください。
https://docs.github.com/ja/get-started/start-your-journey/creating-an-account-on-github

2.repository作成
repository名は任意ですが、公開範囲はデフォルトのPublicのままとし、「Create repository」ボタンを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/812d4332-cfb9-0de2-9226-99f68e610c9f.png)

3.repositoryにソースを登録
ホスティングしたいソースを作成し、repositoryに登録します。
今回はカメラ起動するだけの下記サンプルコードを使用します。
```ruby:index.html
<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset='utf-8/'>
</head>
<body>
  <input type="file" capture="user" accept="image/*">
</body>
</html>
```
localhostで起動するとブラウザに下記が表示されます。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/bfdf7798-6794-51e6-7267-d8d067bc376f.png">

「ファイルを選択」ボタンを押すとするとファイルピッカーが表示されます。
(HTTPS化されていないのでカメラは起動しません)

4.Pages作成
Setting-PagesでBranchをmainに変更し、「Save」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/2e0f8661-49e4-7be5-c1c7-1ee9c5c427f1.png)

しばらくしてリロードするとURLが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/43d04796-d0dc-5e82-d29a-2049e1b999e1.png)
このURLをブラウザで開き、「ファイルを選択」ボタンを押すとするとカメラが起動します。

# Netlifyを使ったホスティング
Netlifyは、静的サイトをホスティングすることができるWebサービスです。
WordPressなどの動的な処理のいらないLPなどの静的なWebサイトであれば、Netlifyを通じて公開することができます。
無料で使用でき、SSLやGitHubとの連携も簡単にできます。
アプリ開発者にとって便利なWebサービスです。

今回は爆速をテーマにしているのでGithubを使用しないでホスティングする手順を紹介します。

1.Netlifyアカウント作成
下記Netlifyのサイトからアカウントを作成してください。
https://www.netlify.com/

2.ソース登録
Team overviewから「Add new site」-「Deploy manually」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/76dd57e1-5138-f383-2e71-1474c841bb42.png)

下記画面が表示されるので先ほどのindex.htmlの親フォルダをDrag and dropします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/49995702-46da-267d-fe86-0d988208e382.png)

Site overviewに作成したURLが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/1d72d82e-524d-1f67-f7f2-8309e9ccc2b0.png)


# 最後に
いかがでしたでしょうか。GitHub PagesやNetlifyを使用することで、簡単かつ迅速に静的WEBページをホスティングし、HTTPS化することができます。
どちらのサービスも使いやすく、無料で提供されているので、プロトタイプの公開や機能のテストに最適です。ぜひ、お試しください。
Rocky Linux 9を日本語化する

# What's？

タイトルどおり、Rocky Linux 9を日本語化するためのメモです。

# 環境

今回の環境はこちら。

```shell
$ cat /etc/redhat-release
Rocky Linux release 9.4 (Blue Onyx)


$ uname -srvmpio
Linux 5.14.0-427.20.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Jun 7 14:51:39 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

作業前のロケールおよびタイムゾーン。

```shell
$ localectl
System Locale: LANG=en_US.UTF-8
    VC Keymap: us
   X11 Layout: us


$ timedatectl
               Local time: Fri 2024-06-14 03:57:49 UTC
           Universal time: Fri 2024-06-14 03:57:49 UTC
                 RTC time: Fri 2024-06-14 03:57:49
                Time zone: UTC (UTC, +0000)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: yes

```

ここから、日本語化していきます。

# ロケールを日本語にする

glibc-langpack-jaをインストールしてから

```shell
$ sudo dnf install glibc-langpack-ja
```

ロケールを日本語に変更。

```shell
$ sudo localectl set-locale LANG=ja_JP.utf8
```

確認。

```shell
$ localectl
System Locale: LANG=ja_JP.utf8
    VC Keymap: us
   X11 Layout: us


$ cat /etc/locale.conf
LANG=ja_JP.utf8
```

キーマップも変えておきましょう。日本語系のキーマップを確認。

```shell
$ localectl list-keymaps | grep jp
jp
jp-OADG109A
jp-dvorak
jp-kana86
jp106
```

今回は、jp106にしておきます。

```shell
$ sudo localectl set-keymap jp106
```

確認。

```shell
$ localectl
System Locale: LANG=ja_JP.utf8
    VC Keymap: jp106
   X11 Layout: jp
    X11 Model: jp106
  X11 Options: terminate:ctrl_alt_bksp
```

# タイムゾーンをAsia/Tokyoにする

タイムゾーンを`Asia/Tokyo`に変更。

```shell
$ sudo timedatectl set-timezone Asia/Tokyo
```

確認。

```shell
$ timedatectl
               Local time: Fri 2024-06-14 13:02:47 JST
           Universal time: Fri 2024-06-14 04:02:47 UTC
                 RTC time: Fri 2024-06-14 13:02:47
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: yes

```

# 日本語言語パックのインストール

langpacks-jaをインストールします。

```shell
$ sudo dnf install langpacks-ja
```

# まとめて

まとめて書くと、こんな感じですね。

```shell
#!/usr/bin/bash

# locale & keymap
sudo dnf install -y glibc-langpack-ja
sudo localectl set-locale LANG=ja_JP.utf8
sudo localectl set-keymap jp106

# timezone
sudo timedatectl set-timezone Asia/Tokyo

# lang pack
sudo dnf install -y langpacks-ja
```
スクラムイベントからわかる、うまくいくスクラム・うまくいかないスクラム

## 一旦、衝撃的なタイトルね
引きを強めに、語彙も強めに。そしてトーンダウンしていくよ。
POとかPO近くのお手伝い（うちではPOリードって呼ぶよ）を数やってると、これはよかったスクラム、悪かったスクラムってあるよね。それをまとめてみようかなって。

## 方法論ではなく、結果論として。
アンチパターンとか●●すべき論とか、そんな難しいこと言うつもりはない（責任持たん）ので、こういう運営されてたらうまくいってないんだなーって状況の予見集くらいに。
ということで、あれはうまくいく前兆だったな、とか、やっぱりあの時あんな雰囲気だったのがまずかったよなーとか考えながらまとめてみました。
決して、これでうまくいってないのわかったからうまくいく方の**やり方を強制する**みたいな使い方はしないでね。表層でなく、もっと根本の原因の追及・解決が基本です。

## デイリースクラム（スタンディング）
### うまくいく
- 会の長さがまちまち。議論長いときは長いが、短いときは即解散
- Devメンバーが仕切りだす、話したがる。SMはタイムキーパー専念
- POはその場にいたりいなかったり
- よほどのことがない限りは開催される

### うまくいかない
- 会の長さは決まっている。議論があっても時間でバッツリ切るし、議論が無くても無理やり話させる、あるいは当番制
- スクラムマスターが進行するが、他メンバーは当てないと話さない
- POが来ない、または、PO毎回出席（義務）になっている
- でもPOは話さない
- たまに開催自体が無い、今日のメンバーの集まり次第でなんとなく開かないことがある

## 開発・ペアプロ・モブプロ中
### うまくいく
- 時間決めて交互に開発が続いている
- たまに特定の人が呼ばれてちょっと抜けてもコーディングは続く
- POにうざ絡みされてもいなすDEVメンバー
- POにうざ絡みし返すDEVメンバー

### うまくいかない
- 機能説明が特定の人しかできない
- それなのに一人でプログラミングし続ける
- 抜けると進まないので休憩に入る、代わりの何かはしない
- POは開発と絡まない、遠くで邪魔しないようにする（強いられている）

## リファインメント
### うまくいく
- 基本、全部は終わらないが、次に持ち越せる
- 本当に足りなかったら臨時開催を誰かしらから提案される
- PBIはPOが作り、SMが清書する、DEVはメモ利用すれどもAC等絶対に触らない領域がある
- DEVからの質問が多い
- POも質問を返す
- 見積がばらけた時に、ばらけた理由を互いに推測する
- ばらけ続けても忖度せず、POに「これ無理」と言い放つ

### うまくいかない
- 次に持ち越せず、当日夕方延長戦に入る
- POからリファインメントの追加開催を要望する
- PBIの清書をDEVが行い始める、もしくはPOが明確にAC記載していない
- 質問が少ない、シャンシャン会で終わる、見積の数を入れることが目的になっている
- POが進め方に疑問を持たない、DEVの質問に回答を持ち越す
- 見積がばらけた時に、ばらけた理由を各々が言い放つだけで再度見積もる
- 見積結果に忖度が見え隠れする

## レトロスペクティブ
### うまくいく
- 雑談ができる
- 課題をあげるが理由を人にしない
- よかった点は人に理由を置く
- どうでもいいTryが出てきてPOが怒る（ウォーターサーバ欲しいとか）
- DEVも諦めない（ウォーターサーバ導入による風邪予防効果とか）
- PO不参加なこともまあまあ多い（課題感が合わないので）

### うまくいかない
- 第一声がスプリント課題
- ボトルネック要因、ストッパーの議題が中心となる
- 核心を突くTryばかりが出る
- 核心すぎてTryできないこんな世の中じゃ
- POもDEVに一言モノ申す系

## プランニング
### うまくいく
- スプリントに入れるチケットをSMが決める
- というかベロシティでおのずと決まる
- チケットに対しての質問・回答がDEV内で完結する（確認で終わる）
- 時間通りに終わる

### うまくいかない
- スプリントに入れるチケットをPOが決める
- というかリリーススケジュール都合でおのずと決まる
- チケットに対しての質問が出てきて、臨時リファインメントが開催される
- 飲み会の時間に食い込み、POがそわそわし始める

## スプリントレビュー
### うまくいく
- POが話し、POが説明をする
- ステークホルダーに向いて話す、ビジネスの話をする
- DEVが技術的な補足を入れる
- ステークホルダーが今の機能を評価する
- 複数のステークホルダーを折見てPOが参集できる

### うまくいかない
- SMやDEVが話し、POが突っ立っている
- POに向いて話す、技術の話をする
- ステークホルダーが納期の話をする
- ステークホルダーがDEVに向かって機能や実施方法の改善を要求する
- ステークホルダーが別会議に参加しがち、来ない
- というか、ステークホルダーって誰？
Raspberry Pi 5のブートローダーをアップデートする

ラズパイ5のブートローダーをアップデートした時のメモ

# ブートローダーのバージョンを調べる

```shell:
nomura@raspberrypi5:~$ vcgencmd bootloader_version
2024/04/20 11:53:30
version d1744d218076d7eee7c14763bbf3d3cf6278191a (release)
timestamp 1713610410
update-time 1715476514
capabilities 0x0000007f
```

今使用しているブートローダーは、2024/4/20版でした。

# ブートローダーのアップデート

コマンドラインでもアップデートできるのですが、今回はraspi- configコマンドでアップデートしてみます。

```shell:
nomura@raspberrypi5:~$ sudo raspi-config
```

raspi-configが起動したら次の手順で進めていきます。

### 「6 Advanced Options」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/d4946552-0760-4997-5f7e-7c1a0649ccc3.png)

### 「A5 Bootloader Version」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/32ec5afc-e40b-d150-7d94-366150c01be7.png)

### 「E1 Latest」を選択する

E1 Latestを選択すると最新のバージョンに、「E2 Default」を選択すると工場出荷時のバージョンになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/908f38bb-aafc-b976-54ae-7dda512ccf2c.png)

確認画面がでるので、「Yes」を選択すると、ブートローダーのアップデートが開始されます。

```shell:
*** CREATED UPDATE /lib/firmware/raspberrypi/bootloader-2712//latest/pieeprom-2024-05-17.bin  ***

   CURRENT: Sat 20 Apr 10:53:30 UTC 2024 (1713610410)
    UPDATE: Fri 17 May 11:29:43 UTC 2024 (1715945383)
    BOOTFS: /boot/firmware
'/tmp/tmp.nmwZJBAKcn' -> '/boot/firmware/pieeprom.upd'

UPDATING bootloader. This could take up to a minute. Please wait

*** Do not disconnect the power until the update is complete ***

If a problem occurs then the Raspberry Pi Imager may be used to create
a bootloader rescue SD card image which restores the default bootloader image.

flashrom -p linux_spi:dev=/dev/spidev10.0,spispeed=16000 -w /boot/firmware/pieeprom.upd
UPDATE SUCCESSFUL
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/c501932a-9ed0-f9ce-0a12-e1c5ddebde09.png)

「OK」を選択すると、メインメニューの画面に戻りますので「Finish」を選択してraspi-configを終了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/c872cb2a-fc07-23a2-b41b-778293276dc0.png)

ツールが終了する時にrebootするか聞かれるので「Yes」を選択します。

# 更新後のブートローダーのバージョンを確認
再起動後にバージョンの確認をします。

```shell:
nomura@raspberrypi5:~$ vcgencmd bootloader_version
2024/05/17 12:29:43
version 72caf66729df313801bcefe9b1ff7099c71bb5ce (release)
timestamp 1715945383
update-time 1718326275
capabilities 0x0000007f
```

バージョンが2024/5/17版になっているので、更新されました。
Docusaurus で画像にデフォルトで枠線をつけたい

## はじめに

Docusaurusは、ReactとMarkdownを使用して、ドキュメントサイトを簡単に作成できるツールです。

個人的な悩みとして、画像を挿入する際に、背景色がウェブサイトの背景色と同化してしまい、境界が不明瞭になることがあります。

これまでは枠線を手動で画像に加えていましたが、作業が煩雑になってきたため、今後はデフォルトで画像に枠線が表示されるよう設定を変更することにしました。

## 前提

この記事はDocusaurusの経験者向けに書かれており、基本的なインストール手順はカバーしていません。 
初心者の方は、日本語で詳しく解説された以下の記事を参照してください。

https://griponminds.jp/blog/docusaurus-01/

## 変更する部分

1. `src/css/custom.css`を編集
2. `docusaurus.js`または`docusaurus.ts`を編集

---

### `src/css/custom.css`を編集

👇️`custom.css`に下記コードを追加します。

```custom.css
/* すべての画像に枠線を追加 */  
img {  
  border: 2px solid #000; /* 枠線の色と太さを設定します（ここでは黒色で2pxの枠線） */  
  border-radius: 8px; /* 枠線の角を丸くします（オプション） */  
}  

/* 特定の画像に枠線を適用しない */  
img.no-border {  
  border: none;  
  padding: 0;  
  border-radius: 0;  
}  
```
---

👇️画像は一例ですが、すべての画像に自動で枠線つくように設定されました👏

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561386/c317e7b4-883f-a337-033b-e1650b0a0270.png)

---

👇️しかし、ナビゲーションにいる可愛い恐竜くんにも枠線がついてしまいました。
これを取り除いてあげるのが次の設定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561386/a2f87bb5-d7fa-256d-3cd3-b618c963ac9d.png)

---

### `docusaurus.js`または`docusaurus.ts`を編集

👇️`docusaurus.js`のnavbarのlogoに設定を追加します。

これでナビゲーションの恐竜くんには枠線がつかないように設定されます。

```diff_javascript
  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // Replace with your project's social card
      image: 'img/docusaurus-social-card.jpg',
      navbar: {
        title: 'My Site',
        logo: {
          alt: 'My Site Logo',
          src: 'img/logo.svg',
+         className: 'no-border'
        },
      },
      footer: {...},
      prism: {...},
    }),
};
```

---

👇️枠線が取れました。
先程よりも笑顔が素敵です😃

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561386/213430c4-ee8b-3f73-dae3-e284e3f6ebfd.png)

## まとめ

CSSの追加設定により、Docusaurusの画像にデフォルトで枠線を追加する方法を解説しました。 
設定変更を行う際に、CopilotやGPT-4oを活用することで、スムーズに目的を達成することができました。
この記事を通じて、読者の皆さんと私がより効率的にウェブサイトのビジュアルを改善できることを願っています。
タブの親グループを取得する【Chrome拡張機能】

# はじめに

ブックマーク関連のChrome拡張機能開発において
「タブ」の「親グループ」を取得する方法について

# 必要な権限

`tabs` と `tabGrooup` の権限が必要です。

```json
"permissions": ["tabs", "tabGroups"]
```

# 「親グループ（`tabGroup`）」の取得方法

```js
const parent = chrome.tabGroups.get(tab.groupId)
```

このときの`tab`は、`groupId` プロパティを持つ単一の`Tab`です。

グループ名を取得したいときは

```js
// 先程の続き
parent.title
```

で取得可能

その他のプロパティはこちら

https://developer.chrome.com/docs/extensions/reference/api/tabs?hl=ja

https://developer.chrome.com/docs/extensions/reference/api/tabGroups?hl=ja

# `groupId` の取得方法

あいまい検索で`tab`を取得したい場合

```js
chrome.tabs.query({}, (tabs) => {

  const regex = new RegExp(`.*${query}.*`, 'i');
  
  tabs.forEach(async (tab) => {
    if (tab.title.match(regex) || tab.url.match(regex)) {
      const parent = tab.groupId !== -1 ? await chrome.tabGroups.get(tab.groupId) : '';
    console.log(parent.title + ' / ' + tab.title)
    // 親グループ / タブ名 というログになる
    }
  })
})
```

シンプルなバージョン
```js
chrome.tabs.query({}, async (tabs) => {

  //なにかしらの方法で tabs から tab を抜き出す
  
  const parent = await chrome.tabGroups.get(tab.groupId)
  console.log(parent.title + ' / ' + tab.title)
  // 親グループ / タブ名 というログになる
})
```

`chrome.tabGroups.get()` はプロミスを返すため `async / await` を使用しています。
# 関連記事

## ブックマークの「親フォルダ」を取得したい時

https://qiita.com/kohki_takatama/items/7734527f2652659fb116

## popupの`console.log`を確認したい時

https://qiita.com/kohki_takatama/items/40097202014a6a0adfaf

# おわりに

以上、タブとグループについてでした。

次は何を書こうかしら・・・
［一般教養］デジタルとは活字である

「バイト」について触れる。何キロバイト、何メガバイト、何ギガバイトという時の「バイト」である。これは8ビット数値のことを言う。1バイトは8ビットである。8ビットは2進数で8桁の数値である。2進数で8桁の数値は16進数で2桁の数値となる。2進数は0と1を用い、10進数は0～9を用い、16進数は数字が足りないので0～9に加えてA～Fを用いる。

1バイトの情報は256通りの状態を区別し得る。この256通りの情報を符号なし整数、もしくは符号付き整数と解釈することが可能である。符号なし整数は256通りの情報を0～255の数値だと解釈する。符号付き整数は最上位のビットが1である2進数値を負数と解釈する慣習であり、1バイトを-128～127と解釈する。この慣習は複数バイトの整数値でも同様である。2バイト整数は符号なしの場合だと0～65535となり、符号付きだと-32768～32767となる。

実数を表現するには浮動小数点を用いる。浮動小数点と言うからには固定小数点もあり、こちらの方は簡易的なものを自前で実装することも可能である。整数部を何ビット、小数部を何ビット、という形で表すのが固定小数点であるのに対し、浮動小数点は何ビットの何ビット乗という形で表す。加減算に強いのが固定小数点で、乗除算に強いのが浮動小数点であると言えるが、いずれにせよ一つの数値を表すために使えるビット数は有限である。

1バイトの情報を、例えばアスキーコードだと解釈することが可能である。これは数値に対して人間が加える解釈である。コンピュータのことを簡単に「万能の活字技術」だと思っていて良い。CPUの処理するもの、メモリの内容物、ファイルの中身、通信網でやり取りされるもの、これらはいずれもビット列、バイト列である。無味乾燥なビット列、バイト列に対して共通の解釈法を定め、情報のやり取りと処理を自動化するのがコンピュータであると言える。

デジタル情報はアナログ情報と違い、複製時に劣化しないのが特徴である。逆に言うとデジタルは、元々デジタルだったものを表すのでない限りはあくまで近似に過ぎないとも言える。
Visual StudioとVisual Assistの記号自動補完を停止する（閉じカッコ、コメント行のアスタリスク、.の->変換）

## 概要
テキストエディタはなるべく入力した通りに入力されてほしい、そう思う幾つかのおせっかい機能を停止する方法をまとめました。

Visual Studioのテキストエディタはデフォルトで様々な記号を自動補完します。自動補完とは、たとえばカッコ開きを入力するとカッコ閉じ、コメント開始（/*）を入力するとコメント閉じが自動補完されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/ebc8a12d-d730-ad26-9872-2cdc79b3eb25.png)

以下はC++の場合ですが、他の言語でも同様かと思います。

## カッコ閉じやコメント閉じの自動補完を止める方法

Optionsを開き、Text Editor -> C/C++ -> General -> Settings にある Automatic brace completionを切ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/73454eae-6b11-b026-2962-982da72370ad.png)


## Visual Assistの自動カッコ閉じを止める方法

Visual Assistにも同様の機能があり、以下のように Editor -> Insert () and closing } ) ] ' " のチェックを外すことで無効化できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/752c9f83-f8fb-4ad6-2398-e090c6d788ad.png)



## コメント行の改行によるアスタリスク自動補完を止める方法

デフォルトでは、コメント行で改行すると以下のとおりアスタリスクが挿入されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/871b5c47-8a48-2578-77fb-b2d589f42973.png)

Optionsを開き、Text Editor -> C/C++ -> Code Style -> Comments にある Insert existing comment style at the start of new lines when writing comments を切ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/adcac2a7-a00e-84c9-837f-99b4dec2d771.png)

## Visual Assistが.を->に変換するのを止める
以下Editor -> Convert dot to -> in C/C++はUnreal Engineのスマートポインタ操作でしばしば意図しない動作になるので止めます。例えば、TRefCountPtrやTWeakObjectPtrのIsValidメソッドを呼ぶ時、.を意図して入力したのにも関わらず->に変換されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66160/729978e2-8652-79fe-08ab-d3e3fdbe4242.png)
Nuxt3をインストール・アップグレードしたときのpackage.jsonの謎

（現在進行中の謎です。分かり次第追記する）

# 概要
- Nuxt3のプロジェクトでvueやnuxtをpackage.jsonのdependenciesに書くのかdevDependenciesにするのか
- ディスカッションであったり、動きを確認してみたけれどいまいちよくわかっていない


# ディスカッション

https://github.com/nuxt/nuxt/discussions/10400

ビルド出力がルートプロジェクトのpackage.jsonではなく、output/serverフォルダの新しいpackage.jsonに依存しているため、すべてをdevDependenciesに含めることができる。とのこと

なるほど（よくわからん）

# 手元で試す

```bash
$ docker run --rm -v $(pwd):/app -w /app -p 85:80 -it node:lts-slim /bin/bash
```

ここからコンテナ上で作業

```bash
$ npx nuxi@latest init
$ cd nuxt-app
$ cat package.json
```

```json
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "nuxt": "^3.12.1",
    "vue": "^3.4.27",
    "vue-router": "^4.3.3"
  }
}  
```

あれ？ `devDependencies`じゃないのか


もちろんビルドはできる
```bash
$ npm run dev
```

一旦まっさらにする

```bash
$ rm -rf node_modules .nuxt .output
```

package.jsonをこうする

```json
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "devDependencies": {
    "nuxt": "^3.12.1",
    "vue": "^3.4.27",
    "vue-router": "^4.3.3"
  }
}
```

これもビルドはできる

```bash
$ npm install
$ npm run dev
```

次はupgradeしてみる

```bash
$ npx nuxi upgrade
```

なるほど？？？？

```json
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "vue": "^3.4.27",
    "vue-router": "^4.3.3"
  },
  "devDependencies": {
    "nuxt": "^3.12.1"
  }
}
```

よくわからん

# 雑感

どこかで追加調査する
Vue 3 で作る！簡単 ToDo アプリ

この記事では、Vue 3 を使用してシンプルな ToDo アプリを作成します。追加、削除の基本的な実装しか取り入れないためものすごくシンプルです。

### 1. プロジェクトの作成
まずは[こちらの記事](https://qiita.com/taka-d/items/a8ef71f9d27285861b5e)のcreate-vue を使用してプロジェクトを作成します。


```bash
npm install -g create-vue
```

プロンプトが表示されたら、デフォルト設定を選択してください。

**フォルダ階層**
```
src
├── App.vue
├──main.css
├── components
│   └── TodoItem.vue
├── main.ts
└── views
    └── TodoList.vue
```


### 2. コンポーネントの作成

`src/components` フォルダに `TodoItem.vue` componentを作成します。

```TodoItem.vue
<script setup lang="ts">
import { ref } from 'vue'

const props = defineProps({
  item: {
    type: Object,
    required: true
  }
})

const emit = defineEmits(['toggle', 'delete'])

const completed = ref(props.item.completed)
</script>

<template>
  <li class="todo-item">
    <input type="checkbox" v-model="completed" @change="emit('toggle', item)" />
    <span :class="{ completed }">{{ item.text }}</span>
    <button @click="emit('delete', item)">削除</button>
  </li>
</template>

<style scoped>
.todo-item {
  display: flex;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #ccc;
}

.completed {
  text-decoration: line-through;
  color: #999;
}
</style>
```
`src/views` フォルダに `TodoList.vue` viewを作成します。

```TodoList.vue
<script setup lang="ts">
import { ref } from 'vue'
import TodoItem from '../components/TodoItem.vue'

interface Todo {
  text: string
  completed: boolean
}

const todos = ref<Todo[]>([])
const newTodoText = ref('')

const addTodo = () => {
  if (newTodoText.value) {
    todos.value.push({
      text: newTodoText.value,
      completed: false
    })
    newTodoText.value = ''
  }
}

const toggleTodo = (item: Todo) => {
  item.completed = !item.completed
}

const deleteTodo = (item: Todo) => {
  const index = todos.value.indexOf(item)
  if (index > -1) {
    todos.value.splice(index, 1)
  }
}

const editTodo = (item: Todo, newText: string) => {
  const index = todos.value.indexOf(item)
  if (index > -1) {
    todos.value[index].text = newText
  }
}
</script>

<template>
  <div class="todo-list">
    <h1>ToDo List</h1>
    <input type="text" v-model="newTodoText" @keyup.enter="addTodo" />
    <button @click="addTodo">追加</button>

    <ul>
      <TodoItem
        v-for="(item, index) in todos"
        :key="index"
        :item="item"
        @toggle="toggleTodo"
        @delete="deleteTodo"
        @edit="editTodo"
      />
    </ul>
  </div>
</template>

<style scoped>
.todo-list {
  padding: 20px;
}

.todo-list h1 {
  margin-bottom: 20px;
}
</style>
```

### 3. アプリケーションへの組み込み

`src/App.vue` を以下のように修正します。

```App.vue
<script setup lang="ts">
import TodoList from './views/TodoList.vue'
</script>

<template>
  <div id="app">
    <TodoList />
  </div>
</template>
```

### 4. 実行

```bash
npm run serve
```

これで、ブラウザで ToDo アプリが起動します。入力欄にタスクを入力して「追加」ボタンをクリックすると、タスクがリストに追加されます。チェックボックスでタスクの完了状態を切り替え、削除ボタンでタスクを削除できる簡単なTodoリストを作成することができました。

### 5. まとめ

この記事では、Vue 3 を使用してシンプルな ToDo アプリを作成する方法を解説しました。慣れているPropsとEmitでのデータのやり取りにしましたがこのコードをベースに、今後機能を追加したりデザインをカスタマイズする記事を作成していきたいと思います。
picoMini by redpwn writeup advanced-potion-making

## advanced-potion-making (Forensics)

Ron just found his own copy of advanced potion making, but its been corrupted by some kind of spell. Help him recover it!

添付ファイル
・advanced-potion-making

とりあえずテキストエディタで開く。と拡張子の部分が`臼B`となっていた。これはPBファイルの拡張しであるが、他の部分に画像ファイルっぽさを感じる。問題文より、ファイルの中身を見てどこかをいじれば良いらしい。おそらく、ファイルヘッダをPBからPNGに変更すれば良いはず。
PNGファイルシグネチャは`89 50 4E 47 0D 0A 1A 0A`であるから、バイナリエディタで変更。ついでに、その先も見たら、IHDRチャンクが必須チャンクで、ここも変更する必要があるらしい。シグネチャの次の8バイトを`00 00 00 0D 49 48 44 52`に変更。
すると、真っ赤な画像が出てきたのでうさ耳ハリケーンでステガノグラフィ解析する。赤色0ビット抽出でフラグが出てきたが、LSB(最下位ビット)を強調の方が見やすい？気がする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/fba479e9-3cd3-9c28-ef1f-8a2e286a772a.png)


`picoCTF{w1z4rdry}`
ぼくの考える最強のFlutterディレクトリ構成

# 導入
私は現在メインの業務ではモバイルアプリ開発はしていませんが、過去にモバイルアプリ開発に携わったことがあります。
当時はFlutter1から2にバージョンアップしたばかりの頃で、小規模開発でしたので、そこまでディレクトリ構成を意識して作成することはありませんでした。

Flutter3になった頃にはモバイルアプリ開発から離れていたので、個人開発でFlutter3に触れ、いくつかモバイルアプリを開発してきました。
業務で利用する際は意識しなかったディレクトリやテストについてもしっかりと考えるようになりました。

今回は、私が個人開発でFlutterを利用する中で、現在でも利用するディレクトリ構成が出来上がったので紹介していきたいと思います。

# ディレクトリ構成

## 基本構造

```text
lib/
├── main.dart
├── core/
│   ├── exceptions/
│   ├── utils/
│   └── constants/
├── data/
│   ├── models/
│   ├── repositories/
│   └── services/
├── domain/
│   ├── entities/
│   ├── use_cases/
│   └── repositories/
├── presentation/
│   ├── view_models/
│   ├── views/
│   │   ├── common/
│   │   └── feature/
│   └── widgets/
│       ├── common/
│       └── feature/
├── routes/
└── di/

```

解説は後ほど。

## テストディレクトリ構成

``` text
test/
├── unit/
│   ├── core/
│   ├── data/
│   ├── domain/
│   └── presentation/
│       ├── view_models/
│       └── widgets/
└── widget/
    ├── common/
    └── feature/
integration_test/
├── common/
└── feature/

```

# 基本構造の解説

- lib/core/
  - exceptions: アプリケーション全体で使う例外クラス
  - utils: 汎用的なユーティリティ関数やエクステンション
  - constants: 定数やアプリケーション設定
- lib/data/
  - models: Freezedを用いて定義したデータモデル
  - repositories: データソース（APIやローカルデータベース）へのアクセスを提供
  - services: 外部サービスとの通信ロジック
- lib/domain/
  - entities: アプリケーションのドメインエンティティ
  - use_cases: ビジネスロジックをカプセル化したユースケース
  - repositories: ドメイン層で使用するリポジトリのインターフェース
- lib/presentation/
  - view_models: Riverpodを使用したViewModel（状態管理）
  - views: 各画面のビュー
    - common: 複数の画面で共有されるビュー
    - feature: 各機能に関連するビュー
  - widgets: ウィジェットコンポーネント
    - common: 複数の画面で共有されるウィジェット
    - feature: 特定の機能に関連するウィジェット
- lib/routes/
... ルーティング設定
- lib/di/
... 依存性注入の設定

# 最後に
正直ディレクトリ構成に関しては、チームや開発者の好みによるところもあります。
私は、疎結合・テスト容易性を重視する(ようになった)ので、今回のディレクトリ構成にしています。
ご参考になれば幸いです。
関数

Public Function CheckFolderExistence(folderPath As String) As Boolean
    If Dir(folderPath, vbDirectory) = "" Then
        CheckFolderExistence = False
    Else
        CheckFolderExistence = True
    End If
End Function

Public Function CheckFileExistence(folderPath As String, fileExtension As String) As Boolean
    If Dir(folderPath & "*" & fileExtension) = "" Then
        CheckFileExistence = False
    Else
        CheckFileExistence = True
    End If
End Functio
未来のエンジニアライフに向けて

# はじめに

みなさん、こんにちは！

私は、Python、React、Node.js、Go、PHP、Java、AWS構築、アプリ開発など、様々な技術に触れながら、ワクワクする開発の日々を送っています。

みなさんは今後、どんなエンジニアライフを思い描いていますか？

私は、**場所にとらわれず、自分のスキルと情熱で世界中の人々と繋がりながら、革新的なプロダクトを生み出す**、そんな未来を目指しています。

そして、その未来は決して夢物語ではないと考えています。

## フルリモートワークやメタバースでの開発

今でもリモートワークのプロジェクトはありますが、近い将来、フルリモートワークやメタバース上での開発が当たり前の世界になるかもしれません。

世界中の優秀なエンジニアとチームを組み、仮想空間で活発な意見交換を交わしながら、プロジェクトを進めていく。そんな刺激的な働き方が、すぐそこまで来ていると感じています。

## AIと人間の共創による開発革命

最近もAI関連で様々な発表があり、進化のスピードには驚くばかりです。

想像してみてください。

* 音声指示でコーディングが進む
* 視線や指先の動きで、直感的にシステムを操作できる
* AIが開発パートナーとなり、最高のコードを提案してくれる

そんなSF映画のような世界が、現実のものになろうとしています。

体が不自由な方でも、意欲があれば開発の現場で活躍できる。AI技術の進化は、私たちに無限の可能性をもたらしてくれると確信しています。

## 未来を勝ち取るために、今できること

では、そんな輝かしい未来を実現するために、私たちは今、何をすべきなのでしょうか。

私は、以下の3つが重要だと考えています。

**1. 幅広い技術の習得**

進化のスピードが速いIT業界では、常に学び続ける姿勢が不可欠です。

言語、フレームワーク、クラウド、セキュリティ、監視など、幅広い分野に興味を持ち、積極的にスキルアップしていきましょう。

**2. 将来的にAIを使いこなすための準備**

AIは、私たちエンジニアにとって、強力な武器となります。

言語化や伝え方が非常に大事なので、AIツールを使いこなせるように、今から準備を始めましょう。

**3. コミュニケーション能力の向上**

どんなに素晴らしい技術を持っていても、それを人に伝えられなければ意味がありません。

イメージを分かりやすい言葉で表現する力、相手の立場に立った考え方や伝え方など、コミュニケーション能力の向上にも力を注ぎましょう。

## 行動を起こす者に、未来は開かれる

未来もチャンスも、ただ待っているだけでやってくるものではありません。

**私たち自身が、未来に向けて積極的に行動を起こしていくことが重要です。**

新しい技術に挑戦する、海外のエンジニアと交流する、DiscordやTelegramのコミュニティーに入ってみる等、自分の未来を切り開くために、できることから一歩ずつ始めていきましょう。

私はこれからも、エンジニアとしての定年は無いという信念のもと、常に学び続け、未来の開発現場で活躍できる人材を目指していきます。

一緒に、ワクワクする未来を創造していきましょう！