OmniAICreator/Qiita-1.07M huggingface dataset:
Android開発でAPIkeyを隠してGithubに上げる方法

# はじめに
今回は、APIキーなどの機密情報を安全に管理するために、Secrets Gradleプラグインを使用する方法について説明します。この方法を用いることで、機密情報を秘匿しつつ、プロジェクトをGitHubにアップロードする手順を解説していきます。
# 手順
詳しい導入方法はこちらに書かれています。

https://github.com/google/secrets-gradle-plugin

### その１
プロジェクトレベルのbuild.gradle.ktsに下記をコピーして貼り付けてください。

:::note warn
こちらより最新バージョンがある場合はそちらを記入して使ってください。
:::

```kotlin:build.gradle.kts(Project)
buildscript {
    dependencies {
        classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
    }
}
```
### その２
次にモジュールレベルのbuild.gradle.ktsに下記をコピーして貼り付けてください。

``` kotlin:build.gradle.kts(Module)
plugins {
    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
```

### その3
もう一度モジュールレベルのbuild.gradle.ktsのbuildFeaturesに"buildConfig = true"を追加してSyncしてください。

```kotlin:build.gradle.kts(Module)
    buildFeatures {
        compose = true
        buildConfig = true
    }
```

### 最後に
Gradle Scriptsの中にあるlocal.propertiesに隠す用のAPIキーを書いてください。
```kotlin:local.properties
APIKey = {"隠す用のAPIキー"}
```

書けたらBuildConfigで参照できるか一度確認してみてください
```kotlin:<例>
val APIKey = BuildConfig.APIKey
```

:::note warn
BuildConfigでアクセスできなかった場合は下記をお試しください。
（実際自分はこの過程を挟まないと絶対BuildConfigから参照できなかったです。）
1\.FileからInvalidate Caches
2\.buildからClean Project
3\.buildからRebuild Project

この手順を組めばとりあえずはBuildConfigからアクセスできると思われます。
:::

# 終わり
多くの場合、機密情報の秘匿にはCLIやコマンドラインの操作が必要で、初心者には難しいと感じることが多々ありましたが、こちらの方法ならもっと簡単に理解しやすいんじゃないんだろうかと思っていたので書けてよかったです。

また、下記の方のnoteも参考にしたのでぜひこちらもみて参考にしてください！

https://note.com/npaka/n/nd2158b288d11
イシューからはじめよ――知的生産の「シンプルな本質」

https://www.amazon.co.jp/%E3%82%A4%E3%82%B7%E3%83%A5%E3%83%BC%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E2%80%95%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E3%81%AE%E3%80%8C%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E6%9C%AC%E8%B3%AA%E3%80%8D-%E5%AE%89%E5%AE%85%E5%92%8C%E4%BA%BA/dp/4862760856


# 本書を手に取った背景
今の業務でイシューの管理をするというものがあるが、どのように勧めていこうか考えていたときにイシュー管理観点で有名な本書を読んでみようと思った。

# 結論
解決策ではなく、課題・イシューを明確にするという点に焦点を絞っている。
そのやり方を詳しく解説しており、今後活かせそうな知識も多分に含まれているため、ためになった。

# 本書のテーマ
イシューとは何かを追求する。
「何について答えを出すべきなのか」の考え方を紹介する本。

# 個人的なポイント
### ①一般常識をすてるところから
問題を解く→問題を見極める
解の質をあげる→イシューの質をあげる
知れば知るほど知恵が湧く→知りすぎると馬鹿になる
一つ一つを早くやる→やることを削る
数字の桁数にこだわる→答えが出せるかにこだわる


### ②イシューへのアプローチ
1日目　イシュードリブン　イシューを見極める
2日目　仮説ドリブン　イシューを砕き、ストーリーの流れを整理する
3,4日目　仮説ドリブン　アウトプットのイメージを描く
5日目　メッセージドリブン　論拠と構造を磨く

### ③よいイシューの条件
１　本質的な選択肢
２　深い仮説がある
３　答えを出せる

### ④構造的な理解の４パターン
共通性の発見
関係性の発見
グルーピングの発見
ルールの発見

### ⑤ 知りすぎ
知れば知るほど「自分ならではの視点」がなくなる

### ⑥イシューを分解する型
新規事業だったら。。。
Where:どのような領域を狙うか
What:具体的にどのような勝ちパターンがあるか
How:具体的なとりくみをどのように実現するか

### ⑦分析とはなにか？
比較、比べること
フェアに対象を並べ違いを見ること
比較の軸が鍵になる

定量分析の型は　
比較　
構成：市場シェア、コスト比率、体脂肪率など　　
変化：時間軸の推移など

### ⑧エレバーターテストでストーリーをまとめる

### ⑨1チャート1メッセージ

### 今後やれること
社内でのイシュー管理に加え、分析業務でも使えそう

### まとめ
一度本を読んだだけでは、身についている感じはなく何度も繰り返して実践する必要があると感じた。
それぐらい馴染みがなく、難しいと感じた本。
ベクトルタイルのspriteについて理解する

# はじめに
ベクトルタイルのスタイルファイルには、ルート要素の一つとしてspriteが存在します。参照するURLが地図記号、線、ポリゴンの塗りなどに使う画像の場所を指定しているというのは、何となく分かるのですが、きちんと理解出来ていないので、spriteについて調べながらこの記事を書きました。スタイルファイルの全体像については、[こちらの記事](https://qiita.com/k96mz/items/1ac756935b685d20dd7c)で記載しています。

# spriteとは
### Mapboxの日本語のサイト
[Mapboxの日本語サイト](https://docs.mapbox.com/jp/help/glossary/sprite/
)に分かりやすい記述がありました。
「スプライトとは、スタイルに含まれるすべてのアイコンを含む1つの画像のことです。たくさんの小さな画像を1つの画像（スプライト）にまとめることで、すべての画像を取得するのに必要なリクエストの数を減らすことができ、パフォーマンスが向上し、マップの読み込みが早くなります。」とのことです。なるほど〜、そういうことだったんですね。
スプライトには、アイコンのサイズやスプライト内の位置など、スプライト内の各アイコンを定義したJSONファイルが用意されていて、以下がJSONファイルの一部です。

```JSON
"airport-15": {
  "width": 42,
  "height": 42,
  "x": 76,
  "y": 300,
  "pixelRatio": 2,
  "visible": true
}
```
airport-15のような名前で参照すると、スプライト内にある位置「"x": 76, "y": 300」のアイコンの大きさは「"width": 42, "height": 42」、ピクセル比は2であり、スプライトの中からこのアイコンのみを表示することが出来ます。



### その他日本語サイト
日本語の[こちらのサイト](https://smellman.github.io/vector_tile_book/docs/knowladge/sprite_url.html)も見てみます。大事な情報としては、以下のとおりです。

・Spriteの位置をPOIなどと関連付けるため、 sprite.json というファイルを用意する必要あり
・実際に必要な構成は以下
├── `sprite.json`
├── `sprite.png`
├── `sprite@2x.json`
└── `sprite@2x.png`
`sprite.json` と `sprite.png` がペアに、 `sprite@2x.json` と`sprite@2x.png` が高解像度のペアとなる。

## MapLibreのサイト
次に[MapLibreのサイト（英語）](https://maplibre.org/maplibre-style-spec/sprite/)を見てみます。概要は以下のとおりです。

◯スプライトに含まれる画像は、他のスタイルプロパティ（background-pattern、fill-pattern、line-pattern、fill-extrusion-pattern、icon-image）で参照することができる。

◯スプライトを読み込むには、スプライトがロードされるURLを以下のように指定する必要がある。
```
"sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite"
```

上記URLの場合、.pngを追加して画像を、.jsonを追加してスプライトを読み込むために必要なメタデータを見ることが出来ます。pngを見てみると下のようになります。

![スクリーンショット 2024-08-29 17.10.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/f8982b5c-14d2-746e-9a34-935bf8b56df2.png)

JSONファイルは以下のリンクから見ることが出来ます。
https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite.json

◯有効なスプライトソースは、以下の2種類のファイルを提供する必要があります。
1.	画像ファイル: PNG形式
2.	インデックスファイル:
スプライトに含まれる各画像の説明を含むJSON形式のファイル。JSONオブジェクトであり、画像の大きさ（widthおよびheightプロパティ）、ピクセル比（pixelRatio）、およびスプライト内での位置（xおよびy）を記述する。


# まとめ
spriteについて理解出来ていなかったので、まとめました。自分自身でspriteを作ることは難しそうですが、すでに用意されたものがあれば、使えるようになった気がします。

# Reference

https://smellman.github.io/vector_tile_book/docs/knowladge/sprite_url.html

https://maplibre.org/maplibre-style-spec/sprite/

https://www.youtube.com/watch?v=Cp2PoIi8J24
【JavaScript】Canvasの描画がじわじわ遅くなる原因


## 結論

図形を描画する前に`context.beginPath()`しましょう。

終わり。

https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/beginPath

## おまけ

Canvasに1/60秒間隔で描画処理をしていたのだが、4分くらいたつとFPSが低下する現象が発生した。
全く原因が分からず

* `setInterval`を`requestAnimationFrame`に変えても効果なし
* [キャンバスの最適化](https://developer.mozilla.org/ja/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas)に従っても効果なし
* メモリの解放忘れでもなさそう
* ググっても全く参考になるサイトが見つからない

という状態で絶望していた。

そんな中、ソースの原因箇所を特定すべく描画処理を消しまくって`context.rect()`が原因だということに気づき、やがて`beginPath()`で解決できることが分かった。

「まあほぼ画像関係が原因だろうな。」と思い込んでいたこと、再現まで時間がかかることから長い間デバグ沼にハマってしまった。

ついでにChatGPTくんに聞いてみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/3f90f1bc-65d0-2292-28fa-cb6a71317c2b.png)

全く知らんかった。。。
ROS2でPC間通信できないときはIPv6が原因かも

ROS2でPC間通信ができなくて困ったので、その解決方法を残しておきます。


# 環境
OS：Ubuntu 22.04.4 LTS
ROS2：Humble


# IPアドレスの設定
IPv4アドレスを固定し、IPv6は無効にします。
ここではGUIで設定する方法を紹介します。

### IPv4アドレスを固定する
![スクリーンショット 2024-09-11 2.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326247/cf749b63-2984-435a-553e-889233ca2cb3.png)

### IPv6アドレスを無効にする
![スクリーンショット 2024-09-11 2.46.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326247/b6bf2ac3-a823-dfbb-b3a3-89c86543edeb.png)


# 環境変数の設定
### 環境変数を確認する（設定前）
```bash:環境変数の確認
printenv | grep ROS
```
次のような表示を確認できます。
```bash:（表示例）
ROS_VERSION=2
ROS_PYTHON_VERSION=3
ROS_LOCALHOST_ONLY=1
ROS_DISTRO=humble
```

### 環境変数を設定する
- `ROS_DOMAIN_ID`はノードを共有したいPCで同じ値を指定します
- `ROS_DOMAIN_ID`のデフォルト値は`0`です
- `ROS_DOMAIN_ID`として安全に使用できる値の範囲は`0 ~ 101`です
- `ROS_LOCALHOST_ONLY`を`0`にすると、ネットワークにノードが公開されます
- `ROS_LOCALHOST_ONLY`を`1`にすると、ローカルホストのみにノードが公開されます

```bash:環境変数の設定
export ROS_DOMAIN_ID=1
export ROS_LOCALHOST_ONLY=0
```
:::note info
`.bashrc`に書き込むと、次回以降はターミナルを開いた際に自動で実行されます。
```bash:環境変数の設定（.bashrc）
echo "export ROS_DOMAIN_ID=1" >> ~/.bashrc
echo "export ROS_LOCALHOST_ONLY=0" >> ~/.bashrc
```
:::
:::note warn
ROS2 Jazzy以降は`ROS_LOCALHOST_ONLY`が非推奨になりました。
代わりに`ROS_AUTOMATIC_DISCOVERY_RANGE`を使用します。
- `ROS_AUTOMATIC_DISCOVERY_RANGE`を`SUBNET`にすると、ネットワークにノードが公開されます
- `ROS_AUTOMATIC_DISCOVERY_RANGE`を`LOCALHOST`にすると、ローカルホストのみにノードが公開されます
```bash:環境変数の設定
# export ROS_LOCALHOST_ONLY=0 に相当
export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET
```
```bash:環境変数の設定（.bashrc）
# echo "export ROS_LOCALHOST_ONLY=0" >> ~/.bashrc に相当
echo "export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET" >> ~/.bashrc
```
:::

### 環境変数を確認する（設定後）
```bash:環境変数の確認
printenv | grep ROS
```
次のような表示を確認できます。
```bash:（表示例）
ROS_VERSION=2
ROS_PYTHON_VERSION=3
ROS_DOMAIN_ID=1
ROS_LOCALHOST_ONLY=0
ROS_DISTRO=humble
```


# まとめ
とりあえずIPv6は無効にしておきましょう。
ROSを活用されるみなさんの助けになれば幸いです。


# 参考記事
https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.html

https://docs.ros.org/en/humble/Concepts/Intermediate/About-Domain-ID.html

https://docs.ros.org/en/jazzy/Tutorials/Advanced/Improved-Dynamic-Discovery.html


# 更新履歴
- **2024/09/11**
・投稿
・微修正
Local Storageに入れたデータが上手く判定できなかった話

## Local Storageに入れたデータを使って条件判定したい
- JavaScriptでを使ってLocal Storageにデータを入れて条件判定に利用
- データはJSON.stringify()メソッドとJSON.parse()メソッドをつかって出し入れ
以上の条件で作業を行っていた。


## Local Storageから取り出した値で判定できない！

「Local Storage内の 'option' の値が 'default' のとき」という条件を書くため、以下のようなコードで一旦動かしてみた。

```JavaScript:JavaScript
const value = localStorage.getItem('option');
if(value !== null && value === "default"){
    //処理   
}
```

ただ、これだとif文の中に入ることができず、「ちゃんと値設定しているのになんでだ？」と小一時間悩んでしまっていた。

## エスケープ処理してみた
結果的には以下のように書き換えることで、解決できた。


```JavaScript:JavaScript
const value = localStorage.getItem('option');
if(value !== null && value = "\"default\""){
    //処理   
}
```

その時は「ええいままよ」という感じでエスケープ処理を書いたら動いた！となってそのままにしていたのだが、原因を辿ってみるとsetItem時に原因があることがわかった。

## Local Storageへの保存方法
Local Storageの特徴として以下が挙げられる。
- Local Storageは仕様上「文字列」しか保存できない

しかし、文字列だとデータが扱いにくいため、本来JSONとして保存したい。
そのため、以下のように出し入れすることも多い。

```JavaScript:JavaScript
let storage = localStorage;
let value =  { name: 'りんご', price: 150 };
storage.setItem('option', JSON.stringify('value')); //setData
let data = JSON.parse(storage.getItem('option'); //getData
console.log(data.name); //　出力結果：りんご
```

基本的には上記のようにオブジェクトのような形で値を保存するため、上記の 'setData' 部分を以下のように関数として使い回していた。

```JavaScript:JavaScript
function setData(key, value){
    let storage = localStorage;
    storage.setItem('key', JSON.stringify('value'));
}
```

## 実際に行った処理

これで文字列しか保存できないLocal Storageでもデータが扱いやすくなるのだが、ここに原因があった。具体的には以下のようデータを格納していた。

```JavaScript:JavaScript
setData('option', 'default');
```

実はこの状態だと、値「default」がJSON.stringifyによって「"default"」として格納され、「dufault」で判定を行ってもマッチしなかったというわけ。

## 関数を使う時は、戻り値を確認しろ
結局のところ、自分で作った関数を理解していなかったというのが原因だが、ついつい使い回してしまって、実際にどんな形で出力されているのか、ということを忘れがち。

- 「文字列」⇔「JSON」の変換は、実際の文字列を意識する
- 似たような処理でも、関数を使いまわせるかはしっかり確認する

この辺りを意識しないとなあと再確認させられた。
pipを使おうとすると「pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.」のwarningが出る場合

## 問題
pipを使うと、
`pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.`のWargningが出るようになってしまった。
pip installができない。

## 環境
Mac book Air M2
python は pyenv 経由で使用
```
$ where python
/Users/ユーザー名/.pyenv/shims/python
```

## どういった時にこのWarningが出るか？

Python が ssl モジュールを正しく認識できていないとき。
- openssl がシステムにインストールされていても、Python が正しくリンクされていない
- Python 環境に問題がある
- OpenSSL の PATH 設定に問題がある



## 原因：python がシステムの OpenSSL を使っていなかった
```
# opensslの場所を確認した結果
$ where openssl
/usr/bin/openssl
/opt/homebrew/bin/openssl
/opt/homebrew/opt/openssl/bin/openssl
/usr/bin/openssl
/opt/homebrew/bin/openssl
/opt/homebrew/opt/openssl/bin/openssl
```
- pyenv 経由でインストールされた Python は、デフォルトではシステムの OpenSSL とリンクされていない可能性がある
- /usr/bin/openssl は macOS にプリインストールされている古いバージョンの OpenSSL であるため、これが原因で ssl モジュールが正しく動作していない可能性があった


## 結果

pyenv を使って Python をインストールした際に、HomebrewのOpenSSLと正しくリンクされるように環境変数を設定し直し、Python を再インストールした。

※OpenSSLは「OpenSSL@3.3」を使用します。記事執筆時点での最新版です。現在のLTSは3.0らしいので、LTSを使う場合は適宜読み替えてください。
参考：https://endoflife.date/openssl

#### 1 . OpenSSL@3.3 をインストール
※すでに openssl@3.3 がインストールされている場合はこのステップはスキップする
``` 
$ brew install openssl@3.3
```
#### 2 . OpenSSL@3.3 のリンク確認
openssl@3.3 を優先的に使うために、次のコマンドでリンクを確認する
このコマンドで openssl@3.3 がデフォルトの OpenSSL として使用されるようになる
```
$ brew link --force openssl@3.3
```

#### 3 . 環境変数を .zshrc に追加
openssl@3.3 をデフォルトで使いたい場合、次の環境変数を .zshrc に追加しておくと良い
```
# OpenSSLパスの設定
export PATH="$(brew --prefix openssl@3.3)/bin:$PATH"
# LDFLAGS と CPPFLAGS の設定
export LDFLAGS="-L$(brew --prefix openssl@3.3)/lib"
export CPPFLAGS="-I$(brew --prefix openssl@3.3)/include"
```
この設定を反映するには、ターミナルで以下のコマンドを実行する
```
source ~/.zshrc
```

#### 4 . pyenv で使用している Python バージョンを確認
```
$ pyenv versions
pyenv install 3.10.6
```

#### 5 . Python の再インストール
openssl@3.3 にリンクされた Python を pyenv を使って再インストール
環境変数を設定して、Python をビルドする際に openssl@3.3 を使用させる
```
$ CFLAGS="-I$(brew --prefix openssl@3.3)/include" \
LDFLAGS="-L$(brew --prefix openssl@3.3)/lib" \
pyenv install <Python_version>
# <Python_version>は上記「pyenv versions」で確認した使っているバージョンを入れる。
# 私の環境だと「pyenv install 3.10.6」となった。
```

> 補足：
pyenv を使って Python をインストールする際に、Homebrew でインストールされた OpenSSL のヘッダーファイルとライブラリを Python のビルド時に指定するためのもの。これにより、Python が ssl モジュールを正しく構築し、OpenSSL ライブラリとリンクされるようにしている。

もし`pyenv install <Python_version>`で`<Python_version> already exists`となる場合は、すでに入っているバージョンであるため、再インストールするには、まず既存の Python バージョンをアンインストールする必要がある
```
# まず、既にインストールされている Python 3.10.6 をアンインストール 
$ pyenv uninstall 3.10.6
remove .../<Python_version>? [y|N] y
<Python_version> uninstalled

# アンインストール後、openssl@3.3 にリンクして再インストール
$ CFLAGS="-I$(brew --prefix openssl@3.3)/include" \
LDFLAGS="-L$(brew --prefix openssl@3.3)/lib" \
pyenv install 3.10.6
```

#### 6 . Python が OpenSSL@3.3 とリンクされているか確認
これでエラーが出ず、OpenSSLのバージョンが表示されればOK
```
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)"
```
いにしえの言語"COBOL"について

# COBOLについてザックリ説明
*COBOL(Common Business Oriented Language)*
* 1959年にアメリカで生まれた事務処理用に開発されたプログラミング言語
* 歴史が古く安定した言語
* 世界中の金融業界や行政で現在も使われる
* 銀行や保険会社、政府機関での給与計算、財務報告、顧客データ管理など、大量のトランザクションを処理するのに適している

## COBOL(コボル)プログラムの書き方

大きく分けて4つの部で構成される
* 「見出し部 *IDENTIFICATION DIVISION* 」
* 「環境部 *ENVIRONMENT DIVISION* 」
* 「データ部 *DATA DIVISION* 」
* 「手続き部 *PROCEDURE DIVISION* 」

見出し部以外は省略することが可能
部（DIVISION）の中にはいくつかの節（SECTION）や段落がある。

## プログラムとしてCOBOLを使用するには
:warning:書いたコードをそのままパソコンが処理することはできない。
そのためパソコンに入っているプロセッサが直接実行できる機械語に変換する必要がある。
この変換作業を **コンパイル** と呼び、コンパイルを行うプログラムを **コンパイラ** と呼ぶ。
コードを書いて、コンパイルして、処理を動かしたときにエラーをはかれても、コンパイルしたコードは全く読めない。
そのためコンパイル元のコードを読んでエラー部分を修正して再度コンパイルを実行する必要がある。

# 参考にさせていただいたページ
https://www.cobol.co.jp/cobol-nyuumon/kiso/k001/

https://www.cobol.co.jp/cobol-nyuumon/benkyou/b015/

https://techsuite.biz/cobol-10%E5%88%86%E3%81%A7%E8%A7%A3%E8%AA%AC/
未経験からエンジニア転職して1年、振り返ったら順調すぎる件ｗｗｗｗｗｗｗｗｗｗｗ

# こんなタイトルで大丈夫なのかな
一抹の不安は捨て去り、前を向いてQiitaデビューしようと思います。
万人の目を惹くタイトルを熟考したらこうなりました。
あなたがこの文章を読んでる時点でこのタイトルをつけた僕の勝ちなんですよ。


# 本記事の読者ターゲット層
* 未経験者
* 初心者エンジニア


# 自己紹介
2024年9月現在31歳
前職は保育士
結婚を機に給与面(薄給)・待遇面(サビ残持ち帰り毎日3～5時間)を改善し、健康で文化的な最低限度の生活を勝ち取るために一念発起して大好きだった保育士を辞職してIT転職しました。
現在のCrane＆Iに入るまでに転職を経ていることもあり、1年間で3案件と少し多いかもしれませんが、どの現場でも自分なりに頑張ってきました。





# そして現在
順調すぎるｗｗｗｗｗｗｗｗｗｗｗ

どの案件でも新しいことに携わらせていただいてスキルアップ↑↑↑
案件面談や顔合わせでも1年目のくせに自信満々に話せるようになって参画始めから好印象↑↑↑
いろんな道がひらけまくりで人生お先明るすぎ～～～↑↑↑


# 積極性を前面に押し出したことがすべてではないか
どうしてこの1年がこれほどまでに順調だったのかを振り返れば、それは僕自身の戦略が功を奏した、つまり*セルフブランディング*の賜物ではないかと思います。

セルフブランディングという単語を使用するにしては、規模が小さいですが、
(従来は自分自身をコンテンツとして市場にマーケティング/宣伝する為の手法だと思います)
僕は現場でも自社でも意図的に“積極性”をアピールしてきました。

もちろん、親切な方々と縁があり、かなり運にも恵まれましたが、それを逃さなかったのも積極性をアピールしたからこそだと信じています。


積極性の中でも、｢できます！｣｢やります！｣とやる気を声高にアピールし、たくさんタスクをこなしていくような業務貢献の積極性だけでなく、
人間関係の積極性こそ未経験者は大切にすべきです。

業務貢献の積極性こそ、スキルアップにもつながりスキルシートを充実したものにする為に必要な要素ですが、この根底には人間関係の積極性があり、特に未経験者は人間関係の積極性が無ければ業務貢献の積極性は獲得し得ないと思っていいと僕は考えます。


# 未経験者にとって人間関係の積極性が大切な理由

掲題について論じるにあたり、以下を前提としていきます。
基本的に上司は、部下に新しいことをさせる場合はそのカバーやフォローの責任があります。
また、上司にとって大半の業務は自分でやったほうが確実で安心で速いのです。
ですから、部下に仕事をさせるのは上司にとって負担であることも往々にしてあります。

ここで自分が上司の立場になって考えてみると、未経験でスキルも浅い、人間関係の積極性が無く、何を考えているかわからない。そんな人間にいろんなタスクを振り分けてみようと思えるでしょうか？
多くの人間はそうは思えないでしょう。上司も人間です。できる限り負担のない生活を送りたいでしょう。

スキルも浅い、人間関係の積極性が無く、何を考えているかわからない未経験者は、結果、スケジュールに余裕が無くて仕方なく、人手不足で仕方なく、そんなネガティブな理由でしかタスクを回してもらえず、スキルアップが遅くなってしまいます。


では、スキルアップしたい未経験者はどうすればよいでしょうか。
多少の負担になってでも成長させてあげたいと上司に思ってもらえる部下になりましょう。
上司も人間です。かわいい部下が成長することに喜びを感じる人は多いですし、かわいい部下が活躍する姿を見たいものです。

そして、僕はこう考えています。
未経験者こそ、かわいい部下になりやすい、と。
未経験者は人間関係の積極性さえ心がけていればかわいい部下になりやすいです。
業務経験が重なれば、それ相応のスキルを備えていないと第一印象が悪くなり、スタートダッシュで躓きます。
でも未経験者は業務上のスキルなんて50歩100歩です。差を生むのは人間関係の積極性です。


# 人間関係の積極性ってなんなんよ
僕が特に意識していたのは3点

* 報連相＋α
* 将来の相談
* 上司の仕事内容に首を突っ込む

多分めちゃくちゃ効果あります。

挨拶や思いやりが人間関係で大切なのは最低限。
雑談が大事！というのもありますが、趣味の違いなどもあって雑談は合う合わないがあると思います。

上記3点は業務内容に絡んだことなので、趣味などの相性等々に左右されず無関係に積極性を発揮できるのが利点です。


# 報連相＋α
報告・連絡・相談　だけで満足するのは二流。
一流のかわいい部下は　＋αで感想を述べるんです。

｢作業終わりました｣
｢ここがこうで難しかったですが終わりました｣

｢これはこうですよね？｣
｢このタイプの作業を実際にやったことがなくてここが不安なので確認なんですが、これはこうですよね？｣

部下から感想を述べることで、上司は意識せずとも部下のスキルの把握が鋭くなっていきます。
自力ですべて完了して報告できるのは簡潔ですが、こういう課題があったけど解決できました！を伝えられるほうが、未経験者にとっては有意義な報告だと考えます。



# 将来の相談
将来の相談といっても老後の話ではありません。エンジニアとしての将来の相談を持ち掛けましょう。
キャリアアップのために頑張っていこうという積極性のアピールにもなりますが、それよりも自分の将来というかなり大きいものに関与してほしいという信頼の証をこちらから明示することに大きなメリットがあります。心理学的な側面での詳細は省きますが、信頼の証を明示することで、相手の信頼を勝ち取りやすくなり、かわいい部下にしてもらいやすいこと間違いなしです
まあそんな難しいこと考えなくても仕事の話って確実な共通の話題なので、とりあえず投げとけばなんか返ってきます



# 上司の仕事内容に首を突っ込む
これは関係をある程度構築してからになりますが、上司がやっている作業の一部でもいいので質問します
｢〇〇さんのやってるこの作業って、××ですよね？どのくらい勉強したんですか？××っていろんな現場で使われてます？｣とかなんでもいいので、余裕のあるときに首を突っ込みましょう。
心理学的な側面での詳細は省きますが、興味を持っていると明示することや、あなたにまつわることを開示してほしいという要求は、相手から好意的に見られやすくなり、かわいい部下にしてもらいやすいこと間違いなしです。



# 自分はかわいい部下になっているか
かわいい部下になろうとしすぎると困った部下になると思います。
思い出してほしいのは、部下を育てることは上司の負担の一部であることが多い、ということです。
業務上の貢献で負担を減らすことはまだまだ難しいかもしれません。それでもかわいがってもらうためには、仕事がしやすい部下だと思ってもらえるように程よい距離感で積極性をアピールするセルフブランディングが肝要だと思います。




# 終わりに
僕は2年目に突入し、31という年齢も相まって、かわいい部下になりにいくのがどんどん難しくなっていくとは思います。
徐々にスキルやコミュニケーションを、かわいがってもらいにいくためではなく、微力ながらも業務のために活かす方向にシフトさせていこうと思っています。

未経験者や初心者の方々におかれましては、己のスキルアップのため日々かわいがられますようお祈り申し上げます。
ドキュメント生成ツールとして使用するSSG比較


静的サイトジェネレーター（SSG）を使用して開発用ドキュメントを生成、管理することを考えてみます。

比較観点：

- 内部用ドキュメントを想定しているため SEO は考慮しない
- 既存のドキュメントが Markdown ファイルなのでそのまま移植することを想定
- ドキュメント内検索をしたい
- SSG は npm でインストールしたい
- かっこいい（主観）画面が良い

### まとめ表

| SSGツール                            | Markdown対応 | ドキュメント内検索                                                      |
| ------------------------------------ | ------------ | ----------------------------------------------------------------------- |
| [Docusaurus](https://docusaurus.io/) | ○            | デフォルトで利用可能。[Algolia](https://www.algolia.com/)などもサポート |
| [Nextra](https://nextra.site/)       | ○            | デフォルトで利用可能。Next.js ベースなので独自にカスタマイズ可能。      |
| [VitePress](https://vitepress.dev/)  | ○            | デフォルトで利用可能。[Algolia](https://www.algolia.com/)などもサポート |
| [Gatsby](https://www.gatsbyjs.com/)  | ○            | Plugin で利用可能<br>[Algolia](https://www.algolia.com/)などもサポート  |

### 1. [Docusaurus](https://docusaurus.io/)

![docusaurus.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/d13918b0-1f97-3cd6-4aab-d164b8b95d94.png)

Facebook が開発した SSG。ドキュメンテーションに特化しており、React ベースでカスタマイズが容易。

インストール直後のディレクトリ構成：

```sh
README.md
babel.config.js
blog/
docs/
docusaurus.config.ts
node_modules/
package-lock.json
package.json
sidebars.ts
src/
static/
tsconfig.json
```

### 2. [Nextra](https://nextra.site/)

Next.jsベースの SSG で、ドキュメント作成に特化しており、シンプルなセットアップでモダンなドキュメントサイトが構築可能。

![nextra.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/6110bc14-344e-2f5f-1fcd-fc3cdbe0033b.png)

ファイル構造：

```sh
# Next.js の追加パッケージのため、ディレクトリ構成は Next.js に従う
.
├─ pages
```

### 3. [VitePress](https://vitepress.dev/)

Vue.jsを使用したドキュメンテーションに特化したSSG。Vueコンポーネントの利用が可能で、拡張性が高い。

![vitepress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/ab3283d6-0598-a9e0-8199-9998994511c8.png)

ファイル構造：

```sh
.
├─ docs
│  ├─ .vitepress
│  │  └─ config.js
│  ├─ api-examples.md
│  ├─ markdown-examples.md
│  └─ index.md
└─ package.json
```

### 4. [Gatsby](https://www.gatsbyjs.com/)

Reactベースの SSG 。高速かつ高機能なプラグインエコシステムを提供し、動的なサイトの構築にも強い。

![gatsby.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/773a49a0-5e63-bd58-b0a2-1e9dd2383f41.png)

インストール直後のディレクトリ構成：

```sh
$ npm init gatsby

README.md
gatsby-config.ts
node_modules/
package-lock.json
package.json
src/
tsconfig.json
```
db:createができなかった話(db:create,rails: not found)

# Railsのサーバ起動してDBがなかった話

## 目次
- [前置き](#前置き)
- [本編](#本編)
- [要約](#要約)
# 前置き
前回はキー設定まで完了しました。
```docker-compose up```でサーバーを起動し直して、```http://localhost:3000```にアクセスしたところ、DBがないと言われました。
# 本編
DBがないなら、一旦サーバ閉じて起動しなおそう。
```
$ docker-compose down --remove-orphans
$ docker-compose build
$ docker-compose run web rails db:create
```
なんか変なの出てきた。
```
[+] Creating 1/0
 ✔ Container todo_app-db-1  Running     
/rails/bin/docker-entrypoint: line 13: exec: rails: not found
```
docker-entrypoint...?　ﾅﾆｿﾚ。ん？どうしてrailsが見つかってないの？
docker-entrypointについて[調べる](https://qiita.com/zakino123/items/dbdea7bc6a490e863bd2)とentrypoint.sh はスクリプトファイルで Dockerfile で指定したタイミングで実行されて、 server.pid が存在するとサーバーが起動できない対策のために server.pid を削除するように設定するらしい。
```docker-entrypoint.tt
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```
こんな感じに書かないといけないみたい。初めて知ったな〜

じゃあ、再びイメージからビルドして、db:createしよ
ん？エラー変わらない。

調べてると同士発見！
[既存のアプリでdocker-compose up後、db:createができない](https://teratail.com/questions/374174)
```Dockerfile
RUN gem install rails
```
Dockerfileに上の文を追加したらいいんだって。(変なとこに追加するとエラー出るよ。)

ではでは、DBを作成しよう。
```
$ docker-compose build
$ docker-compose run web rails db:create
```
```結果
[+] Creating 1/0
 ✔ Container todo_app-db-1  Running                                                           0.0s 
Created database 'myapp_development'
Created database 'myapp_test'
```
できた！🥳
# 要約
DBがないと言われた場合は、以下のコマンドを実行しましょう。
```
$ docker-compose build
$ docker-compose run web rails db:create
```
その際に、以下のような文が出た場合は
```
/rails/bin/docker-entrypoint: line 13: exec: rails: not found
```
Dockerfileに以下の文を追加しましょう。
(変なとこに追加するとエラーが出ます。)
```Dockerfile
RUN gem install rails
```
追加できたら、もう一度ビルドして、DB作成しましょう。
```
$ docker-compose build
$ docker-compose run web rails db:create
```
私の場合はこれで解決しました。

# 参考文献

- [DockerでRuby on Railsの環境を構築する際のentrypoint.shのコマンド及びコード理解](https://qiita.com/zakino123/items/dbdea7bc6a490e863bd2)
- [既存のアプリでdocker-compose up後、db:createができない](https://teratail.com/questions/374174)
- [Docker初心者がRailsのローカル環境を構築してみる](https://zenn.dev/takuty/articles/6f7afabca322d1)
Macでlsやviコマンドが使えなくなってしまったとき

## 問題
.zshrcファイルを修正していたら、ls、viなどのシステムの標準コマンドが一部使えなくなってしまった
```ruby:例
> zsh: command not found: ls
```

## 環境
Mac book Air M2チップ
シェルはzsh

## 原因
`export PATH=...`の最後に`/:$PATH`を書き忘れるとlsなどのコマンドが使えなくなるらしい
``` ruby:例
NG：export PATH="/opt/homebrew/opt/openssl/bin:$PATH"
OK：export PATH="/opt/homebrew/opt/openssl/bin"
```
PATH 環境変数を「追記」ではなく「上書き」してしまい、標準コマンドへのパス設定を消されてしまっていた

## 結果
1. `/usr/bin/vi ~/.zshrc` でzshrcファイルを開く
    - （`/bin/cat ~/.zshrc` で確認もできる）
1. ":$PATH"の設定を修正
1. 最後に標準のシステムパスを追記
`export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"`
1. .zshrc の再読み込み
    - `source ~/.zshrc`


#### 最終的な.zshrcファイル差分
```ruby:前
export PATH="△△△/△△△△/△△△△"
.
.
.
```
```ruby:後
export PATH="△△△/△△△△/△△△△:$PATH"
.
.
.
# 標準のシステムパス
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
```


## 追記


```
# 現在のログインシェルを確認
$ echo $SHELL
```
PATH を消すとどうなるか（環境はzshとします）
```
# bash/zsh でパスを消す
$ unset PATH
```
```
# 消えたことが確認できます
$ echo $PATH
>

# lsコマンドなどは使えません
$ ls
> zsh: command not found: ls
```
```
# 標準のシステムパスを$PATHに再設定
$ export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin"

# 標準のシステムパスが.zshrcに書いてあれば.zshrcの適用でもOK
$ source ~/.zshrc
```
Warpターミナルを使うならBashは諦めよう

# Warpは良い・・・のか？
MacのターミナルエミュレータはずっとiTerm2を使っていましたが1年弱前くらいからなんか流行ってるからという理由でWarpターミナルに切り替えました。
* 背景画像や文字色などの見た目を柔軟かつ簡単に変更できたり（GUIから簡単に変えられてしかも文字色なども背景画像に合わせて自動で変更してくれる！！）
* 優秀なコマンド補完機能でさくさくコマンドを叩けたり
* 動作サクサクだったり

良いところもたくさんあったのですが下記の不具合がちょくちょく出てきており別のターミナルエミュレータに乗り換えを検討していました。

# Bashを使い続けていた私がWarpで悩まされていた現象

### 改行を含む複数コマンドの貼り付けができない
たとえばAWSの環境変数を設定する場面で以下のコマンドを貼り付けると途中で複数行入力モード(正式名称を何ていうのかわからないけどコマンドの途中でバックスラッシュを入力してEnterすると左に>が出てきてコマンドを複数行にわけて書けるようになるやつ)になってうまく貼り付けできません。
ググっても対処法が見つからなかったので毎回メモ帳に貼り付けて１行ずつ貼り付けていました。
(warp terminal multiline pasteとかで検索すると一応GitHubのissueが出てきますが今後のビルドで修正をリリースされるとか書いてあるだけで対処方は見つからず・・・）
```bash
export AWS_ACCESS_KEY_ID="**************************"
export AWS_SECRET_ACCESS_KEY="**********************************"
export AWS_SESSION_TOKEN="**************************************************************************************************:"
```
### バックスラッシュを改行として認識してくれない
上記の現象とは逆でコマンド途中でバックスラッシュを含む複数行コマンドを実行しようとするとエラーになって実行できない現象が起きていました。
複数行にすると上の現象が発生するので仕方なくテキストエディタで置換して１行に直したコマンドを貼り付けていました。
### ブロックの幅がめっちゃ狭くなる
正確な再現方法がわかっていないのですがコマンド結果の表示が多めなコマンドを実行するとたまにブロックの幅がめちゃくちゃ狭くなる現象が発生していました。
結果は表示されなくなるのではなく別のブロックと重なって表示されるみたいな挙動になっていたのでごちゃごちゃして読みづらくなってしまった結果を頑張って読んでいました・・・。
### ページ送りできるタイプのコマンドの実行中たまに文字が消えなくなる
`git log`などのページ送りできるタイプのコマンド実行中たまにページ送りしても文字がそのままで消えなくなる現象が発生していました。
いったんqで閉じて再度開くと元にもどっていたので現象が発生するたび閉じて開いてを繰り返して対処していました・・・。

他にも色々あったと思うのですが覚えているのは上記のような現象です。

# 致命的な現象はないものの地味にストレス
使い続けようと思えば使い続けられるような地味な現象ばかりでしたが地味にストレスが溜まりWezTermかHyperに乗り換えようか、もしくはiTerm2に戻そうか考えていました。
ネットでいくら調べても私と同じ現象に悩まされている人はいないしこんなに不具合ばかり起きているのに誰も不具合の多さについて言及していないのが不思議で仕方がありませんでした。

# ふとした思いつきで悩みが改善するってよくあること
代替となるターミナルエミュレータを検討していたところでふとそういえばシェルをZshからBashに変えていたな・・・と思いあたりました。
Linuxに触れる機会が多いので些細な違いで混乱したくないと思いZshからBashに切り替えしていたのです。
もしかしてこれが原因ではと思いZshに戻してみることに
```bash
chsh -s /bin/zsh
```
これで**上記の現象全て改善しました。**
解消したときは歯の間に挟まっていたネギが取れたかのようなすっきり感でした。
とりあえずいまのところZshにして困ったことはないのでこのまましばらくZshで過ごしたいと思います。

# 所感
Warp使いでBash使いの方あまりいないのかしら・・・
（完全自分用メモ）ホワイトボックステストの網羅基準

## ホワイトボックステストの網羅基準
主に下記の4種類がある。
※書籍によっては「判定条件／条件網羅」が掲載されているものもあるが、ここでは割愛

### 命令網羅
* 全ての命令を一度は通るようにするテスト
    * 命令とはすなわち処理のこと
    * 処理が通りさえすればいいので、最も網羅率が低い

### 判定条件網羅（分岐網羅）
* 全ての分岐を一回は通るようにするテスト
* アクティビティ図の矢印を全て通るようにするイメージ

### 条件網羅
* 条件が真の場合と偽の場合それぞれ満たすようにするテスト
* if文とelse文それぞれチェックするイメージ

### 複数条件網羅
* 複数の条件の真・偽の全ての組み合わせを網羅するテスト
    * if文が複数あった場合、全てのif文がtrueの場合と1つだけfalseの場合と2つfalseの場合...というのを全てチェックする
    * 網羅率は最も高い
【Atcoder解法検討】ABC128 A~D Python

## A - Apple Pie
#### 問題ページ : [A - Apple Pie](https://atcoder.jp/contests/abc128/tasks/abc128_a)
### 考察
標準入力と整数の四則演算、標準出力を利用すれば簡単に実装できます。
### コード
```python
A, P = map(int, input().split())
print((A * 3 + P) // 2)
```
## B- Guidebook
#### 問題ページ : [B - Guidebook](https://atcoder.jp/contests/abc128/tasks/abc128_b)
### 考察
 $(市名, 得点, 店番号)$をデータ単位としてリストを作成してソートすることでまず市名順、同じ市名なら得点順に並べることができます。ただし、このままソートすると得点は小さい順にソートされてしまいますので、$(市名, 得点 \times (-1), 店番号)$をデータ単位とすることで得点も高い順に並べることができます。
### コード
```python
N = int(input())

# (市名, 得点 x (-1), 番号)のリストを作成
G = []                              
for i in range(N):
    city, score = input().split()
    G.append((city, -int(score), i + 1))

# 市名,　得点 x (-1)でソートして順に番号を出力
G.sort()
for c, p, num in G:
    print(num)
```
## C - Switches
#### 問題ページ : [C - Switches](https://atcoder.jp/contests/abc128/tasks/abc128_c)
### 考察
　スイッチの個数が高々10個なので、全てのスイッチのON/OFFの組み合わも高々$2^{10} \sim 10^3$となり全探索が可能となります。
　またスイッチのON/OFFのようなN個の二者択一の組み合わせの全探索にはbit全探索が適しており、本問題にも適用します。
### コード
```python
N, M = map(int, input().split())
KS = [map(int, input().split()) for _ in range(M)]
P = list(map(int, input().split()))

k = [0]* M
switch = [[] for _ in range(M)]
for i in range(M):
    k[i],*switch[i] = KS[i]

ans = 0
for i in range(1<<N):            # N個のスイッチのON,OFの全組合せ（2^N)
    flag = True                  # 上記各組合せで電球が全て点灯してればTrue、そうれでなければFalse
    for bulb in range(M):        # bulb(=0~M)番目の電球にたいして
        tmp = 0                  # つながっていてONになっているswitchの数
        for s in switch[bulb]:
            if (i >> (s-1)) & 1 == 1:
                tmp += 1
        if tmp % 2 != P[bulb]:
            flag = False
    if flag:
        ans += 1

print(ans)
```
## D - equeue
#### 問題ページ : [D - equeue](https://atcoder.jp/contests/abc127/tasks/abc128_d)
### 考察
　一見複雑ですが適切に整理すると全探索が可能となります。まず操作A~Dを任意の順番でK回実施することができるのですが、操作内容をよく見ると、実は左側から任意の回数（変数名$left$と設定）取り出し、次に右側から任意の回数（変数名$right$と設定）取り出し、最後に任意の回数（変数名$back$と設定）価値の小さいものからDに戻す（右側・左側どちらでも良い）、というパターンだけ計算すれば良いことがわかります。
　ここで文中にて設定した各変数の取れる範囲を適切に設定し全探索することで解が得られます。各変数の取れる範囲は以下のようになります。
 ```math
\begin{array}{l}
0 \leq \text{left} \leq \min(N,K) \\
0 \leq \text{right} \leq \min(N-L, K-L) \\
0 \leq \text{back} \leq \min(K-(L+R), L+R) \\
\end{array}
```
### コード
```python
N, K = map(int, input().split())
D = list(map(int,input().split()))

ans = 0
for left in range(min(N,K)+1):                  # left   : Dの左から何個とるか
    for right in range(min(N-left,K-left)+1):   # righth : Dの右から何個とるか
        g = [D[i] for i in range(left)]         # g      : 手元に持っているもののリスト
        for i in range(right):
            g.append(D[-(i+1)])
        g.sort()

        for back in range(min(K-(left + right),left + right) + 1):  # back : 手元からDに返す個数
            ans = max(ans,sum(g[back:]))

print(ans)

```
## E - Roadwork
#### 問題ページ : [E - Roadwork](https://atcoder.jp/contests/abc127/tasks/abc128_e)
## F - Frog Jump
#### 問題ページ : [F - Frog Jump](https://atcoder.jp/contests/abc127/tasks/abc128_f)
　　
青diff以上の問題は後日トライ
【質問】典型90問043 - Maze Challenge with Lack of Sleep（★4）

質問があります。
以下のコードを提出した所TLEが4つ出たのですが、原因が分かりません。
どなたか分かる方がいれば、ご教授いただけると幸いです。

[典型90問043 - Maze Challenge with Lack of Sleep（★4）](https://atcoder.jp/contests/typical90/tasks/typical90_aq)

```C++
#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using vs = vector<string>;
#define rep(i, n) for (int i = 0; i < (n); ++i)

const int INF = 1001001001;
const vi dx = { -1, 0, 1, 0 };
const vi dy = { 0, 1, 0, -1 };

struct Edge {
  int x, y, dir, cost;
  Edge(int x, int y, int dir, int cost): x(x), y(y), dir(dir), cost(cost) {}
  bool operator==(const Edge &e) const { return cost == e.cost; }
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
  
};

int main() {
  int H, W; cin >> H >> W;
  int sx, sy, gx, gy;
  cin >> sx >> sy >> gx >> gy;
  sx--; sy--; gx--; gy--;
  vs S(H); rep(i, H) cin >> S[i];
  
  vector<vector<vi>> cnt(H, vector<vi>(W, vi(4, INF)));
  priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
  rep(k, 4) pq.push({ sx, sy, k, 0 });
  while (!pq.empty()) {
    Edge e = pq.top();
    pq.pop();
    if (e.cost >= cnt[e.x][e.y][e.dir]) continue;
    
    cnt[e.x][e.y][e.dir] = e.cost;
    rep(k, 4) {
      int nx = e.x + dx[k], ny = e.y + dy[k];
      if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
      if (S[nx][ny] == '#') continue;
      
      int ncost = (e.dir == k) ? e.cost : e.cost + 1;
      if (ncost < cnt[nx][ny][k]) pq.push({ nx, ny, k, ncost });
    }
  }
  
  int ans = INF;
  rep(k, 4) ans = min(ans, cnt[gx][gy][k]);
  cout << ans << endl;
}
```
大切にしたいシステムをつくる前に考えておくべきこと

[CBcloud](https://cb-cloud.com/)でエンジニア兼企画をしている[糸村](https://x.com/yoskmr)です。

開発を始めるとき「どうやってコードを書くか？」という技術的な部分から考え始めることも多いと思います。でも、その前にしっかり「何を作るべきか」や「なぜそれを作るのか」を考えておくことが大事なんです。

## Whyから考えよう - ゴールデンサークルって知ってる？
サイモン・シネックという方が提唱した「ゴールデンサークル」・これは「なぜ（Why）それをやるのか」から始めて、「どうやって（How）」そして「何を（What）」っていう順番で考え理論です。

> サイモン シネック: 優れたリーダーはどうやって行動を促すか
> https://www.youtube.com/watch?v=qp0HIF3SfI4

この考え方、実はシステム開発やコードを書くときにもめちゃくちゃ大事なんです。特に、プロジェクトが大きくなるほど関わる人も増えるし、コストや時間もかかるからこそ、最初に「なぜやるのか？」っていうのをしっかり考えておく必要があります。

### Whyがないと迷走しちゃう
システム開発って、ついつい「What」から始めちゃうことが多いんですよね。たとえば、「こんなシステムが欲しい」とか「このソリューションがあれば解決できる」って話が先行しがち。でも、「なぜそれが必要なのか？」が曖昧なままだと、進んでいくうちにゴールが見えなくなって、プロジェクトが迷走してしまうことも。

だからこそ、最初にWhy（なぜ？）を明確にしておくのがポイントです。

## プロジェクトのゴールを明確にする4つのポイント
おすすめの本から良いプロジェクトのゴールの作り方のコツを紹介します。

https://www.amazon.co.jp/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E4%BD%9C%E3%82%89%E3%81%9B%E3%82%8B%E6%8A%80%E8%A1%93-%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E7%99%BD%E5%B7%9D-%E5%85%8B/dp/4532323991

### みんなが使えるゴールにしよう
ゴールって単なるスローガンじゃなくて、実際に判断基準や行動の指針になるものでなきゃいけません。たとえば、「この機能って本当に必要？」って問いに対して、ゴールをもとに「必要かどうか」を判断できるようなゴールが理想です。

### 現実的なゴールにしよう
ゴールが高すぎると、みんながプレッシャーを感じてやる気がなくなっちゃうかもしれません。だからこそ、現実的で達成可能なゴールを設定しましょう。

### Why（なぜやるのか？）をゴールやコンセプトに込めよう
ゴールやコンセプトに「なぜこのプロジェクトをやるのか？」をしっかり入れることで、関わる全員が同じ方向を向いて進めるようになります。

### わかりやすいゴールにしよう
ゴールがわかりやすければ、プロジェクトに関わる全員がその目的に共感して、自分から積極的に動いてくれます。逆に、ゴールが曖昧だと、みんなが同じ方向に進めないし、途中で「何のためにやってるんだっけ？」ってなっちゃうこともあります。

---

というわけで、コードを書く前にしっかりとしたビジョンを持ち、ゴールを明確に定めることが、プロジェクト成功へのカギなんです。Why、How、Whatの順番で考えて、土台をしっかり作っておくことが大事ですよ。
YAMAHA NVR510を導入しました

## 導入の経緯
現在、フレッツ光コラボのマンションタイプをv6プラスで契約しています。
使用していた無線LANルーター（BUFFALO WSR-1166DHL2）が不調になったのがきっかけです。
NVR510を使用すると、
- 回線スピードの向上
- 小型ONU使用による省スペース化
- VPN機能などの充実
- 光電話使用時の機器利用料の節約

などメリットが沢山あります。
今回は「回線スピードの向上」をメインとし、将来小型ONU化も視野に入れた導入となりました。

## 商品情報
YAMAHA NVR510
https://network.yamaha.com/products/routers/nvr510/index

新品は40000円前後、フリマ等の中古は20000円前後が相場です（２４年９月現在）
今回は中古品を使用することにしました。

## いざ、設置！

今までつけていた無線LANルーターはAPモード運用にして、NVR510をIPoE接続で運用させたい。
中古なので初期化しました。やり方は、
- 裏側のINITスイッチを押下しながら電源ONして３秒ほど待つ

そうすることで、ランプが点滅してリセットすることができました。

簡単設定からIPoEの設定をして、インターネットに接続したがトラブル発生...

何故かgoogleやAppleは表示されるがyahooなどの一般的なサイトは表示しない

おそらくIPv4の変換がうまくいってないと考えつくが、対策がわからず...
とりあえずFWを最新にしてみました。

最新FWにすると、IPoE設定時にIPv4インターネット設定が出現しv6プラスも含めて再設定し、解決しました。

## 使用感など

有線の速度ですが、1Gbpsのプラン加入で以下の通り

旧環境       新環境
430Mbps　=>　950Mbps

思った以上にスピードが出ていて驚いています。

## まとめ
ファームウェアのアップデートは必ずしましょう　笑
【AWS】API Gateway マッピングテンプレートではまった

# 概要

　リクエストボディに URL パスパラメータを追加するマッピングテンプレートを書きたかったが、盛大にはまったのでメモを残しておく。

# マッピングテンプレートとは何か

　以下は公式ドキュメントである。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/models-mappings.html

　以下は API Gatewayのマッピングテンプレートについて ChatGPT の説明である。

> API Gatewayのマッピングテンプレートとは、リクエストやレスポンスのデータ形式を変換するためのスクリプトです。これにより、異なるフォーマットのデータをAPIが期待する形式に整えたり、外部サービスとの統合時にデータを適切に送信したりできます。主にVelocity Template Language (VTL)を使って記述され、JSONPathを使ってデータを操作します。

# やりたかったこと

　以下のリソース `/books/{bookId}` に PUT メソッドを定義した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7aa3babe-99cd-b099-9d1b-daac4c6af79e.png)

リクエストボディは以下の形式である。

```json
{
    "title": "sample title",
    "pages": [
        {
            "page": "1",
            "content": "This is a sample content."
            
        },
        {
            "page": "2",
            "content": "This is also a sample content."
        }
    ]
}
```

このボディに `bookId: sampleId` を追加したい。

結論としては以下の記述で実現できる。

```
#set($inputRoot = $input.path('$'))
{
  "bookId": "$input.params('bookId')",
  "title": "$inputRoot.title",
  "pages": [
    #foreach($page in $inputRoot.pages)
    {
      "page": "$page.page",
      "content": "$page.content"
    }#if($foreach.hasNext),#end
    #end
  ]
}
```

マッピングテンプレートによる変換後の JSON は以下である。

```json
{
    "bookId": "ab236276-34a5-4e2a-ae6e-3dfe7796c33a",
    "title": "sample title",
    "pages": [
        {
            "page": "1",
            "content": "This is a sample content."
            
        },
        {
            "page": "2",
            "content": "This is also a sample content."
        }
    ]
}
```

# 解説

- 元のリクエストボディを変数 `inputRoot` に格納する

```
#set($inputRoot = $input.path('$'))
```

- URL パスパラメータを取得する

```
"$input.params('bookId')"
```

なお、URL パスパラメータは以下のように設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/e4421288-6ec3-0a22-e8dd-2574eaef531d.png)

- オブジェクトが要素である配列を記述する

```
  "pages": [
    #foreach($page in $inputRoot.pages)
    {
      "page": "$page.page",
      "content": "$page.content"
    }#if($foreach.hasNext),#end
    #end
  ]
```

# 所感

試行錯誤して書き方が分かった今では、公式ドキュメントが結局わかりやすかったことに気づいた。以下は公式ドキュメントに記載されている例である。

```
#set($inputRoot = $input.path('$'))
[
#foreach($elem in $inputRoot)
  {
    "description" : "Item $elem.id is a $elem.type.",
    "askingPrice" : $elem.price
  }#if($foreach.hasNext),#end

#end
]
```

※注意点はダブルクォーテーションである。数値型にはダブルクォーテーションは書かない：`$elem.price`

あと大事なことはマッピングテンプレート編集後、API をデプロイすること。

# 参考

- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/models-mappings.html
26卒の私がサマーインターンシップを終えて

# はじめに
こんにちは、Kazumaと申します。久々のQiita更新となります...💦
今回の記事では、26卒の私が2024年8月〜9月にかけてのエンジニア職においてのサマーインターンシップのアウトプットとして個人的な感想などを投稿したいと思い、記事を作成いたしました。

:::note warn
インターンの概要や個人的な感想や今後の課題点をアウトプットとして記載した記事になります。
:::



### 改めて、記事書いてる人ってどんな人なのよ..？:thinking:
#### 自己紹介
- 所属：地方にある文系大学経営学部、現在3年生
- プログラミング歴：半年以上(2023年12月頃に開始！←だいぶ遅い..)
 - プログラミングやる前は？：サークル活動、英語学習、趣味の活動を中心に!
- 他のサマーインターンシップ参加実績：営業職(2days)、企画職(5days)
- 最近触れている技術：Next.js、TypeScript、React、FastAPI、GraphQL..etc

このようなプロフィールになっています。

## どんな会社のインターンに行ったの？
#### 1社目
**株式会社ソケッツ**
- 期間：8/29〜9/6　(7days)
- 形式：対面＋オンラインのハイブリッド型
- 参加学生：5名
- ※実習選択式(技術開発コース or システム開発コース)→システム開発コースを選択
- 使用技術：PHP、Laravel、MySQL、Docker、Gitlab、AWS   

[株式会社ソケッツのHP](https://www.sockets.co.jp/)

#### 2社目
**株式会社メディアドゥ**
- 期間：9/11〜9/13　(3days)
- 形式：対面
- 参加学生：20名
- 使用技術：Go、Gin、SQL、Git、Githab

[株式会社メディアドゥのHP](https://mediado.jp/)

### 各インターンでやったこと
#### 1.ソケッツ
**業務に参加する想定の上、エンジニアとして開発を行う!**
業務：音楽ストリーミングサービスの開発
担当箇所：PodCast機能の追加

**チーム構成**
- プロジェクトマネージャー：1名
- 開発メンター：2名
- エンジニア：3名（**インターン生はここに配属**）

##### 主な流れ
1. 課題(issue)を確認し、コーディングをする
1. 問題がなければ、MRを作成して、エンジニアの方にコードレビューをしていただく
1. レビューを確認し、修正を行う or  次のissueに取り組む
1. 必要に応じて、メンターとのMeetingを実施（進捗確認、お知らせ事項など）
1. インターン最終日には、代表取締役社長+社員の方々の前にて全体成果発表
1. 座談会、人事担当者との面談も実施していただきました

`issueの概要`
-
- **issue1**：TSVファイルの読み込みコマンド処理
- **issue2**：RSSフィールド取得コマンドの作成
- **issue3**：ChannelリストAPI作成
- **issue4**：Channelリスト詳細API作成

※issueには含まれていませんでしたが、全て終わり次第、初めて機能（Feature）と単体（Unit）テストコード作成やAWSでのデプロイも行いました...!!

#### 2.メディアドゥ
**実際の業務を理解してもらうための課題にチームで取り組む！**
今回のインターンのテーマ：**パフォーマンスチューニング**
- 各チームメンバーは4名で構成（チームA〜Eまで）
- 技術メンター：4名（実際に働いているエンジニアの方々）
- 人事担当者：3名

**全体的なインターンの流れ**
1. 課題に取り組む
1. 達成できたら、実際に目の前で技術メンターの方に確認してもらう
1. 問題なければ次の課題に進む
1. 最終日に参加学生と人事担当、技術メンターや執行役員CIOの方々の前で成果発表
1. 最後に懇親会(簡単なミニゲームなどで交流を深めました!)

`課題の概要`
-
1. **動作テストをしよう**
1. **APIのログを出力しよう**
1. **高負荷テストをしよう**
1. **APIのエラーログを出力しよう**
1. **エラーを解消しよう**
1. **バリデーションを実装しよう**
1. **システム改善を提案しよう**

※この中で、自分はバリデーションを実装する課題で技術的にアプローチをかけることができました！

# これらのインターンシップを終えて
### 全体的な感想
**A.2社とも本当に参加できてよかった！！！！:punch:**
- 実際に働いているエンジニアの方にコードを見てもらった(特にソケッツにおいて)
- あまり経験したことのない技術に触れることができた
(API開発、テストコード、CI/CD、パフォーマンスチューニング..etc)
- エンジニア職を志望の学生、エンジニアの方とのコミュニケーションの機会
- 実際の業務がどのような取り組みをしているのか知ることができた！
- 初めてPHPやLaravel、GoやGinへの挑戦

### インターンシップに参加して、感じた「課題点」
**技術的な観点から、チームをまとめたりすることができなかった**
→2社のインターンシップに参加してみて、共通した課題点です。
自分の経験が不足している部分が関係していることもありますが、当初の私の考えとしてはエンジニア同士でチームを組む時は技術的な知識からのみではなく、他の能力からチームを動かすことができるだろうと考えていました。しかし実際にインターンでは、それらは通じることができずに終わってしまい、基本的に私はメンバーの方に教えてもらう側になって過ごしてしまいました...

**学び：チーム活動をするからには、それなりの技術力が求められる**
**→**今後も引き続き、勉強を行なっていくこと！

##### インターンシップの後日
**人事担当者、技術メンターの方からの私へのフィードバック**（メディアドゥ）
→評価してくれたこと：かなり難しいと感じることが多かったと思います。しかし、そんな状況でも腐ることなく、メンバーと積極的にコミュニケーションを取る姿勢、難しい技術的なことを自発的に学ぼうとする姿勢は高く評価しました。
（このように言っていただけて、心の中で泣きました..）


→マイナスに感じたこと：スマホをよく見てしまいがちになっていたことは直した方が良いと感じました。
（改めて振り返ってみるとこの振る舞いは良くないと感じました。一緒に働く姿勢として最低な行いだったと本当に反省しています。。)

# 最後に
2社とも一瞬で終わったと感じてしまったインターンシップでした..
今回インターンシップに参加したことで、
- 改めて自分がどのようなエンジニアを目指すべきなのか？
- 自分ならではのエンジニアになるにはどうすれば良いのか？
- 技術力をもっと高めるにはどうすれば良いのか？

このような問いに対する自分なりの答えを見つけることができました。
そろそろ本選考も開始する時期になってきたので、改めて就職活動と技術の勉強の両立を頑張りたいと思います！
ここまで読んでいただき、ありがとうございました！！
SwiftUIでローディング画面を自作してみたけど何か違う？

## 動機

WWDC24で紹介されていた「Create custom visual effects with SwiftUI」[^1]のRipple（波紋）エフェクトが頭に残っていてどこかに使いたいなと思ってました。
個人開発しているアプリ[^2]のローディング画面にちょうどよいのでは？と思ってSwift Packageとして作ってみたのですが、なんかちょっと思ったのと違う気がしています…

[^1]: https://developer.apple.com/videos/play/wwdc2024/10151/

[^2]: 紹介記事は[こちら](https://qiita.com/allmight0000000/items/95f7bed2575ec5d1d407)

## 製作物


https://github.com/b-sakai/LoadingImageView/tree/main

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260695/1fd698ab-5982-5561-8b49-6169bc2bb49c.gif)

## 製作過程

### WWDCのコードを参考にまずはざっくり作る

※以降の動画はQuizionary[^3]という個人開発アプリに導入したときのGIFです

![Simulator Screen Recording - iPhone 16 - 2024-09-30 at 19.39.23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260695/99adba3d-693b-9762-a6aa-9de50e2c212c.gif)

[^3]: https://apps.apple.com/app/quizionary/id6630366339

### なんか違う、、、大きい？

サイズ調整可能にして、小さくしてみる

![Simulator Screen Recording - iPhone 16 - 2024-09-30 at 19.42.26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260695/2f5ccd33-72b6-0370-9a78-fd1853fc78b0.gif)


### 速度が微妙？

速度や振幅、振動数などのパラメータを調整

![Simulator Screen Recording - iPhone 16 - 2024-09-30 at 19.44.54.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260695/2b78edbd-6ef9-20ea-83f7-431e6482f124.gif)


### さらに調整

![Simulator Screen Recording - iPhone 16 - 2024-09-30 at 08.54.53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260695/c4e19d88-7ba6-75f7-7abc-82b5827f676c.gif)

これ以上、無理そうなので完成！

## 苦労したところ

### Metalシェーダを画像のようにリソース管理する必要があった点

* Package.swiftに以下のようにしてリソースとして指定する必要がある

```swift
import PackageDescription

let package = Package(
    name: "LoadingImageView",
    platforms: [
        .iOS(.v17)
    ],
    products: [
        // Products define the executables and libraries a package produces, making them visible to other packages.
        .library(
            name: "LoadingImageView",
            targets: ["LoadingImageView"]
        ),
    ],
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
        .target(
            name: "LoadingImageView",
            dependencies: [],
            resources: [.process("Shaders/Ripple.metal")]
        ),
        .testTarget(
            name: "LoadingImageViewTests",
            dependencies: ["LoadingImageView"]),
    ]
)
```

* 使うときは(bundle :.module)を以下のようにつける必要がある

```swift
        let shader = ShaderLibrary.bundle(.module).Ripple(
            .float2(origin),
            .float(elapsedTime),

            // Parameters
            .float(amplitude),
            .float(frequency),
            .float(decay),
            .float(speed)
        )
```

### パラメータ調整が意外と難しい

* 実際に組み込んでみないとわからないので、Swift Package側でコミット、Githubでリリースバージョン指定、利用するアプリ側で確認という手順を踏む必要があり、効率が悪かった
* 実際のアプリで作ってから、Swift Package化という流れの方が絶対に良い!

## 参考

https://developer.apple.com/videos/play/wwdc2024/10151/

https://qiita.com/uhooi/items/2f36b85f5f41cbd35189

https://qiita.com/sauna1137/items/e3f8dc35dad1f1b5c82b

https://apps.apple.com/app/quizionary/id6630366339
Proxmox Web GUIをCloudflareを有効活用して外部公開する

## 1.はじめに
みなさん、Proxmox使ってますか?
私はよく外出をするのですが、その際に
**「外出先で管理画面アクセスできたら便利だよな...」**
と思い。早速やってみました。
#### 前提条件
・ドメインを所有していて、ドメインをCloudflareアカウントに登録済みであること
・Proxmoxをインストールしているマシンがあること
## 2.Cloudflareの管理画面にアクセスして、アカウント設定をする。
普通にCloudflareを経由してネットワークに公開すると、侵入され放題でセキュリティ的にも大問題なので、まずはセキュリティ対策としてログイン画面を設定します。
[cloudflareのダッシュボード](dash.cloudflare.com)にアクセスして、左側の欄からZero Trustを開きます。
Zero Trustの画面を開いたら、Settingsをクリックして、Authenticationをクリックします。
そしたらこのような画面になると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/fc7d7a3b-81d2-b878-bcdc-71251a6e2f90.png)
Login methodsのAdd newを押して、ログインアカウントを設定します。
私はGitHubアカウントで設定しました。設定方法はチュートリアルがついているので割愛します。

## 3.tunnelの作成
Zero Trustの画面を開いて、Networks→Tunnelsと進みます。
**Create a tunnel**をクリックして、トンネル作成に移ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/6e7a3ee4-32f7-0366-a956-f27e4b07e21e.png)

この画面では**Cloudflared**を選択した状態で次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/9fae705b-7b39-0599-2d64-75a9fa386ac1.png)
次の画面でトンネル名を決めます。好きな名前にしましょう。私はProxmoxと名前をつけました。

そして次に進んだら、Cloudflaredのインストールチュートリアルが出てきます。
Debianの64bitでコマンドを表示してもらい、Proxmox機のコンソールを開いて、インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/e1e27d13-6dc2-2fa4-e1fa-6fd713ff74a1.png)

そしたら色々入力する画面が出てきます。
サブドメインにはお好きなドメイン名を、ドメインはCloudflareに登録しているドメインを選択してください。
TypeはHTTPSにして、URLにはホストマシンのIPアドレスを入力しましょう``例)192.168.11.1:8006``
そして、Additional application settingsのTLSで、**No TLS Verify**にチェックを入れておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/179eba19-eb66-c5bd-3c65-95d3e0b26941.png)
これでtunnelの設定は終了です！

## 4.アプリケーション登録
このままだと、公開されているだけでアクセスされ放題(多分、あまり覚えていない。)なのでしっかり設定を加えていきます。
Zero Trustの画面を開いて、Accessから、Applicationを開きます。
そしたら、**Add an application**からアプリケーション登録を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/1567320f-d9b1-3b4d-e4e5-0af167f37e02.png)

この画面では**Self-hosted**を選択します！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/c831be0d-5ea5-4281-f9d8-864c9e39f03a.png)

この画面では、Application nameをお好きな名前に（私はProxmoxにしています）
Subdomainに先ほど設定したサブドメイン、ドメインに先ほどと同じドメインを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/c1d9ab39-517e-415d-8ad9-cb1663ac2162.png)

そしたら、Nextを押して次の画面に進みます。

Policy nameにお好きな名前を（私はProxmox adminにしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/602f34c0-09d6-7d81-cb76-166ee9fc4108.png)

Configure rulesにはEmailを選択して、自分のメールアドレスを入力します。
私の場合はEmailを選択しましたが、様々な選択肢(GitHub Organizationとか)があるので環境に合わせてください！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522161/89e1964e-2f9e-8158-1c56-b69bdf64701f.png)
これでNextを入力します。
次の画面では特に変更せず、Add applicationをクリックします。

これで全ての手順が完了しました！お疲れ様でした！


## 5.まとめ
途中で設定したドメインにアクセスすると、ログイン画面が表示され、ログインするとproxmoxの管理画面が表示されると思います！お疲れ様でした！
いかがでしたか?あまりまだQiitaの記事に書き慣れていないので、見にくい部分もあったかもしれませんが、最後まで読んでくださりありがとうございました！
これからも快適なサーバーライフを！
PythonでGeminiを呼び出す

# はじめに
本記事では、PythonでGeminiを呼び出すサンプルコードを示します。

# 検証環境
今回は簡単にVertex AI Workbenchでpythonのnotebookを使って試します。
検証では、ユーザーマネージドインスタンスをデフォルトのパラメータで作成して「JUPYTERLAB」を開き、「Notebook」>「Python3」の順にNotebookを開きました。

# 準備
1. 実行に必要なパッケージをインストールします
```
! pip3 install --upgrade --user google-cloud-aiplatform
```
2. パッケージを利用するため、再起動します
```
import IPython

app = IPython.Application.instance()
app.kernel.do_shutdown(True)
```
3. 必要なライブラリをインポートします
```
from vertexai.preview.generative_models import (
    GenerationConfig,
    GenerativeModel,
)
```

# PythonでGeminiを使う
1. Geminiをロードする
```
# ""内で使用するモデルを選択
model = GenerativeModel("gemini-pro")
```
2. Geminiにプロンプトを投げる
```
responses = model.generate_content("ここにプロンプトの中身を入力", stream=True)

for response in responses:
    print(response.text, end="")
```
基本的には以上の使い方となります。
後は、以下のように生成AIのパラメータを指定する方法もあります。
```
generation_config = GenerationConfig(
    temperature=0.9,
    top_p=1.0,
    top_k=32,
    candidate_count=1,
    max_output_tokens=8192,
)

responses = model.generate_content(
    "ここにプロンプトの中身を入力",
    generation_config=generation_config,
    stream=True,
)
```

# さいごに
本記事で紹介したサンプルコードを利用すれば、生成AIを使ったアプリケーションがいくらでも作れそうなので今度試してみたいと思います。
また別の記事として画像を読み込む方法も公開する予定です。

# 参考資料
https://cloud.google.com/vertex-ai/generative-ai/docs/samples/generativeaionvertexai-gemini-pro-config-example?hl=ja
AWSスキルビルダーラボ IAM編

AWS Identity and Access Management (IAM)のスキルビルダーラボを体験し、以下の手順を通じてIAMの基本的な操作を学びました。

### 事前にAWS側が
- 事前に作成された3つのIAMユーザーと3つのIAMユーザーグループ作成済み
- 各ユーザーグループには、EC2やS3の権限が事前に付与済み

## 実施内容
- IAMユーザーとユーザーグループを紐づけ
- 紐づけた後、実際の権限確認を実施

### まとめ

権限が正しく付与されていない場合、エラーが発生するため、問題が明確になり慌てずに対処できます。スキルビルダー自体は有料ですが、ラボで使用するAWSリソースは無料なので、実際に操作に慣れるためには非常に有益だと感じました。
品質の3要素をWebアプリケーション開発の視点で考えてみた

## はじめに
Webアプリケーションをはじめ、モノづくりにおいて「品質」という言葉をよく耳にします。これは製品の信頼性を高め、顧客満足度を向上させる上で必要な概念です。ただ、具体的にどのような種類があるのか知らない方も多いのかと思います。この記事では狩野モデルという「品質の3要素」を紹介し、それにWebアプリケーション開発の例を当てはめながら、3要素に対する個人的意見を述べています。

この3要素を知ることで、プロジェクトの品質について考え直したり、ユーザーの満足度向上につながるヒントを得られるかもしれません。

## 品質の3要素とは？
品質の3要素とは以下のグラフで示される通り、主に**当たり前品質**、**一元的品質**、**魅力的品質**の3つがあります。この図式は世間一般的に狩野モデルと言われています。


![狩野モデル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/69aee9ce-781c-ac72-e804-886278e24b5b.png)

出典：<a href="https://www.vn.japanquality.asia/post/%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%93%81%E8%B3%AA%E3%81%AE%E8%80%83%E3%81%88%E6%96%B9">グローバルにおける品質の考え方</a>

それでは、1つずつ簡単に見ていきます。

### 1. 当たり前品質
**当たり前品質**は、ユーザーが「これがないと使えない」と感じる基本的な要素です。もしこれが欠けていると、ユーザーは不満を抱くことが多いです。

#### 具体例: ユーザー認証機能のセキュリティ
Webアプリケーションを作る上で、ログイン機能やユーザー情報の管理は必要不可欠ですよね。その際、セキュリティが担保されていないと、どんなに他の機能が充実していてもユーザーは安心して使えません。パスワードの暗号化や適切な認証フローの設計など、セキュリティに関する部分は「当たり前品質」としてしっかりと考えるべき要素だと思います。

### 2. 一元的品質
**一元的品質**は、ある要素の品質が高まるほどユーザーの満足度も上がる要素です。反対に、低いと不満につながることもあります。

#### 具体例: ページの読み込み速度
例えば、Webアプリケーションのページがすぐに表示されると、ユーザーにとってはとても心地よい体験になりますよね。ページの読み込み速度が速ければ速いほど「使いやすい！」と感じますし、逆に遅いと「なんだかストレスがたまるな...」と思ってしまいます。ページ速度を改善することは、一元的品質として直接ユーザー満足度に影響を与えるポイントになるので、意識しておくべきです。

### 3. 魅力的品質
**魅力的品質**は、ユーザーが「こんな機能があったんだ！」と感じるような要素です。無くても不満はないけれど、存在すると嬉しいという、まさに「魅力的」な要素です。**付加価値**という言われ方をすることもあります。

#### 具体例: 作業をサポートするヒント機能
例えば、タスク管理アプリで、ユーザーの作業パターンを分析し、「こういうやり方もありますよ」といったヒントを表示する機能があったらどうでしょう？ 必須ではないけれど、こうしたアシスト機能があると「このアプリ、すごく親切だな！」と感じるはずです。ユーザーにとっての新しい発見や意外な便利さを提供できる要素が、魅力的品質です。

## これらの3要素とどう向き合うか
これらの3要素をWebアプリケーション開発などにどう向き合うかについて、私なりの考えをシェアします。

### 当たり前品質をまずは確保
ユーザーがアプリケーションを安心して使えるように、セキュリティやバグを発生させない開発が大切だと思います。特にセキュリティなど、ユーザーが安心・安全にwebアプリケーションを使えるように、特にお客様からの要件になかったとしても自発的に考えて取り入れることで、必要最低限の品質を担保できる開発をしていく必要があると思います。

### 一元的品質を向上させる
パフォーマンスや操作性の向上などが挙げられます。ページの読み込みが速い、フォーム入力がスムーズ、操作が直感的など、痒いところに手が届いている製品がこれに当たるのかと思います。


これを常日頃から意識して開発できるようにするには自分が作成したアプリと世の中の様々なwebアプリケーションを比較して「このアプリのこの部分は自分が作ったものより優れているな」など気づきを得ながら、その感度を向上させ、次の開発に取り入れるなどの取り組みが必要だと思います。

### 魅力的品質は日頃から人を喜ばせることを考えて鍛える
ユーザーやお客様を喜ばせるにはどうしたらいいかを日頃から考えられるようにする必要があります。アプリを使うのは大半が人であるため、人を喜ばせるための発想力が必要だと思います。ただ、そうはいってもなかなか簡単に鍛えられるものでもないと思います。


そのため、webアプリ開発といった狭い範囲だけで鍛えようとするのではなく、まずは身近な人（家族や会社の仲間など）をまず喜ばせるなどからそれを意識することを習慣化し、次のステップで自社を喜ばせるにはどうしたらいいか、最終的にその先のお客様を喜ばせるためにはどうしたらいいかというように発想の幅を広げて鍛えていければいいかなと思います。

## まとめ
品質の3要素（当たり前品質、一元的品質、魅力的品質）は、Webアプリケーション開発において役立つ考え方だと思います。私自身はまだまだ学びながらですが、これらの要素を常に考えながら開発を進めることで、ユーザーやお客様にとってより良い体験を提供できるエンジニアになっていきたいと思います。

皆さんも、ぜひ自身のプロジェクトに投影して考えてみてください。これからもより良いアプリケーションを作っていきましょう！