OmniAICreator/Qiita-1.07M huggingface dataset:
【未経験からエンジニアへの第一歩】派遣からエンジニアデビューする秘訣を徹底解説！

近年IT業界は深刻な人材不足に直面しており、未経験からエンジニアを目指す人が増えています。しかし、近年では参入希望者の増加やAI技術の進歩により、<b>未経験者にとってエンジニア転職の難易度は高まっている現状</b>です。

そこで今回は、IT未経験者でも諦めずにエンジニアへの夢を叶える方法として、派遣という選択肢について提案します。派遣で業界経験を積むことで、正社員登用のチャンスを掴んだり、スキルアップしたりすることができます。

本記事では、IT未経験者が派遣で業界経験を積むメリット、おすすめの派遣会社、成功するための心構えなどを詳しく紹介していきます。IT業界への転職を諦めずに、一歩ずつ夢に向かって歩みを進めたい方にとって、参考になる内容をご紹介します。

[>> 生成AIによってエンジニアになるのが難しくなる！？](https://taishi-official.com/2024/04/16/2149/)

## IT未経験者が派遣で働くメリット

![Advantages-of-working-as-temp-with-no-IT-experience.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/237e8b58-6545-826c-5553-86bdd7442c30.jpeg)


IT未経験者が派遣から始めるメリットは、以下の3点です。

- 正社員よりも初めての参入がしやすい
- 自分に合った働き方が選べる
- 多様な職場環境や業務に触れられる

[>> 各メリットの詳細はコチラ！](https://taishi-official.com/2024/06/29/2579/#toc2)



## IT未経験者にオススメの派遣会社
[>> IT未経験の方におすすめ派遣会社はコチラです！](https://taishi-official.com/2024/06/29/2579/#toc5)



## 派遣からのエンジニアキャリア形成を成功させるための心構え

![Preparing-for-Successful-Engineering-Career-from-Temp-to-Perm.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/cd262ea9-143d-eec5-6e62-c63971be0d03.jpeg)


派遣からのキャリア形成について、おすすめポイントをこれまでに述べてきました。ただノープランで派遣として働いていては、キャリアアップがうまくできない可能性もあります。そこで以下のような心構えで、仕事に臨むことがおすすめです。

- 積極的に学ぶ姿勢を持つ
- 目標を明確にする
- 周囲の人々と積極的にコミュニケーションを取る

[>> 心構えについて詳しくはココをチェック！](https://taishi-official.com/2024/06/29/2579/#toc6)

これらの心構えを意識し、実践することで、派遣という形態を最大限に活用し、IT業界でのキャリアを確実に築いていくことができます。常に向上心を持ち、周囲と協調しながら、自身の目標に向かって着実に前進していくことが、成功への近道となります。



## まとめ
今回は未経験エンジニアになる方法として、派遣から始めることのメリットやおすすめの派遣会社、派遣からのキャリア形成するための心構えについてご紹介いたしました。未経験エンジニア転職となると普通は正社員を思い浮かべがちですが、<b>最近では未経験から正社員エンジニアになるハードルが高くなっています。</b>またIT業界は当たりはずれが大きい業界のため、ハズレの企業に入社してしまうことで心身ともに疲弊してしまう可能性があります。

そこで今回はITキャリアの入り口として、派遣から始めてみることについてご提案してみました。<b>IT業界は他とは異なり、正社員でいたことよりも、どのような経験があるのかが重視されるカルチャーです。</b>ぜひ派遣からのIT業界参入についても、検討してみてください。



### おまけ


https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/first-engineering-career-change/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
【画像で解説】iTerm2おすすめカスタマイズ　ステータスバー編【時刻・ブランチ・パスを常時表示】

# 記事概要

この記事はiterm2のステータスバーにいろんなステータスを表示させる方法の解説です。
![画像 8月 12 2024 11:57:45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/007d7567-8d43-5900-8ffd-1f970e3e349e.png)

参考：何も設定していない状態（これもシンプルで好きです）
![画像 8月 12 2024 13:45:54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/9fc73c28-5619-769b-cb98-1e5daa7c068f.png)

## 環境
MacBook Air （チップ：Apple M2, Sonoma 14.4.1)
iTerm2 （Build 3.5.4）

# 設定方法（10ステップのみ！）
1. iTerm2の Settings... を開きます。
![画像 8月 12 2024 12:12:09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/9e8582b4-ed5d-a1c3-6760-bce4421d2a3f.png)


2. 設定画面が表示されたら　Profiles を押下（クリックすること）します。
![画像 8月 12 2024 12:17:22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/a362e413-2831-6f25-8f45-7f52768e396a.png)


3. 新しいProfileを作ります。今回はわかりやすいようにstatus_barとしました。
![画像 8月 12 2024 12:22:31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/5a28153f-3b0c-9385-60dd-dc098dc53c15.png)

4. 新しく作ったテーマが選択されている状態にします。
![画像 8月 12 2024 12:28:15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/8c54e3ba-bd5e-fe31-6ebd-4518b2a2e36a.png)

5. Session タブへ移動し、Status bar enabledにチェックを入れます。 
![画像 8月 12 2024 12:31:47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/755b10b9-61aa-b2a5-ac1d-293ff493346a.png)

6. チェックをすると Configure Status bar が選択できるようになるので押下します。
![画像 8月 12 2024 12:47:03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/4d7795c7-a1a5-0510-bb76-9fb1921f3046.png)

7. Status Bar の Component Menuが出現しました。ステータスバーに表示させたいものをドラッグ＆ドロップしていきます。（今回は時計をドラッグ&ドロップしてみます。）
![画像 8月 12 2024 13:29:22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/f16f3a19-59a6-4e63-d539-ef7882e10bdd.png)

8. OKを押下します。
![iTerm2 8月 12 2024 13:35:27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/7ba533a1-9669-85c0-0223-1b3fa298a9d8.png)


9. Status barを使うように設定したprofileを利用するように設定します。 Profile status_bar を選択し、Other Actions から Set as Defaultを選択します。
![画像 8月 12 2024 13:38:10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/678c5925-d5a0-98ba-d06f-c596b2690cbb.png)

10. 新しいwindowを開きます。iterm2に日付を表示させることができました。
![画像 8月 12 2024 13:34:04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/8722717e-f8d0-d8ee-ec94-b995bcc8d543.png)

完了です。おめでとうございます。


#### おまけ

手順7で、Clock, git state, Search Tool, Current Directoryをドラッグ&ドロップすると、最初の画像の再現ができます。
![画像 8月 12 2024 13:52:54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/7632d846-e69f-f082-f35c-2ed0f2bba822.png)

![画像 8月 12 2024 13:50:40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3859182/3e47eb1c-c561-862c-aacb-bf9b6c5065ac.png)





# 記事を書いた背景
設定画面を眺めていたら気づいたため。
iTerm2を触り出した方への支援がしたかったため。（応援しています！）


おつかれさまでした。　よきiterm2ライフを！
loading属性を使って画像の遅延読み込みを実装してみる

# はじめに
loading属性を使用する事で画像やiframe要素を遅延読み込みする事ができます。
初回の読み込み時に必要のないものは遅延読み込みにすることにより、初回のページ読み込みのパフォーマンスを向上する事ができます。


# loading属性とは？
loading属性で指定できる値としては、`eager`と`lazy`の2つがあります。
- loading="eager"： 初回の読み込み時に対象のリソースを読み込まれます。
- loading="lazy"：画像やiframe要素などユーザのスクロールが対象の要素に近づいたらリソースが読み込まれます。

https://developer.mozilla.org/ja/docs/Web/Performance/Lazy_loading


# eagerとlazyを指定した要素を作ってみる

下記のようにサンプルページを作ってみます。
ページ上部から`eager`を指定した要素を1つと、`lazy`で指定した要素が2つ作成しています。
初回ロードでは`eager`を指定した「Eager サンプル」要素が読み込まれ、
スクロールに合わせて`lazy`で指定した「Lazy サンプル」要素が読み込まれます。


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sample-page</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div class="blank-space">
        <h1>余白</h1>
    </div>

    <div class="eager">
        <h1>Eager サンプル</h1>
        <img src="https://via.placeholder.com/1000x400" alt="Eager Loading" loading="eager">    
    </div>

    <div class="blank-space">
        <h1>余白</h1>
    </div>

    <div>
        <h1>Lazy サンプル1</h1>
        <img src="https://via.placeholder.com/1000x600" alt="Lazy Loading" loading="lazy">
    </div>

    <div class="blank-space">
        <h1>余白</h1>
    </div>

    <div>
        <h1>Lazy サンプル2</h1>
        <img src="https://via.placeholder.com/1000x800" alt="Lazy Loading" loading="lazy">
    </div>
</body>
</html>
```

<details><summary>index.css</summary>

```css:index.css
body {
  text-align: center;
}

.blank-space {
  height: 1200px;
  font-size: 1.3rem;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightblue;
}
```

</details>


# 検証ツールを使用して動作を確認
vscodeからサーバを起動しブラウザで確認してきます。
chromeの検証ツールからネットワークタブを選択しページを再読み込みすると、
初回の読み込み時には`eager`を指定した画像（1000x400）は読み込まれいるのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/353898e6-191c-20e9-f5a5-8e52dc06ae7b.png)

下にスクロールしてみると、`lazy`を指定した画像（1000x600、1000x800）がスクロールに合わせて読み込まれたのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/08030773-1cf7-4630-b04e-53731ee3cf8d.png)


# 参考

https://developer.mozilla.org/ja/docs/Web/Performance/Lazy_loading
【Kotlin】英単語になるカラーコードを総当たりで探す

元ネタ：

https://qiita.com/hya__ru/items/5b9630f78d7f4b748edb

Kotlin では再帰的にオブジェクトを生成するような処理では
[`sequence` 関数](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/sequence.html)を使うとよい。

JavaScript なら[ジェネレーター](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Generator)で同様にできるはず。

```Kotlin
fun main() {
    alphabetColorCodeSequence()
        .filter {
            TODO("色コードが英単語になるなら true を返す")
        }
        .forEach {
            println(it)
        }
}

/** 色コードの桁数 */
private const val DIGIT_COUNT = 6

/** 色コードの各桁の値でアルファベットのもの */
private val alphabetCode = 'A'..'F'

/**
 * アルファベットのみで構成された色コード（`#ABCDEF` など）のシーケンスを返す。
 */
fun alphabetColorCodeSequence(): Sequence<String> {
    return sequence {
        yieldAlphabetCodes("")
    }
        .map { "#$it" }
}

/**
 * アルファベットのみで構成された色コード（`#ABCDEF` など）のアルファベット部分を [SequenceScope.yield] する再帰関数。
 *
 * @param leadingDigits 既に構築された色コードの先頭部分（`ABCDE` など）
 */
private suspend fun SequenceScope<String>.yieldAlphabetCodes(leadingDigits: String) {
    require(leadingDigits.length <= DIGIT_COUNT) {
        "leadingDigits の桁数が $DIGIT_COUNT を超えています。leadingDigits: $leadingDigits"
    }

    if (leadingDigits.length == DIGIT_COUNT) {
        yield(leadingDigits)
        return
    }

    alphabetCode.forEach { digit ->
        yieldAlphabetCodes(
            leadingDigits + digit
        )
    }
}
```

／以上
Amazon Transcribe


##  Amazon Transcribeとは？

**Amazon Transcribe** は、音声データをテキストへと変換する **自動音声認識（ASR）サービス** です。内部的にはディープラーニングベースの音響モデルと言語モデルを活用しており、医療やカスタム用途など、ドメインに応じた最適化が可能です。

---

##  主な機能

| 機能 | 説明 | MLSでの観点 |
|------|------|-------------|
| **ストリーミング転写** | WebSocketで音声をリアルタイム転写 | コールセンターやライブ字幕 |
| **バッチ転写** | S3にアップロードした音声ファイルを非同期で処理 | 分析・アーカイブ用途 |
| **PIIマスキング** | 氏名・住所・電話番号などを自動的に検出・マスク | GDPRやHIPAA対応 |
| **話者分離（Speaker Diarization）** | 複数の話者を認識して話者ラベルを付与 | 会話分析や議事録作成 |
| **カスタム語彙（Custom Vocabulary）** | 特定の固有名詞・専門用語を事前登録 | 製薬・法務などの精度向上 |
| **カスタム言語モデル（CLM）** | ドメイン固有データで独自の言語モデルを学習 | 高度な精度チューニングが可能 |

---

##  出力形式と活用

出力は **JSON形式** で、以下の情報が含まれます：

- 各単語の信頼度（`confidence`）
- タイムスタンプ（`start_time`, `end_time`）
- 話者ラベル（`speaker_label`）
- センチメント分析やエンティティ抽出（Comprehendと組み合わせる場合）

---

##  機械学習ワークフローへの統合

Transcribeは単体で完結するだけでなく、**SageMaker** や **Comprehend** と組み合わせて高度な分析に組み込むことが可能です。

### 例1：感情分析パイプライン

```text
Amazon Connect（通話録音）
     ↓
Amazon Transcribe（文字起こし）
     ↓
Amazon Comprehend（センチメント分析）
     ↓
QuickSightで可視化
GitHubへのコミット／SSHキーの生成と登録

<h4>1. リモートリポジトリを追加</h4>

```
$ git remote add origin git@github.com:userName/exampleRepository.git
```

<h4>2. ブランチ名の変更</h4>

```
$ git branch -M main
```

<h4>3. ローカルのmainブランチをリモートリポジトリのoriginにプッシュ</h4>

```
$ git push -u origin main
```

<h4>4. ローカルのmainブランチのすべての変更をステージングエリアに追加</h4>

```
$ git add .
```

<h4>5. 変更をメッセージつきでコミット</h4>

```
git commit -m 'message'

```

<h4>6. ローカルのmainブランチの変更をリモートリポジトリのoriginにプッシュ</h4>

```
git push origin main
```
…とここでSSHキーと紐づけたパスフレーズの入力を求められるが、忘れてしまっている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3706432/007500db-8547-0ddc-a08c-66aff18fcc0a.png">

<h4>7. SSHキーの生成</h4>

```
 ssh-keygen -t rsa -b 4096 -C "example@mail.com"
```
既存のSSHキーを上書きするかどうかを訊ねられるので、「y」押下。
```
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
/home/username/.ssh/id_rsa already exists.
Overwrite (y/n)? 
```

SSHキーに紐づけるパスフレーズを入力。
何も入力せずにEnterを押下した場合、パスフレーズなし。
```
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```


<h4>8. SSHキーをGitHubに登録</h4>

まずはSSHキーを取得。

```
cat ~/.ssh/id_rsa.pub
```

GitHubにログイン→Settings→SSH and GPS Keys→New SSH Keysを押下し、取得したSSHキーを貼りつけ。
これで登録が完了。

<h4>9. ふたたびプッシュ</h4>

再度Git Pushを実行。登録したSSHキーのキーフレーズを入力し、ぶじにリモートリポジトリへのコミットが完了！
【会社だけに依存しない】フリーランスへの第一歩！エンジニア副業の始め方

フリーランスエンジニアとして活躍する姿は魅力的ですが、いきなり独立するのは不安ですよね。そんなあなたにおすすめなのが、まず<b>会社員をしながら副業を始める方法</b>です。会社員として安定した収入を得ながら、空いた時間で副業としてエンジニア経験を積み、スキルアップを図ることができます。独立に必要な資金を貯めたり、人脈を広げたりすることも可能です。

<b>副業は収入アップを目指すエンジニアにもおすすめ</b>です。副業をすることで、本業とは別で収入を得ることができます。また別の仕事に取り組むことで新たなスキルを身につけたり、自分の市場価値を高めことにもつながります。こちらの記事では、副業の始め方や成功するためのポイントなどを詳しく解説します。副業に興味のあるエンジニアの第一歩を踏み出すヒントになれば幸いです。



## エンジニアが副業をするメリット
エンジニアが副業をするメリットとして、以下のようなことがあります。

- 収入アップ
- スキルアップ
- キャリアの棚卸し
- 人脈の構築
- マインドの変化

[>> メリットについて詳細はコチラ！](https://taishi-official.com/2024/06/24/2539/#toc1)



## エンジニア副業の具体例
ITエンジニアが副業として取り組めるものには、以下のようなものがあります。

- 個人でのWebサービス開発・運営
- フリーランスエンジニアとしての受注
- オンラインプログラミング教育・講師
- 技術ブログ運営・執筆
- オンラインコーディング添削・メンタリング

[>> 副業の具体例に関する説明はココ！](https://taishi-official.com/2024/06/24/2539/#toc2)



## エンジニアが副業をするにあたって気をつけるポイント
エンジニアが副業をする上での主な注意点は以下の通りです。

- 労働時間の管理
- 本業とのバランス
- 報酬の確保
- 契約関係の理解
- 会社への届出
- 健康管理

[>> 副業での注意点はココをチェック！](https://taishi-official.com/2024/06/24/2539/#toc3)



## エンジニアの副業案件の見つけ方
ITエンジニアは、スキルや経験が活かせる副業案件が多く存在します。ここでは、ITエンジニアが副業を探す方法をご紹介します。

- クラウドソーシングサービスの利用
- フリーランスエージェントの利用
- 知人・友人の紹介
- SNSの活用



## まとめ
今回はエンジニアが会社員をしながら副業をするメリットや注意点・案件獲得方法についてご紹介いたしました。エンジニアは<b>他の仕事と比較して、副業を探しやすい</b>です。また最近はITの進歩も目覚ましいので、会社員として働いている企業がいつまでも安泰であるとは言い難い状況です。副業をすることで本職以外のスキルを習得したり、収入を増やして投資するなりと検討してみてください❗



### おまけ


https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/it-freelance/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
Unity のメインツールバーをカスタマイズ（2024年版）

@iixd_pog さんの投稿を参考に UI Toolkit 側によせる対応を行ったモノです。従来の IMGUI（`EditorGUILayout`系）も引き続き使えます。

動作確認： Unity 2021 LTS ～ Unity 6 Preview

![Unity Editor Main Toolbar](https://dl.dropbox.com/scl/fi/0rs1chxzsn2s6nb8ecivw/UnityEditorMainToolbar.png?rlkey=d2sue6jct3d6s26b5d9s1mqkf&dl=0)



- [`UnityEditorMainToolbar`](#unityeditormaintoolbar)
    - [ソースコード](#ソースコード)
- [参考](#参考)





# `UnityEditorMainToolbar`

`Left` `Center` `Right` ３つのプロパティーを提供するだけのプリミティブなユーティリティーです。

UI Toolkit の利用が前提ですが `IMGUIContainer` を通して `(Editor)GUILayout` 系の機能も使えます。

```cs
// InitializeOnLoadMethod と組み合わせて使う場合は遅延実行が必要
EditorApplication.delayCall += () =>
{
    // 左右のエリアにラベルを追加
    UnityEditorMainToolbar.Left.Add(new Label("Left"));
    UnityEditorMainToolbar.Right.Add(new Label("Right"));

    // 中央エリアに追加
    UnityEditorMainToolbar.Center.Add(new Label("Center-Right"));
    UnityEditorMainToolbar.Center.Insert(0, new Label("Center-Left"));

    // GUILayout 系のメソッドを使う（IMGUIContainer）
    UnityEditorMainToolbar.Center.Add(new IMGUIContainer(() =>
    {
        if (GUILayout.Button("IMGUI Button",
                             EditorStyles.toolbarButton))  // 標準ボタンに見た目を揃える
        {
            EditorUtility.DisplayDialog("DEBUG", "IMGUI Works!!", "Close");
        }
    }));
};
```


とにかく余計なことは何もしない、Unity のメインツールバーへのアクセスを提供するだけクラスなので「良い感じのマージン」等は自前で設定する必要があります。

（冒頭のスクショではボタンの左右に `GUILayout.Space(7)` を配置）

また、一切の配慮がない `VisualElement` への直アクセスでなので、ツールバーの要素を全て消す等あらゆる操作が可能です。

```cs
// ボタンとか全部消す！
while (UnityEditorMainToolbar.Left.childCount > 0)
    UnityEditorMainToolbar.Left.RemoveAt(0);

while (UnityEditorMainToolbar.Center.childCount > 0)
    UnityEditorMainToolbar.Center.RemoveAt(0);

while (UnityEditorMainToolbar.Right.childCount > 0)
    UnityEditorMainToolbar.Right.RemoveAt(0);

// Unity を再起動するかアセンブリーを再コンパイルすれば元に戻る
```



## ソースコード

Unity のメインメニューに `DEBUG > Unity Editor Main Toolbar` が追加されるので色々と試せます。

https://gist.github.com/sator-imaging/3fa76fdc1262f815d556e28a2173dae5





# 参考

いつもありがとうございます。

https://qiita.com/iixd_pog/items/ae7220bfeae49750f354



--

こういう細かいけど全プロジェクトにあったら嬉しいスクリプトは扱いに困りますね。

以上です。お疲れ様でした。
jsでチェックボックスの状態によって背景色を変える

JavaScript苦手すぎるのでメモ。
かなり基礎的な部分から説明しているので初心者向けです

## やりたいこと
チェックボックスがオンの時　→　背景色青
チェックボックスがオフの時　→　背景色無色
にする


## サンプルコード
```html:index.html
   <main>
      <p id="text">ここの背景色が変わります。</p>
      <div class="mt-ios">
        <input id="check" type="checkbox" />
        <label for="check"></label>
      </div>
    </main>
```
id=textの部分の背景を変えていきます。

```javascript:check.js
const check = document.getElementById("check"); /*checkの情報を取得*/
check.addEventListener("change", changeBackgroundColor);

function changeBackgroundColor() {
  if (check.checked) {
    document.getElementById("text").style.backgroundColor = "blue";
  } else {
    document.getElementById("text").style.backgroundColor = "transparent";
  }
}
```


## getElementedById()
getElementById() は Document インターフェイスのメソッドで、 ()の中にidに入っている文字を入れることでidの部分を取得してくれる。
例えば、

const check = document.getElementById("check");

だったら、()の中に"check"が入っているので、`<input id="check" type="checkbox" />`　の部分を取得してきてくれる。ちなみにcheck.checkedでcheckされてるかどうかわかる。
- checkされてるとき→trueを返す
- ckeckされてないとき→falseを返す

document.getElementById("text").style.backgroundColor = blue;

だったら、document.getElementById("text")で、`<p id="text">ここの背景色が変わります。</p>`が取得されて、style.でtextの部分のスタイル（css）を指定。要するに、textの部分のbackgroundColorを指します。

これと同じ
```css:style.css
#text{
        background-color: blue;
     }
```
ちなみに、背景色を無色にするには、background-color: transparent で指定します。noneじゃないんですね。

## addEventListener()
addEventListener()はJavaScriptからさまざまなイベント処理を実行することができるメソッドのこと。ボタンが押されたらこういう処理をしたい！とか○○されたらこうしたい！って時に使われそう（まだそんな使ったことないけど。）

書き方
対象要素.addEventListener( イベントの種類, 関数名（行いたい処理）)

イベントの種類はscrollとかclickとかいろいろあります。
詳しくは

https://www.sejuku.net/blog/57625

に書いてあったので気になる方は見てみて下さい。

今回は、checkがの状態がchangeしたときに行いたい処理を書いていくので、
check.addEventListener("change", changeBackgroundColor);
と記述していきます。

ここで、changeBackgroundColorは関数名。この関数の中に行いたい処理（今回は背景色によって色を変えていく処理）を」書きます。

あとはif文使って記述していけばOK

参考記事

https://bestrong-it-men.com/javascript-change-color/

https://www.sejuku.net/blog/57625

https://developer.mozilla.org/ja/docs/Web/API/Document/getElementById

https://javadrive.jp/javascript/form/index3.html
Discord BOTのPythonテンプレート

## はじめに

久しぶりにDiscordのBOTを作成しようと触ってたら、色々変わっていたので自分のメモがてらテンプレートを作成。簡単なスラッシュコマンドを実装しています。
私が使用している`discord.py`のバージョンは`2.4.0`です。

# 1.テンプレートの方針
* メイン・リスナー・コマンドはCogを利用して分ける。
* 環境変数は.envファイルを作成して外だしする。

# 2.ファイル構成
方針を踏まえてファイル構成は下記の通り。
```:ファイル構成
.
┣━ main.py
┣━ .env
┗━ cogs
　　┣━ commands.py
　　┗━ listenner.py
```

# 3.各ファイルの内容

まずはmain.py。ここではBOT本体を記述しています。
`load_extension関数`を使用して、各cogを記載しているファイルを読み込んでいます。


```python:main.py
import os,discord
from dotenv import load_dotenv
from discord import Intents
from discord.ext import commands

# 外部変数の読込
load_dotenv()
# DiscrodBOTのトークンを取得
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD_ID = os.getenv('GUILD_ID')

class DiscordBOT(commands.Bot):
    def __init__(self) -> None:
        super().__init__(command_prefix='!',intents=Intents.all())
        # 読み込むcogを指定
        self.initial_extensions = [
            "cogs.listener",
            "cogs.commands"
        ]

    #セットアップ時にソースファイルを読み込み
    async def setup_hook(self) -> None:
        for source in self.initial_extensions:
            await self.load_extension(source)
        await self.tree.sync(guild=discord.Object(id=GUILD_ID))

#BOTの起動
bot = DiscordBOT()
bot.run(TOKEN)
```

続いてlistener.py。

```python:listener.py
from discord.ext import commands

class listener(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_ready(self):
        print(f'We have logged in as {self.bot.user}')

# BOTにcogを登録
async def setup(bot: commands.Bot):
    await bot.add_cog(listener(bot))
```

最後にコマンド。
`add_cog`でギルドを登録しているのはギルドコマンドとしているためです。
ギルドコマンドの場合、対象のギルド(サーバ)へ即時反映されます。
グローバルコマンド(ギルド指定をしない)の場合、BOTを導入したサーバすべてに反映されますが、反映までに1時間程度かかるため注意が必要です。

```python:commnds.py
import os,discord
from discord.ext import commands
from discord import app_commands

# DiscordサーバのIDを取得
GUILD_ID  = os.getenv('GUILD_ID')

class MyCommands(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
    
    # スラッシュコマンドを追加するデコレータ
    @app_commands.command(name='hello', description='挨拶をしましょう') 
    async def hello(self,interaction: discord.Interaction):
        await interaction.response.send_message('hello!')

# BOTにcogを登録 ギルドコマンドとして登録
async def setup(bot: commands.Bot):
    await bot.add_cog(MyCommands(bot), guild=discord.Object(id=GUILD_ID))
```

# 4.まとめ
簡単なスラッシュコマンドを作成するDiscordBOTのテンプレートを作成しました。
Cogを利用することで、それぞれの機能を本体から分離して記述しています。小規模であれば直接記述しても問題ないですが、機能やプログラムの量が多くなる場合は管理しにくくなるので、分けてしまったほうが管理しやすいかと思います。不要な機能も１行コメントアウトするだけで無効化が可能です。


# 参考リンク
https://discordpy.readthedocs.io/ja/latest/ext/commands/cogs.html

https://scrapbox.io/discordpy-japan/%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89
AtCoder Beginners SelectionにPythonで挑戦してみた B問題編

## はじめに

普段はSQLしか書いていないので、
Pythonの勉強がてらAtCoderに挑戦してみました。

自分の解答内容と軽い説明を記載します。
一応ACとれていますが、通っただけレベルのコードです。
きれいな正解を探している方は別のサイトをお勧めします。

そのうちメモリが軽い、コード量が少ない解答を見つけては
反省会したいと思います。

さすがにA問題は割愛します。

https://atcoder.jp/contests/abs

## B問題
### ABC081B - Shift only

```python:ABC081B.py
a = int(input())
numbers = list(map(int, input().split()))
res = 0

while True:
  even = []
  for number in numbers:
    if number % 2 == 1:
      break
    else:
      even.append(number / 2)

  if len(even) == a:
    res += 1
    numbers = even[:]
  else:
    break

print(res)
```
とりあえず問題通り実装。
2で割った配列を作成しなおして、2で割れ無くなるまで繰り返す。

もっとやりようがあると思う。
関数作って再帰的に作るとスマートなのかもしれません。

### ABC087B - Coins

```python:ABC087B.py
mount_500 = int(input())
mount_100 = int(input())
mount_50 = int(input())
sum = int(input())
res = 0

for x in range(0, mount_500 + 1):
  if x * 500 > sum:
    break
  else:
    for y in range(0, mount_100 + 1):
      if x * 500 + y * 100 > sum:
        break
      else:
        for z in range(0, mount_50 + 1):
          if x * 500 + y * 100 + z * 50 > sum:
            break
          elif x * 500 + y * 100 + z * 50 == sum:
            res += 1

# output
print(res)
```
金額全探索です。
合計値超えた場合は探索をやめるぐらいしか工夫していないです。

### ABC083B - Some Sums

```python:ABC083B.py
n, a, b = map(int, input().split())
res = 0
for x in range(1, n + 1):
  d = 0
  for y in str(x):
    d += int(y)
  if a <= d <= b:
    res += x

print(res)
```
これも問題文通りの実装です。
数値を文字に置き換えて各桁の合計値(d)を作ってます。



### ABC088B - Card Game for Two

```python:ABC088B.py
n = input()
card_numbers = list(map(int, input().split()))
alice_points = 0
bob_points = 0

sorted_card_numbers = sorted(card_numbers, reverse=True)

i = 0
for number in sorted_card_numbers:
  if i % 2 == 0:
    alice_points += number
  else:
    bob_points += number
  i += 1

print(alice_points - bob_points)
```
Aliceから開始するのが決まっていますので、
カードの数値を降順に並べて
Aliceから順番に取っていくようにしました。

### ABC085B - Kagami Mochi

```python:ABC085B.py
N = int(input())  # 最初の行の入力を受け取る
numbers = []
for _ in range(N):
  d = int(input())  # 2行目以降の入力を受け取る
  numbers.append(d)

numbers_sorted = sorted(numbers)
number_before = 0
res = 0
for number in numbers_sorted:
  if number > number_before:
    res += 1
  number_before = number

print(res)
```
問題文通り実装。
```if number > number_before```のところはもう少しスマートに書き直せそうです。

## おわり
変数名など仕事だと使えないレベルの内容ですが、
業務では使わないPythonを使えたので楽しめました、

いつかソースをブラッシュアップしたいし、
今後も継続して挑戦していきたいです。
[Windows / Python / OpenCV] ちゃんとファイルが存在するのに cv::findDecoder imread_ ... : can't open/read file: check file path/integrity が出たとき

# 概要

- opencv を使っていて、表題のエラーが発生した。
- 画像ファイル自体は確実に存在していることを確認したのに、エラー文には、ファイルが開けないようと書かれている。
- 原因がわからなくて困っていたが、なんとか原因を特定できたので共有する。


# 環境

項目|versionなど
--|--
OS|Windows10
python|3.8.10 (pyenv-win でインストール)
opencv-python|4.6.0.66
terminal|GitBash, VSCode

GitBash 上で実行したときも、VSCode 上で実行したときも、全く同じエラーが発生していたので、おそらく **Windows OS 上で `cv2.imread()`** を実行すると同様の事象が発生すると思われる。


# 解決方法概要

- 開きたいファイルの名前（path 含む）を、半角の英数記号のみにすればよい。


# エラー発生状況

cv2 で、日本語名のついた画像ファイルを読み込もうとしたら以下のようなエラーが発生していた。

```python:powershell
> python
>>> import cv2
>>> path: str = "C:\\Users\\...\\日本語ファイル.jpg"
>>> im = cv2.imread(path)
[ WARN:0@270.836] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_('C:\Users\...\日本語ファイル.jpg'): can't open/read file: check file path/integrity
```

試しに raw 文字列を渡しても同じ結果になった。

```python:powershell
>>> path: str = r"C:\Users\...\日本語ファイル.jpg"
>>> im = cv2.imread(path)
[ WARN:0@270.836] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_('C:\Users\...\日本語ファイル.jpg'): can't open/read file: check file path/integrity
```

# 解決方法

ファイル名を日本語から英数字のみの名前に書き換えてあげたら、何事もなく読み込まれた。

まず、ファイル名を `depicted.jpg` に書き換えておいた。そして以下を実行( *˙︶˙*)وｸﾞｯ!

```python:powershell
>>> path: str = r"C:\Users\...\depicted.jpg"
>>> im = cv2.imread(r"C:\Users\...\depicted.jpg")
>>> im
array([[[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
        ...
```

そしたら読み込めた。。。


# 参考

以下の記事には、 opencv だと読み込めないと書いてあるけれど、 Ubuntu であれば読み込めていたので、 windows 特有の問題のような気がする🤔

https://qiita.com/minato1109/items/df88821e796cd64757aa
vscodeでphpのセットアップ

## メインセットアップ

下記サイトをもとに拡張機能のインストールまで進めていきます。
※デバッグ実行やComposerなどは後述の手順でセットアップをします。
　Gitはすでに入っているため飛ばします。

https://qiita.com/tfukumori/items/97a8f1ac6532612b004f

## サブセットアップ

### デバッグ実行

デバッグ実行時になぜかブレークポイントで止まらなかったので、正常に動いた設定を下記に記載しています。

setting.json
・何もしない

``` launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000
    },
    {
      "name": "Launch currently open script",
      "type": "php",
      "request": "launch",
      "program": "${file}",
      "cwd": "${fileDirname}",
      "port": 9000
    }
  ]
}
```

``` php.ini
[XDebug]
zend_extension = xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_port=9000
```

上記設定をしたあとに、XAMPPのApacheを再起動します。
hello.phpにブレークポイントを設定して、「Listen for XDebug」でデバッグを実行します。
確認用URL: http://localhost/hello/index.html

「submit」ボタンを押すことで、ブレークポイントで止まるのを確認できます。

### Composer、Laravel

下記サイトをもとにComposerとLaravelのセットアップをします。

https://www.sejuku.net/blog/106106

#### Laravel追記

Laravelのプロジェクトを作成したい場所でプロンプトを開き、下記コマンドを実行します。

``` cmd
composer create-project laravel/laravel --prefer-dist Sample
```

E:\xampp\htdocsでコマンドを実行すると下記のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/a5027c8a-4abb-2870-e5e0-109904e42e03.png)

下記ファイルの任意の箇所にブレークポイントを設定します。
E:\xampp\htdocs\Sample\routes\web.php

作成したプロジェクトのlaunch.jsonを下記内容で更新し、「Listen for Xdebug」でデバッグを実行します。
``` launch.json
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9000
    },
```

XAMPP(ザンプ)のApacheを再起動します。
※下記の「apache_start.bat」でapacheを再起動できます。
　apacheが起動中に「apache_stop.bat」を実行しても停止しないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/953e3e89-d2e2-5b33-c301-dc6f3f4cb852.png)


下記URLにアクセスすると、ブレークポイントで止まります。
処理を続行すると下図画面が表示されます。
確認用URL: http://localhost/Sample/public/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/15525f84-9f9f-2d01-9235-bdf41197785b.png)

### ルートパス変更

下記記事の設定をするとhttp://localhost/Sample/public/ をhttp://localhost に省略できます。
設定パス: /xampp/htdocs/Sample/public

https://webstyle.work/xampp-document-root/
SQLのCASE式を集約関数の中に使う

# 背景
case文で初心者からするととっつきづらい。。
ただ、SQLを使う上では避けては通れない道とのこと。

# 背景
条件分岐をselect文で素直に書くのは理解しやすかった。
しかし、sumなどの集約関数内で書くのは少しイメージがしづらい。

# 本文

## 問題
下記のようなデータ（1：男性、2：女性）を、
|都道府県 |性別|人口|
|---|---|---|
|東京|1|100|
|東京|2|30|
|神奈川|1|40|
|神奈川|2|80|

下記のようなデータにしたい。
|都道府県 |男性|女性|
|---|---|---|
|東京|100|30|
|神奈川|40|80|

## 手順
1. まず、都道府県別になっているため、group_by 都道府県をする。
2. 都道府県別にして、SUM(人口)するだけでは、男女混ざった人口が取得されてしまう。
    そのため、`sum(男性の人口) as 男性`、`sum(女性の人口)as 女性`とすることで、
    男女別に人口の合計を求める。
3. 男性の人口、女性の人口を求める部分をcase式で書く。

## 回答
```sql
    select 都道府県,
        sum(case when 性別=1 then 人口　else 0 end) as 男性
        sum(case when 性別=2 then 人口 else 0 end)　as 女性
    from 人口
    group by 都道府県
```

# 学び
select文の結果から、先にgroupbyを考え、sum内の式をどうするか？といった順序で考えると自分は理解しやすかった。

# 次のアクション
case whenがパッと出てくるようになるまでは時間が少しかかりそう。
条件分岐のたびにどうやったらcase式を入れられるか、考えること。
【ChatGPT＋Code Interpreter】で画像サイズを縮小します。


　どうも、カーブミラーです。

　今回は、画像サイズを縮小します。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。あしからず。
:::

　ニュースはないので、
　　さっそく本題です。

　文字列の処理は
　　飽きましたよね。
　　　オイラもです😅

　今回は、
　　画像サイズを縮小します。

　DALL-E3は
　　正方形で描画すると
　　　1024×1024で生成されます。

　ですが、
　　場合によっては
　　　512×512や256×256にする
　　　　必要も出てきます。

　そこで
　　Code Interpreterを
　　　使って縮小します。

　以下のPromptで
　　画像縮小が行なえます。
```Text:画像縮小Prompt
CodeInterpreterで、画像サイズを[✘✘✘×✘✘✘]にしてください
```

　[✘✘✘×✘✘✘]は
　　512×512
　　256×256
　　128×128　が使えます。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Dynabook KIRAにubuntuをインストールしてみる

10年位前に購入して最近使っていないDynabook KIRAが家にあったのでUbuntuをインストールしてみる。

## Dynabook KIRA V832のスペック

|項目||
|---|---|
|モデル名|V832/28HS|
|発売日時|2023/12|
|OS|Windows8|
|CPU|Core i5-3337U|
|メモリ|8GB(DDR3-1600)|
|SSD|128GB|
|モニタ|13.3inch/WQHD(2560x1440)/タッチパネル|
|WiFi|IEEE802.11a/b/g/n|
|Bluetooth|4.0|
|重量|約1.35kg|

## 前準備

### Ubuntuのメディア作成
* **Ubuntu Desktop 日本語 Remix**(22.04 LTS)のダウンロード

https://www.ubuntulinux.jp/download/ja-remix

* Rufusの入手
    * Microsoft Storeで**Rufus**を検索して入手する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/98534a43-25c6-48ff-c6a4-ded0623d2815.png)

 * Rufusを使って起動ディスクを作成します
 
 「選択」を押下してダウンロードしたISOファイルを選択します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/5910503e-ea36-e49a-a040-bbdbbf4b6b8d.png)

ISOHybridイメージの抽出というダイアログが表示されたので、今回は**推奨**のまま「OK」を押下しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/f1f6b9e6-7626-a11b-fd01-931ca7965d84.png)

ダウンロードが必要ですというダイアログが表示されましたので、こちらは「はい」を押下しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/51ae4847-fd61-6b13-735b-40142b3086e0.png)

最終確認ですので「OK」を押下しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/fee1bd78-0eed-6122-7276-4bce4d2af9f6.png)

書き込みが開始されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/e45357cc-7979-f4e7-bbff-ce383e3dbefd.png)

書き込み完了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/0f440917-0f4f-2abc-e7a7-c484989da1df.png)

### BIOSの変更

https://dynabook.com/assistpc/faq/pcdata2/015740.htm

1. **チャーム**の設定をクリックします
2. 下の**PC 設定の変更**をクリックします
3. **全般**をクリックします
4. 一番下のPCの起動をカスタマイズするのところにある**今すぐ再起動する**をクリックします
5. オプションの選択画面になるので**トラブルシューティング**を選びます
6. 詳細オプションの選択画面になるので**UEFIファームウェアの設定**を選びます
6. UEFIファームウェアの設定の画面になるので**再起動**をクリックします 

上記の手順でUEFIファームウェアの設定を選択して再起動するとBIOS画面に入ります

BIOSメニューの画面が表示されたら

 * [Security]の[Secure Boot]をDisable(無効)にします]
     * DefalutはEnable
 * [Advanced]の[>System Configuration]でサブ画面に入り、[Boot Mode]を[CMS Boot]に変更する
     * DefaultはUEFI Boot
 * [Advanced]の[>Change Boot Order]で、[USB Memory]を一番上にします


## ubuntuのインストール

上記で作成したUSBメモリを挿してBIOSから抜けるとubuntuの起動画面が立ち上がります。
一番上の「Try or Install Ubuntu」を選択して「エンター」キーを押します。

### 「’grub-install /dev/sda’ の実行に失敗しました。」が表示されたとき

https://qiita.com/riiiii/items/a8a5f949210b739e2f5a

上記のページを参考に以下のように自分でパーティションを切ってインストールしました。

|サイズ|パーティションタイプ|新しいパーティションの場所|利用方法|マウントポイント|
|---|---|---|---|---|
|20GB|基本パーティション|この領域の始点|ext4ジャーナリングファイルシステム|/|
|16GB(メモリの2倍)|基本パーティション|この領域の始点|スワップ領域||
|200MB|基本パーティション|この領域の始点|EFIシステムパーティション||
|残り全部|基本パーティション|この領域の始点|ext4ジャーナリングファイルシステム|/home|

パーティションのところ以外は大きな問題はなくインストールが完了しました。
これからいろいろと設定などをしていきます。
当面はRustの勉強用PCになるかなー。

## 参考URL

https://seesaawiki.jp/w/haruyama_seigo/d/dynabook%20KIRA%20V832/W2UHS%20%A4%CB%20GNU/Linux

https://gunmagisgeek.com/blog/other/6314

## その他
KIRAの情報を検索していたらBIOSのアップデートがあったので実行
https://dynabook.com/assistpc/download/modify/kira/v832/bios/index_j.htm
SpringBootのapplication設定をAWSパラメータストアで行う

## はじめに

* DBアクセス用パスワード等の秘匿情報を設定ファイルに記載しておくのは管理上好ましくないので、ＡＷＳパラメータストアで管理するにあたり、Spring Bootアプリケーション設定値(application.yml/application.properties)にパラメータストアの設定値を統合（パラメータストアの値をアプリケーション設定値に反映）する作業を行いました。
 
* 本番と開発の設定を分離している点と合わせて手順等を備忘録としてまとめたものです。（乱筆な点、ご容赦ください）

### 注意点

* 実際の設定ファイルの値とは変えている個所がありますので、この値そのもので動作検証して保証したものではありません。

## 環境

* Spring Boot 3.1.0
* Java 17
* gradle 8.8

## 依存関係の追加

まず、Spring BootプロジェクトにAWSパラメータストアを使用するための依存関係を追加します。`build.gradle`ファイルに以下のエントリを追加します。


```groovy
dependencies {
    implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.1.1")
    implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store'
}
```
[👉公式サイト](https://github.com/awspring/spring-cloud-aws?tab=readme-ov-file#spring-cloud-aws)


## パラメータストアの設定値(例)

| パス                                   | 値            |
|--------------------------------------|--------------|
| `/hogehogeapp/mysqlusername`         | `appuser`  |
| `/hogehogeapp/development/mysqlpassword` | `dev_pass123`|
| `/hogehogeapp/production/mysqlpassword` | `prd_pass123`|


## SpringBootのアプリケーション設定値（抜粋）

``` text:application.yml
spring:
  application:
    name: hogehogeapp
  profiles:
    active: ${APPENV} # APPENVには環境変数として production or development のいずれかが定義されている  
  cloud:    
    aws:
      parameterstore:
        region: ap-northeast-1
```


``` text:application-production.yml
spring:
  config:
    import: 'aws-parameterstore:/hogehogeapp/'
  datasource:
    url: jdbc:mysql://db:3306/hogehogeapp
    username: ${mysqlusername}
    password: ${production.mysqlpassword}
    driver-class-name: com.mysql.cj.jdbc.Driver
```


``` text:application-development.yml
spring:
  config:
    import: 'aws-parameterstore:/hogehogeapp/'
  datasource:
    url: jdbc:mysql://db:3306/hogehogeapp
    username: ${mysqlusername}
    password: ${development.mysqlpassword}
    driver-class-name: com.mysql.cj.jdbc.Driver
```


## 少し詰まったところ

*  `import: 'aws-parameterstore:/hogehogeapp/'`について
    * `import: 'aws-parameterstore:/'`だとパラメータストア全体の値が取れることを期待したが、うまく取れないような動きになった。（当初${hogehogeapp.mysqlusername}という紐づけで試行)
    * 同じく`import: 'aws-parameterstore:/hogehogeapp/'`についてアポストロフィで囲んでいる点や`import: 'aws-parameterstore:/hogehogeapp'`とパスの最後にスラッシュがないケースなどでもうまく取得出来ないケースあり試行錯誤して最終的には上記のような構成に。

## 参考にさせていただいたサイトなど（ありがとうございました）

* https://tech.excite.co.jp/entry/2023/08/28/150056
* https://qiita.com/gigilu/items/1fc2adccccfbbedd85fe
AWS Control Tower

# はじめに

この記事はAWS SAA試験勉強のための、 AWS Control Towerに関する知識のまとめです。

# AWS Control Towerとは
AWS Control Towerは、AWSにおけるベストプラクティスに基づいた、セキュアな<font color="red">**マルチアカウント**</font>環境のセットアップを自動化するマネージドサービスです。

# ガードレール(コントロール)

ガードレールとは、AWSにおけるベストプラクティスに基づいた構成や設定、ルールの組み合わせが事前定義されたものです。管理者は、セキュリティやコンプライアンスの要件にあわせてこれらを選択し適用することで、各アカウントに対する設定や適用するルールにばらつきが生じることを防ぎ、統制のとれたマルチアカウント環境を容易に展開することができま

# 使用例

AWS Organizationsを使用して複数のAWSアカウントを管理している企業において、各AWSアカウントの利用を適切に統制したい時に用います。
Amplify gen1でデプロイイベントをEventBridgeで検知する

# 結論
```pattern.json
{
  "detail": {
    "appId": ["YOUR_APP_ID"],
    "branchName": ["YOUR_BRANCH_NAME"],
    "jobStatus": ["SUCCEED", "FAILED", "STARTED"]
  },
  "detail-type": ["Amplify Deployment Status Change"],
  "source": ["aws.amplify"]
}
```

```"appId": ["YOUR_APP_ID"],```と
```"branchName": ["YOUR_BRANCH_NAME"],```を編集するだけです。

# ソース
Amolifyのコンソールから通知を有効化します。

![cap1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/91585694-7292-509c-a377-7e1d12f1c9a3.png)

作成されたEventBridgeのルールを参考にすることでイベントパターンが確認できます。

![cap2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/1d2e52c6-bd3d-b6fd-b850-8a7d87fb7ba8.png)


# おわりに
CloudTrailから探そうと思っていましたが、もっと簡単な方法がありました。
解決してよかったです。
フォームの送信 vs Link コンポーネント：ナビゲーション実装について

# 問題
新規ユーザーを登録する画面を作成していて、登録ボタンを押すと、form内のデータが送信されてDBにデータが登録される部分を実装していました。
実際に画面上から登録ボタンを押すと、ボタンを押してもエラーが発生しないので、DB登録ができているのか確認をしたら登録ができていませんでした。

デバッグをするためconsole.logで登録ができたらログを表示するように設定をしてもログ自体も表示されませんでした。

エラーも出ない・デバッグもできない状況で原因がわかるまで少し時間を要したので共有します。

# 事象
問題のコードがこちら。
returnの中でreact-hook-formのformタグでinput要素と登録ボタンをを囲み、登録ボタンに関しては、react-router-domのLinkコンポーネントで囲み、登録ボタンが押下された後の遷移先を指定しています。

```jsx
   return (
    <Card className="w-[350px]">
      <CardHeader>
        <CardTitle>新規ユーザー登録</CardTitle>
        <CardDescription></CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="grid w-full items-center gap-6">
            <div className="flex flex-col space-y-1.5">
              <Label htmlFor="framework">Name</Label>
              <Input
                id="name"
                placeholder="フルネームを入力"
                {...register("name", { required: "名前の入力は必須です" })}
              />
              {errors.name && (
                <span className="text-red-500">{errors.name.message}</span>
              )}
            </div>
						...一部省略
						<CardFooter className="flex justify-end mt-4">
            <Link to="/login" className="" style={{ textDecoration: "none" }}>
              <button type="submit" className="btn btn-success">
                新規ユーザー登録
              </button>
            </Link>
          </CardFooter>
        </form>
      </CardContent>
    </Card>
  );

```



# 解決法

結論からいうと、react-router-domのLinkコンポーネントを使用して登録後に別ページへ遷移する設定をしていましたが、これがReact-hook-formのformと競合していることが問題だったようです。

今回はLinkコンポーネントの使用をやめて、react-router-domのuseNavigateコンポーネントを使用することで解決することができました。

詳細を確認してみると、Linkコンポーネントはクリックイベントをキャッチして新しいページへの遷移を行うのですが、formの送信イベントよりも早く処理されてしまうようです。
そうするとformの中身がないまま送信処理がされてしまうので、エラーは出ないがDBに登録するデータがないので登録自体ができていないという今回の事象に繋がってしまったということです。

# おわりに

エラーが出ないので何が原因かわからなかったですが、コンポーネントの競合が起こることを予想できませんでした。イベントの処理手順など学びつつ実装ができるように勉強を続けていきたいと思います！
AWS Security Token Service

# はじめに
この記事はAWS SAA試験勉強のための、 AWS Security Token Serviceに関する知識のまとめです。

# AWS Security Token Serviceとは

AWS Security Token Service（STS）は、AWSリソースへのアクセスを必要とするユーザーやアプリケーションに、一時的なセキュリティ認証情報を提供するサービスです。この認証情報は、最短15分から最長36時間の有効期限が設定されており、期限が切れると自動的に無効化されます。


SAML IDプロバイダーに未対応の企業向け認証基盤を利用してIDフェデレーションを行う場合、IDブローカーを使用してSTSによる一時的なセキュリティ認証情報を利用します。
使用されているADがSAMLと互換性がない場合は、代替手段としてカスタムIDブローカーアプリケーションの開発が必要です。

# AssumeRole API


AWS STSの「AssumeRole」APIは、AWS リソースに対する一時的なセキュリティ認証情報を取得するために使用される API です。この API を使用すると、指定された IAM ロールを引き受け、一時的な権限を持つセキュリティ認証情報を取得できます。
AWS Secrets Manager

# はじめに
この記事はAWS SAA試験勉強のための、 AWS Secrets Managerに関する知識のまとめです。


# AWS Secrets Managerとは

AWS Secrets Managerは、データベースなどにアクセスする際のシークレットを管理するサービスです。アプリケーションなどからAWSリソースへアクセスする際にSecrets Managerからシークレットを取得することにより、ログイン情報をアプリケーションにハードコーディングしたり平文で入力しておく必要がありません。
Windowをソースコードで出現させる

# Storyboardを使えば簡単だが、こんな場合はどうする!?
こんな感じで、Storyboardを使えば簡単にWindowsを画面に出すことができます。
![スクリーンショット 2024-08-12 11.10.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/7ffccfe9-69ce-9bcd-1a56-a623071aafba.png)

また、Storyboard Referenceを使えば、別ファイルでWindowのデザインができます。
MainのStoryboard内がスッキリして見やすいです。
![スクリーンショット 2024-08-12 11.05.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/9eef117a-661b-8a86-42fa-d96781e1bb3b.png)

良いUIかどうかの議論は別として、状況によって表示するWindowのNSViewControllerの中身を変えたい場合があったとします。

このような場合は、`ソースコードで状況に応じたNSViewControllerはどれかを判断し、用意しておいた複数のStoryboardからWindowオブジェクトを生成して表示する`というのが現実的でしょう。
# 二つのStoryboardを用意する
`CControlView`と`CCheckView`という二つのStorybardを用意しました。
![スクリーンショット 2024-08-12 11.31.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/a0f86875-62f7-9342-97dc-9a84463c8787.png)
この二つのStoryboardをソースコードで状況を判断し、その状況に応じてWindowの中に入れます。
`Slider`のラジオボタンが選択されている時はCControlViewを採用します。
`Check`のラジオボタンが選択されている時はCCheckViewを採用します。
```swift
extension ViewController {
    @IBAction func showControllWindow(_ sender: Any) {
        let window = NSWindow()
        let winController = NSWindowController(window: window)
        let ctrlView :NSViewController
        
        if sliderRadio.boolState {
            ctrlView = NSStoryboard(name: "CControllView", bundle: nil).instantiateInitialController() as! NSViewController
        } else {
            ctrlView = NSStoryboard(name: "CCheckView", bundle: nil).instantiateInitialController() as! NSViewController
        }

        winController.contentViewController = ctrlView
        window.setFrameAutosaveName("Control Window")
        window.title = "Control"
        window.makeKeyAndOrderFront(self)
    }
}
```

NSWindow、NSWindowControllerを生成します。
ラジオボタンの状態を確認し、Storyboardを読み込みます。
NSWindwControllerのwinController.contentViewControllerプロパティに読み込んだStoryboardのNSViewControllerをセットします。

必要に応じてNSWindowのプロパティを設定し、NSWindowのmakeKeyAndOrderFrontメソッドでウィンドウが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/7d743fc5-d708-6e28-abd9-affa6041ba12.png)
Storyboardでカバーできないような時に、この手法は役に立つと思います。
Markdown PDFでPDF変換できなかったときの対処方法（Windows11）

# はじめに
解決方法を備忘録として記事にします。

# 発生した事象

Vscode上で書いたマークダウンをPDFに変換しようと思ったのですが以下のエラーが出てしまい変換できませんでした。
```
ERROR: exportPdf()

Error: Failed to launch the browser process! TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md
```
実際の画面はこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3344320/a0c59a89-5d59-abb2-9e43-2f1c71a41a4b.png)

変換が上手くいかずtmpのhtmlファイルが作成されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3344320/82653815-5852-5fc1-ba92-f0a191d1be6b.png)

# 試したこと
以下の2つをためしました。

1. settings.json に Chromium または Chrome 実行可能ファイルへのパスを追加する
1. `%USERPROFILE%\.vscode\extensions\yzane.markdown-pdf-1.5.0` 配下の `extention.js` を修正する

## 1. settings.json に Chromium または Chrome 実行可能ファイルへのパスを追加する
[Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf#:~:text=boolean.%20Default%3A%20true-,Configuration%20options,pdf.executablePath%22%3A%20%22C%3A%5C%5CProgram%20Files%20(x86)%5C%5CGoogle%5C%5CChrome%5C%5CApplication%5C%5Cchrome.exe%22,-Common%20Option) に書いてありました。
`settings.json` に 以下の1文を追加する、という内容です。
```json
"markdown-pdf.executablePath": "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
```

Vscodeを再読み込みしてPDF変換してみましたが、エラーは解決されませんでした。

## 2.`%USERPROFILE%\.vscode\extensions\yzane.markdown-pdf-1.5.0` 配下の `extention.js` を修正する
次に `extention.js` を修正してみました。参考サイトは[こちら1](https://github.com/yzane/vscode-markdown-pdf/issues/249)と[こちら2](https://note.com/fmtakano/n/naed69700a658)です。

`%USERPROFILE%\.vscode\extensions\yzane.markdown-pdf-1.5.0` 配下の `extention.js`を開きます。
以下の記述を探します。
```js
const browser = await puppeteer.launch(options);
```

元々あったコードをコメントアウトして以下を追記します。
```js
//const browser = await puppeteer.launch(options);
const browser = await puppeteer.launch({
   ignoreDefaultArgs: ['--disable-extensions'],
  });
```

保存してVscodeを再読み込みしPDF変換します。

今度はエラーが出ず、うまく変換されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3344320/f1b5dca2-b2f3-98ab-5a5e-eb7726bab7cd.png)

# 最後に
同じ内容で困っている方の参考になれば良いなと思っています。

# 備考
Vscodeの再読み込み方法。
`Ctrl + Shift + P` でコマンドパレットを開き `reload window` を入力し、画像赤枠をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3344320/f2892718-0dce-0641-36d8-95c91dbc7ff2.png)
解いてみた。「Bランク：3Dプリンタ」

# 問題
[「Bランク：3Dプリンタ」](https://paiza.jp/works/mondai/b_rank_skillcheck_archive/3d_printer)

# コード
Javaで解いてみました。

``` Java
import java.util.*;


public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int nX = sc.nextInt();
        int nY = sc.nextInt();
        int nZ = sc.nextInt();
        
        boolean[][][] cells = new boolean[nX][nY][nZ];
        
        for (int z = 0; z < nZ; z++) {
            for (int x = 0; x < nX; x++) {
                String sLine = sc.next();
                for (int y = 0; y < nY; y++) {
                    cells[x][y][z] = (sLine.charAt(y) == '#');
                }
            }
            String sDummy = sc.next(); // '--'を読み捨て
        }
        
        for (int z = nZ-1; z >= 0; z--) {
            for (int y = 0; y < nY; y++) {
                boolean exist = false;
                for (int x = nX-1; x >= 0; x--) {
                    if (cells[x][y][z]) {
                        exist = true;
                        break;
                    }
                }
                if (exist) {
                    System.out.print("#");
                } else {
                    System.out.print(".");
                }
            }
            System.out.println(""); // 改行
        }
    }
}
```

# 解説
## 標準入力からの数値と文字列の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値（nX, nY, nZ）を、next()メソッドで文字列（セルの情報）を取得しています。
### 3次元配列 cells を作る
boolean 型の3次元配列 cells[x][y][z] を、標準入力のデータをもとに作成します。y方向、x方向、z方向の順になっていることに注意します。 
## cells から、「正面から見た図」を作成する
cells[x][y][z] について、y（順方向）、z（逆方向）で、xを順に走査していき、1つでもセルが存在すれば、'#'を、1つもセルが存在しなければ'.'を表示します。
## 注意点
この問題、標準入力から取り込む順序（y, x, zの順）や、正面から見た図（Y-Z平面）を表示する方向（y（順方向）、z（逆方向））に気をつける必要があります。
huskyでdocker compose exec でエラーが出て動かなかった

# はじめに

こんにちは、エンジニアのkeitaMaxです。

今回はhuskyを使用してdocker compose exec コマンドを実行した時にエラーが出て困ったことがあったので、備忘録として残します。

# 問題

```.husky/pre-commit
docker compose exec app vendor/bin/phpstan analyze
docker compose exec app composer phpcs .
```

huskyを使用してコンテナの中に入ってコマンド実行したら以下のようエラーが出て実行できませんでした。

```
% git commit -m "add husky"
the input device is not a TTY
husky - pre-commit script failed (code 1)
```


# 解決策

`docker-compose exec` に -T オプションを追加すると治るらしいです。

https://tex2e.github.io/blog/infrastructure/docker-compose-exec-err

以下のようにコードを修正しました。

```.husky/pre-commit
docker compose exec -T app vendor/bin/phpstan analyze
docker compose exec -T app composer phpcs .
```

これでコミットすると問題なく動きました。

# -T オプション

> 割り当てを無効化。デフォルトは docker compose exec に TTY を割り当て
(引用：https://docs.docker.jp/engine/reference/commandline/compose_exec.html#compose-exec-options)

-T オプションは、TTY (テレタイプ端末) の割り当てを無効にするためのオプションらしいです。

TTYは、対話的なシェルを扱う際に使われて、コマンドラインの出力を見たり、ユーザーが入力を行うことが可能にしています。

今回はTTYを無効にすることで、コマンドの実行結果を純粋な標準出力に出力したかったのでこの方法で大丈夫かなと思います。

# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

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

# 参考

https://tex2e.github.io/blog/infrastructure/docker-compose-exec-err

https://docs.docker.jp/engine/reference/commandline/compose_exec.html#compose-exec-options
eslintrc.jsonのproject設定でtsconfig.jsonが読みこなかったケース

原因がわかってないので何に困ったかと、結論だけメモします。

困ったこと。
eslintの設定でいざ`yarn lint`を実行したところ、なぜか`The file was not found in any of the provided project(s)`というエラー文が。

tsconfig.app.jsonを見つけられないことがエラーの原因のようだったので、


    "project": ["./tsconfig.app.json"],//変更後

    "project": ["./tsconfig.json"],//変更前
と修正。


tsconfig.jsonでは下記のようにtsconfig.app.jsonを読み込むようにしていたので、なぜlintがたどり着けなかったのかわからない。
```
    {
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
```

色々調べたけど詳しい原因とか出てこなかったので、とりあえず解決方法だけ共有します。
どなたか知見あるかたいたら、ご指摘やご享受いただけると幸いです。
【Laravel × Stripe】サブスクリプション処理を実装する手順４~カスタマーポータルを表示する~

【Laravel × Stripe】サブスクリプション処理を実装する手順３~Webhookで決済処理~
の続きです。

https://qiita.com/takahiro-2020/items/056c927c5b85aca27f9c

https://qiita.com/takahiro-2020/items/b3473a2fb4f78c425ab9

https://qiita.com/takahiro-2020/items/3df331abc855537c246d

https://qiita.com/takahiro-2020/items/cf3be9352e1a1525a83c

## カスタマーポータルを開いて、ユーザーが契約内容を変更できるようにする
カスタマーポータルを開けるようにします。
ユーザーがサブスクプランをキャンセルしたり、クレジット情報を追加することができます。
UIは自動作成され、サブスクキャンセルの処理などもStripe側で行なってくれるのでとても便利です。

![スクリーンショット 2024-08-11 8.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1248327/b707c797-610e-9958-59f1-352c9a6fd7fc.png)



## カスタマーポータルを開く
`ルーティング(シリーズ１のおさらい)`
```php
# カスタマーポータル
Route::get('stripe/subscription/customer_portal',
[Controllers\StripSubscriptionController::class, 'customer_portal'])
->name('stripe.subscription.customer_portal');
```


`コントローラー：StripSubscriptionController.php`
```php
    /**
     * カスタマーポータル
     *
     * @return \Illuminate\Http\Response
    */
    public function customer_portal()
    {
        Stripe::setApiKey( config('stripe.secret_key') );

        # 顧客情報
        $user = Auth::user();
        $customer = $user->createOrGetStripeCustomer();


        # Stripeクライアントを初期化
        $stripe = new StripeClient(env('STRIPE_SECRET'));

        # カスタマーポータルセッションを作成
        $session = $stripe->billingPortal->sessions->create([
            'customer' => $customer->id,
            'return_url' => route('home'), // ポータルを終了した後にリダイレクトするURL
        ]);

        # カスタマーポータルへのリダイレクト
        return redirect($session->url);
    }
```


こちらのコードで、カスタマーポータルを開くことができます。


## サブスクプランキャンセルのイベントを受け取る








長くなりましたが、LaravelとStripeを利用したサブスクリプションの記述は以上です。
【laravel】Geometry型を使うときに気をつけるべきこと

## Geometry型って一体なんやねん

### 特徴
経度、緯度といった２つの要素を１つの変数として扱うことができる。
複雑な計算式（以下参照）を使わなくとも， 特定の関数を使うだけで簡単に距離を計算できる.

```php:２点間の直線距離を求める計算式(数学が得意な人向け)
6378 * acos(cos(deg2rad($latitude)) * cos(deg2rad($checkin['checkin_latitude'])) * 
cos(deg2rad ($checkin['checkin_longitude']) - deg2rad ($longitude)) + 
sin(deg2rad ($latitude)) * sin(deg2rad ($checkin['checkin_latitude'])));
```

```php5:Geometry型をフル活用した時
  ST_Distance_Sphere(coordinates,ST_GeomFromText(POINT(135 33), 4326))
```


### Geometry型はどんな場面で使われるの？
GoogleMap等の地図アプリで現在位置からの直線距離を計算し、近隣の店舗などを表示するときに用いられる。
例えば近くの美味しいラーメン屋に行きたい人の願いを叶えてくれたり、私たちの生活には必要不可欠なのだ。


## 便利な反面， 気を抜くとハマってしまうのでご注意を

### 注意点① 経度と緯度の下限値・上限値はそれぞれ異なる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401561/e81869df-28e4-efc2-5bb6-6512c4d6995b.png)

管理画面等で登録をする際は必ずバリデーションを設けること。
経度と緯度の限界値は以下の表の通り。

| 変数名 | 英語名 | 上限値 | 下限値 |
| :-: | :-: | :-- | :-- |
| 経度 |Longitude| -180 | 180 |
| 緯度 |Latitude|  -90 | 90 |

ちなみに経度は英語でlongitudeなので、「横に長い＝範囲が広い」と覚えておこう。


### 注意点②　POINT型のデータを直接APIで出力すると文字化け現象が起きる
laravelでは16進数のデータとして保存されるとのこと。

### 注意点③ コンマの有無で緯度と経度の順番が逆転する
ハマる人が続出するので注意してほしい。
非常に性質が悪いことに引数の間にコンマがなくてもエラーが表示されることはない。
コンマの有無で緯度と経度の順番が逆転するため、
何も知らずに使ってしまうと緯度が130°といった訳のわからないデータを登録することになってしまう。

しかしgeometryさんは何も教えてくれない。
そのおかげで人生の貴重な時間をデバッグに浪費するハメになるので、この記事を読んでいる賢明な読者さんは私と同じ轍を踏まないように・・・。



## まとめ

###  メリット
ある関数を使えば複雑な式なしで２点の距離を計算することができる。

### デメリット
便利な反面，使いこなすまでに勉強時間が必要。
コンマの有無で緯度、経度のポジションが逆転してしまうので注意。


## 参考資料
###【SQL Server(T-SQL)にて、空間データ型(geograhy)で遊んだ備忘録】
http://mrgchr.hatenablog.com/entry/2019/09/21/120000