OmniAICreator/Qiita-1.07M huggingface dataset:
IaCとAWS CloudFormation勉強会に参加してみた

# 参加の目的と背景
IaCおよびCloudFormationに関して、AWS資格試験対策の書籍や問題集による学習だけではスキルの定着を実感できなかったため、ハンズオン形式での構築経験や実務における注意点・コツを知りたかったため



# 勉強会の概要
- 開催日時：2025年4月の日曜日　14:30～17:00
- 場所：渋谷のレンタルスペース
- 参加者の規模：10人程度
- 必要なもの・事前準備
    - PC（電源の準備をお忘れなく）
    - AWSアカウント（ログインできることを事前に確認）
- テーマ：AWS（CloudFormation）を使ったIaCをハンズオン形式で学ぶ
- 当日の流れ
    - 自己紹介
    - 講義とハンズオン
    - 質疑

https://primeanswer.connpass.com/event/349344/



# セッション内容
1. Infrastructure as Code（IaC）とは
2. IaCの特徴と利点
3. AWS CloudFormationの概要
4. CloudFormationの使い方
5. テンプレートの構造と書き方の紹介とハンズオン
6. CloudFormationを使いこなすには
7. 実践例とデモ



## 学んだポイントと気づき
### IaCのメリットやデメリット
コードで記述することによる変更履歴や自動化などのメリットは知っていたが、実務で用いる際の課題やデメリットをご紹介いただき、書籍や資格勉強では得られない学びがあった。特にテンプレートのメンテナンスに苦しみ、IaCをあきらめることや部署間での調整の手間（アプリ側とインフラ側）

### AWS CloudFormationの概要
CloudFormationを使ったリソース作成の流れや「テンプレート」「スタック」「チェンジセット」などの用語を理解できた。
　
### ハンズオンで実際に手を動かすことによる理解促進
書籍や資格勉強の知識インプットではCloudFormationでのリソース作成のイメージをつかめなかったが、マネジメントコンソールからYAMLファイルをアップロードしてリソース作成の一通りを手を動かして実施することで、理解が深まった。

 
### 実務でのコツや失敗の紹介
- 複雑化するとメンテナンスしきれないため、YAML/JSON内の記述は最小限にすること

    - 実務でよくある失敗談
        - 汎用性を求めて「Conditions」を多く記載。インフラを定義するテンプレートの記法と、条件を記述する記法の相性が悪く、可読性が著しく下がる。可読性が下がったテンプレートにより、メンテナンスが困難になった。
　
    - 対策
        - 明確な理由がない限り「Conditions」を用いないなど、YAML/JSON内の記述は最小限にすること

　 
- 意図せずリソースを削除しないよう、チェンジセットのアクション欄を確認すること
　
    - 実務でよくある失敗談
        - テンプレートで作成したリソースを意図せず削除してしまう事故。CloudFormationで起きるリソースの挙動に以下がある。「Replacement」は恐ろしい

            - 中断を伴わない更新 - No interruption
                EC2のタグの変更など、リソースの仕様を中断することなくリソースを更新する
　
            - 一時的な中断を伴う更新　- Some interruption
                インスタンスタイプの変更など、一部の実行を中断してリソースの更新を行う
　            
            - 置換 - Replacement
                置換先となる新しいリソースを作成してから古いリソースを削除する。
　
    - 対策
        - チェンジセット（スタックを更新した際の変更履歴）を活用し、アクション欄の内容が意図したものかを確認する。
　
- マネジメントコンソールでの手動更新など、IaC以外でリソース変更された際はドリフト検出機能を利用する
　
    - 実務でよくある失敗談
        - 誰かがコンソール上で設定を手動更新すると、IaCの値と差異が発生する
　
    - 対策
        - 定期的にドラフト検出機能を実行する　※全サービスにある機能ではない

クロススタック間の参照問題が実務でよくある失敗談として紹介、対策もご紹介いただいたが、理解しきれなかったので、本記事からは割愛してますm(__)m



# 感想
IaCおよびAWS CloudFormationの基礎を知ることができた。ハンズオンでAWS CloudFormationの理解がぐっと深まった。
　
ハンズオンに加えて、実務でのよくある失敗談とその対策を知ることができるなど、書籍や資格勉強では得られないものがあった。

主催者の皆様、ありがとうございました！



# 参考
https://speakerdeck.com/opelab/20210722-jawsug-cli-cloudformation?slide=42
https://qiita.com/emiki/items/30e57c8f972481646e41
Redmineに画像ペースト機能を追加

```js
window.issue_notes.addEventListener('paste', e => {
    const textarea = window.issue_notes
    const input = document.querySelector('input[type=file]')
    const dataTransfer = new DataTransfer()
    for (const i in [...e.clipboardData.files]) {
        let file = e.clipboardData.files[i]
        if (file.type.includes('image')) {
            let prefix = new Date().toLocaleString('sv').replaceAll(/\D/g, '')
            if (e.clipboardData.files.length > 1) prefix += `-${i}`
            const fileName = `${prefix}-${file.name}`
            // `![](${fileName})\n`
            textarea.setRangeText(`!${fileName}!\n`, textarea.selectionStart, textarea.selectionEnd, 'end')
            file = new File([file], fileName, file)
        }
        dataTransfer.items.add(file)
    }
    input.files = dataTransfer.files
    input.dispatchEvent(new Event('change'))
})
```

https://www.redmine.org/news/127

Allow pasting screenshots from clipboard (#3816 contributed by Takenori TAKAKI)

You can now paste image data from your clipboard when editing formatted text, eg. using CTRL+V. That will automatically upload the image as an attachment and append the appriorate tag in the text in order to display the image inline. No more need to save your screenshot as a file before uploading it to Redmine.
Note that you can also drag and drop an image file into the textarea to get the same result.
Amazon Q Business を使ってAIに社内規定を質問する

# やりたいこと
Amazon Q Business を使って、社内規定をAIに質問すれば返ってくる状態を作る。

# やったこと
## 1. 社内規定を作る
ChatGPTに適当に作ってもらう。下記のようなオーダーをした。
- 空想の株式会社テックイノベーションの就業規則をテキストファイルで頂戴。
- 上記のような会社で必要なルールを書き出していって。中身もちゃんと書いて。
## 2. 社内規定をconfluenceに転記
ページのリストはこんな感じ
![スクリーンショット 2025-04-07 224833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603181/ee934c0c-bd48-4f74-993c-957542e31b80.png)

中身はこんな感じ
![スクリーンショット 2025-04-07 224906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603181/038e946e-4a7c-4cce-9e7c-06891d0260e9.png)

## 3. Amazon Q に Data Source として登録する。
Data Source としてConfluenceを選ぶことができるようになっている。
サイトURL、ユーザーネーム、APIキーを入力すれば使える。
※https://docs.aws.amazon.com/amazonq/latest/qbusiness-ug/confluence-cloud-credentials-basic.html

## 4. Data Sync を行う
Data Sourceとして登録したconfluenceの情報を同期する

## 5. コンソールからAIに質問してみる
- 回答内容は正しかった。
- 回答のソースとセットで回答してくれる。
![スクリーンショット 2025-04-07 234829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603181/040a9499-bc23-401a-b98f-dac7d9591ae5.png)
![スクリーンショット 2025-04-07 234438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603181/44349302-d8f8-44b9-bc9a-5805d20f2508.png)
![スクリーンショット 2025-04-07 234452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603181/a85dc49c-2646-49ed-929f-ea478713a4a2.png)
AWS SAPがAzure初めて触ってみた①

# 背景
- 職場ではマルチクラウドの利用が進んでおり、AWSしか理解していないのはまずいので基本的な挙動を学習するために無料アカウント利用分で触ってみる。
- アカウント作るのめんどくさい人は公式のチュートリアルでサンドボックス環境使えるので良いかも
    - https://learn.microsoft.com/ja-jp/

# AWSとの比較資料
- 公式
    - https://learn.microsoft.com/ja-jp/azure/architecture/aws-professional/
- サービス対応表
    - https://qiita.com/u_pocket/items/4a50aafb10652fa9f40e

# さっそく始める
- Azureのアカウントから持っていないので作成
    - AWS同じく最初の１年間は無料枠が用意されているみたい。
https://azure.microsoft.com/ja-jp/pricing/purchase-options/azure-account/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/3e76e231-398d-4995-a57d-59c2a69e9436.png)

- アカウントの基本情報を入力して作成
    - 最初の30日は$200のクレジットが付与
    - 無料枠を超える場合は勝手に課金されるわけではなく、超えた分を払うか確認が入るっぽいので良心的かも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/c555ce5f-ee6e-4213-adcf-811aebb3e61a.png)

- 作成が完了してAzureのトップページにきた
AWSではマネージドコンソールというがAzureではAzureポータルと言うらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/dff8db22-41d1-4ace-814a-fe03e40f89b7.png)

- 試しにEC2に該当する仮想マシンを作成してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/9b05a545-a012-49d2-a911-609e9bfb5a1d.png)
- 鍵認証方式でリソースを作成し、ssh接続してみた。Azureでは初期ユーザはazureuserとなるらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/3e6745eb-a321-4af6-bbd5-cec21f3c40c4.png)
ちなみに仮想マシンを作成する際にネットワーク部分などは無ければ自動で作成されたり、冗長構成、負荷分散のオプションで簡単に設定出来たりと親切な感じがする
- Webサーバを試しに立てようと思うのでhttpdをインストールし起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/f00adfa0-3260-476a-ac63-142ab918aac9.png)
- httpdでページ表示させようとするもタイムアウトしたので、おそらくSecurityGroup的なものだろうと確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/0001e1e2-1462-4a85-930d-13f18354f303.png)
結果的に「ネットワークセキュリティグループ」というものでアウトバウンド、インバウンドのルールをしていしていたので80のインバウンドを許可
- httpdのconf周りを編集してテストページをindex.htmlとして作成してあげると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/723a13fd-b4cd-447d-bfd3-8b1da7bf5230.png)
無事webページが表示されることを確認できた。

# まとめ
- AWSの文言が若干変わるくらいでここまではドキュメント無しでもすんなり出来るレベルだった。
- 最初はDBとS3的なものも作成して、冗長構成のWebサーバでも作るかと意気込んでいたが、ここで力尽きてしまった。元気が出たらさらに追加で作成していこうと思います。（無料クレジットのあるうちにやらないと。。）
创建品目外注的PO的时候报错：「構成品目の決定は不可能です」

在创建品目外注（明細カテゴリ=3）的时候报下面的错误。
![img_v3_02l1_c9c2822f-d3d1-4c0f-ace8-1bfba5ef89dg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/b410b3ec-89d8-42c0-bc28-f00bd435694c.jpeg)

但是SAP系统里面的确维护了成品对应的原材料的信息。
※CS03，输入品目，工厂，bom用途可以查询
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/d76c007a-8af3-4629-94c0-18fd5633d01a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/74075ba4-a17a-4600-a776-225d060d9e8e.png)

原因分析
BOM的有效期间是2025/04/07～9999，但是承认日付是2025/04/02，BOM有效期未覆盖承认日期，所以报错。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/cc20f162-f392-4f37-9ded-7c07d75727d7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/48c86139-2901-4fdd-82e4-157cc1ee14ed.png)

💡 PO建单时 SAP 检查 BOM 有效性的流程
开始（PO创建）

     ↓

输入 传票日付（Document Date）
输入 納入日付（Delivery Date）

     ↓

系统根据【納入日付】判断  
是否需要展开成品的BOM？

     ↓
     
是 → 查询BOM主数据（CS03）

     ↓

BOM主数据中有没有  
覆盖【納入日付】的有效版本？

     ↓
     
【有有效BOM】
     ↓
继续 → 成功生成PO

【没有有效BOM】
     ↓
报错 → 構成品目の決定は不可能です
[Vue.js] Options API と Composition API の違い



## In a nutshell
Vue.js には主に Options API と Composition API の2つの記述方法がある．前者は学びやすく，後者は拡張性や再利用性に優れる．プロジェクトの規模や目的に応じて使い分けることが重要である．


## はじめに
Vue.jsについて学ぶ際に，最初に困ったのが Options API と，Composition APIだった．両者の違いについて改めて理解をする為に，以下の記事として概要を纏めた．


## 予想される読み手
 - Vue.js について初学者であり，学びたい
 - 将来的にフロントエンド開発に携わる予定のある人


## 1. Options API

Options API とは，Vue 2 系まで主に使用されていた記述スタイルであり，コンポーネントの構成要素を `data`, `methods`, `computed`, `watch` などの「オプション」として分けて記述する方式である．

### 特徴

- コンポーネントの構成が明確で読みやすい  
- 初学者にとって直感的で理解しやすい  
- 複数の機能が絡み合う場合，処理の見通しが悪くなりやすい  
- 複雑なロジックの再利用が難しい（共通処理の切り出しが困難）

### 実例（カウント機能）

```vue
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>
```

このように，状態 (`count`) は `data()` に，動作 (`increment`) は `methods` に定義する．構造が明確であり，小規模なプロジェクトでは特に有効である．



## 2. Composition API
Composition API は，Vue 3 系で導入された新しい記述スタイルである．ロジックを `setup()` 関数や `<script setup>` の中に記述し，関連する状態と振る舞いを関心ごとにまとめることができる．

### 特徴

- 状態とロジックを同じスコープに定義できるため，見通しが良い  
- 機能単位でコードを整理できるため，大規模開発に向いている  
- 関数として切り出しやすく，ロジックの再利用性が高い（Composable）  
- TypeScript との相性が良く，型安全な開発がしやすい  
- 初学者にはやや抽象度が高く，慣れるまでに時間を要する  

### 実例（カウント機能）

```vue
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>
```

`ref()` を用いてリアクティブな状態を定義し，関数も同じスコープ内で記述することで，処理がまとまりやすくなる．



## 両者の比較表

| 項目                   | Options API                             | Composition API                            |
|------------------------|------------------------------------------|--------------------------------------------|
| 導入バージョン         | Vue 2 〜                                | Vue 3 〜                                   |
| コードの分離方法       | 機能ごとに分離（`data`, `methods` など）| 関心ごとに分離（状態と処理を同じ場所に） |
| ロジックの再利用性     | 低い                                    | 高い（Composable 関数の利用が可能）      |
| TypeScript との相性    | 普通                                    | 非常に良い                                 |
| 初学者への分かりやすさ | 高い                                    | やや難しい                                 |


## どちらを使うべきなのか

 - 学習初期や小〜中規模のプロジェクトでは Options API を選ぶと，学習コストが低く始めやすい．  
 - 機能の再利用性やロジックの整理が重要な 中〜大規模プロジェクトでは Composition API を選ぶことでメリットが大きい．  
 - Vue 3 では，どちらの記法も利用可能であり，両者を併用することも可能である．．

 - 初学者にとっては Options API の方が理解しやすいとされているが，個人の考えとして，今後のスキル拡張性，柔軟性を担保するという観点ではComposition API に早い段階で慣れておく方が良いと感じている．

## Summary

 - Options API は Vue 2 系で使用されていた，直感的な記述方法である
 - Composition API は Vue 3 で導入され，柔軟かつ再利用しやすい
 - 小規模な学習用途では Options API が適している
 - 大規模開発や TypeScript との連携を意識するなら Composition API が有利
 - 両者は Vue 3 において共存でき，プロジェクトに応じた選択が可能
 - 将来の技術拡張性を考慮し，Composition API に慣れるのも一つの選択肢である

## References

[Vue.js GUIDE Getting Started Introduction](https://vuejs.org/guide/introduction.html)
[Vue.js GUIDE Extra Topics Composition API FAQ](https://vuejs.org/guide/extras/composition-api-faq.html)
論理演算子（&&　||　!）を使った条件式

Javaのソースコードで、複雑な条件を使った分岐をしたいときは、「論理演算子」という演算子を使います。

論理演算子の種類には、次のようなものがあります。

### 1. `&&` (AND)
 `&&` 演算子を使った式は、**左辺・右辺がともにtrue**になる場合にのみ、条件がtrueになります。
例を見てみましょう。

```Java:&& の例１
a >= 3 && a == 2
```
上記の式では左辺・右辺の両方が成立することはあり得ないため、falseになります。

```Java:&& の例２
a >= 3 && a == 4
```
上記の式ではaの値が4のときに左辺・右辺の両方が成立するため、trueになります。

### 2. `||` (OR)
 `||` 演算子を使った式は、**左辺・右辺のどちらかがtrue**であれば、条件がtrueになります。
例を見てみましょう。

```Java:|| の例
a >= 3 || a == 2
```
上記の式の場合、左辺・右辺のどちらかがtrueであれば良いため、
**aの値が3以上または2のときtrue** になります。
また、aが1以下の場合はfalseになります。

3以上の場合の条件をみて、その結果がtrueであれば、「a==2」を見ずに、
条件の処理を実施します。

### 3. `!` (NOT)
 `!` 演算子は、オペランド(※boolean型の値)を1つとる単項演算子で、
**オペランドがfalseの時に条件がtrue**になります。
例を見てみましょう。

```Java:! の例
!(a == 6)
```
この式では **aの値が6以外のとき、true** になります。
注意点は、 **a == 6** を先に比較するため、この条件式を（）で囲う必要があります。
その条件に対して、`!` 演算子で否定します。

***
### 組み合わせて使う
複数の条件を組み合わせて使うこともできます。  
例えば「 `&&` 」で分岐する式を2つ用意した後、それぞれを（）で囲んで論理演算子の左辺・右辺に配置することで、それらの条件を踏まえた上で更に分岐をさせることができます。

例を見てみましょう。

```Java:条件式の組み合わせの例
(age >= 18 && gender == "男性") || (age >= 18 && gender == "女性")
```
この式では、左辺と右辺の条件は以下です。
* 左辺  `(age >= 18 && gender == "男性")` でtrueになる条件 
  ⇒　**ageの値が18以上でgenderの値が男性** 
* 右辺  `(age >= 18 && gender == "女性")` でtrueになる条件
  ⇒　**ageの値が18以上でgenderの値が女性** 

最後に、これら2つの条件を `||` 演算子を使って判断します。


どちらかがtrueであれば良いので、
　**age（年齢）が18以上の**
　**gender（性別）が「男性」、「女性」どちらの場合でも true**となります。
***
### まとめ
if文などの中で論理演算子を使えば、より複雑な分岐をする処理ができるようになります。

一見「 `==` で良いのでは？」と思うような `!` 演算子は、実は一番使うようになる演算子です。 

冗長的なソースコードを防ぐためにも、論理演算子の練習をして慣れていきましょう！

***
### 参考文献
* やさしいjava 第6版
 高橋麻奈 (著),  SBクリエイティブ, 2016年8月
【Django】親→子？子→親？モデルのリレーション取得方法を整理してみた

# はじめに
この記事では、コードレビューを受けた際に生まれた
- この2つのコードって結局同じ結果じゃないの？
- どうやって使い分ければいいの？

という疑問を整理しながら、「親→子」・「子→親」関係のアクセス方法についてアウトプットしていきます。

# 例
以下が今回のモデル構成です。
ユーザー、投稿、いいねの3つを用意しました。
```python
class User(models.Model):
    name = models.CharField(max_length=100)


class Post(models.Model):
    user = models.ForeignKey(User, related_name="posts", on_delete=models.CASCADE)
    content = models.TextField()


class Like(models.Model):
    user = models.ForeignKey(User, related_name="likes", on_delete=models.CASCADE)
    post = models.ForeignKey(Post, related_name="likes", on_delete=models.CASCADE)
```

# どっちも同じ結果になるコード
今から2つのコードを比較していきます。
以下のコードの目的は
**プロフィールページにおいてユーザーがいいねした投稿一覧を取得**することです。
## ① 子→親 （`Like`起点）
```python
user = User.objects.get(id=1)
likes = Like.objects.filter(user=user).select_related("post")
posts = [like.post for like in likes]
```
実行順序は以下です。
1. `users` テーブルから IDが「1」のユーザーを取得
1. このユーザーが押した「いいね（`Like`）」をすべて取り出す
1. 各 `Like` に紐づく投稿（`Post`）も、DBから一緒に取得（`select_related("post")`）
1. for文で、各 `Like` に対して投稿を取得してリストにする

## ② 親→子 （`User`起点)
```python
user = User.objects.get(id=1)
likes = user.likes.select_related("post")
posts = [like.post for like in likes]
```
実行順序は以下です。
1. `users`テーブルから IDが「1」のユーザーを取得
1. このユーザーが持つ「いいね（`user.likes`）」をすべて取り出す
1. 各 `Like` に紐づく投稿（`Post`）を、DBから一緒に取得（`select_related("post")`）
1. for文で、各 `Like` から投稿を取り出してリスト化

:::note warn
細かく説明しているので2,3はあえて分けています
:::

# どのようなケースで利用するか
同じ結果を得られる2つのコードでも、「何を起点にしてデータを取得するか」で使い分けができます。
## 子→親
`Like`, `Post`, `Comment` など「アクション的なデータ」からユーザーや投稿にアクセスしたいときです。
### 具体例
- 通知一覧：誰がどの投稿にいいね・コメントしたか
- タイムライン：投稿＋投稿者情報
- リアクション履歴：最近のいいね履歴など

```python
# 投稿＋投稿ユーザー情報をタイムラインで取得
def get_post_list():
    return Post.objects.select_related('user')

posts = get_post_list()

for post in posts:
    print(post.message)           # 投稿本文
    print(post.user.username)     # 投稿したユーザー名
    print(post.user.profile_img)  # 投稿したユーザーのプロフィール画像
```

## 親→子
ユーザーを起点に、関連する投稿・いいね・コメントなどを取り出したいときです。
### 具体例
- プロフィールページ
  - 投稿一覧
  - いいね一覧

```python
user = User.objects.get(id=1)

# 「ユーザーが」.「いいねした」.「投稿一覧」
user.likes.select_related("post")
posts = [like.post for like in likes]
```

# 今回のケースでは
今回のように「特定のユーザーがいいねした投稿一覧を取得する」という目的では
**親→子（User起点）** でデータを取得するのがベターです。

理由は、そのユーザーに紐づいたデータ（いいね）を扱っているため、`user.likes.select_related("post")` のように記述することで、可読性が高くなり、将来的にコードの保守や拡張もしやすくなるからです。

# 最後に
今回のアウトプットでは
以下の3点が理解できました。
- 「親→子」「子→親」は、目的や視点に応じて使い分ける
- ユーザーが中心なら `user.likes.select_related(...)` のように親→子が自然
- 通知や全体表示など、アクションを起点にするなら子→親も有効

もし、私のアウトプットで間違っている部分や
もっと別の書き方がいいんじゃないかと思う方は
是非コメントをお願い致します。

最後まで読んでいただきありがとうございました。
自留Java sliver 

1.Lambda式里捕获的变量必须是final或有效final，也就意味着它不可以被更改。
2.调查class和module的依存关系时可以使用以下代码
jdeps--list-deps/Java-show--module-resolution
3.switch句子必须声明变量的值，否则java会自动判断为null，导致在分支配对时出现抛出异常
4.抽象方法必须在子类中实现
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051474/e1ad294e-bf7e-4050-903b-80c754ae102a.png)

5.创建数组时必须写好每个维度的值
6.C继承B，B继承A。C中写入super，意味着C可以访问A
7.Class在同时接触两个interface，并且这两个interface有相同的方法时，会发生编译错误。因为实行时无法区别究竟使用哪个接口。
8.10.0是double
9.X++为后置操作，先打印出原有的X值才会进行下次循环
10.listof表示不允许添加任意值
11.Localdate在没有特别声明的情况下显示的格式为yyyy-mm-dd
12.Pow指的是幂次方，比如mathpow(2,3)结果为8
13.模块a依赖模块b，用的是requires。访问test包，则用exports test


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4051474/019b9de3-6ef1-4935-a257-cc2a5324c860.png)
IBM Cloud：マスター・アカウントの変更方法(2025年版)

# 前書き

本稿は以前ある記事の更新版となります。

https://qiita.com/dicekm-i/items/df2433ff8648c884f127

アカウントオーナー不在の際のオーナー変更の方法を追記しましたので、オーナー変更時の１ケースとしてぜひ参考にしてください。
(ケース対応者によって必要な情報が異なる場合もありますのでご注意ください)

# はじめに

IBM Cloudを長く利用していると、最初の契約時に登録した所有者（マスター・アカウント）を変更したいといったことが、たまにあります。
※アカウントオーナーのメール・アドレスを共有のものにしたいといった場合にも有効です。

この記事ではその方法について記載いたします。
（尋ねられたので、docsより少し丁寧に書いてみました...)

ちなみに IBM Cloudのマニュアル上はこちらに記載があります。
[アカウントの所有権の移動](https://cloud.ibm.com/docs/account?topic=account-transfer)

マスター・アカウントの変更する場合は、大きく２つの種別があります。
① 既存のアカウントオーナーが存在する場合（自分がアカウント・オーナーの場合）
② 既存のアカウントオーナーが退職などで不在となり、ポータルにログインできない場合

どちらの場合も「ケース(Case)」を起票して実施いたします。
②のほうが、本人がいないため、「証明書の添付」など少し複雑になります。
① 既存のアカウントオーナーが存在する場合（自分がアカウント・オーナーの場合）

手順は以下になります。

1. 新しくアカウント・オーナーにしたいユーザの作成とアカウントへの招待
1. アカウント・オーナーで、アカウント・オーナー変更のCaseを起票

Caseをあげる前に、手順1でアカウント・オーナーを委任するユーザを作成して、そのアカウントに招待しておくと、手順2のケースでのやり取りがスムーズになります。

ユーザの招待の方法については省略いたします。
例えば、こちらの記事とかご参考にしてください。
# ① IBM Cloudでのユーザ招待、他ユーザへの多要素認証の要求設定

手順1でアカウント・オーナーのユーザを招待した後、ケースを起票します。
ケースの内容は以下のような感じで大丈夫です。

### a) 「ケース作成」の画面で、「Account」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2625926/a4889b68-807a-428b-925f-027b75e759c0.png)

### b) 「アカウント変更依頼」のケースを作成

以下の文面はあくまでも例ですので、本文は自分好みに変更してもらえればと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2625926/6e1c9a44-3cdd-4821-8e42-a024a6bd9784.png)

```Text:Subject
Request for changing the master account
```

```Text:Description
Hello,

We would like to transfer ther ownership of the current owner account <現在のアカウントオーナーのIBMid(ユーザーのメールアドレス)> to my other member <変更先のIBMid(ユーザーのメールアドレス)>.
We have already added him to this account.

Would you please do this ownership movement?
Is there any more information you need from me?

Thank you.
```

このあと、Case上で"承認（Approval）"プロセスがまわって、アカウント・オーナーが変更されます。基本的にはすぐに（掛かっても一両日くらいで）承認されると思います。
変更されましたら、必要に応じて、アカウント・プロファイルも変更してください。（必須ではありません）

ケースの作成は本人以外でも作成することは可能ですが、承認プロセスの途中で、アカウント・オーナーからの承認を求められる場合があります。その場合は、アカウント・オーナーの方にログインしていただき、"Approved"とCaseにインプットしてもらえればと思います。
# ② 既存のアカウントオーナーが退職などで不在となり、ポータルにログインできない場合

ちなみにアカウントオーナが退職などして不在な場合、基本的には上の手順と同じですが、以下の内容をケースに記載する必要があります。

a.会社の公式レターヘッド
b.会社の定款 (該当する場合)
c.当該個人がもう会社とは関係ないという記述
d.アカウント所有者を新しい所有者に変更したいという説明
e.新しいアカウント所有者の姓名
f.新しいアカウント所有者の E メール・アドレスおよび電話番号
g.会社の執行役員の署名
h.移動するアカウントのアカウント番号

過去実施したケースでは、c,d,e,f,g,h があれば大丈夫です。（e,f,hは①でも必要）
g以外の情報についてはCaseの文面にて共有すれば問題ないです。

gについては、新しいアカウントオーナー変更に対する文面に対して上司の直筆署名入りのPDFファイルをケースに添付します。ワードファイルに記載した例文はこちらです(ワードファイルのダウンロードは[こちら](https://ibm.box.com/s/bfsacq2549ud6wedzxne1pg85bictmar))。

![スクリーンショット 2025-05-09 0.10.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2625926/0ae4cfd2-8ec7-4da2-b537-0c65476b52be.png)

こちらのワードファイルには必要な情報(オーナー移行に必要なa~hの情報)が含まれております。


また、gの別パターンとして直筆署名のPDF+承認メールでも問題ないです。
ワードファイルと同様の内容(I would likeから始まる文章)を記載したメールに対し、上司に承認の旨を記載した返信をもらってください。

回答分サンプル
「承認します（As Manager, I approve to proceed the Account Owner Change.）」

以上となります。
【Apple】Mac OS Sequoia 15.4 で Android Studio クラッシュ する場合


なぜ? こうなるのか。

![sc 2025-04-07 at 22.39.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/f8afde92-4426-4f1c-ae30-3d31be765e11.png)

以下2つに対応したらいけた。

[👉️ IntelliJ-based apps (and Fleet) crashes on macOS 15.4 Beta 3 (developer beta) : JBR-8422](https://youtrack.jetbrains.com/issue/JBR-8422)

[👉️ IDEa crashes at startup on macOS if macOS keyboard shortcuts for Window tiling have been changed : JBR-8562](https://youtrack.jetbrains.com/issue/JBR-8562/IDEa-crashes-at-startup-on-macOS-if-macOS-keyboard-shortcuts-for-Window-tiling-have-been-changed)


以下詳細、ありがとうございます。


### ■ 詳細参考

https://android.benigumo.com/20250407/crash-idea-sequoia/
QA志向タイプ診断が生まれるまでのAIとの掛け合い

## はじめに
ざっくりと、伝えたいことを先に書いておきます。
・UIUXの改善提案だけがQAのステップアップではない
・ちょっとしたアイデアをAIに投げることで、思考が整理されていく体験がとても良い

では、本編をどうぞ！

## 本編

> 「QAエンジニアの中には、プロダクトをよくしたい人とプロセスを良くしたい人がいるのではないだろうか」

という、ふと舞い降りてきた発想をきっかけに、  
**QAにおける“成長の方向性”は一つではない**のでは？と考え始めました。

その考えを整理していく中で。ChatGPTとの対話を活用しながら、  
アイデアを構造化し、分類の仮説を立て、診断プロトタイプの設計まで形にしてみたことを記事にしました。

---

## プロダクト志向ばかりが注目されがち？

こんな声を耳にすることがあります。

- 「UX改善のアイデアが出せない自分って、QAとしてイケてないのでは？」
- 「ドメイン知識がないと成長できない気がする…」

こうした悩みの背景には、  
**“QAとして価値を出すには、プロダクト志向（後述）であるべき”**  
という雰囲気が少なからずあるように感じました。

でも、本当にそれだけが正解なのでしょうか？

---

## 「志向」という切り口で考えてみた

AIとの壁打ちを通じてこの違和感を掘り下げていったところ、  
**QAとしての関心や貢献の方向性にはいくつかパターンがあるのでは？**  
という考えに至りました。

そこで見えてきたのが、以下のような4つのタイプです。

---

## QAの4つの志向タイプ

| 志向タイプ     | よくしたい対象         | キーワード例                         |
|----------------|--------------------------|--------------------------------------|
| プロダクト志向 | ユーザー体験・仕様       | UX改善、提案、ユーザー目線         |
| プロセス志向   | 開発フロー・仕組み       | テスト設計、再現性、自動化         |
| 関係性志向     | チーム間の認識・対話     | 仕様読み合わせ、ファシリテーション |
| 組織志向       | 評価制度・育成・文化     | チームづくり、教育、制度設計       |

このように整理することで、  
「自分はどこを改善したいと思っているのか」が少し見えやすくなりました。

---

## 診断プロトタイプをつくってみた

さらに、これを **簡単な診断形式にしたら面白いかも？** となり、  
以下のような形でプロトタイプを設計しました。

- 各志向タイプにつき5問ずつ、計20問の自己評価式質問票を作成
- Googleフォームで回答
- スプレッドシートでスコアを集計
- レーダーチャートで結果を可視化

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984275/ae7bce42-0764-40f0-acc3-fad3b04e0b5c.png" alt="QA志向タイプ表" width="300">

この診断も、AIとやり取りしながら形にすることができました。  
ここまでの所要時間およそ2時間程度。
AIを活用することで、ここまで早く進められるのかと実感しました。

肝心な診断の手応えはというと...。
自分を実験台として試しましたが各志向にあまり差が出ず、診断にするには改善の余地がありそうです。
自分が興味ある志向を選ぶ程度でいいのかも？と思い、
診断の作成と運用はいったん見送りにしました。

---

## おわりに

**QAとしての成長にはいろんな方向がある**のではないでしょうか。

「プロダクトを良くする」のは良いことです。
しかも提案数や採用数は定量化しやすく、成果が見せやすい側面もありますよね。

ただその裏で、
・プロセスを整える人がいるから再現性が保たれてるし
・関係性を築いてくれる人がいるから職種間が円滑なのだし
・組織志向の人がいなかったら、制度も文化もボロボロに...

なんてこともあるわけです。
そういった視点から価値を発揮している人たちも、同じように認められていいと思うのです。

そしてもうひとつ、**こういう整理や内省のプロセスに、
AIがかなり良い相棒になってくれる**という発見はとても大きいです。


> 「QAエンジニアの中には、プロダクトをよくしたい人とプロセスを良くしたい人がいるのではないだろうか」

という発想に端を欲した出来事でしたが、これがたったの数時間で、
4志向の作成および診断ツールのトライアルまでできたのだと思うと
AIの効率化への貢献は計り知れないものがあります。
特に、診断のための質問20個を爆速で考えてくれるのは本当に助かりました。


会話の中で、上述の**4志向×スタイル（リーダー型、支援型など）** という形で整理してみるのも面白そうだね、という話にもなったので、このあたりも今度掘り下げてみたいと思います。
LSLのデータ型まとめ

# 📦 LSLの主なデータ型まとめ

## 基本データ型一覧

| データ型       | 説明                                  | 使用例                              |
|----------------|---------------------------------------|--------------------------------------|
| `integer`      | 整数（-2,147,483,648 ～ 2,147,483,647） | `integer count = 5;`                 |
| `float`        | 小数（単精度）                        | `float time = 3.14;`                 |
| `string`       | 文字列（セリフや名前など）            | `string name = "賢ちゃん";`         |
| `key`          | UUID（オブジェクトやアバターの識別子）| `key avatar = llDetectedKey(0);`     |
| `vector`       | 3次元の位置やサイズ（x, y, z）        | `vector pos = <10.0, 20.0, 30.0>;`   |
| `rotation`     | 回転（クォータニオン）                | `rotation rot = <0, 0, 0, 1>;`       |
| `list`         | 複数のデータを1つにまとめる配列的な型 | `list names = ["A", "B", "C"];`      |

---

## 型ごとの詳細

### `integer`（整数）
- 演算OK（`+`, `-`, `*`, `/`, `%`）
- `TRUE` / `FALSE` は `1` / `0` として扱われる

### `float`（小数）
- 小数点あり、時間や比率、座標などに使う
- 丸め誤差に注意（例：0.1 + 0.2 ≠ 0.3）

### `string`（文字列）
- メッセージ、名前、UUID文字列の保持などに使う
- 結合は `+` 演算子でOK → `"Hello " + name`

### `key`（UUID）
- オブジェクトやアバターなどを識別する「ユニークID」
- `llDetectedKey()` や `llGetOwner()` で取得

### `vector`（座標・サイズなど）
- `<x, y, z>` の3D座標で構成
- 位置、色、サイズなどで使用される

### `rotation`（回転）
- `<x, y, z, s>` のクォータニオン形式
- 直感的ではないけど LSL では標準

### `list`（リスト）
- 異なる型をまとめて保持できる
- 要素取得に `llList2String()` などを使用

---

## 型変換（キャスト）

```lsl
string s = (string)123;               // 整数 → 文字列
integer i = (integer)"456";           // 文字列 → 整数
float f = (float)"3.14";              // 文字列 → 小数
vector v = (vector)"<1.0,2.0,3.0>";   // 文字列 → ベクター
```

## list型チェック（リストの中身）

0番目の要素の型を以下のように取得できる

```lsl
llOwnerSay("Type: " + (string)llGetListEntryType(myList, 0));
```
helidon MP デフォルトエンドポイントの制御

# Helidon MP 4系で利用できるデフォルトエンドポイントまとめ

Helidon MP 4.x を使ったマイクロサービス開発において、自動で提供されるデフォルトの管理系エンドポイント（Health、Metrics、OpenAPI）についてまとめました。

本記事は、Helidon MP 4.x を導入した開発者向けのリファレンスとなります。

---

## 対象バージョン

- Helidon MP 4.x（例: 4.0.3, 4.1.0 など）

---

## 1. ヘルスチェック `/health`

Helidon MP では [MicroProfile Health](https://github.com/eclipse/microprofile-health) に準拠したエンドポイント `/health` がデフォルトで提供されます。

### 主な利用例

- システムの稼働状態の監視
- コンテナオーケストレーション（例: Kubernetes）の Liveness / Readiness Probe に利用

---

## 2. メトリクス `/metrics`

[MicroProfile Metrics](https://github.com/eclipse/microprofile-metrics) に基づいたメトリクス情報が `/metrics` エンドポイントで取得できます。

### 主な利用例

- JVMヒープ使用量、スレッド数、GC回数などの取得
- アプリケーション固有のカウンター・ゲージの導入も可能

---

## 3. OpenAPI `/openapi`

[MicroProfile OpenAPI](https://github.com/eclipse/microprofile-open-api) に準拠し、Helidon MP は `/openapi` エンドポイントを通じて自動生成された API 仕様（YAML/JSON）を提供します。

### 主な利用例

- APIドキュメントの自動生成
- Swagger UI との連携

---

## 4. これらのエンドポイントを無効化するには？

これらのエンドポイントは **デフォルトで有効化** されています。  
**本番環境ではセキュリティの観点から不要なエンドポイントは無効化することを推奨**します。

### `application.yaml` を使用する場合

```yaml
# src/main/resources/application.yaml

health:
  enabled: false

metrics:
  enabled: false

openapi:
  enabled: false
```
### `microprofile-config.properties`を使用する場合
```
# src/main/resources/META-INF/microprofile-config.properties

health.enabled=false
metrics.enabled=false
openapi.enabled=false
```

Helidon MP では MicroProfile の各仕様が自然に統合されているため、追加実装なしでエンドポイントが利用可能です。

しかし、本番環境では 情報漏洩防止や攻撃対象縮小のため、必要最小限のエンドポイントだけを有効にすることが重要です。
指定したファイル以外を一括削除する方法

## ディレクトリ構造
```
project-root/
├── config/
│   ├── app.properties
│   ├── db.properties
│   ├── temp.txt
│   └── readme.md
├── resources/
│   ├── messages.properties
│   ├── dummy.json
│   ├── data.xml
│   └── nested/
│       ├── nested.properties
│       ├── notes.txt
│       └── info.log
└── scripts/
    ├── deploy.sh
    └── clean.properties
```

## 使用コマンド
上記から`.properties`がつくファイル以外をすべて削除したい場合
```shell
find ./project-root -type f ! name '*.properties' | xargs rm -f
```
`xargs` は前のコマンドの結果を次のコマンドの引数として渡してくれるコマンドなので、今回でいくとfindで探してきた`*.properties‘以外のものが引数として渡されて削除される形になります。

他には下記のような方法もあります。
```shell
find ./project-roo -type f ! -name '*.properties' -exec rm -f {} \;
```
`-exec` はfindで見つけたファイル１つ１つに対して別のコマンドを実行したいときに使用します。
ちなみに`xargs`はfindで見つけたファイルすべてに対して一括で実行してくれます。

## 追記
```shell
find ./project-roo -type f -name '*.properties' -exec rm -f {} \+
```
さいごを`;`ではなく`+` にすることで１つ１つのファイルではなく、多くのファイルに対して（制限はある）実行できるそうです！


## まとめ

どちらを使用してもいいとは思いますが、xargsを使用する方法でいくとファイル名にスペースなどが入っている場合に思った通りの動作にならない可能性もあるので使い分けるのがいいかと思われます。
スマホアプリ 下調べ ざっくりリリース手順

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680230/c6d5e20c-7e7e-42a8-8f6c-1432247cff78.png)

## はじめに

前回の「[スマホアプリ 下調べ ざっくりと流れを理解](https://qiita.com/magic10r/items/1767ae75f79da7145a2f)」に続き、スマホアプリについてです。
Android（Google Play）とiPhone（App Store）でアプリを公開する方法を、**開発者登録 → ビルド → ストア申請 → 公開** の流れを下調べします。

## ざっくり手順

### Androidリリース手順（Google Play）
1. Google Play Console登録
2. アプリを署名＆ビルド（.aab）
3. ストア情報を入力
4. Google審査後、公開！（数時間～2日）

### iPhoneリリース手順（App Store）

1. Apple Developer Program登録
2. Xcodeでアプリをビルド＆署名
3. TestFlightでテスト
4. Appleの審査後、公開！（約1週間）

## 1. Androidアプリのリリース手順（Google Playストア）

### ① Google Play Consoleの準備

Google Playストアでアプリを公開するには、**Google Play Console**のアカウントが必要です。

1. [Google Play Console](https://play.google.com/console) にアクセス
2. Google Play デベロッパーアカウント登録（初回のみ）
   - 料金: **25ドル（1回のみ）**
   - Googleアカウントが必要
3. Google Play デベロッパーポリシーに同意
4. 支払い情報を登録

### ② アプリの準備

#### 1. アプリの署名

1. Android Studioで `Build > Generate Signed Bundle / APK`
2. `.keystore` ファイルを作成（初回のみ）
3. 署名情報を入力し、`.aab` ファイル（Android App Bundle）を作成

#### 2. 必要なアセットを準備

- アイコン: 512×512px（PNG）
- スクリーンショット: 最低2枚（スマホ・タブレット）
- プロモーション画像（任意）: 1024×500px（PNG）
- アプリの説明: 80～4000文字
- カテゴリ選択、プライバシーポリシーURL設定

### ③ Google Play Consoleでアップロード

1. 新しいアプリを作成
2. 「アプリリリース」 → 「新しいリリースを作成」
3. .aab ファイルをアップロード
4. リリースノート（変更点）を記載

### ④ Googleの審査 & 公開
1. 「アプリの公開」を申請
2. Googleの審査 **（通常数時間～2日）**
3. 承認後、ストアに公開！

## 2. iPhoneアプリのリリース手順（App Store）

### ① Apple Developer Programの登録

1. [Apple Developer Program](https://developer.apple.com/) にアクセス
2. Apple ID で登録**
3. **年会費 99ドル（毎年）を支払い**
4. Appleの審査完了後、アカウント有効化

### ② アプリの準備

#### 1. 署名付きのアプリを作成

- Xcodeで「Archive」を作成
- Apple IDで認証し、App Store Connectへアップロード

#### 2. 必要なアセットを準備
- アイコン: 1024×1024px（PNG）
- スクリーンショット: 5.5インチ、6.5インチ、8.3インチなどの解像度が必要
- アプリの説明、キーワード、カテゴリ設定、プライバシーポリシーURL登録

### ③ App Store Connectでアップロード

1. [App Store Connect](https://appstoreconnect.apple.com/) にログイン
2. 新しいアプリを作成し、詳細情報を入力
3. TestFlightで内部テスト（任意）
   - テスターを追加し、TestFlight経由で配布

### ④ Appleの審査 & 公開
1. 「App Storeへ審査をリクエスト」
2. Appleの審査開始　**（通常1週間程度）**
3. 承認後、ストアに公開！

## 3. Android & iOSのリリース手順の違い

| 項目 | Android (Google Play) | iOS (App Store) |
|------|----------------------|------------------|
| **開発者登録** | 25ドル（1回のみ） | 99ドル/年 |
| **署名付きアプリ** | `.aab` ファイル | `.ipa` ファイル |
| **ストア登録情報** | Google Play Console | App Store Connect |
| **内部テスト** | Google Playの「内部テスト」 | TestFlight |
| **審査時間** | 数時間～2日 | 約1週間 |
| **リリース後の更新** | すぐ反映 | Appleの再審査が必要 |


Androidは **即時公開しやすい** のがメリット、
iOSは **審査が厳しい** ものの、**TestFlightでの事前テスト** が便利。


---

**参考（感謝）**

- [Google Play Console](https://play.google.com/console)
- [Apple Developer Program](https://developer.apple.com/)
- [App Store Connect](https://appstoreconnect.apple.com/)
Firebase Cloud Functionsで発生するCORSエラーの解決方法

# はじめに
FirebaseのCloud FunctionsでCORSエラーにハマってしまいました。
同じ問題で困っている方のために、原因と解決策をまとめてみます。

# やったこと
WebアプリからCloud Functionsのエンドポイントを呼び出そうとした際に、以下のようなCORSエラーが発生しました。

実際のコード
```ts
import { onCall } from "firebase-functions/v2/https";

export const getData = onCall(async (request) => {
  const data = { 
    success: true
  }
  return data
})


CloudFuntion呼び出し部分
```ts
import { httpsCallable } from "firebase/functions";
export class CallFunction {
  async callCloudFunction() {
    try {
       const cloudFunction = getFunctions(app)
       const getDataFun = httpsCallable(cloudFunction, 'getData')
       const data = await getDataFun()
       return data.data;
     } catch (error) {
       throw error
     }
``````

### エラーの詳細
ブラウザのdev toolのコンソールで以下のエラーが出ていました。
```
Access to fetch at 'https://us-central1-app.cloudfunctions.net/getData' from origin 'https://app.web.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

ログエクスプローラーのログ
Firebase CloudFunctionのページからGoogle Cloudのログエクスプローラー画面に飛べます。
そこでもログを見てみます。
```
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client
```

# 対象方法
CORS設定ができていないようです。
Firebase SDKではデフォルトでcorsの設定がされるみたいですが、私の環境ではcorsのエラーが出たままでした。
[公式のcorsの説明](https://firebase.google.com/docs/functions/callable?hl=ja&gen=2nd#cors)
Firebase SDKを使用するのを諦めてHTTPで通信する方法を試みます。

## 解決したコード
以下のように関数を修正することで問題を解決しました：

1. onCallからonRequestへの変更：
通常のHTTPリクエストを処理できるように関数タイプを変更しました。
2. CORS設定の追加：
レスポンスヘッダーにCORS関連の設定を追加して、クロスオリジンリクエストを許可しました。

実際に修正したコード
```ts
export const getData = onRequest(
  {
    region: 'asia-northeast1'
  },
  async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.set('Access-Control-Allow-Headers', 'Content-Type');
  
  res.status(200).send({
    success: true
  });
});
```

呼び出し部分
```ts
  async getData() {
    try {
      const res = await fetch(`https://asia-northeast1-app.cloudfunctions.net/getData`)
      const data = await res.json();
      return data;
    } catch (error) {
      throw error;
    }
  }
```

## やったこと
 - onRequest関数を使用してHTTPリクエストを直接処理
 - Access-Control-Allow-Origin: '*'で全てのオリジンからのアクセスを許可
 - Access-Control-Allow-MethodsとAccess-Control-Allow-Headersで必要なメソッドとヘッダーを指定

なお、本番環境ではAccess-Control-Allow-Originを特定のドメインに限定するなど、よりセキュアな設定にすることをお勧めします。

# 最後に
今回はFirebase SDKの使用を諦めましたが、またリベンジしようと思います。
参考になる公式ドキュメント：

[Firebase Cloud Functionsドキュメント](https://firebase.google.com/docs/functions?hl=ja_
[Google Cloud のCORS設定について](https://cloud.google.com/functions/docs/writing/write-http-functions?hl=ja)
[Python] 正確な整数平方根を得るにはmath.isqrt関数を使おう

# 結論
$\sqrt{N}$以下の最大整数（整数平方根）を取得するには`math.isqrt`関数を使うとよい

# 経緯
先日行われたAtCoder社の競技プログラミングコンテストで以下のような出題がありました。
### [ABC400 C問題 2^a b^2](https://atcoder.jp/contests/abc400/tasks/abc400_c)
> #### 問題文
>正の整数 $X$ は、次の条件をみたすときかつその時に限り、良い整数と呼ばれます。
>+ 正の整数の組 $(a,b)$ を用いて、$X=2^a \times b^2$ と書ける。
>
>例えば、$400$ は $400=2^2 \times 10^2$ と書けるため、良い整数です。
>正の整数 $N$ が与えられるので、$1$ 以上 $N$ 以下の良い整数の個数を求めてください。
>#### 制約
>+ $1≤N≤10^{18}$
>+ $N$ は整数

問題文の例に上がっている$400$のように、$400=2^2 \times 10^2=2^4 \times 5^2$などと複数通りに表すことができる数があるため、愚直に数え上げると重複の管理が厄介です。
$b$を奇数に限定すればすべての良い整数を一意に表せることに着目して、以下のように実装しました。
```python:提出コード
import math
N = int(input())
ans = 0
pow = 1
n = N//(2**pow)
while n>0:
    r = int(math.sqrt(n))
    # 1~rまでの奇数の数
    if r%2 == 0:
        ans += r//2
    else:
        ans += (r+1)//2
    pow+=1
    n = N//(2**pow)
print(ans)
```
ところが結果は`WA`でした。
ただ、テストケースのほとんどで正解しており、考え方自体は悪くなさそうです。小数切り捨ての関係で不具合を出しているのかな……と考えている間に時間切れになりました。（悔しい……）
# 原因
[公式解説](https://atcoder.jp/contests/abc400/editorial/12634)がほぼ同じ方針での解法でした。本質的な差異は整数平方根を求める部分にあります。筆者が`math.sqrt`を使った部分で、公式解説は`math.isqrt`関数を採用していました。
そして、筆者の上述のコードの
```python
r = int(math.sqrt(n))
```
を
```python
r = math.isqrt(n)
```
に変更すると、いとも容易く`AC`になりました。
この`math.isqrt`とはいったい……？

[Pythonのドキュメント](https://docs.python.org/ja/3.13/library/math.html#math.isqrt)によると、以下のような関数だそうです。
>非負整数$n$の整数平方根を返します。これは$n$の正確な平方根の床であり、 $a^2 \leqq n$ を満たす最大の整数$a$と等価です。

__正確な__ という記述が気になりますね。`sqrt`関数では不正確な値になる場合があるのでしょうか。簡単なコードで検証しました。

# 検証
$N = n^2 - 1$とします。当然$\sqrt{N} \lt n$ですから、`int`関数で整数部分だけを取れば$n-1$になるはずですね。しかし、実際に試すと以下のようになります。

```python
import math
N = 10**16 - 1
print(math.sqrt(N) == 10**8) # True
print(int(math.sqrt(N)))     # 100000000
print(math.isqrt(N))         # 99999999
```
`sqrt`の結果が間違っていますね。
念のため追記しますが、`sqrt`関数が不正確、という単純な話ではありません。実際、$N=10^{15}$くらいで試すと正しい結果になります。
$\sqrt{N}=n-(微小量)$ ですが、$N$が一定以上巨大だと微小量のオーダーが小さくなりすぎて、内部的に$0$と区別できないということでしょう。
今回の問題では$10^{18}$までのテストケースがあり得たため、見事にこのパターンに陥っていたわけです。

# まとめ
正確な整数平方根を取得するには、公式ドキュメントの通り、`math.sqrt`ではなく`math.isqrt`を使うのが良いです。

なお、[sqrtの誤差について](https://atcoder.jp/contests/abc400/editorial/12642)という解説がAtCoder公式から出ていて、同じ部分について書かれています。二番煎じになってしまいましたが、まあ手元で検証して学びがあったのでヨシです。
rex0220 計算式プラグイン 仕入れ先別テーブル集計に入力用請求日を追加

[rex0220 計算式プラグイン 仕入れ先別テーブル集計](https://qiita.com/rex0220/items/3087313a2fb3dec02d3d)に、入力用請求日を追加してみます。
集計先テーブルに入力用項目を設定する例になります。

# 概要

申請社給品、購入金額、購入元が指定されたテーブル行を仕入テーブルに集計します。
仕入テーブルには、入力用請求日を追加します。
※仕入先別合計テーブルと仕入テーブルは横並びプラグインで並べています。

単純にテーブル集計を行うと請求日がクリアされるので、「仕入先 & "-" & 発注品 & "-" & 単価」をキーとして、請求日を集計後にも反映させます。

![2025-04-07_21h34_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3a865cd5-51c7-40fa-b9aa-fd399483b93c.png)


# 操作例

![2025-04-07_21h49_23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e313f151-b947-454f-96fe-5ea9ede7b4d6.gif)

# 計算式プラグイン設定

![2025-04-07_21h36_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c12f6ba8-8207-4429-be15-709d9e61aeb9.png)

- 仕入テーブルの計算式
    - dic 変数に、集計前の請求日を格納
    - psum 変数に、仕入テーブル用の集計データを作成
    - 仕入テーブルにpsumの値をセット
    - dic 変数から集計前の請求日を請求日にセット

```JavaScript:
OPTION: 循環参照を許可

// 購入.購入引当 NUMBER
LET(
  w, TR_SUM(申請個数,-在庫対応),
  IF(w>0, w, 0)
)

// 購入.購入金額 NUMBER
購入引当*申請単価

// 仕入先別合計 SUBTABLE
TLTABLE(購入,
    TPFILTER(AND(申請社給品,購入金額>0,購入元)),
    TPKEY(購入元),
    TPVAL(購入金額),
    TPOUT(仕入先T,発注金額T)
)

// 仕入先別合計.発注金額:発注金額T NUMBER


// 仕入 SUBTABLE
LET(dic, DIC(), // 辞書作成
  dummy, TARRAY(
    LET(key, 仕入先 & "-" & 発注品 & "-" & 単価, // キー作成
      DIC_ITEM(dic, key, 請求日) // 辞書登録
    )
  ),
  psum, TLTABLE(購入, // 購入集計
    TPFILTER(AND(申請社給品, 購入金額 > 0, 購入元)), // 条件指定
    TPKEY(購入元, 申請社給品, 申請単価), // 集計キー
    TPVAL(購入引当, 購入金額), // 集計値
    TPOUT(仕入先, 発注品, 単価, 発注個数, 発注金額) // 出力項目
  ),
  dummy, FSET(仕入, psum), // 仕入反映
  dummy, TARRAY(
    LET(rowno, ROWNO(仕入), // 行番号取得
        key, 仕入先 & "-" & 発注品 & "-" & 単価, // キー作成
        FSET(請求日, DIC_ITEM(dic, key), rowno) // 日付反映
    )
  ),
  "" // 終端
)

// 仕入.仕入先 DROP_DOWN
// 仕入.発注品 DROP_DOWN
// 仕入.発注個数 NUMBER
// 仕入.単価 NUMBER
// 仕入.発注金額 NUMBER
```
「React has detected a change in the order of Hooks called by〜」のエラーの対処法

Reactで「React has detected a change in the order of Hooks called by〜 . This will lead to bugs and errors if not fixed.」のエラーが発生した場合の対処法です。

上記エラーは、useStateなどのHooksが呼び出される順序が変わったときに発生するそうです。

Reactでは、Hooksはトップレベルで呼び出す必要があります。

> フックをループや条件分岐、あるいはネストされた関数内で呼び出してはいけません。代わりに、あなたの React の関数のトップレベルでのみ、あらゆる早期 return 文よりも前の場所で呼び出してください。これを守ることで、コンポーネントがレンダーされる際に毎回同じ順番で呼び出されるということが保証されます。これが、複数回 useState や useEffect が呼び出された場合でも React がフックの状態を正しく保持するための仕組みです

参考：https://ja.legacy.reactjs.org/docs/hooks-rules.html

そのため、以下のようにif文や下記のような早期return文の後にHooksを書くとHooksの順序が変わってしまいエラーが発生します。

```
import { useEffect, useState } from "react";

const Sample = ({ count }: { count: number }) => {
  const [flag1, setFlag1] = useState(true);
  if (count === 0) {
    return <></>;
  }

  const [flag2, setFlag2] = useState(true);

  return <>{count}</>;
};

export default Sample;
```

## 対処法その1：Hooksは関数のトップレベル、早期return文より前に書く

Hooksは条件分岐内や早期return文の後ではなく、トップレベルに書く必要があります。
下記のように、早期return文より前にHooksを書けばエラーは発生しなくなります。

```
"use state";

import { useEffect, useState } from "react";

const Sample = ({ count }: { count: number }) => {
  const [flag1, setFlag1] = useState(true);
  const [flag2, setFlag2] = useState(true);
  if (count === 0) {
    return <></>;
  }

  return <>{count}</>;
};

export default Sample;
```

## 対処法その2：コンポーネントとして切り出す

下記のように、コンポーネントとして切り出した場合もエラーは発生しません。

```
import { useEffect, useState } from "react";

const Parent = ({ count }: { count: number }) => {
  const [flag1, setFlag1] = useState(true);
  if (count === 0) {
    return <></>;
  }

  return <Children count={count} />;
};

const Children = ({ count }: { count: number }) => {
  const [flag2, setFlag2] = useState(true);
  return <>{count}</>;
};

export default Parent;
```

## そもそも

VSCodeでeslintの設定されていれば、コード書いているときに以下のようにエラーを表示してくれるので気付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382613/c44cf4b5-ddd5-4a97-86b5-7ccbd039e2bc.png)
タスクスケジューラでネットワークからのファイルコピーバッチが動かない

# 1. はじめに
* タスクスケジューラからファイルをコピーしたい
* コピー元、コピー先をネットワークドライブにしても動くようにしたい

# 2. 動作環境
* Windows 11

# 3. 原因
* タスクスケジューラとして実行する場合、特定のユーザープロファイルで保持しているネットワークドライブ接続情報が使用できなくなるため

https://obenkyolab.com/?p=3288

# 4. 対処法
* バッチファイル内に、ネットワークドライブの割り当てと削除を記述する

```
rem  ネットワークドライブを割り当てる
net use X: \\TEST /user:< ユーザーID> <パスワード>

copy Y:\<ファイル名>> C:\<ファイル名>

rem ネットワークドライブを切断する
net use X: /delete
```

# 5. 参考文献

https://obenkyolab.com/?p=3288

https://umauma2010.hatenablog.com/entry/2023/06/01/031149
Notebook LMで爆速オンボーディング

「ドキュメントはあるがとっ散らかってる」
「ていねいなオンボーディングのための人と時間が足りない」
そんな時Notebook LMに主なドキュメントを片っ端から投げ込めば、あっという間にオンボーディング用資料の完成である。


# 0. 前提

Google Workspace環境が前提。

# 1. アクセス

https://notebooklm.google.com/
にアクセスする。

# 2. 新規作成

`新規作成`をクリックする。

![スクリーンショット 2025-04-04 16.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555024/82708cc9-6d22-4a37-9bc7-818c82b82b9b.png)


# 3. ソースアップロード

主要なドキュメントをソースとしてアップロードする。
(ドキュメントやスライドは使えるけどスプシは現状使えない)

![スクリーンショット 2025-04-04 16.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555024/2927c8b9-7497-498e-8aae-6a552d1ab0da.png)


# 4. 活用

ノートブックが利用できるようになる。

![スクリーンショット 2025-04-04 16.19.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555024/23ec4de6-6be2-47ce-b560-be6f75b4b18a.png)


あとはAIによる要約を読みながら構成図を閲覧したり、

![スクリーンショット 2025-04-04 16.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555024/61782b64-b428-4fd7-9e33-3b76102219e9.png)


構成図を閲覧しながら疑問点を質問したりできる。
(差異が際に誤字ってますが、当然のように汲み取ってくれてる)

![スクリーンショット 2025-04-04 16.24.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555024/b31315fe-f0f8-40fa-addc-076dc2f9ceda.png)

注意事項として、ドキュメントの質にもよると思うが解釈違いはままあるので、情報が合ってるかの確認は必要になりそう。
(それでも0から情報を漁るよりは格段に早いと思う)
C#でSpire.XLS for .NETを使用してExcelファイルをサイレント印刷する

# 1. はじめに
* Excelファイルをサイレント印刷したい
* Spire.XLS for .NETを使用して実行したい

# 2. 動作環境
* C#
* .NET 8
* Spire.XLS for .NET
* Visual Stduio 2022
* Windows 11

# 3. Spire.XLS for .NETとは
* E-ICEBLUE社が開発したExcel の文書ファイルを迅速かつ高品質で作成・編集・変換・印刷するために設計された専門的な Excel.NET ライブラリです。

https://jp.e-iceblue.com/introduce/spire-xls-for-net.html

# 4. サンプルソース
* ホームページあるサンプルを実行するだけで簡単に動いた

```C#:Program.cs
using Spire.Xls;
using System.Drawing.Printing;

namespace SilentlyPrint
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // ワークブックオブジェクトを作成
                Workbook workbook = new Workbook();

                // Excelファイルをロード
                workbook.LoadFromFile(@"C:\Sample.xlsx");

                // 印刷プロセスを表示しないようにStandardPrintControllerを設定
                workbook.PrintDocument.PrintController = new StandardPrintController();

                // ワークブックからPrinterSettingsを取得
                PrinterSettings settings = workbook.PrintDocument.PrinterSettings;

                // プリンタ名、両面印刷モード、および印刷ページを指定
                settings.PrinterName = "プリンタ名";

                // ワークブックを印刷
                workbook.PrintDocument.Print();
            }
            catch (Exception e)
            {
                // エラー処理
            }
        }
    }
}
```

# 5. 参考文献

https://jp.e-iceblue.com/tutorials/net/spire-xls-net/xls-net-print/c-print-excel-documents.html
VB-ReportのWindowsForm用のビューアーコントロールで印刷する

# 1. はじめに
* C#のコンソールアプリからExcelファイルを印刷したい
* Excelで印刷せず、VB-Reportのビューアーコントロールから使用したい

# 2. 動作確認
* C#
* .NET .8
* VB-Report 11
* Windows 10
* Visual Studio 2022

# 3. VB-Reportとは
* アドバンスソフトウェア株式会社が開発したExcel で帳票デザインを作成する帳票開発ツールです。
* ビューアーコントローを使用することでプレビュー、印刷することが可能です。

https://www.adv.co.jp/product/product_vb-report11.htm

# 4. サンプルプログラム
* Excelファイル名、シート名、プリンタ名を固定で出力する。

```C#:Program.cs
using AdvanceSoftware.VBReport;
using System.Windows.Forms;

namespace ConsoleApp
{
    internal class Program
    {
        /// <summary>
        /// 必要なデザイナー変数です。
        /// </summary>
        static System.ComponentModel.IContainer components = null; 
        static ViewerControl viewerControl1;
        static CellReport cellReport1;

        static void Main(string[] args)
        {
            components = new System.ComponentModel.Container();
            cellReport1 = new CellReport(components);
            viewerControl1 = new ViewerControl();

            // 帳票出力前にビューアコントロールをクリア
            viewerControl1.Clear();

            // Excel帳票ファイル名を指定
            cellReport1.FileName = @"C:\sample.xlsx";

            // 帳票ドキュメントの作成開始
            cellReport1.Report.Start();

            // 帳票処理の開始
            cellReport1.Report.File();

            // 帳票のページ処理開始（Excelシート名、ページ数）
            cellReport1.Page.Start("合計請求書1", "1");

            // 帳票のページ処理終了 
            cellReport1.Page.End();

            // 帳票ドキュメントの作成終了
            cellReport1.Report.End();

            // 印刷ジョブ名の指定
            viewerControl1.PrintDocumentName = "印刷ジョブ名";

            // 印刷プリンタの設定
            // プリンタ名が存在しない場合、通常使うプリンターへ出力
            viewerControl1.SetPrinter(false, "プリンタ名");

            // ビューアコントロールに帳票ドキュメントを設定
            viewerControl1.Document = cellReport1.Document;

            // ビューアコントロールからプリンタ印刷
            viewerControl1.PrintOut();

            // 出力が失敗した場合、ErrorNo にてエラー内容が取得できます。
            if (cellReport1.ErrorNo != AdvanceSoftware.VBReport.ErrorNo.NoError)
            {
                MessageBox.Show(cellReport1.ErrorMessage);
                return;
            }

        }
    }
}
```

# 5. 参考文献

https://qiita.com/HAGITAKO/items/59bc13e53088b9ebcc88
[javascript]文字の切り出しを行う時に<br>には要注意

## 背景の説明
あるPHP＋Laravelで動作するシステムにて入力情報として渡された文字列を下記のように変換していた。

```sample.php
 nl2br(e(mb_substr('渡された文字列', 0, 10)))
```

全く違う構成で動くシステムにて、これと全く同じ文字列編集＆整形を実現させねばならなくなり、現状のままでも利用可能なjavascriptを使い構築しました。
その試行錯誤の中で、熟年者でない故の思い込みではまった箇所があり、備忘録も兼ねて記事にしました。


## 問題概要
javascript上で実現する際に、一般的によく知られるsubstringとinnerHTMLを使いましたが、表示結果を見ると文字の中身によっては改行コード（```<br>```や\n）で文字がぶった切られる事に。。

## 詳細説明
冒頭のPHPソースコードの意味を解説する所から始めます。
上記で登場する関数のそれぞれの意味はこのようになり
	1. nl2br			→	文字列内に登場する全改行文字 (\r\n、 \n\r、\n および \r)を```<br>```に置換して返します。
	2. e				→	laravelフレームワークのヘルパ関数、PHPのhtmlspecialchars関数をdouble_encodeオプションにデフォルトでtrueを指定し実行される
	3. mb_substr		→	入力文字列を指定した範囲で切り出す事ができる（日本語のようにマルチバイトであるときはこれ）

プログラムでは3→2→1の順に行われる事になります。

参考リンク
・https://readouble.com/laravel/9.x/ja/helpers.html#method-e
・https://www.php.net/manual/ja/
・https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference
<br><br>


この動作を再現させようとして下記プログラムを組みました。
```失敗していた時の記述.js
// 値は適当なサンプル
var stationInfo = "3月15日に開業する上所駅。<br><br>JR越後線の新潟駅と白山駅の間に設置されます。<br><br>JR新潟支社管内の在来線で、新しい駅が誕生するのは20年ぶり。<br><br>地元住民にとって悲願の新駅です。<br>";
if (stationInfo.length > 20) {
    stationInfo = stationInfo.substring(0, XX);
    stationInfo += "...etc";
}
// HTML上のある領域を指定して記述
$("#main .prefecture_15 li dd.detail")[0].innerHTML = stationInfo;
```
substringを使う時に切り出し終点位置（第２引数）を指定しますが、そこがこの文字列で```<br>```に当たる20や50が指定されると改行を理解せずそのまま切り出してしまう。
``` 切り出し後の値の例.txt
3月15日に開業する上所駅。<br><b
```

## 解決する方法
・substringを使用する前にreplaceを用いて```<br>```を```\n```などに置換しておく。
・切り出した文字列を代入する際は、innerTextを用いる。

```改善した記述.js
// 値は適当なサンプル
var stationInfo = "3月15日に開業する上所駅。<br><br>JR越後線の新潟駅と白山駅の間に設置されます。<br><br>JR新潟支社管内の在来線で、新しい駅が誕生するのは20年ぶり。<br><br>地元住民にとって悲願の新駅です。<br>";
stationInfo = stationInfo.replace(/<br>/g, "\r\n");
if (stationInfo.length > 20) {
    stationInfo = stationInfo.substring(0, XX);
    stationInfo += "...etc";
}
// HTML上のある領域を指定して記述
$("#main .prefecture_15 li dd.detail")[0].innerText = stationInfo;
```

### 理由について
デベロッパー向け公式サイトでも述べられていますが、innerTextで渡された値に改行コードにあたるものはサイトレンダリング時に```<br>```に置換するので、その仕組みを活用します。
	https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText

### 検証とまとめ
仮に50文字目で切り出した場合の実行結果は次のようになります。最初と違い不自然な切り方も無く改行コードを理解した文字列情報として出力されます。
``` 実行結果（仮）.txt
3月15日に開業する上所駅。

JR越後線の新潟駅と白山駅の間に設置されます。

JR新潟支...etc
```
今のところsubstringは、改行（```<br>、\n、\r\nなど```）は全て1文字扱いで計算しているので、そこを考慮して切り出し位置を考えれば想定通りになります。
気が付いたらGeekじゃなくなっていた？原因を考察する

# はじめに
先週無事？に誕生日を迎え、もうすぐ40歳になりそうなアラフォーエンジニアな自分。

少し前にはエンジニアの寿命は30歳まで～なんて風潮があったものの、バリバリの現役エンジニアとしてやっていってる…つもりだった。

「あれ...？そういえば最近、登壇もしてなければ、技術ブログも書いて無くね…？？:fearful:」

そんな事実にはたと気づいた今日この頃。

5年くらい前はバリバリ登壇もしてたし、勉強会の参加や、Qiitaの投稿もちょいちょいやってたが、ここ1，2年はめっきりご無沙汰になっていた。
加えてQiitaの記事を読む回数もめっきり減ってたし、Twitterの技術的なツイートも目にする機会が減っていた:cold_sweat:。


なぜ…？Why…？昔はあんなにGeekっぽかったのに。。。:cry:

と、いうことでここはエンジニアらしく自分の身に起きた様々な事象から原因分析という名の考察をしてみる。:thinking:

もしアラフォー近くになって、あら？今自分ってGeek…？ってなった人のきっかけになれば…。

# ５年前と今と比べて変わったこと

### コロナによってフルリモートになった
バリバリ登壇や勉強会に参加していたころは出社していた。最もよくあったパターンは会社の終わりに勉強会へ参加して、その後懇親会でご飯たべて終バスで帰宅、というケースだった。

しかしコロナによってフルリモートになった結果、とんと勉強会に参加しなくなってしまった。

自分の家は都内まで片道1時間半かかるため、業務終わりに勉強会へ参加するために片道1時間以上をかけていく…というのは流石にハード過ぎた結果、勉強会とも疎遠となってしまった。

### 二人目の子供が産まれた
ライフステージが変わって～というのはよくあるパターン。二人目の子供(もうすぐ3歳)がいるため、特に夕方～夜の家事がてんてこ舞いになる。

そのためちょうど夕方ごろに開催されがちな勉強会へ参加するのが難しくなった。

加えてフルリモートも相まってさらに難しい状況になっていた。

### 会社でのポジションが変化した
昔は現場の最前線でバリバリコーディングしている立場だった。しかし時が経つにつれ、チームのテックリードになり、最前線でコーディングするというよりも、チームメンバーを育てることが多くなった。
それに伴い情報のインプットとアウトプットの方向が社外から社内に向くことが多くなった。

例えば昔はAndroidのチートシートだったり、実装方法だったりといった社外にも公開できるような知識をインプットし、それをQiitaなどにアウトプットしていた。

しかし最近ではプロダクトのノウハウだったり、社内ツールの使い方などをインプットし、それを社内のWikiなどにアウトプットすることが多くなった。社外向けに公開可能な知識でも、チームが分かりやすいよう、まずは社内向けに公開することが多くなってしまっていた。

### Vtuberにハマった。
たーぶん影響ない…と思う。もともとVtuberにハマる前はSplatoonにハマってたりゲームしてたりするのでそこまで影響はない…はず。

### Twitterのサブ垢を作った
もともとAIイラスト用にサブ垢を作ったが、気づいたら趣味用のアカウントとなった結果、メインで確認するアカウントがサブ垢になってしまい、メイン垢を確認する機会が少し減った。

メイン垢にはエンジニアを結構フォローしていたため、メイン垢の確認回数が減った結果、技術の最新情報に触れる機会が少し減った…気がする。

# Geekだったころと変わらないこと
### プライベートの時間の使い方
その時に一番興味のあるものをやる。ゲームだったりAIイラスト生成だったり、技術ブログ書いたり…。その辺の優先度は今も昔も変わっていない…気がする。

### 新しい技術に触れることは楽しいという気持ち
直近だとやはりAI関連。AIイラスト生成も結構遊んだし、ChatGPTもいろいろ試してみた。ただ無料で遊べる範囲にとどまってる。特にChatGPTやNovelAIとかは有料プランだと出来ることがググっと広がるのでそれらはある意味で足かせになってる…気はする。

# 結論と今後どうしたいか
勉強会など、外部のエンジニアに触れ合う機会は減った。原因はフルリモートやライフステージの変化が大きいだろう

インプット・アウトプットの量は大きくは変わらないが、社外が社内かという点、そしてその内容がより社内向けの情報になった結果、対外的にはアウトプットが減ったように見えてしまう。
しかし、社外の情報のインプット機会が減ってしまっていたのは事実なので、これは別途対応が必要だろう。

今後はやはり対外的に出せるものはQiitaにも投稿するようにしていきたい。もちろん社内にしか公開できない情報はあるが、社外向けに公開可能な知見などは積極的にQiitaに書いていきたい所存。
そこはやはりAIくんの力を借りて、社内向けの情報をイイ感じに社外向けにマスクしてくれるようにすれば今までよりはずっと簡単にできる…んじゃないかなぁー（AIくんへの情報の渡し方も気を付けないといけないけども。。）

週一・・・いや月２くらいが目標でQiita更新かな…。