OmniAICreator/Qiita-1.07M huggingface dataset:
rex0220 印刷屋プラグイン 請求書の作成例

[rex0220 印刷屋プラグイン](https://qiita.com/rex0220/items/9be2d9b20a3a1f016c76)で、請求書を作成する例です。

# 概要

基本的なHTML, CSSの構成は、見積書と同じです。
上部に登録番号、一番下に銀行の振込先が追加されています。

![2025-02-26_22h47_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c53d4f90-8b81-4d3f-8ca3-e28fc1798630.png)

見積書と請求書の比較

![2025-02-26_22h49_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7a79f026-4e9d-4b79-8772-fd258f31963a.png)

# 印刷屋プラグイン設定

計算式ですべての HTML を生成する例です。
見積書と同様に、HTML+計算式の設定でも対応可能です。

![2025-02-26_22h54_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7a83adca-a99e-458c-a81b-c22d7fecaba8.png)

- HTML 設定

![2025-02-26_22h55_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/8a517300-83a3-4b2b-be8a-73ff5b13bbfe.png)

```js:請求書-計算式
PAGE_HTML(
  TAG("div", ATTR("class", "pcraft-inv-header"), "請求書"),

  TAG("div", ATTR("class", "pcraft-inv-info"),

    // header left
    TAG("div", ATTR("class", "pcraft-inv-left"),
      TAG("p", 宛名 & " 御中"), VTAG("br"),
      TAG("p", ATTR("class", "pcraft-inv-estimate-amount"), "請求金額:", TAG("span", FVAL(合計金額))),
    ),

    // header right
    TAG("div", ATTR("class", "pcraft-inv-right"),
      TAG("p", "請求番号: " & 請求番号),
      TAG("p", "発行日: " & DATE_FORMAT(請求日, "YYYY年M月D日")),
      TAG("p", "登録番号： T0000000000000"),
      TAG("p", "株式会社サンプルサンプルサンプル"),
      TAG("p", "開発 太郎"),
      VTAG("img", ATTR("class", "pcraft-inv-seal", "width", "250", "height", "120", "src", "#{&f(20250224144344126E43A90D994A32B0C6FE39295544E7236)}"))
    )
  ),

  // table
  TABLE_HTML(見積明細,
    OPT("pref", "pcraft-inv-item-"),
    ARRAY("#", ROWNO(見積明細) + 1),
    商品名, 数量, 単価, 金額
  ),

  // summary
  TAG("div", ATTR("class", "pcraft-inv-summary-section"),
    // 備考
    TAG("div", ATTR("class", "pcraft-inv-remarks-section"),
      TAG("strong", "備考:"), VTAG("br"),
      TAG("span", "ご注文ありがとうございます")
    ),
    // 合計
    TAG("div", ATTR("class", "pcraft-inv-total-section"),
      TAG("table",
        TAG("tbody",
          TAG("tr", TAG("th", "小計"), TAG("td", FVAL(小計金額))),
          TAG("tr", TAG("th", "消費税 (10%)"), TAG("td", FVAL(消費税))),
          TAG("tr", TAG("th", TAG("strong", "合計")), TAG("td", TAG("strong", FVAL(合計金額))))
        )
      )
    )
  ),

  // footer
  TAG("div", ATTR("class", "pcraft-inv-footer"),
    TAG("p", "お振込先: 〇〇〇〇銀行 〇〇支店（普）0000000 〇〇〇〇〇〇"),
    TAG("p", "＊お振込み手数料はご負担をお願い致します")  
  )
)
```

# 見積書と請求書の比較

コードを比較すると、よく似ているのがわかります。
実際に、見積書を流用して、請求書のコードを作成しています。

![2025-02-26_23h15_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/065b7178-e670-403b-b5c1-6cdd0d13860b.png)
バックエンド不要、ブラウザだけで動く物体検出システムを作ってみた。

3連休で生きた証を残したかったので、「そういや物体検出システムって触ったことないな。なんか作ってみるか」と思ってやってみたプロジェクトのようなものです。

## とりあえず触ってみたい方
下記リンクからどうぞ。
https://miupa.jp/projects/MimamoriAI/
カメラは許可してもらう必要がありますが、録画してどっかに転送とかはしてないのです。

## きっかけ
冒頭にも書きましたが、「3連休だしなんか作ってみるか」という単純な興味から始まったプロジェクトです。
特に

- サーバーサイドの実装なしで動作する
- AIの技術を使ってみる
- リアルタイムで処理する

という要素に興味があり、これらを組み合わせて実験的に作ってみました。

## 使用した技術
- TensorFlow.js：ブラウザ上で機械学習モデルを実行できるJavaScriptライブラリ
- COCO-SSD：一般的な物体を検出できる事前学習済みモデル
- HTML5 Canvas：検出結果を表示するために使用
- MediaDevices API：カメラからの映像取得に使用

## 実装のポイント
1. モデルの読み込み
    ```
    const model = await cocoSsd.load();
    ```

2. カメラ映像の取得
    ```
    const video = document.getElementById('video');
    const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: 'environment' }
    });
    video.srcObject = stream;
    ```

3. リアルタイム検出
    ```
    const detectFrame = async () => {
        const predictions = await model.detect(video);
        drawPredictions(predictions);
        requestAnimationFrame(detectFrame);
    };
    ```

## 学んだこと
### 良かった点
- ブラウザだけで物体検出が実現できた
- サーバーサイドの実装がいらない
- スマートフォンでも動作できる

### 課題
- （許容範囲だとは思うけど）モデルの読み込みに時間がかかる
- バッテリーの消費が激しい（たぶん）

## デモ
改めて、実際に動くものを見てみたい方は、以下のURLからアクセスできます
https://miupa.jp/projects/MimamoriAI/
※ 実験的なプロジェクトのため、動作が不安定な場合があります。

## ソースコード
https://github.com/MiUPa/miupa_works/tree/main/projects/MimamoriAI

## 今後の展望
現状は実験的な実装ですが、以下のような発展の可能性を考えています。（本当にただ考えているだけです。）
- 検出精度の向上
- 特定の物体に特化した検出（畑に出現するイノシシとか検出したい）
- 検出後の通知（イノシシを検知したらSNS、あるいはそこで爆音を鳴らすなど）
Qiitaでエンジニアが自己アピールを最大化する方法【後編】～どうやったら効果アップするか攻略法を大公開～

## はじめに
前編では、Qiitaでの投稿がなぜ重要なのか、そのメリットと背景について詳しく解説しました。今回は、実際に効果的な記事投稿を行うための具体的な攻略法に焦点を当てます。ここでは、テーマの選定から記事の構成、露出を高めるための工夫、さらに継続的なアウトプットのコツまで、実践的なテクニックを余すところなくご紹介します。

---

## 1. 投稿するテーマの選び方
### 具体的なアイデア出し
- **実務で直面した課題と解決策**  
  自身が経験した問題点やハマったポイントを整理し、その解決方法を詳細に記述することで、同じ悩みを持つ読者の助けになります。  
  例：「AWS Lambdaのデプロイ自動化で発生したエラーとその対処法」
- **社内で頻繁に出る質問への回答**  
  新入社員や若手エンジニアが抱えがちな疑問点をテーマにすることで、広く役立つ記事が作れます。  
  例：「Gitの基本操作とよくあるトラブルシューティング」
- **最新技術の学習成果をアウトプット**  
  新たに学んだ技術やツールの使い方を記事化し、自分の知識を整理するだけでなく、業界内での注目度を高めましょう。  
  例：「ChatGPT APIを使った業務効率化の実践例」
- **初心者向けのステップバイステップチュートリアル**  
  初学者が理解しやすいように、具体的なコード例や図解を交えた記事は常に高い評価を得られます。  
  例：「Docker入門：初めてのコンテナ環境構築ガイド」

---

## 2. 読まれる記事の構成
### 記事の「黄金ルール」
1. **タイトルの重要性**  
   タイトルは記事全体の印象を決定付けます。具体的でわかりやすく、検索キーワードを盛り込んだタイトルを設定しましょう。  
   例：「PythonでExcel操作【openpyxl徹底解説】」
2. **導入部分で引き込む**  
   記事の最初の100～200文字で、読者が「読む価値がある」と感じる情報を提供します。  
   - この記事で解決できる問題は何か？  
   - どのような知識やスキルが得られるのか？
3. **本題はセクション分けで明確に**  
   - **具体例やコードスニペット**：実際のコードや図解を挿入することで、理解を深める。  
   - **段落ごとに見出しをつける**：長文になりすぎないよう、適宜箇条書きや見出しを利用する。
4. **まとめと次へのアクション**  
   記事のポイントを整理し、読者に「次に何をすべきか」アドバイスを提供することで、エンゲージメントを高めます。  
   例：「この記事が役に立ったら、いいねやコメントをお願いします！」

---

## 3. 露出を最大化するための工夫
### SEOとSNS活用のポイント
- **SEO対策**  
  - タイトルや冒頭文に主要キーワードを入れ、検索エンジンでの露出を狙います。  
  - 適切なタグ（例：「Python」「AWS」「Docker」）を選定し、ターゲット読者にリーチしましょう。
- **SNSでの拡散**  
  - X（Twitter）、LinkedIn、Facebookなど、複数のプラットフォームで記事をシェアし、より多くの読者に届けます。  
  - ハッシュタグや企業アカウントへのタグ付けを活用することで、拡散力がアップします。

### コミュニティとの連携
- **他のQiitaユーザーとの交流**  
  - 他の記事にコメントを残したり、いいねをすることで、自身の記事へのフィードバックやフォロワー獲得に繋がります。
- **マルチプラットフォーム戦略**  
  - Qiitaだけでなく、Zennやはてなブックマークなどの他プラットフォームにも記事を紹介することで、異なる読者層にアプローチできます。

---

## 4. 継続的な投稿のための戦略
### 投稿頻度と記事ストックの作り方
- **定期的な投稿**  
  毎月最低1本、可能ならば週1本を目標に記事を投稿し、アウトプットの習慣を作ります。  
- **記事のストック作成**  
  アイデアを常にメモしておき、まとまった記事の下書きを作成しておくことで、急なスケジュールの乱れにも対応可能です。
- **時間管理とルーチン化**  
  毎週決まった時間を記事作成に充てることで、無理なく継続できる環境を整えましょう。  
  例：「毎週土曜の朝は1時間、記事作成タイム！」

### フィードバックの活用
- **社内外の意見を反映**  
  記事に対するコメントやSNS上でのフィードバックを参考に、内容のブラッシュアップを図りましょう。  
- **改善と再投稿**  
  定期的に過去の記事を見直し、最新情報や改善点を加えることで、長期的に価値のあるコンテンツとなります。

---

## 5. 社内評価に直結するアウトプット
### 自己アピールと評価のシナジー
- **社内共有の重要性**  
  投稿した記事は、社内のSlackチャンネルやミーティングで積極的に共有し、技術力やアウトプットの実績として評価されるようにしましょう。  
- **上司や評価担当者への報告**  
  定期的にQiita投稿の実績を報告することで、ナレッジ共有への貢献をアピールし、キャリアアップに繋げることができます。

---

## まとめ（後編）
効果的なQiita記事投稿には、テーマ選定、記事構成、SEO対策、SNS活用、継続的なアウトプットという複数の戦略が必要です。今回ご紹介した具体的な攻略法を実践することで、単なる情報発信に留まらず、自己ブランディングの強化、社内評価の向上、さらには転職や副業といったキャリアパスの拡大にも大いに役立ちます。

ぜひ、前編で感じた投稿の必要性を踏まえ、後編のテクニックを実践して、あなたの技術や知識を存分に発信してみてください。成功への第一歩は、今この瞬間から始まります！

Happy Posting!

[Qiitaでエンジニアが自己アピールを最大化する方法【前編】](https://qiita.com/comty/items/84736ce7a3963d059321)
[Qiitaでエンジニアが自己アピールを最大化する方法【後編】](https://qiita.com/comty/items/b65cbdf7917e020eae56)
Qiitaでエンジニアが自己アピールを最大化する方法【前編】～なぜエンジニアが投稿するのか～

## はじめに
ITエンジニアとしてのキャリアアップや自己ブランディングは、日々のアウトプットが大きな武器となります。近年、Qiitaでの技術記事投稿が注目されているのは、単なる知識共有に留まらず、企業内外での評価や信頼獲得、そして市場価値向上に直結するためです。本記事（前編）では、なぜQiitaで記事を投稿する必要があるのか、その背景とメリットを具体的に解説していきます。

---

## 1. 市場価値を高めるための自己アピール
### 技術力の「見える化」
- **実績の証明**  
  Qiitaは、あなたの技術的な取り組みをドキュメントとして残す場所です。プロジェクトの成功体験や、課題解決のプロセスを記事にすることで、具体的なスキルセットを証明できます。  
- **ポートフォリオとしての活用**  
  転職活動や社内評価の際、記事は「実績のポートフォリオ」として機能します。採用担当者や上司に対して、実際にアウトプットしていることを示す強力な証拠となります。

### 実践事例
- **企業内での評価アップ**  
  社内で「技術のアウトプットを評価する」風土がある場合、Qiitaへの投稿は直接的に昇進や重要プロジェクトへの抜擢に繋がります。  
- **採用市場での強み**  
  「アウトプットできるエンジニア」は、常に求められる存在です。実務で培ったノウハウを記事にすることで、外部からも高い評価を受けやすくなります。

---

## 2. コンサルタント視点から見るアウトプットの効果
### 分かりやすさが評価を決める
- **情報整理力の向上**  
  専門的な知識を、誰にでも理解できる形でまとめる訓練になります。これにより、ドキュメント作成やプレゼンテーションの能力が自然と鍛えられます。  
- **論理的思考の強化**  
  記事作成を通じて、複雑な概念を整理し、構造化する力が養われます。これは、コンサルタントとしてクライアントに分かりやすく提案する際にも大きな強みとなります。

### コミュニティ内での信頼獲得
- **情報発信による影響力**  
  有益な記事を継続的に発信することで、同僚や業界内で「頼れるエンジニア」という評価を得られます。結果、内部だけでなく外部からの問い合わせやオファーにもつながる可能性が高まります。

---

## 3. キャリアパスを広げる可能性
### 転職・副業へのアピール
- **転職市場での優位性**  
  実績としての記事は、転職活動時に他の候補者との差別化要因となります。企業は、アウトプットを通じて実践力を見極める傾向があるためです。
- **副業・フリーランスとしての信頼**  
  自身の技術や知見を広く公開することで、フリーランスとしての案件獲得にもつながりやすくなります。

### 社外ネットワークの構築
- **コミュニティ参加のきっかけ**  
  Qiitaを通じて、同じ分野のエンジニアとの交流が生まれ、セミナーや勉強会などのオフラインイベントにも発展するケースがあります。  
- **最新技術へのキャッチアップ**  
  他のエンジニアの記事を読むことで、自身では気づかない新たな技術やトレンドを学ぶことができます。

---

## まとめ（前編）
Qiitaでの技術記事投稿は、単なる情報共有の場を超え、エンジニアとしての市場価値の向上、社内外での信頼獲得、そして幅広いキャリアパスの構築に大きく貢献します。次回の後編では、ここまでの背景を踏まえ、具体的にどのようにして記事の内容を充実させ、効果的に発信していくか、その攻略法について詳しく解説します。

次回もどうぞお楽しみに！

[Qiitaでエンジニアが自己アピールを最大化する方法【前編】](https://qiita.com/comty/items/84736ce7a3963d059321)
[Qiitaでエンジニアが自己アピールを最大化する方法【後編】](https://qiita.com/comty/items/b65cbdf7917e020eae56)
Pythonスクリプトを軽量サンドボックスで割と安全に実行する

LLMのPythonスクリプト出力を比較的安全に実行したい、そういう時って割とありますよね。使うのは自分だけなので怖いのは偶然危険なコードが出てきた時だけ、みたいなケースです。

でも世間に出回ってる情報はDockerを使ったもの ([llm-sandbox](https://github.com/vndee/llm-sandbox)) とか、WebAssemblyを使ったもの ([Pyodide](https://pyodide.org/en/stable/)) とか、CPython以外の実装を使ったもの (PyPyの[サンドボックス機能](https://doc.pypy.org/en/latest/sandbox.html)) とか、Webサービス向けの重量級のものばかり。軽かったであろう [pysandbox](https://github.com/vstinner/pysandbox) はデザインに欠陥があり、制限も多く開発中止となっていました。

そんな中でさてどうしよう、サンドボックスのPython環境でもホストのPython環境と同じものが使えれば管理が楽なのに、と思いながら調べていました。

その結果、Pythonライブラリの中では決定打が見つからなかったものの、Linux環境の中では systemd-nspawn を読み込み専用マウントで使う方法を思いつき（但しルート権限が必要）、その systemd-nspawn に似ながらもルート権限が不要なbubblewrap (bwrap) を見つけ、その bwrap を使ってサンドボックスで Python スクリプトを実行するコードを書いてみました。

```python
import os
import subprocess

home_dir = os.path.expanduser("~")

try:
    os.makedirs("/tmp/mysandbox_root")
except FileExistsError:
    pass

def sandbox_pyexec(code):
    proc = subprocess.Popen(
        ["bwrap", "--bind", "/tmp/mysandbox_root", "/", "--ro-bind", "/bin", "/bin", # システムファイルをRead-Onlyで共有する
         "--ro-bind", "/lib", "/lib", "--ro-bind", "/lib64", "/lib64", 
         "--ro-bind", "/usr", "/usr", "--ro-bind", "/etc", "/etc", # あんまり良くない
         "--ro-bind", home_dir + "/.local/lib", home_dir + "/.local/lib", # pip ライブラリをRead-Onlyで共有する
         "--ro-bind", home_dir + "/.local/bin", home_dir + "/.local/bin",
         "--ro-bind", home_dir + "/.local/share", home_dir + "/.local/share",
         "--bind", "/proc", "/proc", "--unshare-all", "--", # なるべくホストと非共有（systemd-nspawnと違ってプロセスリストは共有してるけど）
         "bash", "-c", "python -"],  # Pythonで標準入力のコードを実行
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True  # stdin / stdout を文字列として扱う
    )
    result, err = proc.communicate(code)
    return (result.strip(), err.strip())
    

r, err = sandbox_pyexec( """print("これはテストです")""")

print("stdout:", r)
print("stderr:", err)
# stdout: これはテストです
# stderr: 

r, err = sandbox_pyexec( """import os
os.system("ls /")""")

print("stdout:", r)
print("stderr:", err)
# stdout: bin
# etc
# home
# lib
# lib64
# proc
# usr
# stderr: 

r, err = sandbox_pyexec( """wrong python syntax here""")

print("stdout:", r)
print("stderr:", err)
# stdout: 
# stderr: File "<stdin>", line 1
#     wrong python syntax here
#           ^^^^^^
# SyntaxError: invalid syntax
```
新世代ブラウザ「Arc」って結局何がすごいの？便利機能と導入方法！

# 【はじめに】
#### 次世代の主役ブラウザ？「Arc」
こんにちは。エンジニアの藤原です。
皆さんは日常的にお使いの気に入っているブラウザはありますか？
Chrome？ Edge？ Safari？...etc たくさんの選択肢がありますよね。

今回は次世代を担うブラウザとして注目が集まる「Arc」について、
現在の主流ブラウザとの比較、便利な機能、最後には導入方法をご紹介します。

※約5分でお読みいただけます。

# 【目次】
[1.はじめに](#1-はじめに)

[2.ブラウザ「Arc」とは](#2-ブラウザ「Arc」とは)

[3.特徴的な機能](#3-特徴的な機能)

[4.Arcの導入方法](#4-Arcの導入方法)

[5.さいごに](#5-さいごに)

# 2-ブラウザ「Arc」とは
改めましてですが、
皆さんはWebブラウザ「Arc」をご存知でしょうか。

Arcはニューヨークに本社を構える「The Browser Company」によって、2023年4月にリリースされてから世界中でどんどん愛用者が増えているブラウザで、
近年リリースされたブラウザの中では、完成度が高いと評価されています。

操作性の高さや革新的なデザイン、拡張性など今までのブラウザとは一線を画したWebブラウザとして注目が集まっているそう。

日本ではまだまだ「ブラウザはChrome一択でしょ！」という声も聞こえてきそうですね..。
いやいや！
日頃愛用しているお気に入りブラウザがあるという方も、今回は一緒にArcの魅力に迫っていきましょう～！

:::note warn
警告
本記事情報は、作成当時の2024年7月現在の情報です。
:::

# 3-特徴的な機能
それではさっそくArcの特徴的な機能を順々にご紹介です！

<h3>①サイドバー</h3>
まずぱっと目に付くUIがサイドバーです。
こんな感じ↓

![Arc_SideBar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/5e9d87fa-0183-89d4-0ba5-de1992ee196e.png)


Arcではサイドバーを使ってブラウジングをしていくことになります。
Webサイトでは横幅よりも縦幅が表示領域としては大切になるので、これは使いやすさポイントの1つです。

従来のブラウザであれば画面上部にタブやアドレスバーがあるかと思います。
それがない分(サイドバー表示)縦の情報量が増えるので、単純なネットサーフィンでも使い勝手が良いと思います。

<h3>②ブラウジング階層概念(タブ溜まりすぎ問題の解決！)</h3>
仕事柄、毎日の仕事でも調べごとが多いですが、気が付いたらブラウザのタブ数が増えていき orz
こんな状態になったことはないでしょうか？

![Arc_Tab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/455e4b24-cdc4-8749-9bb2-37acaf949029.png)

これではどのタブにどの情報があるか一目でわからない...
見返したいけどどれだっけ...
ってなりがちですよね。

じゃあ、お気に入り機能があるじゃん！といっても、
意外とお気に入りに入れても見ないですよね。

そんな時に、Arcでは階層構造による仕分け機能が備わっていて、基本的な概念としては「スペース > フォルダ > タブ」となっています。

実際にお見せした方が早いので..

![Arc_Space.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/0bb57cad-1e48-7b8d-94f3-bfbf37e5e433.png)

スペースがいわゆる作業場となり、その中でフォルダ -> タブとまさに階層構造になっているわけです。

仕事とプライベートでスペース自体を分けることも出来ますし、リネームやアイコンを好きなものに変更することも可能です。
サイドバーで常時階層が表示されるため(もちろん閉じることも可)、従来のブラウザのようにタブだらけになる問題も解消できちゃいます！

<h3>③スプリットビューで画面を分割表示！</h3>

ブラウザで調べごとをしている際に同時に複数のページを見たい場面ってありませんか？
Arcではスプリットビューと呼ばれる画面分割機能が備わっています。

これもお見せしてしまう方がイメージしやすいと思います。

![Arc_Split.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/f90be54d-0f31-5a2d-e067-b7585e7d2d4c.png)

こんな感じ！
分割したい際にいちいち複数起動する手間が省けて楽ですね。
片方で調べ毎ごとをしながら、もう片方ではノートにまとめるなど、毎日の使い方次第ではかなりの恩恵を得られる便利な機能です。
Youtube視聴しながらネットサーフィンなんて使い方も便利ですね！

どうでしょうか！今回軽くご紹介しただけでも従来のブラウザとは一線を画していますよね。

他にも↓こんな良いところが..

<details><summary>Arcその他のメリット</summary>

+ タブの有効期限設定
+ Easel(イーゼル)によるホワイトボード機能
+ ブーストでサイトの見た目を好きな装飾に！
+ メディアやダウンロードの一括管理

</details>

# 4-Arcの導入方法

それでは最後にArcの導入方法をご紹介！
※Arcは無料でご使用いただけますので、ご安心ください。

:::note info
インフォメーション
Windows版・Mac版どちらも対応
:::

①Arc公式ページ([こちら](https://arc.net/ "Arc公式ページ"))へ

![Arc_Download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/64ab5318-41c6-f03d-7a88-8cac6f5b5393.png)

②ダウンロードボタンをクリック

![Arc_Download2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/68227fa2-f3d1-c6dd-4261-69914e41e93d.png)

後はダウンロードが完了したら、案内に従って初期設定を済ませるだけです。
とっても簡単。

# 5-さいごに
いかがだったでしょうか。

今回は近年注目が集まるWebブラウザ「Arc」についてご紹介しました。
使い慣れた既存ブラウザももちろん良いですが、これを機会にぜひ皆さんもArcの良さに触れてみてください～！

以上、藤原でした。
【SQL Server】IDENTITYで注意すべきこと

こんにちは。エンジニアの藤原です。

最近はC#を用いたWebアプリケーション開発をしています。
データベースにはSQL Serverを採用していますが、ある日こんな問い合わせが・・。

一瞬「？？？」となった私の経験を備忘録として記事に残しておこうかと思います。

:::note warn
注意
本記事は基本的なデータベース概念を理解している方向けに記載しています。
:::

# 目次
・何が起きたか
・原因
・解決策

# 何が起きたか
とある日、いつも通りPCに向かっていると他開発メンバーが開発した機能で問い合わせがきました。
「〇〇テーブルへの新規登録が全部コケるんですけど・・」

ステージング環境だったので良いですが、
開発者にとって唐突な問い合わせは本当に嫌なものですよね。
だけどそうもいっていられない。

まあ、見てみれば直ぐにわかるでしょ～と「承知です！確認します。」と返事しました。
(何故私にきた..)

機能としてはごく単純で、ボタンが押されたらテーブルAにINSERTするだけ。
いままでは普通に動いていたらしいし、、

取り合えずログを確認。
確かにInsertエラーログを出力していて、内容は「制約 '%.*ls' の %ls 違反。 オブジェクト '%.ls' には重複したキーを挿入できません。」初めての開発で親の顔ほどよく見るやつですね:grinning:

これは簡単に解決できそうだ。

挿入対象のテーブル構造がどうだったかと定義書を確認していると、
あるカラムがPrimary KeyとしてIDENTITYプロパティを設定しており、INSERT時に自動的に一意の値を生成してくれています。

どうやらこの値が重複してINSERTが失敗している様子。
さらに情報が欲しかったのでヒアリングをすると、とあるメンバーが対象環境の該当テーブルに誤ってDELETEをかけてしまったとのこと。

# 原因
登録時の処理内容としては、最初の1レコード目を新規挿入時に必ずSEED値を0指定で挿入する作りになっており(それはそれでというのは一旦置いておいて)、最初の1レコード目の登録かどうかは登録レコード数で判定するフローになっていました。(元凶)

つまり、以下の流れで今回の事象が起きたと思われる。

1.何件かのレコードをテーブルAに登録
2.誤ってDELETE(IDENTITY の現在のカウントであるSEED値はそのまま)
3.登録レコードが0件であるため、SEED値を0指定で挿入を試みる
　※DBCC CHECKIDENT('Users', RESEED, 0)
4.挿入失敗

それは当たり前に失敗しますね・・。
TRUNCATEならまだよかったですね。(良くない)

# 解決策
色々と作りに突っ込みどころは多いですが、かなり急ぎの対応でもあったので
IDENTITY をリセットする場合でも RESEED の値は MAX(ID) に合わせる修正
＋フローの改修をすることで解決しました。

詳しく書けば、排他制御の考慮ももちろん欠かせないですが、
「IDENTITY便利だな～」だけの軽い考慮で使用するとこのようなことになるのでご注意を。

以上、藤原でした。
BFFアーキテクチャについて調べてみた

## はじめに
こんにちは！SIerに入社して１年目の新人エンジニアです。日々の業務で当たり前のように使われている用語で「えっ、それって何？」と思ったものを調べて、自分なりにまとめていきます。

今回は「BFFアーキテクチャ」について調べてみました。

## 目次
- [BFFって何の略？](#bffって何の略)
- [なぜBFFが生まれたのか？](#なぜbffが生まれたのか)
- [従来のアーキテクチャとの違い](#従来のアーキテクチャとの違い)
- [BFFのメリット](#bffのメリット)
- [BFFのデメリット](#bffのデメリット)
- [BFFとマイクロサービスの関係](#bffとマイクロサービスの関係)
- [まとめ](#まとめ)
- [参考資料](#参考資料)

## BFFって何の略？
まず最初に、BFFは「**Backend For Frontend**」の略だということがわかりました。日本語では「フロントエンド専用のバックエンド」といった意味です。

より具体的に説明すると、「フロントエンドとバックエンドの中間に配置され、双方の複雑な処理を緩和させる責務を持つアーキテクチャ設計パターン」、あるいは「バックエンドのAPIから取得したデータをフロントエンド向けに加工するフロントエンド専用のサーバー(API Gateway)」ということです。

## なぜBFFが生まれたのか？
従来のシステムでは、バックエンドAPIは「汎用的」に設計されることが多く、さまざまなクライアント（Webブラウザ、スマホアプリ、タブレットなど）からのリクエストに対応していました。しかし、各クライアントの特性やニーズが異なるため、次のような問題が発生していました。

1. 必要以上のデータを取得してしまう（オーバーフェッチング）
2. 1つの画面表示に複数のAPIリクエストが必要になる
3. クライアント側で複雑なデータ加工処理が必要になる
4. デバイスごとに最適化が難しい

これらの問題を解決するために、2015年頃にSoundCloudのエンジニアチームがBFFパターンを提唱し、広まっていったようです。

## 従来のアーキテクチャとの違い
従来のアーキテクチャでは、すべてのクライアントが同じAPIを使用していましたが、BFFアーキテクチャでは、クライアントの種類ごとに専用のバックエンドサービス（BFF）を用意します。これにより、各クライアントに最適化されたAPIを提供できるようになります。

## BFFのメリット
### フロントエンドとバックエンドの責務分離
BFFを導入することで、フロントエンドとバックエンドそれぞれの責務がより明確になります。フロントエンドはUI/UXに集中でき、バックエンドはビジネスロジックとデータ管理に専念できます。

### フロントエンド開発の効率化
フロントエンド開発者が求める形式でAPIを設計できるため、フロントエンド開発の効率が向上します。データの取得や加工処理をBFF側で行うことで、フロントエンドのコードを簡潔に保つことができます。

### パフォーマンスの向上
クライアントは1回のリクエストで必要なデータをすべて取得できるようになるため、複数回のAPI呼び出しが減少します。また、不要なデータを除外してネットワーク転送量を削減できるため、特にモバイル環境では大きなメリットになります。

### クライアント特性に合わせた最適化
各クライアント（Web、iOS、Android）ごとに最適化されたAPIを提供できます。例えば、画面サイズが小さいスマートフォン向けには、データ量を削減したAPIを提供するといった対応が可能です。

## BFFのデメリット
### 開発・運用コストの増加
クライアントの種類ごとにBFFを開発・運用する必要があるため、リソースやコストが増加します。また、メンテナンスや監視などの運用コストも考慮する必要があります。

### 通信量の増加と遅延の可能性
API結合によって通信量が増加し、レスポンスに遅延が発生する可能性があります。特に複数のマイクロサービスからデータを取得・集約する場合は注意が必要です。

### サーバー障害のリスク増加
BFFはその性質上、サーバー障害などが発生すると依存しているフロントエンド側にも大きく影響が及びます。アクセスの一元化によってリスクが増加するため、適切な対策が必要です。

### バックエンドへの依存
BFFはバックエンドのAPIに依存するため、デプロイなど連携が必要になります。バックエンドの変更がBFFにも影響を与える可能性があります。

## BFFとマイクロサービスの関係
マイクロサービスアーキテクチャでは、バックエンドが複数の小さなサービスに分割されています。この場合、1つの画面表示のために複数のマイクロサービスからデータを取得する必要があることが多く、クライアント側の実装が複雑になりがちです。

BFFはこの問題を解決するために、マイクロサービスの前に立ち、必要なデータをすべて集約して、クライアントに最適な形で提供します。つまり、マイクロサービスの複雑さをクライアントから隠蔽する役割を果たしています。

## まとめ
どのようなアーキテクチャにもメリットとデメリットが存在するので、Netflixのような大手テック企業が採用しているからといって盲目的にBFFを採用するのではなく、システムの特性や要件に合わせて慎重に判断すべきだと感じました。

## 参考資料
https://zenn.dev/overflow_offers/articles/20220418-what-is-bff-architecture

https://www.thoughtworks.com/insights/blog/bff-soundcloud

https://netflixtechblog.com/seamlessly-swapping-the-api-backend-of-the-netflix-android-app-3d4317155187
Warning: Each child in a list should have a unique "key" prop.ってなんだ？

エンジニアの風速です。
Reactなどで開発をしていると、以下のエラーに遭遇したことはありますでしょうか。
`Warning: Each child in a list should have a unique "key" prop.`
自分はよく遭遇して、このメッセージをみると体が勝手にkeyをつけなきゃと動き出すのですが、
直訳すると、`リスト内の各子要素はユニークなkeyプロパティを持つ必要があります。`と書いてあります。

レンダリング自体はされるし、実際なんでkeyを付けないとダメなのか気になりましたので今回調べてみようと思います。

## 実際に発生させてみる

以下のような5個`<li />`をレンダリングするコンポーネントを書くとコンソールにエラーが発生します。

``` jsx
function App() {
  const numberArray = [1, 2, 3, 4, 5]
  const list = numberArray.map(n => <li>tests</li>)

  return (
    <ul>
      {list}
    </ul>
  )
}
```
mapで`<li />`を作っている部分に以下のように一意のkeyを設定すると解決します。

``` jsx
function App() {
  const numberArray = [1, 2, 3, 4, 5]
  const list = numberArray.map(n => <li key={n}>tests</li>)

  return (
    <ul>
      {list}
    </ul>
  )
}
```

実際に以下のようなエラーが確認できます。
```
Each child in a list should have a unique "key" prop.

Check the render method of `App`. See https://react.dev/link/warning-keys for more information.
```

## なぜkeyが必要あるのか
リストのアイテムを再レンダリングする際に、keyを元に変更、削除、追加などの要素が変更されたのかを認識するのでkeyがないと誤った要素を認識してしまったり、keyがないとどの要素に変更があったのか認識できず、リスト全体の再レンダリングがかかり、パフォーマンスも悪くなります。
keyが設定されていない場合は、配列のindexが使用されます。なので今回のエラーが出ている状態は配列のindexがそのまま使用されているので、動きはするという感じでしょうか。
設定する場合はindexをそのまま使用することは避けて、テーブルのユニークキーなど設定するのが推奨されています。

## 参考
https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key
AWS SAAに合格したので勉強方法のメモ

# はじめに
2025/2に合格しました。
試験までに時間に余裕がある人向けの勉強方法です。

# 勉強時間
計っていないので正確な時間は分かりません。
一応、4ヶ月ほど前から少しずつ進めていました。

# 主に使用した教材
使用した順で下記になります。
- Udemy
    - Ultimate AWS Certified Solutions Architect Associate 2025
    - 【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集
- AWS
    - 公式問題集

# 各教材の特徴と進め方
### Ultimate AWS Certified Solutions Architect Associate 2025
- 特徴
    - 各サービスについて網羅的に学ぶことができる
    - ハンズオンもついている
    - 各単元ごとにテストがついている
    - 講座内で使っているスライドをダウンロードできる
    - 最後に本番の練習テストがついている
    - 以前資格を取った人向けのディスカウントの適用の方法も載っている
- 進め方
    - スライド(860ページほど)を日本語に訳してノートを作成
        - 後ほど問題を解いたときに各サービスのノートに追記していました
    - 各単元のノートを読んで、小テストを５周
    - 最後の65問演習も5周
### 【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集
- 特徴
    - 65問の模擬試験が6セットある
    - 一問解いて解答をみるという方式でチャレンジすることができる(演習モードβ)
- 進め方
    - 最低でも3周ほど
### AWS 公式問題集
- 特徴
    - AWS公式の問題である
- 進め方
    - 三周ほど
    - (本番前には全て正解できるようにしておいて自信をもつ)

# その他
解答を見てスッキリしないところや、理解できないところは公式のリソースなどを調べました。

# おわりに
何から手をつけていいかわからない人のラーニングパスの参考になれば幸いです。
メモ：ローカルにある自作ライブラリを仮想環境へインストールし、そのライブラリを使うpyファイルをexe化する

ローカルで作成していたスクリプトから関数を分離し、モジュールにまとめ、パッケージ化した。
main.pyではこのモジュールをimportしていろいろやっている。
ここで、main.pyをexe化して配布したくなった。
しかし、PCにはNumpyやPandasなど容量の大きなライブラリがインストールされており、
そのままexe化すると容量の大きなファイルになってしまう。

仮想環境にローカルにあるパッケージをインポートしてmain.pyをpyinstallerでexe化すれば、
NumpyやPandasを除外し、必要なローカルのパッケージだけ同梱できるはず。

しかし、仮想環境に直接パッケージをインポートすることはできないようで、
パッケージをライブラリにする必要がある。

ライブラリ内には表に出したくない情報が載っているので、PyPIやGit上に公開したくない。

よって、自作ライブラリを公開せずに仮想環境下でpipインストールできるような方法を探していた。

ネット記事をつまみ食いして編み出したのが以下の方法
orenolib：ライブラリ
main.py：exe化したいスクリプト。mylibパッケージを参照する
mylib：main.pyで参照するパッケージ。モジュール2個入り。
階層はこんな感じ。
~~~
orenolib
├── setup.py
├── main.py
└── mylib
    ├── __init__.py
    └── function1.py
    └── function2.py
~~~

この状態でorenolib上に.venvフォルダを作成し、activateして仮想環境へ。

~~~
orenolib
├ .venv
├── setup.py
├── main.py
└── mylib
    ├── __init__.py
    └── function1.py
    └── function2.py
~~~

あとはpip install mylibで仮想環境に自作ライブラリをインストールし、
pip install pyinstallerでpyinstallerをインストールして
pyinstaller main.py --onefile
でmain.pyをexe化すれば完了。

とりあえず手元では動いている。
mylibの名前を変えても動作したので自作ライブラリはexeファイルに同梱されたと思う。

まだまだ勉強不足だが、関数、モジュール、パッケージ、ライブラリの違いについてなんとなくこうかな？という感じの理解だったのがだいぶ改善されたと思う。
しかし、orenolibがライブラリなのか、mylibがライブラリなのか判然としない…
setup.pyでバージョンを指定すると、mylibがそのバージョンでインストールされるのでmylibはインストールされているらしい。ライブラリを参照し、その中身のmylibというパッケージをインストールしている？このあたりの機微は肌感覚ではつかめていない。
Pythonチュートリアルには自作ライブラリの参照方法は載っていなさそうだった。

仮想環境からはちゃんとexitで抜け、.venvも作りっぱなしにせずちゃんと消しておくのが大事。
.venvが大量に残っていると、仮想環境にインストールしたつもりのライブラリがインストールできておらず、過去に他のフォルダで作成した.venvにある想定外のライブラリやモジュールが同梱されてしまう。

他にも色々(特にsetup.py関連で)あるらしいが、自作ライブラリをPyPIやGitに公開する予定は無いので当面は大丈夫だろう。

趣味として自作ライブラリを作成し、PyPIに上げたりGitで管理したりするのはべんきょうになるかもしれ
【小ネタ】WHOISをゆるく調べてみた！！

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

ネットワークを触っている人間なら触ったことがない**WHOIS**について、知っているようで知らないと思いましたので、自身のナレッジをためる意味合いで記事を執筆してみました。

初学者でもサクッと読めるように平易な表現で執筆しておりますのでお気軽に、読んでいただければ幸いです。

## そもそもWHOISとは

JPRSさんのページでいい感じにまとめられていたのでそちらを引用したいと思います。

https://jprs.jp/about/dom-search/whois/

>Whoisとは、IPアドレスやドメイン名の登録者などに関する情報を、インターネットユーザーが誰でも参照できるサービスです。このサービスは、主に以下の目的でレジストリやレジストラが提供しています。

>ネットワークの安定的運用を実施する上で、技術的な問題発生の際の連絡のために必要な情報を提供

>ドメイン名の申請・届け出時に、同一ドメイン名や類似ドメイン名の存在を確認するために必要な情報を提供

>ドメイン名と商標などに関するトラブルの自律的な解決のために必要な情報を提供

言葉だけだといまいちピンとこないかと思いますが、すごくざっくり言えば**不動産情報**みたいなものと思ってもらえればわかりやすいかと思います。

例えば、**hogehoge.com**と呼ばれるドメインを持っている会社（個人）誰なのか調べる機会があった場合、WHOIS登録されていれば、**所有者情報、登録日時**などの情報をキャッチすることができます。

提供情報に関しては大きくは以下の通りです。
- 登録ドメイン名
- レジストラ名
- 登録ドメイン名のプライマリおよびセカンダリネームサーバ
- ドメイン名の登録年月日
- ドメイン名の有効期限
- ドメイン名登録者の名前および住所
- 技術的な連絡の担当者の名前、住所、電子メールアドレス、電話番号
- 登録に関する連絡の担当者の名前、住所、電子メールアドレス、電話番号
JPドメイン名のWhois（JPRS WHOIS）では、次の情報を提供しています。
- 登録ドメイン名
- 登録ドメイン名のネームサーバ
- ドメイン名の登録年月日
- ドメイン名の有効期限
- ドメイン名登録者の名前(ne.jpドメイン名についてはネットワークサービスの名前)
- 技術的な連絡の担当者の名前、所属組織名、電子メールアドレス、電話番号
(属性型・地域型JPドメイン名の場合)
- 登録に関する連絡の担当者の名前、所属組織名、電子メールアドレス
(属性型・地域型JPドメイン名の場合)
- 登録者への連絡窓口担当者の名前、電子メールアドレス、電話番号、Web Page*、住所*
(汎用JPドメイン名の場合。*付きの項目は任意項目。)

そのうえで、近年では**ドメイン情報の更新漏れによる正確性**や**マーケティング目的での情報収集**などの課題があるようですね。

直近では、**WHOISの利用ってどうなの？**といったニュースも取り上げられるようになりました。

https://xtech.nikkei.com/atcl/nxt/column/18/00001/10146/

## Qiitaドメインを調べてみた

試しに私が持っているドメイン情報をWHOIS検索してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/f9f6f020-3513-4e75-a8ad-c39c8b3cef9e.png)

登録者名に関しては非公開にされていたので、個人的には**セキュリティ考えていますね**といった印象を持ちました。

:::note alert
WHOISに掲載されている担当者情報・メールアドレスを通じて攻撃を行うことも可能ですので、企業担当者はドメイン管理は慎重に行うことを推奨します。
:::

個人的にゆるく調べてみましたが、うまく活用できる反面、扱いには注意したほうがい機能だと思いました。

最後までお読みいただきありがとうございました！！

## 参考サイト

https://www.jstage.jst.go.jp/article/bplus/2008/7/2008_7_7_59/_pdf

https://www.oslaw.org/newsletter/074.pdf

https://www.soumu.go.jp/main_content/000724725.pdf

https://www.soumu.go.jp/main_content/000263716.pdf
ストーリーテリングを活用したスクラム開発

## ストーリーテリングを活用したスクラム開発

### **はじめに**

ストーリーテリングという技術をご存じでしょうか。これは、情報を単に伝えるのではなく、「物語の形」にすることで、**相手の共感を得やすくし、記憶に残りやすくする技術**です。歴史に残るプレゼンの達人達もこの手法を駆使しています。

### **1. ストーリーテリングの要素**

ストーリーテリングには、以下の要素が含まれます。

1. **登場人物（Characters）** - 物語の中心となる存在。主人公や対立者、協力者など。
2. **課題や問題（Conflict）** - 物語の核心となる課題や試練。これが関心を引き、展開が生まれます。
3. **行動と変化（Action & Change）** - 課題に対する行動と、それによって生じる変化。
4. **結末（Resolution）** - 課題が解決されたり、新たな気づきが生まれる部分。
5. **感情（Emotion）** - 感動や共感が生まれることで、印象に残りやすくなります。

スクラム開発においても、このストーリーテリングの手法は役立つ場面が多いです。本記事では、**スプリントプランニングとスプリントレビュー**の場面で、どのようにストーリーテリングを活用できるかを紹介します。

### **2. スプリントプランニングでの活用**

スプリントプランニングでは、ストーリーチケットの説明を行う場面があります。ただ単に「この機能を追加する」と説明するのではなく、**なぜこの機能が必要なのか、どのような背景があるのかをストーリーとして伝える**ことが重要です。

#### **実践例**

**例: ユーザープロフィール編集機能の追加**

- **現在の課題**：「現在、ユーザーがプロフィールを編集する機能がなく、名前を変更するだけでもカスタマーサポートに問い合わせる必要があります。このため、ユーザーの手間が増え、運営側も問い合わせ対応に時間を取られています。」
- **新機能による改善**：「この新機能を追加することで、ユーザーが自分でプロフィールを編集できるようになり、問い合わせ件数が削減され、運営の負担も軽減されます。」
- **デモを活用**：「現在のアプリの動作をデモし、新機能追加後の改善点を具体的に説明します。」

このようにストーリーテリングを意識することで、
- **開発チームとステークホルダーの仕様認識のズレが軽減されます。**
- **実装者がイメージしやすくなります。**
- **テストケースの洗い出しが直感的にできるようになります。**

### **3. スプリントレビューでの活用**

スプリントレビューでは、**今回のスプリントで実装された機能をお披露目します**。この際も、単なる機能紹介ではなく、ストーリーテリングの手法を用いることで、ステークホルダーにとって分かりやすいデモとなります。

#### **実践例**

**例: 商品のお気に入り機能の追加**

- **これまでの課題**：「ECサイトのユーザーが気に入った商品を簡単に保存する方法がなく、毎回検索し直す必要がありました。そのため、購入機会を逃してしまうことが多かったのです。」
- **新機能による変化**：「今回の新機能では、ワンクリックで商品をお気に入りリストに保存できるようになりました。これにより、ユーザーがスムーズに商品を管理でき、購入率の向上が期待できます。」
- **デモを活用**：「実際の操作画面を見せながら、どのように使うのかを説明します。」

このアプローチにより、
- **ステークホルダーが新機能の価値を直感的に理解できるようになります。**
- **仕様の認識のズレが減り、フィードバックが的確になります。**
- **次のスプリントに向けた改善点がスムーズに洗い出せるようになります。**

### **おわりに**

スクラム開発では、単に仕様を説明するのではなく、**「なぜこの機能が必要なのか？」をストーリーとして伝えることが重要です。**

ストーリーテリングをスクラムに組み込むことで、開発チームとステークホルダー間の認識が統一され、**プロダクトの付加価値を最大限に伸ばすことができます。**

スプリントプランニングでは、背景や課題を明確に伝えることで、開発者が仕様の意図を理解しやすくなり、実装やテストの質が向上します。スプリントレビューでは、ストーリーを用いたデモにより、新機能の価値が直感的に伝わり、より良いフィードバックを得ることができます。

ストーリーテリングを活用することで、**開発の方向性が明確になり、ユーザー視点での価値が伝わりやすくなります。** ぜひ、次のスクラムイベントでストーリーテリングを試してみてください。

### **参考**
https://www.hrpro.co.jp/miraii/post-1419/?utm_source=chatgpt.com
【AWS】TerraformでS3バケット作成 🔰

## 1. はじめに 📝
本記事では、TerraformのインストールからS3バケット作成のみを実施します。
筆者はCloudFormationは扱い慣れていますが、Terraformは未経験です。
構文すら分かってない状態ですが、今後使っていくことになりそうなので、
まずはどんどん触れてみようと思います。

📌 参考は公式ドキュメント  
 👉[What is Terraform?](https://developer.hashicorp.com/terraform)  

## 2. 本記事の環境 💻
以下の環境で実施しました。

- **PC**: M1 MacBook Air  
- **OS**: macOS Monterey 12.7.6  
- **Terraform**: v1.10.5
- **エディタ**: Visual Studio Code (VSCode) 

## 3. Terraformのインストール ⚙️
### Macにインストール
MacではHomebrewを使って簡単にインストールできました。

```zsh
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
```
以下コマンドでインストールできているか確認します。
```zsh
terraform -v

Terraform v1.10.5
on darwin_arm64
```

### その他の環境
WindowsやLinuxでのインストール方法については公式サイトに記載があります。
 👉[Install Terraform](https://developer.hashicorp.com/terraform/install)  



## 4. Terraformの基本概念 📌
Terraformの設定ファイルや基本コマンドを確認します。

### ファイル構成
以下のようなファイルを作成しました。

```bash:ディレクトリ
terraform-s3/
├── main.tf   # リソース定義
└── variables.tf   # 変数定義
```


### 基本コマンド
Terraformの基本的なコマンドを確認します。
```sh:コマンド
terraform init    # 初期化
terraform plan    # 実行プランの確認
terraform apply   # 変更の適用
terraform destroy # リソース削除
```



## 5. S3バケットの作成 🪣
ここからS3バケットを作成していきます。

### variables.tf の作成
今回はS3バケット1つのみですが、Terraformの基本を学ぶために作成しました。
```hcl:variables.tf
variable "bucket_name" {
  description = "S3バケット名"
  type        = string
  default     = "任意のS3バケット名"
}
```

### main.tf の作成
続いてmain.tfを作成しました。

```hcl:main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"  # AWSリージョン
}

resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name  # 変数を使用
}
```

### 適用手順
以下のコマンドを順番に実行しました。
```hcl:コマンド
terraform init
terraform plan
terraform apply
```
ちゃんと出来てました☺️
![CleanShot 2025-02-26 at 21.01.48@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007885/ece4b15a-4359-4a4c-a16b-35d6c112da43.png)

---
TerraformでS3バケットを作成する方法を試してみました！
今後もたくさんリソースを作成して、早く使いこなせるように学習していこうと思います。
既存リソースのインポートもできる？みたいなので、いづれ試してみようと思います！
サクラエディタの個人的に便利だと思った設定3選！

こんにちは！エンジニアの篠原です:penguin:
今回はサクラエディタで個人的に便利だと思った設定をいくつか紹介したいと思います！

前々回＆前回はこちら↓

https://qiita.com/pesysyon/items/2282ebfd730aea9232bb

https://qiita.com/pesysyon/items/11521b5fcd9ae988b0a8


## ①ウィンドウのグループ化

サクラエディタをいくつか開いたとき
デフォルトではそれぞれ独立したウインドウで開かれますが
これを一つのウインドウにまとめることができます。



設定＞共通設定＞タブバー＞動作モード欄で
ウィンドウをまとめてグループ化するにチェックを入れます。
またタブの外観欄の閉じるボタンを常に表示にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/5b11281a-8d4b-43d7-806a-4ce49cf05563.png)




<br>

実際に設定してみると…


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/6c1d820e-ca0e-4ecd-ba60-be8aa2549e89.png)


2ファイルが1つのウインドウで表示することができました:clap:
また閉じるボタンを常に表示にしたことで
各ファイルタブに閉じるボタンが表示されました。
これがとても便利です！








## ②ファイルの自動保存

こちらも設定しておくと便利な機能
ファイルの自動保存です:sparkles:

設定＞共通設定＞ファイル＞ファイルの保存欄の自動的に保存するに
チェックを入れるだけです。
保存する間隔も自由に設定できるので
自分の作業ペースに合わせることができます🙌

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/b6d47ad4-043f-49d4-92f8-63471922d91c.png)


## ③折り返し設定

サクラエディタは、以下のようにデフォルトで一定桁数での折り返しが設定されています。
これを折り返さないようにしたり、指定桁数で折り返すというような設定ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/7c253aa1-c65f-4801-aaff-83d228d2f985.png)

<br>
設定＞タイプ別設定＞スクリーンのレイアウト欄で
折り返し方法、折り返し桁数等を設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/ac6d2833-47d3-4712-8241-b76d6cc18dc3.png)

<br>
「折り返さない」で設定すると先ほどのファイルが以下のようになります！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/bc1489dd-cb51-4edb-9a91-a1f2de30a7ca.png)


## まとめ

今回は、サクラエディタで設定しておくと便利な設定を紹介しました。
どれも細かい設定ではありますが、痒い所に手が届く的な
便利な設定なので是非活用してみてください:thumbsup:

以上、篠原でした:penguin:
Azureの更新情報を効率よく受け取る方法(英語の情報を自動で翻訳する)

みなさまこんばんわ。
今日はエンジニアの皆様も頭を悩ませているであろう、最新情報のキャッチアップ方法です。

# 最新情報の仕入れ先
色々な方法があると思いますが、私は公式サイトが一番良いと考えています。
理由としてはやはり公式の発表なので間違いがなく、ときに不親切な案内もありますが情報の精度と速度という意味では最も信頼がおけるからです。

# 具体的なURL

Azureは以下のURLです。
https://azure.microsoft.com/ja-jp/updates/
ここです。
RSSのURLは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/d620725f-8fb8-4970-b750-fa23aad0d853.png)
この赤枠の部分にあります。

AWSはこちら。
https://aws.amazon.com/about-aws/whats-new/recent/feed/
私のQiitaにたまに出てくる<font color="Orange">**AWS兄さん**</font>から教えてもらいました！

# 具体的なプログラム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/aa153c4c-3d8e-45fc-aabd-03e5b0ce2749.png)
たったこれだけです。

# プログラムの詳細
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/2aa9dac8-1a88-444f-868a-74d837420ffe.png)
RSSフィードのURLに先ほどのURLを入力します。

# フィードのタイトルを翻訳する
今回は情報ソースが英語なので、日本語に自動で翻訳します。
まずはRSSのタイトルを翻訳します。

事前にAzure Translatorを作成し、Power Automateで接続できるようにしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/b3c91c6b-4a91-4fcc-9c3c-5f292eb16020.png)
赤枠の通り[ターゲット言語]を[日本語]に設定し、翻訳する内容に[フィード タイトル]します。(画像では入りきっていませんが、タイトル、となっています。)

# フィードの概要を翻訳する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/27322aa7-c5e7-4c0f-923d-65d11efc27d2.png)
次はフィードの概要です。
タイトルと同じ方法です。

# Teamsのチャネルに投稿する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/6fd0de71-0bd6-40ca-9e16-dd59df3a6437.png)
これまでの手順で翻訳したタイトルや概要をチャネルに投稿します。
画像の通りですね。

# 投稿された内容を確認する
RSSが更新されないと確認できませんが、無事投稿されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/a662cd5a-98f2-47b2-8d0a-4c1acee2fa8f.png)

色々と応用が利く内容になっているので、よければ皆様もご利用ください。

本日はこれまで。
緑によるABC394振り返り


# はじめに

投稿サボってごめんなさい(X使えるようになって浮かれてる)

> ユーザ名	hidehico
> コンテスト名	鹿島建設プログラミングコンテスト2025（AtCoder Beginner Contest 394）
> 順位	4264th / 12405 
> パフォーマンス	806
> レーティング	933 → 920 (-13) :(

えーはい、回文の性質を完全に忘れていました
ABCDの早解きにも失敗してこのようなザマです

### コンテスト中どうだったか
#### 開始3秒
acc newを実行

#### 開始54秒
AをAC

#### 開始 2分22秒

BをAC

#### 開始 16分

CをAC
問題文を誤読して時間をロスした

#### 開始 30分

1ペナ食ってDをAC
こちらも、解法がなかなか思い浮ばず時間をロスした

#### 時間が過ぎていく

回文がずっと頭をグルグルしたけど、結局EをACできず、コンテスト終了
こんな感じでした

### 使っているライブラリ

https://github.com/hidehic0/library

docstringを大幅に強化したぐらいです

そんじゃ一問ずつ感想書きますか

# [A問題](https://atcoder.jp/contests/abc394/tasks/abc394_a)

置き換えるか、個数の数だけ2をprint

後日vimでACした

ACコード(ライブラリ抜粋、vimもあります)

```py
S = s()

print("2" * S.count("2"))
```

```
:%s/[^2]//g
ZZ
```

# [B問題](https://atcoder.jp/contests/abc394/tasks/abc394_b)

普通にソートした

ACコード(ライブラリ抜粋)

```py
N = ii()
A = li(N, s)
L = []

for a in A:
    L.append((a, len(a)))

L.sort(key=lambda x: x[1])

for l in L:
    print(l[0], end="")

print()
```

# [C問題](https://atcoder.jp/contests/abc394/tasks/abc394_c)

WAは、ACとなるので、絶対に後ろ側にAは移動しないと言い換えられる
なので、逆順ループでACできた

ACコード(ライブラリ抜粋)
```py
S = list(s())

for i in reversed(range(1, len(S))):
    if S[i] == "A" and S[i - 1] == "W":
        S[i] = "C"
        S[i - 1] = "A"

print("".join(S))
```

# [D問題](https://atcoder.jp/contests/abc394/tasks/abc394_d)

SortedSetと、DFSでACした
もうちょっと簡単なやり方がありそう

ACコード(ライブラリ抜粋)

```py
S = s()
ans = len(S)
D = {"(": ")", "[": "]", "<": ">", ")": None, "]": None, ">": None}
nokori = SortedList([])

for i in range(len(S)):
    nokori.add(i)

L = []

for i in range(len(S) - 1):
    if D[S[i]] == S[i + 1]:
        L.append((i, i + 1))

while L:
    a, b = L.pop()
    ans -= 2
    na, nb = nokori.index(a) - 1, nokori.index(b) + 1

    if len(nokori) and na >= 0 and nb < len(nokori):
        na, nb = nokori[na], nokori[nb]

        if D[S[na]] == S[nb]:
            L.append((na, nb))

    nokori.discard(a)
    nokori.discard(b)

YN(ans == 0)
```

# [E問題](https://atcoder.jp/contests/abc394/tasks/abc394_e)

s + 回文 + sは回文という事に気づけなかったのが敗因

# 最後に

なんかひどかったですね(僕の結果が)
まあレートの被害はそこまでないし、まあいっか、ていうとこです

次回は頑張ります
DjangoのJSONFieldで痒いところに微妙に届かなかった話

JSONFieldの項目を別テーブルのキーとマッチさせてSubqueryで項目を取りたかったのです。

結果としては
```python
ename = Subquery(Event.objects.filter(eid=RawSQL("url_kwargs->>'eid'", [])).values('ename')[:1]),
```
として動いているんですが。

見ての通り、RawSQLを使うことになりました。

① 素直に考えると
```python
ename=Subquery(Event.objects.filter(eid=OuterRef('url_kwargs__eid')).values('ename')[:1]),
```
でいけそうなのですが、
operator does not exist: character varying = jsonb
と型が一致しないとエラーになりました。

② 型エラーならばと
```python
ename=Subquery(Event.objects.filter(eid=Cast(OuterRef('arguments__eid'),CharField())).values('ename')[:1])
```
とCastするとエラーは出なくなりましたがマッチするレコードがある場合でもenameが取得されてきません。
色々確認すると、JSONFieldをキャストするとダブルクオート(")で括られた文字列になるせいでマッチしなくなってました。

私はここで諦めて、RawSQLで実装することにしました。
もしRawSQLでなく実装する方法が分かる方がおられましたらご教示いただけると幸いです。

今回の事象を確認した各種バージョン
Python 3.12.3
django 5.1.5
PostgreSQL 16.6 (Ubuntu 16.6-0ubuntu0.24.04.1)

余談
ちなみに、AIに上記①でエラーになる旨の対処方法を聞くと②が提案されて、
②の状況を伝えて対処方法を聞くと①の提案が返ってきました。
次善策としてRawSQLでの方法も提案されますが。
ちゃんと有償の優秀なAIに聞けばより良い返答があるのかも気になるところです。
【Python】毎週勉強するシリーズ ～リスト～

# 概要
AI が流行ってる昨今 Python は必須級のスキルになってきてます。
時代に取り残されないようにコツコツと Python を勉強しようと思います！
三日坊主にならないように Qita でアウトプットしながら進めます💪

# 今日やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) のリストを理解する。

# リスト(list)

### 1. 基本的な書き方
`[...]` でリストを表します。他言語でいう「配列」ですね。

```py
colors = [
    'red',
    'green',
    'blue',
]
```
JavaScript を経験したことある人は馴染みがある書き方ですね👀

### 2. 異なる型の要素のリストを作る
異なる型の要素のリストを作ることもできます。
```py
a = [10, 'ABC']
```

### 3. リストの要素にアクセスする
リストの要素にアクセスする方法はいくつかあります。

#### 方法①：for で参照する
```py
a = [1, 2, 3, 4, 5]
for n in a:
    print(n)
```

#### 方法②：`[n]` で n番目の要素を参照する
```py
a = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
a1 = a[0]       # 0番目: 'A'
a2 = a[2]       # 2番目: 'C'
```
他言語と同様に最初の要素を 0番目と数えるようです。

#### 方法③：`[n:m]` で n番目から m番目の前まで参照する
```py
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a1 = a[2:4]     # 2番目から3番目: [2, 3]
a2 = a[2:]      # 2番目から最後: [2, 3, 4, 5, 6, 7, 8, 9]
a3 = a[:4]      # 最初から3番目: [0, 1, 2, 3]
```
JavaScript で言うと `slice()` をおしゃれな書き方にしてる感じですね！
この書き方は他言語含めて初めて見ましたが、慣れると便利そうだなぁって印象です。

#### 方法④：`[n:m:s]` で s個とばしで参照する
```py
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a1 = a[2:4]     # 2番目から3番目: [2, 3]
a2 = a[2:]      # 2番目から最後: [2, 3, 4, 5, 6, 7, 8, 9]
a3 = a[:4]      # 最初から3番目: [0, 1, 2, 3]
```

### 4. + 演算子を用いてリストを結合する
```py
print([1, 2, 3] + [4, 5, 6])       #=> [1, 2, 3, 4, 5, 6]
```

\+ 演算子で結合できるのは便利ですね～！
他言語だと関数をかまさないと結合できないことが多いので、シンプルに実装ができて良きですね◎

### 5. `len()` を用いてリストの個数を調べる
```py
print(len([1, 2, 3]))          #=> 3
```
他言語は `${配列}.length()` みたいな書き方が多いので、ちょっと慣れないです笑
とはいえシンプルな書き方なので、慣れたらコーディングの効率は上がりそうですね！

# 感想
今日はリストをやってみました！
慣れない書き方もありましたが、シンプルかつスマートだなぁって印象です。
今のところ躓く内容もないので良い調子です💪

今回も見ていただきありがとうございました。
また次回お会いしましょう！！

# 次回やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) のタプルを理解する。

# 【Python】初心者が毎日勉強するシリーズ一覧
- [【Python】初心者が毎日勉強するシリーズ ～数値・文字列・型～](https://qiita.com/ikeyuki0220/items/0feda65a9eb5aa7fe60d)
- [【Python】初心者が毎日勉強するシリーズ ～変数・定数～](https://qiita.com/ikeyuki0220/items/c9333d92b344c516084c)
- [【Python】初心者が毎日勉強するシリーズ ～リスト～](https://qiita.com/ikeyuki0220/items/4384e039bec2b542d6ac)
- [【Python】初心者が毎日勉強するシリーズ ～タプル～](https://qiita.com/ikeyuki0220/items/cc21a57af8eddda6fe07)
EntityFrameworkCore でログを出力したい！

こんにちは。エンジニアの藤原です。

最近は .NET Webアプリケーション開発でDBフレームワークである EntityFrameWorkCore(以下、EFCoreと記載)を使用していました。

実際にコーディングを進めていくと、EFCoreが動いたときにどのような動きをしたかログに出力して確認したいことが多々あるかと思います。
ログを確認できれば実際に発行されたクエリをみて様々な対処が可能になります。

当たり前ですが、EFCoreもデータベースにSQLを投げているので当然ログ出力が可能です。

ではどのようにログ出力をすれば良いのか。を今回は記事に残しておこうかと思います。

:::note info
本記事は以下を満たしている方向けです。
・簡単なプログラミング経験
・VisualStudioの使用経験
:::

# ログ出力方法
ログ出力するために、今回はDbContextクラスを改造します！
まだ手を加える前ですが、下記のようなDbContextクラスがあるとしましょう。

```cs
namespace TestProject.Test
{
    internal class TestDbContext:DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var builder = new SqlConnectionStringBuilder();
            builder.DataSource = @"(localdb)\\MSSQLLocalDB";
            
            builder.InitialCatalog = "TestDB";
            builder.IntegratedSecurity = true;

            optionsBuilder.UseSqlServer(builder.ConnectionString);
        }
    }
}
```

ログ出力をしたい場合には使用するデータベースをオプション指定しているコードに手を加えます。
今回はVSの出力ウィンドウに表示したいので、「System.Diagnostics.Debug.WriteLine」を使用します。

```cs
namespace TestProject.Test
{
    internal class TestDbContext:DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var builder = new SqlConnectionStringBuilder();
            builder.DataSource = @"(localdb)\\MSSQLLocalDB";
            
            builder.InitialCatalog = "TestDB";
            builder.IntegratedSecurity = true;

            // 追加
            optionsBuilder.UseSqlServer(builder.ConnectionString)
                .LogTo(message => System.Diagnostics.Debug.WriteLine(message));
        }
    }
}
```

コンソールで動かしている場合には「Console.WriteLine」を使用してください。
実際に確認してみるとVS上の「出力」ウィンドウでEFCoreの挙動を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/13c8883b-9887-4981-b159-f3eedd4655f9.png)

# 最後に
いかがだったでしょうか。
わずかな手間でEFCoreの実際の動きを確認できますので、開発中や不具合調査などで使わない手はないと思います。

開発において便利なEFCoreですが、今回のように実際の挙動を確認することは開発に欠かせません。
ぜひ試してみてください。

以上、藤原でした。
GitHubのリポジトリのWikiをローカルにSSHでクローンする

# GitHubリポジトリのWikiをローカルにSSHでクローンする

GitHubのWikiはプロジェクトのドキュメントや情報を共有するのに便利なツールです。

通常Webブラウザ上で編集しますが、ローカルにクローンすることでオフラインでの編集やバージョン管理が可能になります。

公式の手順は以下に記載されています。

ローカルでウィキページを追加または編集する
https://help.github.com/articles/adding-and-editing-wiki-pages-locally/

この手順ではHTTPSを使用しています。ただ、ほとんどの場合SSHでクローンした方が便利だと思うのでその手順をまとめました。（手順というほどのものではありませんが）

# 手順

Wikiページの右側にある「Clone this wiki locally」セクションではHTTPSのURLが表示されます。SSHにするにはSSHのURLが必要です。SSHのURLは構築する必要があります。それ以外は通常のリポジトリと同じです。

## 1. WikiのSSHのURLを構築する

URLは次のような形式です。

`git@github.com:ユーザー名(org名)/リポジトリ名.wiki.git` です。リポジトリ自体のSSHクローンURLの末尾の`.git`を`.wiki.git`に変えるだけです。

例えば `https://github.com/yt-dlp/yt-dlp/wiki` の場合、SSHのURLは `git@github.com:yt-dlp/yt-dlp.wiki.git` です。

### 2. ローカルにクローンする

ターミナルを開き、以下のコマンドを実行します。

```bash
git clone git@github.com:ユーザー名(org名)/リポジトリ名.wiki.git
```

github.com にアクセスするためのSSH鍵が設定されていればクローンできます。

あとの手順は通常のリポジトリと同じです。

# まとめ

GitHubのWikiをローカルにクローンすることで、より柔軟な編集や管理が可能になります。
SSHを使用することで、より便利にリポジトリにアクセスし、変更をプッシュできます。ぜひ活用してみてください。
Github Copilot入門

## はじめに
GitHub Copilotのライセンスを購入してもらっているのに、あまり使いこなせていなかったため主な機能についてまとめました。

### この記事が参考になる方
🙆 会社などでGithub Copilotを導入しているが、 **Tab補完(インラインコード補完)** しか使えていない方

🙅 既に**Copilot Chat,Inline Chat**などを駆使している方 

## 主な機能

**目的別おすすめ機能**
🔍 コードを理解したいとき
- 複雑なコードやレガシーコードの解析 → **Copilot Chat `/explain`コマンド**
- 特定箇所の動作確認 → **インラインチャット**

🐛 バグ修正・改善したいとき
- エラー修正、パフォーマンス改善 →**Copilot Chat `/fix`コマンド**
- リファクタリング、モダンな書き方への移行 →**Copilot Edits**

✅ テストを書きたいとき
- ユニットテスト自動生成 →**Copilot Chat `/tests`コマンド**

⚡ 効率的にコーディングしたいとき
- 新機能追加、コードの最適化 → **Copilot Edits**

✏️ 固定の制約やルールをコンテクストとして渡したいとき
- 予めCopilot ChatやEditsの挙動をコントロールしたい → **カスタム指示機能**

## Copilot Edits
Githubのように変更前と変更後を比較して、変更を適用することができる機能
それに加え、Github Copilotが機能提案や機能追加をしてくれます。
(現状1番hotなCursorのような機能🔥)

**使用方法：`cmd` + `shift` + `l` or copilotのメニューの`Copilot Editsを開く`を選択**



## Copilot Chat
対話形式でコードの質問や説明・改善をもらうことができる機能です。


**使用方法：`cmd` + `ctrl` + `i` or メニューの`チャットを開く`を選択**

chat内で`/help`と入力するとヘルプが表示されます。
その中で使用頻度が多そうなコマンドは下記の3つです。

1. `/explain` (コード説明)
ユースケース：新規参画したプロジェクトのコード理解、レガシーコードのリファクタリング前の分析
2. `/fix` (問題修正)
ユースケース：コンパイルエラーの修正、パフォーマンス最適化
3. `/tests` (テスト生成)
ユースケース：新機能実装時のユニットテスト作成、既存コードのテストカバレッジ向上






> [!TIP]
> 求めている回答によってEditsとChatを使い分けるのが良さそうです。
> - Copilot Editsは「どう変更すべきか」
> - Copilot Chatは「何をすべきか」「なぜそうなのか」


## インラインチャット
特定の箇所を指定して、ファイル画面内でチャットできる機能

**使用方法：copilotに聞きたい箇所を選択して、`cmd` + `i` or copilotのメニューの`エディタ内でのインラインチャット`を選択**


## インラインコード補完
コードを書いている最中にリアルタイムで提案が表示される機能です。

灰色の文字で提案されるのを受ければ入れる場合は、`Tab`キーを押します。

アクティブなユーザーかつ管理者のみを抽出


**使い所**
- mapやfilterなどの定型的なコードを書くとき
- コメントベースでコードを自動生成したい時
- コンストラクターやメソッドの引数を生成したい時


## カスタム指示機能
予め、プロジェクトのルールや方針を事前に設定しておくことでCopilot Chatの挙動をコントロールする機能です。

使用方法
1. リポジトリのルートに `.github/copilot-instructions.md` という名前のファイルを作成します。
`.github` ディレクトリがまだ存在しない場合は作成します。
2. Markdown 形式で自然言語の指示をファイルに追加します。

公式docsによると、記述内容は**短く**、 **その文章だけで意味が通じる(外部情報を参照させない)** ことが重要だそうです。

[GitHub Copilot のリポジトリ カスタム命令を追加する](https://docs.github.com/ja/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)

Copilot Editsで使用したい場合は、コンテキストに該当ファイルを含めることで毎回プロジェクトのルールや制約を書く手間が省略できます。

Edits画面を開いて、`ファイルの追加` からcopilot-instructions.mdを選択してください。




## 今後試したいこと
- Github CopilotとCursorの比較
- modelを変更して他のmodelとの出力結果(量・質)の比較
TypeScriptの個人メモ

# この記事について
TypeScriptで開発をする中で忘れたくない内容を個人的にメモしました。


# Object.keysの戻り値を文字リテラルユニオンの型にする
文字リテラルユニオンの型とは`("apple"|"orange"|"banana")[]`のような形式で、appleかorangeかbananaのいずれかの文字リテラルを値にもつ配列の型のこと。

`Object.keys()`の戻り値の型は`string[]`になる。これはオブジェクトのキーに指定できる型がstring型とnumber型の両方あることが原因。

これで生じる不都合としてはkeyの値をもとにしたSwitch文による条件分岐とか、下の例のような、元のオブジェクトとkeyから値を取得しようとしたりすると、エラーになること。

```ts
const testObj = {
  name: "shun",
  food: "ramen",
  hobby: "volleyball",
};

// testObeKeys:string[]
const testObeKeys = Object.keys(testObj);

// エラー:型 'string' の式を使用して型 '{ name: string; food: string; hobby: string; }' にインデックスを付けることはできないため、要素は暗黙的に 'any' 型になります。
// 平たくいうと"testObj"の値をキー指定で取得する時は、文字リテラルにしてね。というエラー（string型だと、キーに無い値も指定できてしまうから）
const rtn = testObeKeys.map((key) => {
  return {
    key: `NEW_${testObj[key]}`,
  };
});

```

上の例の場合、`Object.entry`を使えば解決するけど、今回は`Object.keys`の戻り値の型をstring[]型から文字リテラルユニオン配列型に変える

```ts
// 引数のオブジェクトのキーを文字リテラルユニオンの配列型で返す関数
const getKeys = <T extends { [key: string]: unknown }>(obj: T): (keyof T)[] => {
  return Object.keys(obj);
};

const keys = getKeys(testObj);

const rtn = keys.map((key) => {
  return {
    key: `NEW_${testObj[key]}`,
  };
});
```

分解して解説します。
まず大前提として、文字リテラルユニオンの配列型にするのだから、そもそもキーにnumber型が存在するオブジェクトは受け付けないようにする。
それをやっているのがここ。
```ts:
// extendsを使い、キーがstring型のobjのみ引数として受け付けるようにする。
<T extends { [key: string]: unknown }>(obj: T):
```

次に`getKeys`関数の戻り値の型`(keyof T)[]`の部分。
```ts
// keyof Tの戻り値は"name" | "food" | "hobby"となる。それを()で閉じて、[]を付けると、
// ("name" | "food" | "hobby")[]となる。
(keyof T)[]
```

`Object.keys(obj);`は通常string[]型を返すけど、関数の戻り値の型として`(keyof T)[]`を指定することで、string[]型が(keyof T)[]型にキャストされる。
（厳密には、関数の戻り値の型を(keyof T)[]型に指定しているので、TypeScriptが(keyof T)[]型と型推論してくれる）

め
Qiita始めてみました

とりあえず、よくわからないけど、Qiitaに登録してみた。
そうか、Markdownなんですよね～
とりあえず、Qiitaがどういう「場」なのか知りたくて登録してみました。
いろいろ試してみます。
基本、ポエムしか書かない（書けない）と思います。

【その後再編集】
当然、こうやって再編集はできると。
【UiPath】AssistantからOrchestratorを開く【Automation Cloud】

うっかりOrchestratorのブックマークを忘れた時などのため、Assistantから接続しているOrchestratorをブラウザで開く方法を記載する。

1. UiPath Assistantを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/e9c6cb67-04b3-4ed8-9a0e-c38e2538c14a.png)

1. 画面右上のプロフィールアイコン（ステータスアイコンの隣）をクリックし、「設定」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/f5d5b9f2-44f5-4d7f-9ea1-8affe28d66af.png)

1. 「Orchestratorの設定」から「サービスURL」の隣のアイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/fdb5d95d-a46f-46d5-9c2b-3e318ecc6065.png)

1. 既定のブラウザでOrchestratorが開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/6fe0a0dc-af47-4698-8f55-2c45094e4189.png)

ものぐさな私にとって、このようにキーボードを使わずにマウスだけで操作できる方法があるのは大変ありがたい。

## 動作環境
UiPath Assistant 2025.0.161
C# の配列いろいろ (Array, ArrayList, List<T>)

バージョン：.NET 8

| 名前空間 | クラス | 利用場面 |
|:-|:-|:-|
| System  | Array  | 要素数が固定<br>インデックス指定で読み書きがメイン  |
| System.Collections  | ArrayList  | 使わない（Microsoft 非推奨）  |
| System.Collections.Generic  | List\<T>  | 要素数が可変<br>検索や並べ替えなど柔軟な操作が必要  |

# System.Array クラス
https://learn.microsoft.com/ja-jp/dotnet/api/system.array?view=net-8.0

> System.Collections 名前空間のクラスとは異なり、Array には固定容量があります。 容量を増やすには、必要な容量を持つ新しい Array オブジェクトを作成し、古い Array オブジェクトから新しいオブジェクトに要素をコピーし、古い Arrayを削除する必要があります。

# System.Collections.ArrayList クラス
https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.arraylist?view=net-8.0

> 必要に応じてサイズが動的に拡大される配列を使用して IList インターフェイスを実装します。
> 新しい開発には クラスを ArrayList 使用しないことをお勧めします。 代わりに、ジェネリック List\<T> クラスを使用することをお勧めします。 クラスは ArrayList 、オブジェクトの異種コレクションを保持するように設計されています。 ただし、常に最高のパフォーマンスを提供するとは限りません。

# System.Collections.Generic.List\<T> クラス
https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.list-1?view=net-8.0

> インデックスでアクセスできるオブジェクトの厳密に型指定されたリストを表します。 リストの検索、並べ替え、操作を行うメソッドを提供します。

# ジェネリッククラスとメソッド
https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/types/generics

> ジェネリックを使用すると、コードでクラスやメソッドを使用するまで 1 つ以上の型パラメーターの指定を遅延させるクラスおよびメソッドを設計することができます。 ジェネリック型パラメーター T は、コンパイル時に型引数に置き換えられます。 
> .NET クラス ライブラリには、複数のジェネリック コレクション クラスが System.Collections.Generic 名前空間に含まれています。 System.Collections 名前空間の ArrayList などのクラスの代わりとして、ジェネリック コレクションをできる限り使用してください。

# System.Collections.Concurrent 名前空間
https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.concurrent?view=net-8.0

> 複数のスレッドがコレクションに同時にアクセス可能なスレッド セーフなコレクション クラスをいくつか提供します。