OmniAICreator/Qiita-1.07M huggingface dataset:
Windows11の記憶域プールのパフォーマンス備忘録

# 前置き
HDD(2TB)×2でダイナミックディスクを使用したミラーボリューム（RAID1）を構成していたのですが、
ダイナミックディスクは非推奨になったという話を聞いたので別の方法でミラーすることにしました。

> ダイナミック ディスクは Windows では非推奨になり、推奨されなくなっています。 ディスクをプールしてより大きいボリュームにする場合は、代わりにベーシック ディスクまたは新しい記憶域スペース テクノロジを使ってください。
https://learn.microsoft.com/ja-jp/windows-server/storage/disk-management/change-a-dynamic-disk-back-to-a-basic-disk

よく考えたら高可用性を確保したいのではなく、いつHDDが死んでも良いようにバックアップを取っておきたいだけだったので2個のHDDをそれぞれシンプルボリュームとして構成してrobocopyコマンドで同期させておけば良い話である。
しかもrobocopyコマンドで同期させる方法を取るのであれば普段使用する用のディスクは高速のもの、robocopyでのバックアップ先となるディスクは低消費電力のものを使うなど、ディスクの選び方の幅が広がり楽しくなりそうじゃん。

話は戻ってミラーの方法ですが、今は「記憶域」という機能が推奨されているらしい。
さらにこの「記憶域」の機能がすごくて、容量に違うディスクでRAID0が組めるらしい。
例えば2TBのHDDと100GBのSSDでRAID0のようなことが出来る。
上記の場合使えるディスク容量は2.1TBになる（普通のRAID0なら200GBのディスクしか作れないよね？）
しかもSSDとHDDを組み合わせた記憶域プールを作った場合、SSDにキャッシュ(ライトバックキャッシュ)をもたせることでHDD以上のスピードがだせるとのこと。

# 検証すること
- HDD単体の速度測定
- SATA SSD単体の速度測定
- HDD＋SSDで作成した記憶域プールの速度測定（ライトバックキャッシュ機能のおかげで早くなる想定）

# 記憶域プールの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443283/174434ce-0a20-5b1e-8aa8-ef995412a8d1.png)

## HDD単体の速度
うん、遅い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443283/dcf9e70b-ab03-f066-626a-c68264a12ca3.png)
- WD Green 3.5inch IntelliPower 2.0TB 64MBキャッシュ SATA3.0 WD20EZRX/N
https://www.amazon.co.jp/gp/product/B009QWUF6M/

## SATA SSD単体の速度測定
まあ、こんなもんか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443283/0a1fd66e-a43d-fe30-3ffb-521c73ee9616.png)

## HDD＋SSDで作成した記憶域プールの速度
シーケンシャルはまあまあ早くなった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443283/61b33295-72f8-865d-62ae-1136187fbe54.png)

## おまけ
m.2 SSDの速度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443283/67c2d08e-e4d7-ee7b-cbce-f202e1b85bda.png)

はやすぎ
【Shopify】裏技:カスタムCSSで設定できないはずのセクションセレクターにCSSを適用する

カスタムCSSで設定できないはずのセクションセレクターにCSSを適用する方法を解説します。

通常、カスタムCSSで`shopify-section`や`section`クラスにCSSを設定しようとすると、
下記のようなエラーが発生します。

> 無効なカスタムCSS: セクションセレクターはサポートされていません。 削除して変更を保存します。

ですが、これを回避する裏技があります。
下記のコードのようにクラス名を記述せずに、カスタムcssを設定します。
そうすると、`section`タグにcssが適用されます。

```css:custom.css
{
  text-align: center; #任意のcss
}
```
Condaを使ってRubyとRedArrowをインストールする

## はじめに

Rubyでデータ解析をする時、サーバーに管理者権限がない状態でも、Arrowを使いたい場合があります。Condaを利用して、RedArrowを導入することができましたので記録に残します。

## Conda環境へのRubyの導入

前提として、Rubyをconda-forgeで導入する

https://qiita.com/kojix2/items/70c16beff07665f5d8e8

```sh
conda install -c conda-forge ruby
conda install -c conda-forge compilers
```

## 必要なパッケージを追加でインストール

```sh
conda install -c conda-forge arrow-c-glib
conda install -c conda-forge gobject-introspection
# conda install -c conda-forge arrow-cpp 今は要らないらしい
```

## PKG_CONFIG_PATH と バージョン指定に注意

`PKG_CONFIG_PATH` は自動で設定されることが多いようですが、設定されていない場合は、以下のように設定して `conda`のファイルを見に行ってくれるようにします。また、`arrow-c-glib` と gemのバージョンは一致させる必要があります。

```
PKG_CONFIG_PATH=${CONDA_PREFIX}/lib/pkgconfig gem install red-arrow -v 11.0.0
```

この記事は以上です。
キャリアって結局自分が「どうありたいか」だと思う

## はじめに

本記事はこちらのキャンペーンの参加記事となります。

https://qiita.com/official-events/0d4c7ac216324bd6a3b9

私が思うエンジニアのキャリアについてつらつら書いていこうと思います。

:::note warn
本記事の内容は全て個人の主観でありポエムです。
:::

## あなたは誰？

33歳です。
WEBアプリケーションのエンジニアをして10年目になる者です。
今は20人規模の開発組織のマネージャーをしています。

## エンジニアキャリアって何？

本記事内では「自身がエンジニアとしてどうなりたいか？」をエンジニアキャリアと呼ぶこととします。
| 期間 | 私の定義 |
|:-:|:-:|
|  半年~1年後にどうなっていたいか |  目標 |
|  3~5年後にどうなっていたいか | キャリア  |
|  10年後にどうなっていたいか |  夢 |

ざっくり私のイメージとしてはこんな感じで、キャリアは3~5年後の自分のなりたい姿、と捉えてくれれば良いです。
目標ほど目下に見えたものでもないし、夢ほど遠いものでもない。
こうなっていたいよな〜って思う自分の将来像/理想像、みたいなものだと思ってもらえれば良いかと思います。
ここの期間については人それぞれだと思います。
あくまで私の定義です。

## エンジニアにはどういうキャリアがあるの？

ざっくり２軸あると思っています。
* マネジメント領域を伸ばす（マネージャールート）
* エンジニアスキル領域を伸ばす（テックリードルート）

もちろんこれ以外にも色んなキャリアがあるかなと思いますが、あくまで主観ではこの２軸が主かなと思います。

### マネージャールート

皆さんが1番想像しやすいルートなのかなと思います。
メンバー→サブリーダー→リーダー→サブマネージャー→マネージャー→役員？？？→？？？
所謂役職がついて「昇進」というイメージが湧きやすいルートです。
常に人と話し、マネジメントする人たちのことを考え、どうしたらもっと働きやすくなるか、成果がでるか、などを考えていく必要があります。
技術とは手段の1つで、ビジネスやソリューションを考えていく脳が必要となります。

### テックリードルート

最近よく聞く言葉なのでご存知の方も多いと思いますが、技術やスキルに特化していくルートです。
人の管理をするマネージャーとは対極に近く、技術に向き合っていき、仲間への技術支援であったり相談/提案/改善などを行っていくのが主の役割となります。
常に技術を磨き、最新情報をキャッチアップし、己のチカラを維持成長する必要があります。
ある課題があった時に技術でどうやって解決するか、を考えるの主となります。

## みんなどうやってキャリアを決めてるの？

正解はないです。
結局「自身がなりたいと思った」ものがキャリアなので、まず己とよく向き合うことが大切かなと思います。
人のことは分からないので自分のことを語ります。
私は10年前に入社したときに「がんばるぞ！」→「昇進するぞ！」→「マネージャーになるぞ！」という思考を持ち、現在マネージャーになった、という状況です。
エンジニア35歳定年説というのを半分信じている人間で、ずっと最前線で技術を追い求めていく働き方は難しいだろうなと思っていました。
技術1本で生きていくのは難しそう…ってことはマネージャールートか、というくらいの判断基準でこちらのルートに進みました。
なので「なんでマネージャールートを選びましたか？」と聞かれると答えに悩んでしまいます。
強いてあげるならば「メンバーと話してて楽しい」「組織のために何かしてあげたい」と思う思想が人より少し強かったかな？と思うくらいです。
ただ、少なくともテックリードルートを選ばなくて正解だった、とは思っています。
私の身近のテックリードたちはみんなずば抜けて技術に優れ、とても張り合えるとは思えないです。
私自身もそこに時間を割き、勉強していけば追いつけるかもしれませんが
30歳で結婚し子供が生まれ、家事に育児に大忙しの33歳。
とてもじゃないですが自身のスキルを伸ばす時間を十分に確保することはできません。
同じ状況化において「俺は勉強してる。甘えるな。」と言われる方もいらっしゃるかもしれませんが、私は家庭が大事で優先したいと考えています。
じゃあマネージャーは勉強しなくてもできるのか、と言われると決してそんなことはないです。
日々挑戦と失敗の連続です。
マネージャーになるにあたり本もある程度読みました。
本当はもっと読みたいけど読む時間もそんなに取れないので本当に隙間隙間で読んでいく感じです。
マネージャールートの方は過去の経験の積み重ねが活きる場面が多いため、私はこちらのルートを選んだおかげで今まだ戦えているなと感じています。

人生の諸先輩方にお話を伺ったところ「子供に手がかかるのなんでたかだか10年そこそこ。また頑張るのはそこからでも遅くないのでは？」
私はこの言葉に結構救われていて「じゃあ今は家庭を大事にするフェーズでいいんだ」という思考になりました。
まだまだ手のかかる子供ですが、数年後には1人でなんでもできるようになり、休日もパパよりも友達と遊ぶことが多くなるでしょう。
そうなって再び時間ができたときに、改めて学び直し、再スタートを切るのが良いのかなと今は思っています。
「なりたい自分」という意味ではこれも1つの「キャリア」　なのかもしれません。
私の今のキャリアは「パパを精一杯楽しんでがんばる！」ですかね。

## どうやったらマネージャーになれるの？

私は現在マネージャーです。
テックリードにはなったことがないのでどうやったらなれるかは答えを持っていないので割愛します。
マネージャーの方は少しは語れると思うので書きます。
私がマネージャーになれたのは一言でいうと「メンバーからの信頼が1番高かった」だと思っています。
10年働いてる中で何度もリーダーポジションを経験し、その度に成果を出してきました。
困ってるメンバーの相談には積極的に乗ってきたし、トラブル対応や「誰か拾って〜」系も率先して拾ってきました。
そういう日々の積み重ねがみんなの信頼を得て「あなたにだったらマネージャーを任せられる」と言っていただけるようになったのだと思っています。
銀の弾丸はないです。
草の根活動、あとは運とタイミングです。
あなたにその適正があっても、あなたよりも適任がいればそのポジションは空かない。
組織体系的にマネージャーという役職がなければそもそもその役につくことはない。
大事なのは常にマネージャーという姿勢や視点を常に持ち「いつなんどき声がかかっても大丈夫な状態にしておく」ことだと考えています。
運が巡ってきたときに選んでもらえるように、日々精進です。

## まとめ

私が思うエンジニアのキャリアについてつらつらと書かせていただきました。
総じてお伝えしたいことは「キャリアとは難しいものではなく、自分がどうありたいか」ということです。（まぁそれが難しいとも言える）
その結果趣味を優先したり家庭を優先したり、私はその選択も正解だと思います。
ただ「エンジニアとしてこうなりたい！」がある場合は、そりゃあ頑張るしかないですよね。
今自分にとって何が大事でどうなりたいか。
今1度考えてみてはいかがでしょうか！
LeetCode 配列の基本的な質問

# 基本的な質問

## リートコード 26

問題の簡単な説明:

ソートされた配列を指定した場合、各要素が 1 回だけ表示されるように、繰り返される要素を所定の位置で削除し、削除された配列の新しい長さを返す必要があります。

ここには大まかに 2 つの解決策があります。1 つ目はダブル ポインターです。

```java
public int removeDuplicate(int[] nums){
    if(nums.length==0){
        return 0;
    }
    int j= 0;//遅いポインタ
    for(int i =1;i<nums.length;i++){//高速ポインタ
        if(nums[i]!=nums[j]){
            j++;
            nums[j]=nums[i];
        }
    }
    return j+1;
    
}
```

この質問で最も重要なことは、重複データをすべて削除する必要はなく、最初のいくつかを置き換えるだけであることを明確にすることです。 たとえば、{0,0,1,1,2,2} の場合、最終的には {0,1,2} ではなく {0,1,2,1,2,2} に変更するだけです。 この点を明確にしておけば、この質問ははるかにやりやすくなります。

ここで初心者が混乱しやすいのは、配列内の繰り返しデータがどのようにカバーされるかということです (具体例としては、テスト ケースの入力 {0, 0, 0, 1, 1, 2, 3})。 具体的な演算過程は、ファストポインタ i が 1 になるまで j は常に存在し、i が 3 に増加したときのみ、この時点で次の判定文が実行され、つまりまず j が 1 に増加します。次に、nums[j+1]、つまり nums[1] を num[i]、つまり nums[3] の数に変更します。 等々。

2 つ目の書き方は、**LinkedHashSet** の内容が繰り返されず、順序が保証されるという特性を利用する方法です。

```java
public int removeDuplicate1(int[] nums){
        LinkedHashSet<Integer> set = new LinkedHashSet();//
        for(int n : nums){
            set.add(n);// for ループ で配列内の数値をセットに詰め込みます
        }

        int i =0;
        for(int j : set){
            nums[i++]=j;
        }//元の配列を上書きします
        return set.size();//必要な数値を返す
    }
```
Go Conference 2023 に参加しました！

# はじめに

2023.06.02 (金) に開催された Go Conference 2023 (以下 GoCon ) に参加してきました！

https://gocon.jp/2023/

https://gocon.connpass.com/event/248757/

> Go Conference は年に1回行われるプログラミング言語 Go に関するカンファレンスです。
> 
> カンファレンスは YouTube で配信されますが、参加者は reBako というバーチャル空間で集まって配信を楽しむことができます。ぜひみなさんで集まってカンファレンスの臨場感を楽しみましょう！
> 
> reBako では YouTube 配信だけではなく、スポンサー様や Go コミュニティのブースがたくさん企画されます。お楽しみに！！

私が所属する株式会社ビットキーは Silverスポンサーとして協賛いたしました。

https://bitkey.co.jp/newsroom/20230524/

GoCon は YouTube で過去に開催されたアーカイブを見たことがありましたが、1日を通してフルで参加したのは初めてでした。
また、カンファレンス系のイベントについてもエンジニア人生を歩み始めてから初の参加だったのでとてもわくわくしていました。
そんな私の参加レポートを記事として残そうと思います。

# 前日までの準備

私は　GoCon に参加するということで「とにかくたくさんセッションを見まくるぞ！」と意気込んでいました。
そして各セッションの内容をメモアプリに洗い出し、それぞれのセッションについてコメントを書きまくりました。

- 興味があるセッションを洗い出す。
- なぜ興味を持ったか記載する。

そしてセッションを聞いたあとに

- 新たな発見
- 今後業務で活かせそうなこと

を整理しようとしていました。

# 当日

では、各セッションについて感想を述べていきます！
という予定でしたが...

**当日ほとんどセッションは見ませんでした！**

では、あなた何してたの???というと...

**各スポンサーさんのブースにお邪魔しに行ってました!!!**

https://gocon.jp/2023/floor_guide/

GoCon は [reBako](https://rebako.io/) というサービスにて下図に示すような形でオンラインイベント会場が提供されていました。
各スポンサーさんのロゴが掲載されているスペースがブースとなります。このスペース内のテーブルをクリックすることで着席ができ、同席している方とお話できる(ブースにお邪魔できる)という仕組みです。

![reBako-layout.9b42e62b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961759/3aace7bd-58f2-8e88-d3f9-4acb9c6fdce2.png)

ブース参加へのきっかけは最初の休憩時間にビンGoに取り組み始めたことです。

:::note info
ビンGoとは ... Goやスポンサーさんに関する問題が記載されたビンゴカードを回答し埋めていくゲーム
:::

ビンGoの回答を知るためにはスポンサーさんのブースに直接お話を聞きに行かないと答えがわからない問題がありました。
最初は「答えを知るためにお話を聞きに行こう」くらいの軽い気持ちでブースへ訪問しましたが、あいにく訪問されている方とお話中でした。
お話が途切れたらビンGoの回答だけ効いて撤退しようと思っていましたが、話が進むにつれGoをはじめとした技術の話やスポンサーさんの事業の話を聞けて楽しくなってきました。
これをきっかけにこんな話をほかのスポンサーさんからも聞いてみたくなり GoCon はセッションを見るのではなく、スポンサーさんのブースを回ることに徹しよう！と決めました。
また、ブース参加に全振りしようと決意できたのは後日各セッションが YouTube でアーカイブされることが予定されていたことも影響しています。

具体でお聞きした内容は私が勝手にスポンサーさんの情報を間違って伝えてしまうといけないので伏せさせていただきますが、ざっと以下のような内容についてお話しました。

- Go関連
    - インフラ構成ってどんな感じですか？
    - Web用のライブラリってなに使われてますか？
    - ORMってなに使われてますか？
    - ログライブラリってなに使われていますか？
    - ディレクトリ構造ってどんな感じですか？
    - 静的解析ってどんな感じですか？
    - Gopherって何名いらっしゃいますか？
    - Goを使っててつらみとかって感じたことありますか？
    - GoCon に採択されるには？
- そのほか
    - 副業について
    - 事業について

ブースに着席する際は軽い自己紹介をしつつ、「雑談しにきました〜」や私のビンGoカードに問題がなかったとしても「ビンGoの答え教えてください〜」とあいさつをして参加していました。
Goの話からエンジニアの副業の仕方について、まだまだ若輩者の私にとっては**とても楽しく刺激となり有意義な時間を過ごすことができました！**

# 振り返り

GoCon に参加できて本当によかったです。
ただ、一方で「ああしていればよかった」など反省するところもあったので記載しておきます。

こちらは GoCon 終わりに内省したものから、チームで振り返りミーティング（2023.06.05開催）を実施して挙がったものを列挙しています。

- 自社ブースにほとんど滞在していなかった。ごめんなさい。
- 各スポンサーさん、お話の流れで公開されている記事を共有いただいた。
    - イベント時に記事に誘導できるのいいな。
    - 記事として言語化しておくとイベント参加時にも引き出しとして話が楽にできそう。
- 各スポンサーさんの業務をもう少し知ってからブースへ参加すればよかった。
    - 業務の特性 × Go の話とか膨らませることができたかもしれない。
- 聞きたいことリストをちゃんと整理しておくべきだった。
    - テスト系の話をほぼしなかった。
- 自社で扱っているGoについてもっと整理しよう。
    - Goライブラリどんなの使っているのか、なぜそれを選定したのか。
    - ディレクトリ構造について。

# おわりに

Go Conference 2023 を開催していただいた運営のみなさま および Silverスポンサーとして協賛させていただいたことに本当に感謝です。
次回参加するときは今回以上に参加した価値を高めたいです。
そのためにもGoの理解、記事やイベント登壇でのアウトプットをしつつよりよいものづくりをしていきます！

また、GoCon スポンサーブース設営をきっかけに私のDevトークを展開しました。
気になる方がいましたらぜひ、気軽にお話しましょう！

https://jobs.qiita.com/employers/240/dev_talks/569

# ちなみに...

ビンGoの結果はこんな感じでした。

https://twitter.com/otakakot/status/1664546457289097220?s=20
APEXの中、複数エラーメッセージの取得方法

 とても基本の知識だけど、ちょっと注意するケースがあります。

下記の場合、

１．triggerを使って、バリデーションが効く
２．あるapexでtriggerが見つかったエラーをログに登録するとか
　　あるいは、trigger自体がエラーをログオブジェクトに登録したい場合とか

３．処理対象が複数レコードの場合（エラーも複数）

ここで、もしtry...catch..を使って、複数のエラーが取れないだ！

いろいろ調べましたけど、具体的な根拠がない。現象としては、catch メソッドは最初のエラーを取れて、catchの中に入った。

その２番目のエラーとか、全然取れていないです。


だから、今後もし複数のエラーを利用しようとする場合、全部下記のソースで取得する。

そう覚えてくれれば、一番楽勝です。


~~~
Database.SaveResult[] srList = Database.insert(yourlist, false);
    for (Database.SaveResult sr : srList) {
        if (!sr.isSuccess()) {
            // Operation failed, so get all errors                
            for(Database.Error err : sr.getErrors()) {
                System.debug('The following error has occurred.');                    
                System.debug(err.getStatusCode() + ': ' + err.getMessage());
                System.debug('Fields that affected this error: ' + err.getFields());
            }
        }
    //   system.assert(
    //     true,
    //     String.valueof(e.getMessage())
    //       .contains('検証したいもの')
    //   );
   }
RubyでcsvファイルをParquet形式に変換

[PythonでcsvファイルをParquet形式に変換](https://qiita.com/TaigoKuriyama/items/cedcc9436f4456191601)という記事を見て、Rubyでもできるやんけと思ってメモ。

たぶん一番簡単なのは[Polars](https://github.com/ankane/polars-ruby)を使う方法。

```ruby
require "polars"

df = Polars.read("foo.csv")
df.write_parquet("foo.parquet")
```

簡単ですね。[RedArrow](https://github.com/apache/arrow/tree/main/ruby/red-arrow)を使う場合は、

```ruby
require "arrow"
require "parquet"

tb = Arrow::Table.load("foo.csv")
tb.save("foo.parquet")
```

ですね。この記事は以上です。
AIイラスト｜自分好みのキャラをつくるときのプロンプト備忘録（※順次更新）

# はじめに

あくまでも自分用の便利メモですが、お役に立てればです。
時間のある時にコツコツ追加していきます。

+ Python
+ Stable diffusion


# 構図

| Category | prompt | result |
|:-|:-|:-|
| カメラの向き  | from above | 上  |
|   | from below | 下  |
|   | from side | 横  |
|   | from behind | 後ろ  |
| 視線  | looking at viewer | カメラ目線  |
|   | looking away | 目をそらす  |
|   | looking back | 振り向く  |
| 被写体  | full body | 全身  |
|   | face focus | 顔によせる  |
|   | portrait | 肩〜顔  |
|   | upper body | 上半身  |
|   | lower body | 下半身  |
|   | cowboy shot | 太ももより上  |


# 表情

| Category | prompt | result |
|:-|:-|:-|
| 笑う  | smile  | 笑顔  |
|   |  wink | ウィンク  |
|   | happy  | 幸せそう  |
|   | laugh  | 笑う  |
| 怒る  | angry  | 怒り  |
|   | scowl  | むすっ  |
|   | displeased  | 不機嫌（軽め）  |
|   | annoyed  | 不機嫌（強め）  |
| 悲しい  | sad  | 悲しい  |
|   | uneasy  |  不安 |
| 困る  | anguish  |  困る |
|   | uneasy  |  不安げ |
|   | terrified  |  怖がった感じ |
| 驚き  | surprised  |  驚いている |
|   | stunned  |  呆然とした感じ |
| 照れ  | blush  |  頬が赤くなる |
|   | nose blush  |  鼻まで赤くなる |
| 他  | expressionless  |  無表情 |
|   | sleepy  |  眠そうな顔 |




### 性別・年齢

| Category | prompt | result |
|:-|:-|:-|
| 女性  | woman | 女性  |
|   | girl | 女性（若め）  |
|   | female child | 女性（子供）  |
|   | mature female | 熟女  |
|   | old woman | 老女  |
| 男性  | boy | 男性  |
|   | male child | 男性（子供）  |
|   | mature male | おじさん  |
|   | old man | おじいさん  |
スマホアプリのテスト観点

## 何を使ってテストするか

#### 1.エミュレーターによるテスト
レスポンシブ対応のチェックで使う（UI）
準備が不要

#### 2.実機のテスト
実際のスマホを使う（準備が大変）
機種が多いため、主要な機種に絞って行う
エミュレーターでは見つからないハードの部分も検証できる

#### 3.リモートテストキット
実機を用意せずに実機をリモートでレンタルできる→リモートワークメインの会社で使われることが多い？
複数OS、複数機種の検証ができる
単純な挙動であれば複数台同時操作もできる

## テスト項目(機能・結合テスト)
#### 1.アプリ設定のテスト
アプリがデバイスに正常にインストールされるか
アプリアイコンがデバイスに表示されるか
アップデート後も既存データが消えていないか
アンインストールが正常にできるか

#### 2.起動時のテスト
アプリの起動が5秒以内であるか

#### 3.UIテスト
フィールドやオブジェクトが設計書通りの位置にあるか
デザインが設計書通りであるか
各種バリデーションチェック
画面遷移
画面を縦持ちの場合と横持ちの場合でレイアウト崩れがないか

#### 4.アプリの使用が中断される際のテスト
使用中に電話がかかってきた時
バックグラウンド動作
電池切れからの再起動
充電中/電池が少ない状態でも正常に動くか
システムメンテナンス時の挙動
スリープからの復帰

#### 5.ネットワークのテスト
Wifi、3G、4Gなど、さまざまなネットワークの場合
4GとWifiの両方がある場合、Wifiを優先して使用するか
ネットワークを4GからWifiに切り替えた場合（Wifi優先）その逆の場合（Wifiネットワークの損失を通知）
Wifiを使用しているときにネットワークが失われた場合、ユーザーに通知できているか

#### 6.デバイスメディアでのテスト
アプリのBGMのON・OFF
別の音楽アプリが再生されている状態でアプリを起動する
アプリで音量が操作できるか
バイブレーションモードなど

#### 7.パフォーマンステスト
OS、処理速度、容量、画面サイズが異なるデバイスで性能テストをする
特定の時間帯に、多くの人が同時にアクセスする場合
一度に多くの人がインストールする場合

#### 8.セキュリティテスト
アプリが求める権限は必要以上のものではないか
ユーザーのデータにアクセスする前にアプリは許可を求めるか
ログインに失敗したとき、回数制限はあるか
認証機能SSO（サードパーティ）でサインインできるか

#### 9.アプリのストア申請 (Google Play Store)
1.カテゴリーが正しくないアプリではないこと
2.著作権・商標権侵害していないアプリであること
3.不正広告アプリではないこと(※アダルト系は注意です)

https://play.google.com/intl/ALL_jp/about/developer-content-policy/

####  9.アプリのストア申請 (Apple Store)
1.クラッシュするアプリではないこと
2.アプリにバグがないこと
3.インストールや起動の前に、iOSデバイスの再起動を推奨するアプリではないこと
4.個人情報を有するアプリではないこと
5.プッシュ通知を使って、個人情報を送信するアプリではないこと
6.空のiAdを含んだアプリではないこと
7.広告表示のためだけに設計されているアプリではないこと
8.急激にバッテリーを消費したり、過度の熱を発生させるアプリではないこと
9.政治批判やユーモアは誹謗、中傷なコメントではないこと
10.非公開APIを使用するアプリではないこと
11.初回起動時ブラウザ立ち上げがないアプリであること
12.ユーザー自身でアカウントを削除する機能を有すること
※他にもあります

https://developer.apple.com/app-store/review/guidelines/
ファイルメーカ、カスタム関数のインポート参考URL

https://fmhelp.filemaker.com/fm19/ja/pro-help/content/importing-custom-functions.html?Highlight=%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E9%96%A2%E6%95%B0
QAエンジニアのキャリア形成ってナンダ？

 ## 経験年数

1年目
レベル1　テスター
 - 結合/総合テスト実施
（画面・確認テスト）
 - バグ排出・報告/レポーティング
 　→基礎的なテスト技法を適用できる
 　→準備されたテストツールを使える

2〜3年目
レベル2　QAエンジニア（メンバー）
 - 結合/総合テスト実施
（画面・機能・シナリオテスト）
 - テストケース（画面・機能）設計
 - テスト実施
 - バグ報告・デバック・分析
　→QAのトレードオフ、ドメインへの理解
　→JSTQB Foundation
　→ツールを使ったプロセス改善

レベル3　QAリーダー　（年収500〜600万円？）
 - テスト計画～実施
 - チームのマネジメント
 - チームビルディング
 - テストプロセスの改善提案
 - サービス・仕様設計（レビュー）
 - バックエンドテスト、非機能テスト
　→ドメインへの深い理解
　→技術・プロセスのベストプラクティスを標準化できる

レベル4　PM/QAコンサル / QAマネージャークラス（年収600〜1000万円？）
 - テスト計画～実施
 - クライアント折衝/調整
 - テスト実施自動化
 - テストプロセス改善
 - パイプラインの設計・構築
 - 脆弱性診断


## キャリアパス
![スクリーンショット 2023-06-14 13.10.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/791219/2526093a-fade-6830-1507-b70949930dde.png)

## 待遇
### アメリカのQAエンジニア　
平均:838万円
Apple:1711万円
### 日本のQAエンジニア
平均:540万円
ファーストリテイリング:942万円

参照：Indeed　https://jp.indeed.com/cmp/%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%95%E3%82%A1%E3%83%BC%E3%82%B9%E3%83%88%E3%83%AA%E3%83%86%E3%82%A4%E3%83%AA%E3%83%B3%E3%82%B0/salaries/QA%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2

## QAエンジニアになると視野が広がる
各専門家と連携しながら品質を最適化していく必要があるので、PdmやPM、SETエンジニアなどにもなれそう。
CDKでLambdaレイヤーを作成して使用する

## 概要

[以前の記事](https://qiita.com/haruki-lo-shelon/items/2eb7c05f1dd3d4df2ca9)でFastAPIをLambdaで使用してAPIを設計し、APIGatewayでデプロイするのをCDKで行うというのをあげたのですが、その際にLambdaレイヤーをCDKで作成するのに詰まった点があったのでその部分をとりあげます。

## Lambdaレイヤーを作成する準備
FastAPIとMungumをLambdaで使うことを想定する。
レイヤーとなるdependencies.zipを作成する。

使いたい外部ライブラリをまとめたrequirements.txtを作成
~~~text:requirements.txt
fastapi
mangum
~~~

依存関係をzipにまとめる
~~~
mkdir python
pip install -r requirements.txt -t python/python/lib/python3.10/site-packages/
cd python
zip -r ../dependencies.zip .
cd ..
rm -rf python
~~~
最初に作成したPythonファイルは一時的にインストールしたライブラリ置いておくためのものであるため、最後に削除のコマンドを入れている。
もし必要であればpackage.jsonにこれらのコマンドを定義しておいて１コマンドで簡単に実行できるようにしておくといいかもしれない。

レイヤーの中身のファイル構造(python/lib/python3.10/site-packages)は決まっていて、これに沿っていなかったらレイヤーを作成しても中身を認識してくれない。（[公式ガイド](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html)参照）

## CDKでlambdaとレイヤーを作成して関連づける

~~~typescript
    ...

    // レイヤー作成
    const layer = new lambda.LayerVersion(this, "CustomLayer", {
      // レイヤーzipファイルのパスを指定
      code: lambda.Code.fromAsset("dependencies.zip"),
      compatibleRuntimes: [lambda.Runtime.PYTHON_3_10],
      description: "A layer to hold the FastAPI and Mangum dependencies",
    });

    // Lambda関数の作成
    const fn = new lambda.Function(this, "handler", {
      runtime: lambda.Runtime.PYTHON_3_10,
      handler: "app.handler",
      code: lambda.Code.fromAsset(path.join(__dirname, "../lambda")),
      layers: [layer], // ここでレイヤーを関数に追加
    });

    ...
~~~

## レイヤー作成自動化

レイヤーzipを作成した以下のコマンド部分を自動化した方がいいかもしれないと思った。
~~~
mkdir python
pip install -r requirements.txt -t python/python/lib/python3.10/site-packages/
cd python
zip -r ../dependencies.zip .
cd ..
rm -rf python
~~~

CDKにはpackage.jsonというファイルがあり、ここでコマンドを定義することができるのでこれを使う。
~~~json:package.json
{
    ...
    "scripts": {
        "build": "tsc",
        "watch": "tsc -w",
        "test": "jest",
        "cdk": "cdk",
        "layer": "mkdir python && pip install -r requirements.txt -t python/python/lib/python3.10/site-packages/ && cd python && zip -r ../dependencies.zip . && cd .. && rm -rf python"
      },
    ...
~~~
"script"に上記の"layer"のようにコマンドを設定できる。名前はlayerでもなんでもいい。

実行する方法は、
~~~
npm run layer
~~~
となる。これをcdk deployの前に実行すれば良い。

## まとめ

CDKでLambdaレイヤーを実装する方法についてまとめました。
Lambdaに必要な外部ライブラリはローカルにインストールしていても動作しないので、直接ライブラリファイルを含めてデプロイするか、本記事のようにレイヤーを作成するかなどの処理が必要です。
[Rails6]　Heroku&AWSデプロイ時トラブルシューティング（忘備録）

# はじめに

2023/6/14時点の現在、以下の環境でRailsアプリを作成し、Herokuにデプロイしようとするとエラーが多発する状態です。エラーが出る根本的な原因はわからないのですがデプロイをするところまで出来たので方法をシェアします。

#6/17追記
    AWSデプロイ時に出たbabelエラーにも同じ対応で解消できたので記事タイトルを変更

---

### 環境

Ruby 3系
Ruby on Rails 6.1系

---

# Two different lockfiles found.package-lock.json and yarn. lock

```ruby
rails new
```

で作成したアプリにpackage-lock.json と yarn. lockの両方あると発生するエラー。

どちらかを消せば解決します。

```ruby
git rm package-lock.json
```

今回は上のコードを実行しpacage-lockを消します。

実行後、git add , git commitをして `git push heroku master` をすると以下のトラブルがでます。

---

# The Ruby version you are trying to install does not exist on this stack.

![スクリーンショット 2023-06-14 11.11.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/68b080b6-627a-844c-29db-3911ed3f821e.png)



Rails6.xx系はHeroku-22に対応してないのでこのエラーが出ます。

`heroku stack:set heroku-20`

をターミナルで実行すれば解決します。

上のコードを実行後 `git push heroku master`をすると以下のトラブルが発生。

---

# Failed to install gems via Bundler.

![スクリーンショット 2023-06-14 11.12.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/bfe61cc8-d2c5-2d03-8151-56d96f77f4be.png)

エラー文にある通りx86_64-linuxをロックする必要があるときに出るエラー。

`bundle lock --add-platform x86_64-linux`を実行後git add ,git commitをすると解決します。

上のコードを実行後 `git push heroku master`をすると以下のトラブルが発生。

---

# Error: Cannot find package '@babel/plugin-proposal-private-property-in-object'

![スクリーンショット 2023-06-14 11.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/d6053ccb-cb0a-1c37-ffd0-d8817976870e.png)
![スクリーンショット 2023-06-14 11.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/89f915b2-58c6-d27b-e418-e2fdc497c035.png)

最近、@babelがアップグレードしたことに起因するエラー？

```ruby
yarn upgrade @babel/core
```

をターミナル上で実行

次にアプリのpackage.jsonに

```json
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"webpack-dev-server": "^3",
"@babel/core": "^7.0.0"
```

の3行を追加。
本番環境で使用したいので"dependencies"配下に追記する必要があります。
”devDependencies"配下に追記しない様に注意

![スクリーンショット 2023-06-14 12.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/d7d313bc-512e-4acc-019e-8d851e2c72db.png)


git add , git commitで解決します。

上のコードを実行後 `git push heroku master`をすると以下のトラブルが発生。

---

# error Your lockfile heeds to be updated……--frozen-lockfile'

> error Your lockfile heeds to be updated, but yarn was run with
--frozen-lockfile'
> 

`yarn.lock`ファイルのバージョンが異なっているためBuildで失敗しているらしいです。

```ruby
yarn install
```

をターミナルで実行後、git add , git commitで解決します。

---

# Error: error:0308010C:digital envelope routines…

Error: error:0308010C:digital envelope routines: :unsupported

![スクリーンショット 2023-06-14 11.53.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3379147/a2241c6c-0c68-caff-4b7c-6d37fb4b190d.png)

HerokuにおいてNode.jsのデフォルトバージョンが18系になっていることが原因。

package.jsonに

```json
"engines": {
  "node": "16.x"
  }
}
```

をターミナルで実行後、git add , git commitで解決します。

---

以上のトラブルを乗り越えると無事、Herokuにデプロイすることができました。
MAMPでMySQLが起動しなくなった！

## はじめに
久しぶりにMAMPを使ってmysqlに入ろうとしたらエラーになり入れなくなったので
そちらの解消方法の備忘録になります。

## 原因
MAMPを起動してもPCがbrew側のmysqlを参照していたためエラーが起こっていた。
### 解消方法
brewのMySQLを削除し、bashファイルでMAMPのMySQLを参照するように設定する

## エラー内容
実際の内容を記載しています
MAMPを起動し、MySQLに接続する

```terminal:ターミナル
mysql -u ユーザー名 -p
```
パスワードを入力すると、以下のエラーになり接続できない。

```terminal:
Can't connect to local MySQL server through socket '/Applications/MAMP/tmp/mysql/mysql.sock' (2)
```

ソケットがないとエラーが出ているがソケットを生成してみてもエラーは変わらずでした。
　

・MySQLの確認
```terminal:ターミナル
$ which mysql
/usr/local/opt/mysql@5.6/bin/mysql
```

どうやらbrewのMySQLを参照しているみたい💦
MAMPのMySQLを参照するようにしたい！
　

・brewのMySQLを削除する
```terminal:ターミナル
$ brew unlink mysql
```
　
・もう一度MySQLを確認
```terminal:ターミナル
$ which mysql
mysql not found
```
パスにMySQLが渡されていなくなった！
ここから参照したいパスを設定する

その前にシェルを確認
```terminal:ターミナル
$ echo $SHELL
/bin/bash
```
　
bashファイルを参照しているのでbash.profileに以下のパスを設定
```terminal:bash.profile
export PATH=$PATH:/Applications/MAMP/Library/bin
export PATH=$PATH:/Applications/MAMP/bin/php/php7.4.21/bin
```
　
　
ファイルを適応
```terminal:ターミナル
$ source ~/.bash_profile
```
　
・MySQLの確認
```terminal:ターミナル
$ which mysql
/Applications/MAMP/Library/bin/mysql
```
MAMPのMySQLを参照している！

MAMPを起動し、MySQLに接続する

```terminal:ターミナル
mysql -u ユーザー名 -p
```
無事入れました！！以上です！！
phpDocumentor を利用してドキュメントを自動生成

**「ドキュメントのメンテナンスとか面倒でやってられない」と思っている方が弊社に多い** ので、 「せめて PHPDoc のメンテはやってください。ドキュメント自動生成するから」 と言ってみましたがどうなることやら。

という状況なので、とりあえず弊社のみんなに見てもらいたく phpDocumentor の使い方を簡単にまとめてみました。



# 実行方法

以下の3つ

## PHAR 

docker 使ったら死ぬ呪いに掛かっている人はこちら

```bash
# phpDocumentor ダウンロード
wget https://phpdoc.org/phpDocumentor.phar
# 実行権限付与
chmod +x phpDocumentor.phar
# グローバルで実行したい
mv phpDocumentor.phar /usr/local/bin/phpDocumentor

# 実行
# -d  ドキュメント出力元
# -t ドキュメント出力先
phpDocumentor -d [path] -t [path]
# example 
# app ディレクトリのドキュメントを documents ディレクトリに出力
# phpDocumentor -d app -t documents
```

## Docker

普段 docker 使っているならコレ一択

```bash
# コンテナイメージダウンロード
docker pull phpdoc/phpdoc
# 実行
# -d  ドキュメント出力元
# -t ドキュメント出力先
docker run --rm -v $(pwd):/data phpdoc/phpdoc -d [path] -t [path]
# example 
# app ディレクトリのドキュメントを documents ディレクトリに出力
# docker run --rm -v $(pwd):/data phpdoc/phpdoc -d app -t documents
```

## composer

一応用意されてはいるが、依存関係に関する問題解消が非常に困難のため、使ってほしくない模様。

https://packagist.org/packages/phpdocumentor/phpdocumentor

# 自動生成されたドキュメントを参照する

ドキュメント自動生成後、-t オプションで指定したディレクトリ内の index.html を参照する


![phpdocumentor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/df3594de-8006-d5f9-6594-2892228b8ae5.png)



# PHPDoc メンテ時に参考に出来そうなサイト

## PHPDoc リファレンス
https://zonuexe.github.io/phpDocumentor2-ja/references/phpdoc/index.html

## phpDocumentor
https://docs.phpdoc.org/
Raspberry Pi3にVSCodeでリモート接続する

# 環境
- Pi3（Pi3+じゃない）
- Ubuntu Server 22.04.2 LTS(32bit)

# VSCodeで接続しようとしたらエラー
メモしていなかったのでもしかしたら違うかもですが、以下のようなエラー。
```
Resolver error: Error: The VS Code Server failed to start
    at m.ServerInstallError (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:584322)
    at f (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:578379)
    at t.handleInstallOutput (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:581404)
    at t.tryInstall (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:681793)
    at async c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:644041
    at async t.withShowDetailsEvent (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:647359)
    at async t.resolve (c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:645091)
    at async c:\Users\Roy\.vscode\extensions\ms-vscode-remote.remote-ssh-0.98.0\out\extension.js:1:720839
```

# build-essentialをインストール

build-essentialをインストールして再度接続したらうまくいきました。
```bash
sudo apt install build-essential
```
【Query Builder：Expression】Try using Switch statement

I will use the **Switch** statement as a basic expression.
Start **Query Builder** from the application menu of [Sharperlight](https://sharperlight.com/).
Configure the filter settings as follows and prepare the custom dataset.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2cf7b06c-5c50-82ad-f840-96cc5ffb47df.png)
A preview returns a dataset like this.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a1cdc253-050e-4fc3-557d-0c550ea8e8d8.png)

Now go back to the query definition and select `Add Expression` from the right-click menu in the output area to open the Output Options dialog.
Enter **Swi** in the Find field, find the **Switch** statement template from the function list, and double-click to transfer it to the upper editor.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d282934e-a9e4-60c1-40b5-faf0b37e09d6.png)
This time, I just want to display text depending on the condition so if the code is A100, it displays `The code on this line is A100.`, and if the code is A200, it displayes `The code on this line is A200.`.
Now rewrite the template like this:
```
Switch( {%Code}
,"A100","The code on this line is A100."
,"A200","The code on this line is A200."
,"A300","The code on this line is A300."
,"This line of code is neither A100 nor A200 nor A300." )
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4f83e6c8-b6de-47a6-c6e5-156117f5e9c7.png)
The query result is like this;
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/dc31c873-b636-1ff4-cdfd-d32b78392622.png)

I hope this will help your work.
アプリ開発におけるプロモーション起因のリリース日変更の話

## これはなに
iOS/Androidアプリ開発の際に起こりうる様々なリリース日変更について、自身の経験からプロモーション起因によるものを紹介したいと思います。
対象としてはゲーム系のアプリ、ツール系アプリがメインになります。

このようなお話を知ることで、開発に関係ないところで起こるリリース日変更に対して「こういう背景があるのか」や「事前にこういう準備をしておこう」とか、心に余裕を持てるといいなあと思い記事を書こうと思います。


あくまで自身の体験をメインにした内容ですので以下のようなシチュエーションでの話になります。
- ゲーム系アプリは数十人で事業会社として自社開発をしているもの
- ツール系アプリでは数名で事業会社として自社開発をしているもの


## 1. ストアの掲載状況による日程の変更
こちらはApp Storeやgoogle Playの掲載枠に関する理由での日程変更です。

アプリビジネスはリリース時の露出が非常に重要なため各社がストアでの露出を狙います。
App Storeなら「Today」、Google Playなら「トップバナー」など非常に効果の高い枠があります。

![iOS-11-Apple-Official-Preview.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502865/1084b07f-c2bd-b7db-db1b-f2685b22683a.jpeg)



ここへの掲載は難度が高く、AppleやGoogleの編成担当との調整のうえ掲載が決まります。ただし非常に間口は狭いので掲載されるには一定の認知度や様々な条件があります。

なので、ここへの掲載が決まった際はそのスケジュールに合わせることがビジネスとしては非常に効果が大きいため、たとえリリース日は数週間、もしくは数ヶ月前後したとしてもここに合わせることがあります。
※Today広告枠については出稿すれば掲載可能です。

https://searchads.apple.com/jp/help/ad-placements/0083-today-tab



これが理由でリリース日が前後したときは

**前倒し：非常に効果が高いので頑張って間に合わせる**
**後ろ倒し：せっかくなのでクオリティアップに時間を使う**

というくらいの意識で臨むのが吉かと思います。


## 2. 広告プランの予定によるリリース日の変更
こちらはよく起こるかと思いますが、リリース時の広告プランによる変更です。
先程も書いた通り、アプリビジネスはリリース時の立ち上げが非常に重要です。
なので広告プランもリリース直後の数週間に集中させることが多いです。（場合によって一度リリースして安定してから実施する場合もあります）

プランについてですが、ただ通常の運用系広告やSNS広告を出稿するだけなら比較的柔軟に調整が出来ます。
しかし、TVCMやOOH、各種ジャック系の広告、Twitterのテイクオーバー系など（タイムラインやトレンドの上部に出るアレです）については各社が枠を取り合っており、基本的に全て自分たちが望むタイミングで実施することは難しいです。

https://business.twitter.com/ja/advertising/takeover.html

そんな中でプロモーション担当者はリリース日にアプリの露出（と費用対効果）が最大化するために複数の広告を組み合わせを調整して、最大化するタイミングでのプランを作ります。

ただし、これについては1の話と少し温度感が違い、リスクのある「開発の前倒し」を選択することは慎重に判断する必要があります。

感覚としては
1のストア掲載の調整は **「ピンポイントであり、次にチャンスは無い」**
2の広告プランは **「難しい場合は第2、第3の日程を組むことは可能」**
くらいの感覚を持っておくと良いと思います。


## 最後に

以上、私が経験した中で2つの事例を紹介させて頂きました。

開発とプロモーション双方でリリース日について意見が対立することもあるかと思います。

しかし双方ともに「良いプロダクトを作って1人でも多くの人に届けたい」「事業としての機会を最大化したい」という目的は一緒なはずです。
そのための相互理解の一助になれば幸いです。
[AWS Q&A 365][StepFunctions]AWSのよくある問題の毎日5選 #78

# 1. AWSステップファンクションとは何ですか？
答え：AWSステップファンクションは、ビジュアルワークフローを使用して分散アプリケーションとマイクロサービスを調整することを可能にするサーバーレスのワークフローサービスです。

# 2. AWSステップファンクションの主要な概念は何ですか？
答え：AWSステップファンクションの主要な概念には、状態、ステートマシン、入出力処理、エラーハンドリング、および実行履歴が含まれます。

# 3. AWSステップファンクションの標準ワークフローとエクスプレスワークフローの違いは何ですか？
答え：AWSステップファンクションの標準ワークフローは、数日、数週間、あるいは数ヶ月にわたって実行可能な長期間の耐久性のあるワークフローのために設計されています。一方、エクスプレスワークフローは、数秒から数分間実行できる短命でイベント駆動型のワークフローのために設計されています。

# 4. AWSステップファンクションの実行保証は何ですか？
答え：AWSステップファンクションは、状態遷移に対する強い一貫性の保証を提供し、ステートマシンが入力ごとに一度だけ実行されることを確保します。

# 5. AWSステップファンクションのエクスプレスワークフローを使用してコストを最適化する方法は何ですか？
答え：AWSステップファンクションのエクスプレスワークフローは、長期間稼働するワークフローインスタンスの実行と管理のオーバーヘッドを削減することでコストを最適化するのに役立ちます。エクスプレスワークフローは、ワークフローインスタンスの持続時間ではなく、ステート遷移の数に基づいて請求されます。
[AWS Q&A 365][StepFunctions]Daily Five Common Questions #78

# 1. What is AWS Step Functions? 
Answer: AWS Step Functions is a serverless workflow service that enables you to coordinate distributed applications and microservices using visual workflows. 

# 2. What are the key concepts of AWS Step Functions? 
Answer: The key concepts of AWS Step Functions include states, state machines, input/output processing, error handling, and execution history. 

# 3. What are the differences between standard and express workflows in AWS Step Functions? 
Answer: Standard workflows in AWS Step Functions are designed for long-running, durable workflows that can run for days, weeks, or even months. Express workflows, on the other hand, are designed for short-lived, event-driven workflows that can run for seconds or minutes. 

# 4. What are the execution guarantees of AWS Step Functions? 
Answer: AWS Step Functions provides strong consistency guarantees for state transitions and ensures that state machines only execute once per input. 

# 5. How can you optimize costs using express workflows in AWS Step Functions? 
Answer: Express workflows in AWS Step Functions can help optimize costs by reducing the overhead of running and managing long-lived workflow instances. Express workflows are billed based on the number of state transitions, rather than the duration of the workflow instance.
WSL2で32bitバイナリをビルドー＞デバッグする（C言語）

#### インストール
gcc-multilib, g++-multilib, gdb-multiarchをインストールする。
```
apt install gcc-multilib
apt install g++-multilib
apt install gdb-multiarch
```
#### ビルド
-m32を付与すればOK。
```
gcc -m32 -o hoge hoge.o
```

#### デバッグ
アーキテクチャを指定してデバッグ！
デバッグ自体はruすればできるので割愛する。
```
gdb hoge
(gdb) set architecture  i386
```

#### 課題
pでp memset(Hoge_area,0,sizeof(Hoge_area))すると
「'at 0x……00' has unknown return type; cast the call to its declared return type」とエラーになる。  
この対処はp (int)memset(Hoge_area,0,sizeof(Hoge_area))すれば解決するが、もっと正しい解決方法あると思われる。
分かったら追記するかな…。
【ChatGPT無】、君の中で、文章はどう扱われているの？

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::
　どうも、カーブミラーです。

　今回は、
　　「ChatGPT内で、
　　　プロンプトの文章は、
　　　　どういう風に
　　　　　扱われているのか？」です。

　みなさんが入力したプロンプトが、
　　ChatGPTに
　　　どのように
　　　　受け入れられているのか。

　入力される
　　プロンプトの多くは、文章です。
　　　一文を「。」まで入れて
　　　　改行しますよね。

　　　場合によっては、
　　　　空白行を入れたり、
　　　　　一文を私みたいに
　　　　　　段々に入力したり。

　これを受け取ったChatGPTは、
　　ムダな空白を削除し、
　　　改行を削除して、取り込みます。
　　　　また、文章の最後に
　　　　　必要な記号（。？など）を
　　　　　　追加します。

　このことは、入力した文章を
　　出力させてみて、わかりました。

　ただし、
　　全文をまとめているわけではなく、
　　　段落は理解している、とのこと。

　以下が、ChatGPTさんの説明です。
>はい、段落で入力された文章もまとめて受け取り、処理することができます。
>
>私は文章の解析や生成において、文脈や意味の理解を行います。段落に区切られた文章を処理する場合でも、各段落の文章を個別に扱うのではなく、文章全体の文脈を考慮して応答を生成します。
>
>つまり、入力された段落の文章をまとめて処理し、それに基づいて回答を生成することができます。段落ごとに切り分ける必要はありませんが、適切な文脈を保つために段落の情報は重要です。

　それから、こうも言っています。
>段落に関連する情報を明示的に指定するためには、以下のような方法があります。
>
>1. 段落番号を付ける: 各段落に番号を付けて、質問や要望を特定の段落に関連付けることができます。例えば、「1. 質問内容」「2. 要望内容」といった具体的な番号を使って区別することができます。
>
>2. キーワードを用いる: 各段落の先頭に特定のキーワードを付けることで、その段落に関連する内容を示すことができます。例えば、「[質問] 質問内容」「[要望] 要望内容」といったように、キーワードを使って明示的に区別することができます。
>
>3. 文脈を説明する: 入力する文章の前後に、どの部分がどのような文脈や段落であるかを簡単に説明することもできます。例えば、「以下の段落は、それぞれ質問と要望に関する内容です」といったように、文脈を事前に説明することができます。
>
>これらの方法を使うことで、明確に特定の段落に対する質問や要望を伝えることができます。私はそれらの情報を利用して、適切な回答を生成するように努めます。

　また、
　　プログラムコードなどは、
　　　基本的に変更しないそうです。

　以下が、ChatGPTさんの説明です。
>一般的に、プログラミングのコードやテンプレートは厳密な構文に基づいており、正確な表現が重要です。そのため、私は入力されたコードやテンプレートを変更することなく、忠実に出力するよう設計されています。
>
>ただし、コードのシンタックスハイライトやインデントの整形など、表示上の装飾を行う場合は、それを適用することがあります。しかし、コードの意味や構造を変更するような変更は行いません。

　結論。
　ChatGPTさんは、
　　コードなどは別として、
　　　まとめて扱う、
　　　　ということです。

　言われてみれば、
　　当然ですね。

　ChatGPTさんは、
　　目で見ているわけでは
　　　ないのですから、
　　空白や改行の意味はない
　　　に決まっています。

　どうしても必要で
　　空白文字を使う場合は、
　　　「」や“”などで囲えば、
　　　　正しく扱ってくれますよ。

　では、今回は、ここまで。
<br>と<br />の違いについて

## 概要
ふと、Railsを使用している中でHTMLを記述していると`<br />`を見かけ、`<br>`との違いは何なのだろうと思ったので調べたものをまとめさせて頂きます。
先んじて説明させて頂きますと、**HTMLとXHTMLにおけるタグの使用方法の違いが、`<br>`と`<br />`の主な違いです**。

## `<br>`の使用

`<br>`は、HTMLにおける改行を表すタグです。HTML4.01やHTML5といった、より新しいバージョンのHTMLでは、開始タグと終了タグのペアを必要としない「空要素」として定義されています。

これは次のように使用されます。

```html
<p>これは一つの段落です。<br>これが新しい行です。</p>
```

使用に関しては、`<br />`も同様に使用できるのですが、[W3C](https://validator.w3.org/)では、**INFO**と表示されるので、一応使用しないことお勧めします。

https://oops0011.blog.fc2.com/blog-entry-679.html

## `<br />`の使用

一方、`<br />`は、XHTMLやXMLにおける改行を表すタグです。XHTMLやXMLでは、全ての要素が明確に閉じられている必要があります。そのため、`<br />`は自己終了（self-closing）またはボイド（void）タグとして表現されます。

これは次のように使用されます。

```html
<p>これは一つの段落です。<br />これが新しい行です。</p>
```

## 注意点

どちらの形式を使用するにしても、`<br>`タグは文章の間隔を空けるためのものであり、パラグラフの分割には適していません。新しいパラグラフを開始する場合は、適切な段落タグ（`<p>`）を使用することが推奨されます。

## まとめ

基本的に、HTMLドキュメントであれば`<br>`を、XHTMLやXMLドキュメントであれば`<br />`を使用します。


## 参考
- [<br /> じゃなくて <br> だよ #HTML - Qiita](https://qiita.com/irxground/items/dc3e688d7d48c01c3988)
- [`<br>`と`<br />`の違いは？どちらで書くべきなのか？ | Qumeruマガジン](https://qumeru.com/magazine/549)
- [`<br>`と`<br />`どっちを使えばいいの？ - code-snack - Medium](https://medium.com/@bbxxuw/br-%E3%81%A8-br-%E3%81%A9%E3%81%A3%E3%81%A1%E3%82%92%E4%BD%BF%E3%81%88%E3%81%B0%E3%81%84%E3%81%84%E3%81%AE-fdd271a9a145)
インスタンスメソッドとは

## インスタンスメソッド
:::note
オブジェクト指向プログラミングにおいて、クラスのインスタンス（オブジェクト）に対して実行される操作や振る舞いを表現するためのメソッド
インスタンスメソッドは、インスタンス変数にアクセスし、そのインスタンス固有の振る舞いを実現するために使用される
:::

インスタンスメソッドのできること

- クラス内に定義され、そのクラスのインスタンスに対して呼び出す
- インスタンス変数の値を読み取る、変更する
- 他のメソッドを呼び出す
- 計算をする
- 特定の操作を実行する

### インスタンスメソッドの使用例

```java
public class Person {
    String name;
    int age;

    public void sayHello() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

    public void celebrateBirthday() {
        age++;
        System.out.println("Happy birthday! Now I am " + age + " years old.");
    }
}
```
PersonクラスにはsayHello()とcelebrateBirthday()という2つのインスタンスメソッドが定義されている
sayHello()メソッド：インスタンスのnameとageの値を使用して挨拶文を表示
celebrateBirthday()メソッド：インスタンスのageを1つ増やし、誕生日のメッセージを表示

- インスタンスメソッドは、クラスのインスタンスに対して呼び出される
　　→各インスタンスごとに異なる結果を生成できる

- インスタンスの状態や属性にアクセスするためにインスタンスメソッドを使用し、インスタンス固有の操作や振る舞いを実現できる
viでファイル作成、ファイルの中身追加、エンコードSJISに変更、保存までやってみた

# はじめに
viでファイルをいろいろいじる機会がありましたので、記録用にまとめたいと思います。

# ファイルが存在するディレクトリまで移動
```
cd /xxx/xxx/xxx
```
※xxxはご自身のディレクトリのパスを入れてください。

# ファイル作成
```
vi xxxxx.csv
```
※今回はcsvファイルを例にします。

# ファイル編集
```
i
```
iコマンドで編集モードにしてから、中身を編集する。

# 編集から抜ける
```
Esc
```
Escボタンで編集から抜ける。

# エンコードをSJISに変更
```
:set fileencoding=shift-jis
```
※エンコードはSJIS以外もありますので、ご自身が変更したいエンコードを設定してください。

# ファイルを保存
```
:w
```

# 保存して終了
```
:wq
```

# 最後に
簡単にまとめましたが、誰かの参考になりますと幸いです。
インスタンス変数とは

## インスタンス変数

:::note
オブジェクト指向プログラミングにおいて、クラスのインスタンス（オブジェクト）ごとに独立して持つデータのこと
インスタンス変数は、**クラスの属性や状態を表現する**ために使用される
:::

インスタンス変数はクラス内のメソッドの外側で宣言
→そのクラスの各インスタンス（オブジェクト）に対して個別のデータを保持する

言い換えると、**同じクラスから生成された複数のインスタンスが存在する場合でも、それぞれのインスタンスは異なる値を持てる**

インスタンス変数は、通常、クラス内で属性や状態を表現するために使用される

EX)
Personクラスがあるとすると、nameやageといったインスタンス変数を定義することができる
各インスタンスは独自のnameやageの値を持ち、それぞれのインスタンスに対して異なるデータを格納することが可能


### インスタンス変数の使用例

```java

public class Person {
    String name; // インスタンス変数 name
    int age;     // インスタンス変数 age

    public void sayHello() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }
}
```

・Personクラス内でnameとageという2つのインスタンス変数を定義
　　→これらの変数は、各Personオブジェクトの状態を表している
・sayHello()メソッドでは、インスタンス変数の値を使用して挨拶文を表示


**インスタンス変数は、各インスタンスに対して異なる値を持ち、そのインスタンスの属性や状態を表現するために使用される**
ITパスポート合格体験記（非IT系文系卒）

# はじめに


実際の試験を受けてみました。試験約１か月前の出来具合は以下です

https://qiita.com/MasaruYamazaki/items/191beb366e48f4a3a4de

# テスト一週間前

その後

ITパスポート１週間前の正答率は

令和５年度は７８％でした。８割きってしまった。。。

けれどあきらめず対策を続けます。

このように正答率の低い分野や年度がある場合集中的に解きなおすのがおすすめです。

# 受験後

その後１週間程度たち・・・受験してきました！結果は合格点を超えておりました。よかった・・・。

公開問題よりは難易度は低く感じました。公開問題をできるようにしておけばIT系は怖くないのでは。

文系非ＩＴ系卒が基本情報技術者を3年前に受けようと思ってからITパスポートを受験し合格点を取るまで３年かかりました。基本情報を一回諦めました。それとかいろいろな考えの変化で受験をためらっていました。

もっと良い解説を求める検索能力や、よりよい講座を探す能力は実際に必要だと思って経験しないと力はつかないと思っています。少なくとも私はそうでした。だから予備校は価格は高いですが頻出問題やある程度の解説のわかりやすさがあるので、予備校の講座はとっかかりとしてよいかもしれません。私は資格予備校を使いませんでしたが。今後お世話になるかもしれないですね。

# 対策として行ったこと

対策として何をしたかを話します。ITパスポート新しい順に5年分を90％以上解けるようにしました。問題集の問題を３回以上解きなおしました。

類題を解きたいという方必見の情報があります。過去5年分のわからなかった語句をググりましょう。「ITパスポート　選択　射影」「過去問　選択　射影」などITパスポートや過去問という語句と合わせてググると違う解説が見られることがあります。古い問題の類題も見れたりするので頻出がどうかわかります。中には3回以上出てくるものもあります。

Google Bardに英語で語句を説明してもらうこともやっていました。

# 試験当日の注意点

①試験当日、PCで受験する方式なことはお分かりかと思います。ア～エの選択肢をピンポイントでクリックして回答するのが地味に大変で慣れませんでした。これは練習しても本番で受けるPCは自分のPCを使えないので、覚悟しておく必要があります。
②もう一つ試験中大変だったことがあります。見直しをするのではなくその場で解答解説を見れる状態で試験対策をしていました。そのため、見直しをしているといつもと違うと思ってしまい少し焦りました。見直しをして１００問をもう一度見直す練習もしておいた方が良いかもしれません。
Roomを使って検索履歴を残す

# 初めに
今回はRoomを使ってローカル用の検索履歴機能を実装していこうと思います
### 本文
まず初めにデータベースを作ります
```kotlin: Database.kt
@Database(
    version = 1,
    entities = [
        SearchHistoryEntity::class
    ]
)
abstract class SearchDatabase: RoomDatabase() {
    companion object {

        const val DB_NAME = "search.db"
    }
    abstract fun SearchDao(): SearchDao
}
```
次にデータを格納するためのEntityクラスを作っていきます
```kotlin:Entity.kt
@Entity(tableName = "search_history")
data class SearchHistoryEntity(
    @PrimaryKey
    @ColumnInfo(name = "search_word")
    val searchWord: String,
)
```
最後にデータの読み書きをするためのDaoを作っていきます
```kotlin:Dao.kt
@Dao
abstract class SearchDao {
    @Query("SELECT * FROM search_history ORDER BY search_word")
    abstract fun getSearchWords(): List<SearchHistoryEntity>

    @Insert(entity = SearchHistoryEntity::class, onConflict = OnConflictStrategy.IGNORE)
    abstract fun insert(searchWord: SearchHistoryEntity)

    @Query("DELETE FROM search_history WHERE search_word = :searchWord")
    abstract fun deleteLastSearchHistory(searchWord: String)
}
```
`onConflict`を`IGNORE`にした場合は同じ要素が来たときに無視するようになりますが、置換したい場合は`REPLACE`を使ってください
また、今回は特定のものを削除したい場合の書き方をしていますが、全件削除をしたい場合は`@Query`の内部を下記のようにしてください
```kotlin
DELETE FROM search_history
```
これで準備は完成したのでDIをしていきます
```kotlin:DI.kt
@Provides
    @Singleton
    fun providesSearchDatabase(
        application: Application,
    ): LeafletSearchDatabase = Room.databaseBuilder(
        application,
        SearchDatabase::class.java,
        SearchDatabase.DB_NAME
    ).build()
```
あとは`Repository`などを作って下記のように呼び出し処理を書いてあげれば完成です
```kotlin:Repository.kt
private val dao by lazy { database.SearchDao() }

    override fun getHistories(): List<String> {
       return dao.getSearchWords().map { it.searchWord }
    }

    override fun saveHistory(searchWord: String) {
        val entity = SearchHistoryEntity(searchWord = searchWord)
        dao.insert(entity)
    }

    override fun deleteLastSearchHistory(searchWord: String) {
        dao.deleteLastSearchHistory(searchWord)
    }
```
### 最後に
今回ローカル保存用のデータベースをRoomで実装したので備忘録用に残しておきます
どなたかのお役に立てれば幸いです
VSCodeを開くたびにGitHubの認証を求められるようになってしまった（Jira and Bitbucket (Atlassian Labs)も）

GitHub Copilot Nightly（chat）を利用したくて VSCode insider をインストールしたら、VSCodeを起動するたびに「Sign in to use GitHub Copilot.」と表示され、なおかつ、Accountタブも未連携のまま「Sign in Sync Setting」をクリックしないと同期できなくなってしまった。

また、同じようにJira and Bitbucket (Atlassian Labs)も「cannot get client for: Bitbucket」となってしまい、全く使えなくなってしまった。


解決にかなり時間がかかってしまったので備忘録を残しておく。

## 対応1 VSCodeをアンインストールしてキャシュを削除後、最新版のInsiderをインストールする

多くの場合はこれで解決する（らしい
私は解決しなかった。
ググるとほとんどこの内容しか出てこない。

## 対応2 ログアウト → 再ログイン

Copilotで「Your GitHub token is invalid」が表示されるときの対処法。
Tokenを更新する作業だが、これでも治らず。


## 対応3 登録済みの資格情報を削除する

さて、どうしたもんかと、ログ（`Ctrl + Shift + P` → `open log file` → `GitHub Authentication`）を漁ってみると、やはり認証に失敗している（Got 0 sessions for～みたいのが出ている）

そこで「github authentication error」で探すと以下の記事が

https://stackoverflow.com/questions/71558011/visual-studio-code-authentication-error

コントロールパネルから資格情報マネージャを開き、「vscode-insidersvscode.github-authentication...」の資格情報を削除し、再度VSCodeからログインしてみると・・・できた！

これはつまり、Bitbucketも同じなんじゃないかと「atlascode-insiders-authinfo...」を削除して再度ログインすると・・・できた！

## 現象が発生するのは一部の環境だけみたい

私の別のPCでは全くこのようなことが起きず、問題なく利用できたので、**VSCode Insderをインストールした時期により発生する可能性がある**と見ている。
現象が発生した端末は5/22にインストールしたもの。
発生しなかった端末は6月に入ってからインストールしたもの。

モノが資格情報に入るため、アンインストール → 再インストールでも消えずに残ってしまい、いつまでも解決できずに毎回サインインするという面倒くさい作業をしていたが、やっとスッキリした。

クリーンインストール時に拡張機能や設定もまるっと消えてしまったりして、なおかつそれが同期されて正常端末も全部消えたりして、かなり悲しくなったので供養のために書いておく。

多分、10万人に1人くらいは同じ現象に悩むと思う。
【Query Builder：Expression】Try using IF statement

Today I will use the **IF** statement as a basic expression.
Start **Query Builder** from the application menu of [Sharperlight](https://sharperlight.com/).
Configure the filter settings as follows and prepare the custom dataset.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2cf7b06c-5c50-82ad-f840-96cc5ffb47df.png)
A preview returns a dataset like this.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a1cdc253-050e-4fc3-557d-0c550ea8e8d8.png)

Now let's write the **IF statement**. In Sharperlight, it's actually an **IIF statement**.
Select **Add Expression** from the right-click menu in the output area.
When the Output Options dialog opens, select `Functions` -> `Conditional` -> `IIF(ConditionGoesHere, TrueValue, FalseValue)` from the function list. You can transfer it to the editor area by double-clicking it.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0a2533a1-3ae8-7fd7-1aa3-de72f8a175cc.png)
Let's try using the Output Item: **Value** as the conditional value and set what to do when the condition is True or False. 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/dcd2e3e8-7e25-86e0-7b63-ef62008bf029.png)
Change the **Description** of the added `Expression` like this.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a138ad7f-ff4a-1f13-063c-eadc6f7a1a8a.png)
Preview now! !
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b3769f5e-b0b2-b98f-59b5-6fada7e55cd7.png)
This is the basic usage of the **IIF** statement.
The **IIF** statement can be **nested**, so I think it would be useful for more complex conditional requirements.

I hope this will help your work.
【SwiftUI】Appleミュージックみたいにスワイプで閉じられるfullScreenCoverを作る方法


# はじめに
SwiftUIでfullScreenCoverを使うと、sheetのようにスワイプで閉じることができません。
この記事では、Pullerというライブラリを使ってAppleミュージックのようにスワイプで閉じられるfullScreenCoverを作成する方法を紹介します。

# デモ
https://twitter.com/shota_appdev/status/1668796583700496384?s=61&t=vwrC4-Hv1w9XOYSsdCSyog

# 準備
PullerをSwift Package Managerでインストールします。
https://github.com/zsergey/Apple-Inspired-Puller

# 使い方

```swift
import Puller

struct ContentView: View {
    @State private var isPresented = false
    
    var body: some View {
        Button("Show") {
            isPresented.toggle()
        }
        .puller(
            isPresented: $isPresented, 
            model: PullerModel(detents: [.full])) 
        {
            Text("Hello, world!")
        }
    }
}
```

基本的な使い方は、fullScreenCoverと同じです。
PullerModelのdetentsで、custom, medium, large, full, fitsContentからサイズを指定することができます。
ここではfullを指定します。
これで、Appleミュージックのようにスワイプで閉じられるfullScreenCoverが完成しました！

# まとめ
Pullerを使うと、Appleミュージックのようにスワイプで閉じられるfullScreenCoverを簡単に作ることができます。
ぜひ、試してみてください！
インスタンスって何

## インスタンス

:::note
オブジェクト指向プログラミングにおいて、クラスを基にして具体的なオブジェクトを生成したもの
クラスはオブジェクトの設計図であり、実際にメモリ上に存在するデータはインスタンス
:::

具体的には、クラスを元に作成されたオブジェクトのことをそのクラスのインスタンスと呼ぶ
クラスが設計図であるのに対し、インスタンスは設計図に基づいて作られた実体

EX)
Personというクラスがある場合、Personクラスから生成された個々のオブジェクトはPersonクラスのインスタンスとなる

インスタンスは、クラスの属性（フィールド）や操作（メソッド）にアクセスすることができる
各インスタンスは独自の状態（属性の値）を持ち、独自の振る舞い（メソッドの呼び出し結果）を示す

EX)
Personクラスのインスタンスでは、nameやageといった属性にアクセスし、sayHello()といったメソッドを呼び出すことができる

インスタンス化は、newキーワードを使用して行う


```java
Person person1 = new Person(); // Personクラスからインスタンスを作成
Person person2 = new Person(); // 別のPersonクラスのインスタンスを作成

person1.name = "Alice"; // person1の属性に値を設定
person2.name = "Bob";   // person2の属性に値を設定

person1.sayHello(); // person1のメソッドを呼び出す
person2.sayHello(); // person2のメソッドを呼び出す
```

Personクラスからperson1とperson2という2つのインスタンスを作成
それぞれの属性を設定し、メソッドを呼び出している
それぞれのインスタンスは独立して存在し、個別のデータと振る舞いを持っている
AWS LambdaでSystem Manegerのパラメータから情報を取得したい(Node.js 18)

## はじめに

AWS Lambda(Node.js 18)で、System Manegerのパラメータストアのデータを取得しようとして苦戦したので備忘録として残しておきます。
以下System ManegerはSSMと表記します。
## 実装方法
結論です。以下のようなコードを書くことで実装できます。
```js
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";

export const handler = async (event) => {
    const ssmClient = new SSMClient({ region: 'ap-northeast-1' }); 
    const command = new GetParameterCommand({
        Name: '/test/hoge',
        WithDecryption: true,
    });
    const parameterStore = await ssmClient.send(command);
    console.log(parameterStore.Parameter.Value);
};
```

簡単に解説していきます。
```js
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
```
Node.js 16以前では`const AWS = require("aws-sdk");` のように記述していましたが、18以降ではimportで書きましょう。



```js
const ssmClient = new SSMClient({ region: 'ap-northeast-1' }); 
```
ap-northeast-1のSSMパラメータストアに埋まっている場合上記のような引数の指定が必要です。

```js
const command = new GetParameterCommand({
    Name: '/test/hoge',
    WithDecryption: true,
});
```
`Name`でSSMパラメータストアの名前を指定できます。この場合、`/test/hoge`という名前で埋まっているSSMパラメータストアのデータを取得します。
`WithDecryption`で暗号化されたデータを複合するかを指定できます。`true`の場合複合します。

```js
const parameterStore = await ssmClient.send(command);
console.log(parameterStore.Parameter.Value);
```
上記の記述でSSMパラメータストアのデータを出力できます。`await`を記述しないと出力に失敗するため注意しましょう。

## 参考記事
[async/await 入門（JavaScript）](https://qiita.com/soarflat/items/1a9613e023200bbebcb3)

## 終わりに
これでSSMのパラメータストアの値を自由自在に使うことができます。最高ですね。
セキュリティのためにも秘密情報などはできるだけLambda上に直接記述することは避け、SSMパラメータを使っていきましょう。
【メモー】要件定義やること

# はじめに

皆さん、こんにちは。
最近、要件定義の作業に関与しています。各案件により違いはあると思いますが、要件定義の一連のプロセス、それぞれのプロセスの目的、そしてその成果物を図にまとめました。

# 図

![要件定義.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343120/46da8aba-5046-90f6-abda-df830bf61016.png)