OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Lambdaレイヤーをローカル環境で構築する方法（Python）

# AWS Lambdaレイヤーをローカル環境で構築する方法（Python）

## はじめに
この記事では、Pythonを用いてAWS Lambdaレイヤーを作成し、ローカルでのLambda環境のコンテナを構築し、そこでレイヤーを作成してS3にプッシュする方法について説明します。

## 目次
１．AWS Lambdaレイヤーとは
２．前提条件
３．ローカルでのLambda環境の構築
４．Lambdaレイヤーの作成
５．LambdaレイヤーのS3へのプッシュ
６．Lambda関数でのレイヤーの利用
７．おまけ

## １．AWS Lambdaレイヤーとは
AWS Lambda Layerは、Lambda環境下おいて共有ライブラリ、依存関係、その他のカスタムランタイムコンポーネントを管理するための機能になります。これらの共有コンポーネントをLambda関数から分離することにより、コードの管理と再利用を容易にすることができ、効率的な開発を実現することができます。

## ２．前提条件
AWS　Lambdaレイヤーを構築する際には、Lambdaと同じランタイム環境での構築が必要となります。これは、ローカル環境で構築すると「バイナリ互換性」や「 実行環境の整合性」などで問題が発生する可能性があるためです。
このLambdaのランタイム環境としては、AmazonLinuxが利用されているため、EC2インスタンスを立ち上げて、レイヤーを作成することも可能ですが、今回はより手軽にローカルでコンテナを立ち上げてレイヤー構築を実施する方法をご紹介します。

## ３．ローカルでのLambda環境の構築
Dockerリポジトリからlambda環境のイメージをプルします。
```
docker pull public.ecr.aws/lambda/python:3.8
```
コンテナを起動して、コンテナ内にアクセスします。
```
docker run -it --entrypoint /bin/bash public.ecr.aws/lambda/python:3.8
```

## ４．Lambdaレイヤーの作成
今回はPyMuPDFという PDFのデータ抽出や変換を行うライブラリを題材として、レイヤーを作成します。
まず、任意のパスに`python`ディレクトリを作成します。
```
mkdir /path/to/layer/python
```
`python`ディレクトリは、Lambdaがパッケージを認識するために必須となるため注意してください。

ライブラリをインストールします。
```
pip install PyMuPDF -t /path/to/layer/python
```

パッケージ化するため、`zip`をインストールします。
```
yum insatll zip
```

レイヤーのパッケージングを実施します。
```
cd /path/to/layer
zip -r lambda_lauer.zip .
```

## ５．LambdaレイヤーのS3へのプッシュ
Lambdaレイヤーはローカルからでもアップロードできますが、容量に制限があるため、S3を利用する方法が推奨されます。
今回はコンテナから直接S3へアップロードする方法で実施します。

まず、レイヤー用のS3バケットを作成します。
S3バケットはAWSの全リージョンで一意の名称を付与しないといけないので、注意してください。
![スクリーンショット 2023-12-04 22.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629574/b6acde32-20e9-fe22-30f7-1957eecc78a3.png)

次にコンテナでAWS CLIを利用可能にするため、下記のコマンドを実行します。
```
pip install awscli
aws --version
```

awscliが無事にインストールされたら、認証情報を設定します
```
aws configure

※下記の内容を問われますので、環境に合わせて変更してくだしさい。
AWS Access Key ID [AWSアクセスキーを入力]: 
AWS Secret Access Key [AWSシークレットアクセスキーを入力]: 
Default region name [使用リージョンを入力]:
Default output format [出力形式を入力]: 
```

認証情報を設定完了後、AWS S3へアップロードを行います。
```
aws s3 cp lambda_layer.zip s3://your-bucket-name/
```

![スクリーンショット 2023-12-04 23.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629574/ec8bc5d4-9b7b-0c80-bb30-dbe7ad310f27.png)

## ６．Lambda関数でのレイヤーの利用
コンソールからLambdaを選択して、レイヤー作成画面に遷移します。
アップロード方法として、「AmazonS3からファイルをアップロードする」を選択し、S3から該当するレイヤーのオブジェクトURLを貼り付けます。
![スクリーンショット 2023-12-04 23.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629574/20b3a050-8f51-6db9-34d9-8d2c3ffbde2f.png)

レイヤーを作成後は、Lambda関数の「コード」タブの最下部にある、レイヤーの追加を押下し、カスタムレイヤーを選択し、先ほど作成したレイヤーを設定します。
![スクリーンショット 2023-12-04 23.19.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629574/c177fb27-fc82-decb-d478-e674e110571d.png)

以上でLambda環境でLambdaレイヤーが使用できるようになりました。
EC2を立ち上げてレイヤーを構築する方法よりは効率的だと思いますので、活用してみてください。
今後Lambdaレイヤーを利用される方の参考になれば幸いです。

## ７．おまけ
上記ではローカルでコンテナを立ち上げてLambdaレイヤーを立ち上げる方法を紹介しましたが、よく使用されるライブラリなどは有識者の方がARNとして用意していてくれたりします。
構築内容にもよりますが、用途によってはこのように既に構築されているものを利用することも、効率的かもしれません。
下記のURLより確認できますので、よろしければ確認してみてください。
https://github.com/keithrozario/Klayers/tree/master/deployments
以上、記事をご覧いただき、ありがとうございました。
多次元配列の勉強

配列に関する問題集を解きながら多次元配列の勉強。
一番下の部分は列・行の定義をしっかりしておかないと
混乱しそう。。。

```py
A = [[1,2,3],[4,5,6],[7,8,9]]
#多次元配列の行数の算出
print(len(A))
#多次元配列の列数の算出
print(len(A[0]))
#各行の行数の出力
for i in range(len(A)):
    print(len(A[i]))
#配列i行目j列目の出力
print(A[i-1][j-1])
#各行各列の折返し出力
for j in range(len(A)):
    for i in range(len(A[j])):
        print(A[j][i],end="")
        
        if i < len(A[j])-1:
            print(end=" ")
        else:
            print()
n をやめて Volta にする

今まで node のバージョンを `n` コマンドで管理していましたが、ナウいパッケージ管理ツールを見つけたので乗り換えることにしました。

https://volta.sh/

# インストール
公式で書いてある通りにします。
```shell
curl https://get.volta.sh | bash
```
ターミナルを再起動します。.bashrc に勝手にパスを書いてくれるので、次回起動時に `volta` コマンドが使えるようになっています。
他にも `zsh` や `fish` でも自動インストールできるようになっています。便利！

# セットアップ

### 補完
そのままだとコマンド補完が効かないので、補完の設定をします。

Volta はコマンド補完のための設定を `volta` コマンドから生成できるように作られています。
雑には次のコマンドを実行してターミナル再起動すれば補完が効くようになります。

```shell
volta completions bash >> ~/.bashrc
```

### node
以下のコマンドで node18 が入ります。
```shell
volta install node@18
```

### yarn
yarn も簡単に入ります。
```shell
volta install yarn
```

# バージョン管理
```shell
$ volta list
⚡️ Currently active tools:

    Node: v18.19.0 (default)
    Yarn: v4.0.2 (default)
    Tool binaries available: NONE
```

volta の面白い点は、これらのツールのバージョンを `package.json` に書いておける点です。

node20 を使うプロジェクトを yarn でセットアップし、このプロジェクトでは node20 を使うよう制約します。

```shell
~/node-20-playground$ volta install node@20
success: installed and set node@20.10.0 (with npm@10.2.3) as default

~/node-20-playground$ volta run yarn init
➤ YN0065: Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry
➤ YN0065: Run yarn config set --home enableTelemetry 0 to disable

➤ YN0000: · Yarn 4.0.2
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 113ms

~/node-20-playground$ volta pin node
success: pinned node@20.10.0 (with npm@10.2.3) in package.json

~/node-20-playground$ volta pin yarn
success: pinned yarn@4.0.2 in package.json
```


node18 をデフォルトで使うように戻してから、node20 を使うようにしておいたディレクトリでパッケージバージョン確認をすると、無事に node20 が使われるようになっています。

```shell
~$ volta install node@18
success: installed and set node@18.19.0 (with npm@10.2.3) as default

~/node-20-playground$ volta list
⚡️ Currently active tools:

    Node: v20.10.0 (current @ ~/node-20-playground/package.json)
    Yarn: v4.0.2 (current @ ~/node-20-playground/package.json)
    Tool binaries available: NONE
```

package.json をプッシュしておけば同じプロジェクトの他のメンバーも同じパッケージバージョンで開発できます。

# おわり
`n` も名前かっこよかったですが `volta` もかっこいいですね。
[実験手法] プログラムのインストールが必要ないPCR増幅領域の調べ方

# きみ、どこの遺伝子領域を増やそうとしてるの？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/b0fd1d32-8e62-18e9-9c50-903dde82ac67.png" width=600>

遺伝子工学的な実験を行う時に、PCRをよく使います。筆者のようなバクテリアを取り扱う人なんかは、PCRがなければできないことは多いでしょう。

PCRをやり始めた時に最初に躓くのは、増幅領域とバンド長の計算です。どうやって測ればいいのか、わからない人は多いでしょうし、ネットを調べても簡単にはわかりません。研究室ごとに代々伝わるやり方があるとは思います。しかし、独学の方々は・・・、なかなか難しいものです。

そこで、本記事では筆者なりのPCR増幅領域の調べ方を紹介します。プログラムのインストールがないので、どのパソコンでもできるはずです。
# 目次
調べる際に必要な情報は以下の二つです。それぞれの取得方法を説明します。
1. primer配列
1. テンプレートDNAの配列
1. Primer-BLAST

## primer配列の取得
読者の方々で作成したprimerの配列情報があれば大丈夫です。
本記事では例として、緑膿菌の外膜タンパク質遺伝子oprDを増やすprimerを用います。今回は適当に作った仮プライマー（本当に適当です）を使って増幅場所を探します。
| primer| sequence (5'->3') |
| ---- | ---- |
|F-primer|CGTTGCCGCCAAGAAGAAAA|
|R-primer|GGCACTGTGATGGCAGAGAT|

## テンプレートDNAの配列
まずは、ゲノムの取得できるページに移ります。NCBIにデータはあるので、それの取得方法を説明しましょう。今回使うのは緑膿菌PAO1のゲノムですので、NCBIのサイトに飛んで、タブを`Nucleotide`に変えて`PAO1`か、もしくはアクセッション（AE004091.2）を入力します。アクセッションの方が早く飛べます。

以下の写真のページに飛べましたか。飛べたら、大きく太字で書かれた株名の下に`Graphics`というタブがあります。そちらをクリックしてください。
![スクリーンショット 2023-12-05 16.54.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/e2b58a4f-d39d-73fa-cbe6-cb03ee8363ce.png)

こちらの画面に飛んだと思います。こちらは、ゲノム情報が視覚されたもので、どこにどの遺伝子があるかヴィジュアライズされたものです。写真の矢印にあるタブに、目的の遺伝子を入力します。今回は`oprD`です。
![スクリーンショット 2023-12-05 16.55.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/07728789-1968-2f2c-08c3-a316d9865a07.png)

ヒットすると以下のウインドウが出るので、遺伝子名をクリックしてください。
![スクリーンショット 2023-12-05 17.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/db51b7a9-72c5-8ca7-97f9-40f6b6af69a9.png)

クリックすると、図が変わったと思います。クリックした遺伝子の領域が拡大されました。今回は遺伝子周辺にもprimerがつくか調べたいので、図を縮小（広域）します。ズームアイコンのマイナスボタンを一回押してもらえれば十分です。
![スクリーンショット 2023-12-05 17.00.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/dda8ae9b-def7-7303-04ff-d5d12fdce207.png)

最後に、表示された範囲の遺伝子情報をダウンロードします。
四角で囲まれた箇所をクリックすれば、FASTAファイルが取得できます。
以上によって、テンプレートDNAの情報がゲットできました。
![スクリーンショット 2023-12-05 17.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/67059966-24c0-f0e8-a33f-3319217ad1ad.png)

## Primer-BLAST
最後に増幅領域を調べます。`Primer-BLAST`と検索してみてください。
こちらの画面が出たと思います。①にテンプレートDNAのファイルをアップロードして、②にprimerの配列を入力し、③のチェックを外してください。スクロールして`Get primers`をクリックすればOKです。
![スクリーンショット 2023-12-05 17.11.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/2729eba5-4187-b2de-89ad-8fce2889eaa5.png)

![スクリーンショット 2023-12-05 17.11.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/b32a8df8-c6d4-2a03-3fe5-354ba08df32f.png)



出てきた結果に増幅される領域が表示されます。テンプレートDNAと参照して、場所を決めましょう。また、増幅されるサイズ④も表示されます。こちらを電気泳動等の結果と照らし合わせればよろしいかと。
![スクリーンショット 2023-12-05 17.13.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519906/c1c322e3-6dec-132b-c2f1-8fc651ec1c0d.png)

# 終わりに
PCRの増幅領域の調べ方は、意外にネットに載ってないものでした。プログラムのインストールの必要ないものを紹介しましたが、PCRを何回もする方は、プログラムを使ったやり方がいいかなと思います。そちらに関しては、または別記事で紹介します。

お疲れ様でした！
初めてIT業界に飛び込んだ人事のエンジニア採用日記

## はじめに
初めまして。
リンクラフト株式会社で人事（主に採用）をしています、ミナミと申します。
この度、[Lincraftアドベントカレンダー](https://qiita.com/advent-calendar/2023/lincraft)の18日目を担当することになりました。

最初にお伝えすると、私はエンジニアではないので技術に関する話は一切でてきません。
それでもご興味をお持ちいただけたら、読み進めていただけると嬉しいです！

早速ですが、まずは私の自己紹介から失礼します。

リンクラフトに転職してきたのは今年の4月。
1社目では求人関連の広告代理店で営業を、
2社目では建設関連の派遣会社で人事を、
そして3社目が当社。

つまり、IT業界歴は8ヶ月ちょっとです。

当社に入社するに至った経緯はまたいつか、機会があればお話したいと思います(笑）

## 入社直後
それではここから、この8ヶ月間で私がどんなことをやってきたかを書いていこうと思います。

IT業界未経験な私、入社直後からIT業界の洗礼を受けまくりました。
とにかく、みんなが何を言っているのか分からない。
呪文を唱えているようです。

どれくらいのレベルかと言うと、
「JavascriptってJavaの略でしょ？」
「Git……？じっと？」
「Amazonって通販以外になんかやってるの？」
って感じです。

もちろん今記事を書いている「Qiita」なんてのはこれまでの私の人生に1度も出てきてません。

ヤバい業界に入ってしまったかもしれないと思いました。
面接で「IT業界の知識はいらないよ！」と言っていた社長のことを大ウソつきだと思いました。

## 入社3ヶ月くらいまで
そんなわけで入社後しばらくは毎日必死でした。

それでもありがたいことに応募はきます。
とにかくたくさんの人と面接をして、知らない単語が出てきたら都度調べる。
頭がパンクしそうな日々がしばらく続きました。

そんな私を救ってくれたのが、一緒に働くリンクラフトの人たちです。

大ウソつきだと思った社長は、つきっきりに近い形で会社のことや業界のことを何から何まで教えてくれました。
エンジニアさんたちは、「インタビューをさせてほしい」という依頼に嫌な顔ひとつすることなく時間を取ってくれました。（ほとんど話したこともないのにです。優しすぎる。）

なんて温かい会社なんだ…とじんわりきていたのはここだけの話です。
（転職成功かも、と内心ガッツポーズだったのもここだけの話です。）

## 入社半年くらいまで
入社3ヶ月を過ぎたくらいで新しい環境にはだいぶ慣れました。
呪文のようだった専門用語も、なんとなく聞こえるようになってきました。

そうとなれば、やることは山積みです。

ちなみにこのタイミングでお話しておくと、私の入社前後で当社の採用体制には大きな変化がありました。

ーーーーーーーーー
私が入社する前：社長がほぼ一人ですべてを担当
私が入社した後：私+エンジニアで構成される採用チームを新たに作り、社長は実務から離脱
ーーーーーーーーー

これまで社長が構築してきたやり方を踏襲しながら、日々変わり続ける採用市場に適応していく力を作り上げていく必要があります。

これがなかなか大変でした。
というか今も大変です。
現在進行形でPDCAを回し続ける毎日です。

## 現在
そんなこんなであっという間に時が過ぎ、今に至ります。

最近はある程度「型」もできてきて、採用チームとしても安定感（？）が生まれてきたような気がしています。
（これを読んでる社長および採用チームの方、「そんなことねーよ」と思っていたらごめんなさい。）

当社に興味を持ち、応募してくれた方が一番最初に接点を持つのは私です。
私がどんな対応をするかで応募者の方が抱く印象は大きく変わると思っています。

だからこそ、機械的でマニュアル通りの対応は絶対にしないと決めてます。
これは営業をしていた時からずっと変わりません。

人間味にあふれ、親しみやすい。
そんな人事を目指してこれからも頑張っていきたいと思います。

てことで、ご応募お待ちしています♡(笑)

## おまけ
私、広報もやってます！
SNSの運営もしてるので、ご興味ある方は覗いてみてください！
Instagram：https://www.instagram.com/lincraft.inc/
X（旧Twitter）：https://twitter.com/lincraft_inc

## 最後に
### 一緒に働く仲間を募集中です！
リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。
面白いHPの会社3選

## 面白いホームページを作りたい
ホームページを作るにあたって　見やすさ・印象に残るか　は重要なポイントだと思います。

せっかく作るなら、よりたくさんの人に見てもらえるような印象に残るホームページを作りたいですよね。

でも、「どうやったら印象に残るのか分からない！」と思う方にオススメのホームページを紹介します。

少しでも参考になれば幸いです。
## TBWA\HAKUHODO
![TBWAHAKUHODO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635412/4d5077ea-1a54-650f-8440-e9765626c41f.png)
ホームページ→https://www.tbwahakuhodo.co.jp/

TBWA\HAKUHODOさんは、東京都港区に本社を置く外資系総合広告代理店です。

ホームページ全体が斜めになっていて最初に見た時の衝撃が強く感じました。※見ずらい方用にページの一番下に水平に戻すボタンがありました。

斜めにする工夫で印象に残るいいホームページに感じました。![TBWAHAKUHODO2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635412/e35db16b-cfed-3721-1b75-5f4706977366.png)
F12 または 左クリック→検証 でこのようなプログラムを閲覧することができます。
## 株式会社LIG(リグ)
![liginc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635412/580eca56-255f-a97d-0b80-66d90d6bcf77.png)
ホームページ→https://liginc.co.jp/

株式会社LIG(リグ)さんは、システム開発・Web制作・マーケティング支援を中心に、グローバルリソースを活用したDX支援を行う会社です。

大きな文字に加えて、ページをスクロールするたびに変わる背景の映像に魅了され、印象に残ります。
## KINCHO
![kincho.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635412/b4ab92d1-0c4c-371a-b370-30c043fdd8bb.png)
ホームページ→https://www.kincho.co.jp/yayoi/index.html

大日本除虫菊株式会社(KINCHO)さんは、大阪府大阪市西区土佐堀に本社を置く、殺虫剤など衛生薬品の製造・販売をおこなう日本の日用品メーカーです。

このページの面白いところは、ホームページの中に飛ぶ 蚊 をクリックで撃退することができることです。

ゲーム感覚で見るのもよし、蚊取り線香の歴史を閲覧することもできる非常に印象に残るホームページだと思います。
## まとめ
他会社の印象に残るホームぺージをもっと紹介したいですが、投稿日が迫ってきて苦しくなってきたので3社で紹介を終えたいと思います。(日清さんもオススメ)

私もホームページに限らず、紹介したもののような印象に残るものを作りたいと思いました。

閲覧ありがとうございます！
EBSボリュームを増やした後のパテーション/を変更する方法コマンドメモ

EBSのボリュームを増やして


df -h

#ファイルシステムの状態を確認
lsblk

#パーティションの拡張
sudo growpart /dev/nvme0n1 1

#ファイルシステムの状態を確認
lsblk

df -hT

#ファイルシステムの拡張
sudo xfs_growfs -d /

df -hT
ICカードやバーコードリーダを用いたシステム連携


## ◆制作学習のきっかけ
アワードの発表を見据えて以下の意見が出たのでそれに沿って制作学習を実施
 ・PowerShellを使ってみたい
 ・書籍管理(DB＆アプリ)システムを作ってみたい
 ・RFID読み取りシステムを作ってみたい
 ・会社説明会＆インターンで使えるものを作ってみたい
 ・AIを使ってみたい
 ・3Dモデルを作ってみたい
 ・ICカードを使用したシステムを作ってみたい
 上記意見の中から下記2点を制作学習することに決めました。
 ICカードを使用したシステムの作成/書籍管理(DB＆アプリ)システムの作成

## ◆体制

下記メンバーで担当を決めて作業を実施

全体統括/サポーター
　→担当　3人
社員証のシステム
　→担当　4人
書籍管理システム
　→DB班　3人
　→データ連携　2人
## ◆今回使用した備品
▼カードリーダー（SONY®MODELRC-S380）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567451/42fb4dcb-bb04-e403-a300-3c2471871075.png)

▼ICカード（FeliCa Lite-S RC-S966　ビジネス（業務/e-TAX）用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567451/650e3577-44bc-5464-e3c2-7b317eb26a12.png)

▼バーコードリーダ（OPL-6845 SN:1147659）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567451/3679b318-417f-1d57-c801-36bccfd1f919.png)

## ◆社員証システム

▼できたこと
　　→ICカードを読み込ませることにより、Googleのホーム画面を表示することが出来た。
▼最終目標
　　→Googleのホーム画面ではなく、
　　ジョブカンの人材紹介ページが表示されるようになること。

　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567451/c909e0e9-810c-a0ed-fff6-0877e2d64d05.png)


## ◆書籍管理システム
▼できたこと
　　→書籍JANコードをバーコードリーダーで読み込み、書籍JANコードをキーにしてDB内を
 　　　検索し、書籍データを表示する。（書籍名、タイトルでも検索可能）
▼最終目標
　　　centOS側での検索をできるようにしたい	　　　
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567451/d8ac5c01-a0b0-469f-62a7-9cbaaf36daa4.png)
CentOS側にあるMySQLと連動して、書籍情報を取得するようにしている
【PySpark】フィルタリング(filter)にて不等号(!=)を扱う際に気を付けるべき点

# はじめに
PySpark の filter 関数 は SQL でいうところの where みたいなもので、データフレームを指定した条件で絞りたい場合にフィルタリングできる関数になります。
PySpark を使用していると当たり前のようによく使う関数なのですが、フィルタリングの条件式の中で不等号演算(!=)を扱う際に、知らないと予期しない出力結果を招く可能性があるので共有します。
# 前提条件
本記事では以下のような簡単なデータフレーム df を作成して検証しています。
```python
import pyspark.sql.functions as F

data = [
    ("田中", None), 
    ("佐藤", 95), 
    ("山田", 50), 
]

cols= ["name","score"]
df = spark.createDataFrame(data = data, schema = cols)
display(df)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/6856106d-fbc9-78a0-b53b-47ec6e13dd6f.png)

分析環境は Databricks を使っています。
# case1
まず本題の前に一般的な filter 関数の使い方から見ていきます。
score カラムの値が 95 のレコードをフィルタリングしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/326ac80c-4f44-b377-971d-8c3350bf38db.png)

この場合、1行目で等号演算(==)を使い、うまくフィルタリングできているかと思います。

# case2
こちらが本題です。
先ほどは、score カラムの値が 95 のレコードをフィルタリングしてみましたが、今度は score カラムの値が 95 でないレコードをフィルタリングしようと思います。
そのために不等号(!=)の演算を以下のように使用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/b3e265cc-2e28-0f11-de13-7e056a7b184f.png)

しかし結果を見て、ん？となりました。
なぜなら score カラムの値が 95 でないレコードは山田さんのレコードはもちろん、田中さんのレコードも出力されると予想していたからです。
どうやら不等号演算を使用する場合、値が 「null」 の場合は 「95 でない」という条件に当てはまらないようです。

# case3
case2 の解決策になります。
score カラムの値が95でないという条件だけでは足りないので、論理演算(|)を使用して score カラムが null でもフィルタリングするように指定してあげます。
「|」 は日本語で言うところの「または」という意味になります。
以下のようにしてあげます。
「score カラムの値が 95 でない、または null のレコード」のフィルタリングです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/88d3a6c0-d022-a407-b2a8-a43b6d258aa0.png)
こちらでうまくいきました。
# まとめ
filter 関数を使用するときは、大抵の場合上記紹介した簡単なデータフレームではなくレコード数が多いデータフレームになるかと思います。
null 値のデータもフィルタリング対象として想定していたが、実はされていなかった等の事態をふせぐためにも、filter 関数の中で不等号演算を使用する際には十分気を付けましょう。
また、不等号と似たような演算でチルダ(~)と呼ばれる Not 演算子も同様の仕様なので注意が必要です。
(リンクだけです)材料力学「Stress_resultants(合応力)」を調べた。

・**「Stress_resultants」** について、ギャンギャン？？？説明されている**youtube**を探しています。

# resultantsをdeepl翻訳
　
https://www.deepl.com/translator#en/ja/resultants

# wikipedia

https://en.wikipedia.org/wiki/Stress_resultants

日本語版なし。不思議？

# google 検索

https://www.google.com/search?q=Stress+resultants&rlz=1CAUHAM_enJP1038JP1038&oq=Stress+resultants&gs_lcrp=EgZjaHJvbWUyCwgAEEUYExg5GIAEMgkIARAAGBMYgAQyCAgCEAAYExgeMggIAxAAGBMYHjIMCAQQABgFGA8YExgeMgwIBRAAGAUYDxgTGB4yDAgGEAAYBRgPGBMYHjIGCAcQRRg8qAIAsAIA&sourceid=chrome&ie=UTF-8

https://www.google.com/search?q=%E5%90%88%E5%BF%9C%E5%8A%9B&sca_esv=587945461&rlz=1CAUHAM_enJP1038JP1038&sxsrf=AM9HkKmFXLow3p8LP7Zn5J2fEr4Va7xSZA%3A1701761515540&ei=69FuZeKcIJHT2roPpquY6A0&ved=0ahUKEwiivoDV4_eCAxWRqVYBHaYVBt0Q4dUDCBA&uact=5&oq=%E5%90%88%E5%BF%9C%E5%8A%9B&gs_lp=Egxnd3Mtd2l6LXNlcnAiCeWQiOW_nOWKmzIFEAAYgAQyBRAAGIAEMgQQABgeMgYQABgeGA8yBhAAGB4YDzIGEAAYHhgPSKLFAVCjBFi6twFwEHgBkAEAmAG-AaABxyeqAQQxLjQyuAEDyAEA-AEBqAIUwgIKEAAYRxjWBBiwA8ICDBAjGIAEGIoFGBMYJ8ICBBAjGCfCAgcQABiABBgTwgIGEAAYHhgTwgIIEAAYHhgPGBPCAggQABgFGB4YE8ICCRAAGIAEGA0YE8ICCBAAGB4YDRgTwgIIEAAYHhgTGArCAgcQABiABBgNwgIGEAAYHhgKwgIHEAAYgAQYBMICCxAAGIAEGLEDGIMBwgIOEAAYgAQYigUYsQMYgwHCAggQABiABBixA8ICEBAAGIAEGIoFGEMYsQMYgwHCAgoQABiABBiKBRhDwgINEAAYgAQYBBixAxiDAcICChAAGIAEGAQYsQPCAgcQIxjqAhgnwgIWEAAYAxiPARjlAhjqAhi0AhiMA9gBAcICChAjGIAEGIoFGCfCAgYQABgDGATCAgkQABiABBgEGArCAgYQABgEGB7CAggQABgEGB4YD8ICEBAAGIAEGAQYsQMYgwEYyQPCAgoQABiABBgEGJIDwgIHEAAYgAQYCsICDRAAGIAEGLEDGIMBGArCAggQABiABBiiBOIDBBgAIEGIBgGQBgG6BgYIARABGAs&sclient=gws-wiz-serp

# いつもの目次です。

https://qiita.com/mrrclb48z/items/fbc5eb2c237586966ce0

# 参考

https://www.google.com/search?q=%E3%83%A2%E3%83%BC%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A8%E6%9B%B2%E3%81%92%E3%83%A2%E3%83%BC%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E9%81%95%E3%81%84&rlz=1CAUHAM_enJP1038JP1038&oq=%E3%83%A2%E3%83%BC%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A8%E6%9B%B2%E3%81%92%E3%83%A2%E3%83%BC%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E9%81%95%E3%81%84&gs_lcrp=EgZjaHJvbWUyCQgAEEUYORiABDIGCAEQRRg9MgYIAhBFGD2oAgCwAgA&sourceid=chrome&ie=UTF-8

＞ある面上の合応力ｐは１つの垂直応力と２つのせん断応力成分に分解できる。 
https://aitech.ac.jp/~narita/telastic01.pdf
＞●応力テンソル［σij］は...
https://aitech.ac.jp/~narita/telastic01.pdf#page=5


＜

https://aitech.ac.jp/~narita/


https://qiita.com/mrrclb48z/items/40ceadf74a7562aaeafa

# 文献

＞P22 2.4 断面力
＞応力を断面全体に加え合わせると...三つの断面力となる。これを**合応力(stress resultant)** ともいう。
複数形でありませんでした。

https://www.coronasha.co.jp/np/isbn/9784339050448/
Vue 基礎勉強 v-bind (2)

(Vue.js 3.1.5を使用)

**v-bind**
属性のデータバインディング

前回は、以下のように書いたが、
(valueに値を表示させる。( v-bind:value="変数名" とする。))
```javascript:javascript
const app = Vue.createApp({
    data: () => ({
        message: 'データバインディング'
    })
})
app.mount('#app')
```
```html:html
    <div id="app">
        <p><input type="text" v-bind:value="message"></p>
    </div>
```
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/722caf49-b565-58d1-afdc-26bdcb8b29de.png)



classの値について、v-bindを使用する場合は、以下のように書く。
( v-bind:class= とする。)
```javascript:javascript
const app = Vue.createApp({
    data: () => ({
        isRed: false
    })
})
app.mount('#app')
```
```css:css
#app span.red{
    color: red;
}
```
```html:html
    <div id="app">
        <span v-bind:class="{red: isRed}">こんにちは！</span>        
    </div>
```
 `isRed: false` のときは、文字列は、黒文字のまま。
 ![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/5d0d934d-9fdf-c4eb-e054-481e73ef86a3.png)

 `isRed: true` のときは、文字列は、赤文字になる。
 ![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/4945d663-d7a0-0632-9207-b483a1f921c4.png)

参考：

https://v2.ja.vuejs.org/v2/guide/class-and-style

> v-bind:class にオブジェクトを渡すことでクラスを動的に切り替えることができます:


この形`v-bind:class="{red: isRed}" `でオブジェクトを渡すことになる。
【Python】forループとlambda式関数を組み合わせるときのTips

# 概要

ご無沙汰しております。うらさくと申します
この記事は[TechCommit Advent Calendar 2023](https://adventar.org/calendars/8839)の5日目の記事です
3年連続のアドカレです

今回はPythonのtkinterでボタンにlambda式関数をバインドするときに躓いたので、備忘録として共有します

# 修正前コード

```Python
buttons = [tkinter.Button(root, text="テスト", command=lambda: self.test_function(True, i)) for i in range(5)]
```

こんな感じでtkinterのボタンコンポーネントをfor文で5つ作る際、そのボタンのインデックス（0～4）を押したときに発火する関数の引数に入れたいというケースがありました

# 起こった事象

このコードを組み込んだプログラムを実行してそのボタンを押してみると、**すべてのボタンでindexの引数に4、つまり、ループの最後の値が反映されていました**

原因は、**変数名はforループの各繰り返しで再代入される**という仕様でした

# 解決策

lambda式内でデフォルトのキーワードパラメータを使用することで解決できます

```Python
buttons = [tkinter.Button(root, text="テスト", command=lambda index=i: self.test_function(True, i)) for i in range(5)]
```

# まとめ

tkinterに限らず、for文×lambdaの組み合わせはPythonではたまにあると思うので、同じところで詰まっている方は参考にしていただけると幸いです

# 参考

https://stackoverflow.com/questions/17677649/tkinter-assign-button-command-in-a-for-loop-with-lambda
【PHP】シングルクォーテーションとダブルクォーテーションの違い

## はじめに
この記事は、PHPを勉強し始めたばかりの初心者向けの記事になります。

PHPを勉強していて、
**シングルクォーテーションとダブルクォーテーションに明確な違いがある**
ことに驚いたので今回記事を書いてアウトプットしようと思います。

結論はこちら⏬
- シングルクォーテーションで囲うと、変数が入っていようが**絶対に文字列になる**
- ダブルクォーテーションで囲うと、**変数が展開される**

## 実際に見てみる
```$hensuu```という変数を用意して、実際に確認してみます。
```php:hello.php
$hensuu = 'Hello World!';
echo $hensuu.'<br>';  # Hello World! と表示される
echo '$hensuu<br>';   # $hensuu<br> と表示される
echo "$hensuu<br>";   # Hello World! と表示される
```

実際にWebで確認したところ、以下のように表示されました。

![screenshot 2023-12-05 16.31.12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3080550/b853f21d-b537-5440-b692-ad11c1c20056.jpeg)

シングルクォーテーションで囲った部分は、
```$hensuu```が文字列として表示されていることがわかります。

ダブルクォーテーションで囲った部分は、
```$hensuu```が変数として扱われ、その中身の```Hello World!```が表示されていることがわかります。

このように、ダブルクォーテーションを使うと、
**文字列連結の```.```を使わなくても簡単に変数を変数として扱える**ことが分かりました。

これを使えば、面倒だった文字列連結が楽に実装できそうです。

## まとめ
PHPでは、シングルクォーテーションとダブルクォーテーションでは
明確な違いがあることが分かりました。

シングルクォーテーションは、中身を文字列として扱い、
ダブルクォーテーションは、中身に変数がある場合は変数として処理してくれます。

これを使って、シンプルに文字列連結を実装できそうです。
メンバー育成について

# はじめに
皆さんおはこんばんわ！

今年もアドベントカレンダーの時期がやってきました！

今年はどんな記事を書こうか考えていたのですが、一番注力していたメンバー育成について記事にしたいと思います。
育成周りで結構悩む方も多い気がしますが、実際に私がやってみて感じたことや意識したことなど、少しでも参考になれば幸いです。


# 背景
弊社のチームではQAテスターを採用しているのですが、プロジェクトの兼ね合いでいままでにない規模での採用が必要になり、早急に育成体制を固める必要がありました。
そのためには、今いるメンバーでどういった研修をすればよいのか？、もっと効率化するにはどうしたらよいか？、どういう育成方法をとればよいか？、などを考える必要が出てきました。
今回は育成メニューや効率化についてではなく、**育成方法や心構え、育成をする上での注意点**についてお話していきます。

# 相手を知る
取り組むうえでまず大事なのは相手を知ることです。
新しく入社される方は基本的に若い方、いわゆるz世代（1990年代中盤から2000年代終盤に生まれた世代のこと）と呼ばれる人たちがほとんどだと思います。
z世代は生まれたときからインターネットが利用できる環境で価値観や考え方が異なります。

例えば、
- ワークライフバランス
- 柔軟な働き方
- 協力や連帯感
　　　　　　　　　　　を大事にする傾向があります。
           
「個人」や「自分らしさ」という考え方を大事にする傾向も強く、自分自身の考えや価値観を認めてもらいたいという承認欲求が強いのも特徴に上げられます。

前述した通り、z世代は承認欲求が強い傾向があるので、何か失敗してしまった時に否定から入られると強い嫌悪感を抱きます。
なので、否定するようなことはせずに挑戦したことを褒めたたえましょう。
例えば、会議の場で見当違いなことを言ってしまった場合、そのことを責めるようなことはせずに、大勢の前で自分の意見を言ったことに対して褒めるみたいな感じです。
褒められると、自分を認められたようでホッとするし、また頑張ろうという気力にもなります。


# 育成方法
最初に言っておくと育成方法は正解がないので、自身が接するパターンの一つとして知見をためておくぐらいで読んでいただけると幸いです。

どの時代も自立的、能動的に動けるように育成したいというのが理想としてあると思います。
しかし今は仕事の専門性が増したり、環境変化のスピードが速かったり、より繊細な対応が求められることが増えています。
そのため、知見がないため不安を感じ、思ったようにチャレンジできない人がほとんどです。

たまに、「一旦やってみて」みたいに促したりする人を見たりしますが、
育成される側の視点だとどうしたらいいかわからないので、実務に入る前にテストに関連する知識を説明したり、実践を交えながら教えていくなどの作業がとても大事になってきます。
説明するとしないのでは理解力に差が出ると思っていて、育成される側の新鮮な視点から「もっとこうしたほうがいいのでは？」といった意見が出ることもあります。


例えば、
- テストとは？
- テストとデバッグの違い
- テストケースとは？
- 仕様書の見方
- テストの心得

他にもゲームの基礎という観点から、
- クライアントとアセット
- テスト環境とは？
- マスタデータとは？

上記などのテストの基礎部分やゲームを構成している要素について説明があると理解力が上がり、効率よく進めることができます。
私も育成用の資料を作っていましたが、文字だけだと伝わりにくいので、なるべく図や表などを用意してわかりやすいように工夫したりしていました。


他にダメなパターンとして、「わからないことがあったら聞いて」みたいに放置するようなこともあまりよくないです。
私は教えられる側から質問することは基本的にないと考えています。
なぜなら、遠慮して聞き逃していたり、わからないことがわからないといったことに陥っている可能性が高いからです。
なので、定期的にMTGなどをセットして強制的に話す場を作るといったことも一つの手だと思います。
話すときもいきなり仕事の話をするのではなく、雑談などで緊張を解いてから本題に入るのがよいです。


実際に私が取り組むときは以下のような手を打ちました。
- 隔週で質疑するためのMTGを開催
    - 冒頭は雑談等で質問しやすい雰囲気を作る
- 質問するためのシートを準備
    - いつでも質問できる環境を作る
- 説明するときに横文字はなるべく使わない


# QAテスターの育成をやってみて
一般的な育成論を意識しつつ、QAにおける基礎的なことから説明をしていきましたが、
IT業界特有の横文字の多さに苦戦しているテスターさんが多く見られました。
定期的に面談をしているのですが、「この単語ってどういう意味ですか？」が一番多い質問で、
一度説明した単語の意味も質問されることがあったので覚えるためにも復習が大事だなと改めて気づかされました。
なので、用語集を作成したり、分からなかった単語は調べたりするなどしておくとよいかと思います。
中途採用でもIT未経験だと同じ事に陥りがちなので、きちんと復習する時間を作っていければなと思います。


# 終わりに
少しではありますが、育成周りについて私が意識していることを纏めてみました。
正直な話、過保護すぎるかなとも思ってたりしますが、少しでも皆さんの参考になれば幸いです。

それでは、みなさんよいクリスマスを:xmas-tree::xmas-wreath1::xmas-wreath2:
Node-REDで自作パッケージデバッグするときはnpm iしておきましょう


久々に開発する時に

https://qiita.com/n0bisuke/items/7a1ae5a95f9ce7e2e6fa

こちらの記事を見ますが少しハマったのでメモです。

## 手順通りにインストールをしていったけど表示されない

理想はこんな感じですが

> ![スクリーンショット 2023-12-05 16.11.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/9ed9dc26-939a-7b35-8d6c-d5f8e0b13ba7.png "スクリーンショット 2023-12-05 16.11.07.png")

一向にこの状態

> ![スクリーンショット 2023-12-05 16.11.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/c544d8c5-b59f-a13a-3ecb-00a3374e31ad.png "スクリーンショット 2023-12-05 16.11.45.png")

## Git Cloneしたままにしていた。

手順的にはcloneしてNode-REDのライブラリや設定などがいる`~/.node-red`フォルダ内でローカルパス指定インストールをしましょう。って感じでした。

```
$ git clone node-red-contrib-line-messaging-api
```

これだけではなく、以下も実行する必要があったという感じですね。

```
$ cd node-red-contrib-line-messaging-api
$ npm i
```

npm install(npm i)してからNode-REDを立ち上げると無事にローカルの自作パッケージが読み込まれます。
【Splide】ズームインしながらフェードで切り替える


ヒーローイメージでよく利用するズームインしながらフェードで切り替えるスライダー。

検索してみると Swiper での実装方法は見つかりますが、Splide での実装方法が見つからなかったのでまとめてみました。

ちなみに Splide はアクセシビリティに配慮した軽量・高機能スライダーです。
Swiper は多機能すぎてカスタマイズが大変だ…:weary:
という方にオススメです！

https://ja.splidejs.com/

## バージョン

Splide のバージョンは `4.1.4` を利用しました。

```html:HTML
<link href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js"></script>
```

## HTML

各スライドの要素を任意のタグで囲む必要があります。
以下サンプルコードだと、`splide__slide` の子要素に `span` を利用して要素を囲んでいます。

```html:HTML
<div id="js-splide" class="splide">
  <div class="splide__track">
    <ul class="splide__list">
      <li class="splide__slide"><span>1</span></li>
      <li class="splide__slide"><span>2</span></li>
      <li class="splide__slide"><span>3</span></li>
      <li class="splide__slide"><span>4</span></li>
    </ul>
  </div>
</div>
```

## CSS

Splide によって自動で追加される `class` にズームインアニメーションの設定をします。

* `is-active` （現在表示しているスライド）
* `is-prev` （1つ前のスライド）

ただし、このままだと最後から最初へ移動した時に、最後の要素（1つ前）に `is-prev` が追加されず表示がおかしくなります。

そのため、Splide のイベントハンドラを利用して `splide__slide` の子要素の `span` にアニメーション設定用の `class` を追加するようにします。

:::note warn
`splide__slide` に `class` を追加しても Splide によって削除されてしまうため、子要素への設定が必要となります。
:::


```css:CSS
.splide__slide.is-active span,
.splide__slide.is-prev span,
.splide__slide span.is-prev {
  animation: scale 7s linear 0s normal both;
}
@keyframes scale {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.5);
  }
}
```

## JavaScript

`Splide#on()` メソッドを利用して、 `move` イベント（スライダーが動く直前に発生）に `class` を追加する処理を記述します。

https://ja.splidejs.com/guides/events/

```javascript:JS
const option = {
  type: 'fade',
  autoplay: true,
  rewind: true,
  interval: 6000, // 自動再生の間隔
  speed: 2000, // フェードする時間
}
const splide = new Splide('#js-splide', option)

// 最後から最初へ移動した時に、
// 最後の要素（1つ前）の子要素にclassを追加する
splide.on('move', function () {
  const lastElement = splide.root.querySelector('.splide__slide:last-child span')
  if (splide.index === 0) {
    lastElement.classList.add('is-prev')
    return
  }
  if (lastElement.classList.contains('is-prev')) {
    lastElement.classList.remove('is-prev')
  }
})
splide.mount()

```

## DEMO

<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="rNPQZEz" data-user="taqumo" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/taqumo/pen/rNPQZEz">
  Splide  Zoom In Animation</a> by Takuya Mori (<a href="https://codepen.io/taqumo">@taqumo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
Footprint の一括ダウンロード・ソリューションでトレードのバックテストが容易に

<h3></h3><img src="https://statichk.footprint.network/article/2912996d-1f36-4d43-9d14-9ce765b8c2bd.png">

著者一覧： lesley@footprint.network
バックテスト（Backtesting）とは、過去の暗号通貨価格データを使用して、取引戦略やアルゴリズムのパフォーマンスをシミュレートし評価するテストです。

<img src="https://statichk.footprint.network/article/a91718df-38d7-4ea4-8605-a491a126ad18.png">

ブロックチェーンの分野では、バックテストは成功する取引戦略を開発する上で極めて重要な役割を果たします。 取引戦略の強みを明らかにすることで、トレーダーはルールに基づいたアプローチを構築し、より合理的な視点で取引を行うことができる。
これに加えて、バックテストは実際の資金を投入する前に戦略の実行可能性を徹底的に評価することで、信頼性を高める。

<h3>しかし、中小企業にとってバックテストは難しい</h3>バックテストは暗号通貨取引に体系的なアプローチをもたらしますが、実用的なバックテストを構築するには多くの課題があります：<ul><li>過去データへのアクセス時間</li></ul>

ブロックチェーンには取引の網羅的な記録が残されているが、この生データから正確なバックテストのデータセットを作成するには、豊富な専門知識とインフラが必要であり、時間や効率の点で、ほとんどの中小企業の能力を超えている。<ul><li>高品質データのコスト</li></ul>

パブリック・ブロックチェーンがオープンソースであるとはいえ、ブロックチェーンのデータ全体を解析するにはかなりの費用がかかります。 ノードの構築、データのクレンジング、整理のすべてに専門知識とリソースが必要だ。
未加工の公開データは自由に入手できますが、アルゴリズム取引のバックテストに適した形式に変換するには、かなりのアルゴリズムリソースと専門知識が必要です。

<h3>Footprintのバッチダウンロードソリューションでバックテストツールを構築</h3>Footprintのバッチダウンロードソリューションは、過去のブロックチェーンデータに効率的にアクセスするのに理想的です。
<img src="https://statichk.footprint.network/article/4b68dc4a-a7ca-4608-9358-64f7d0001523.png"><ul><li>完全な過去データへのアクセスを最大10倍高速化</li></ul>

Footprintのバッチダウンロードソリューションで、30を超える過去のブロックチェーンデータセットにアクセスできます。 クラウドストレージの効率性を活用して、さまざまなファイル形式間で大量の履歴データを簡単に転送できます。
このデータは完全な履歴をカバーしており、完全な履歴と増分更新を含む増分データに1日中アクセスできます。<ul><li>自社でデータインフラを構築する場合に比べ、最大80％のコスト削減が可能</li></ul>

Footprint のバッチダウンロードソリューションなら、大幅なコスト削減が可能です。 高品質で構造化された過去のブロックチェーンデータへのアクセスがお客様の負担にならないよう、開発者優先の手頃な価格設定になっています。 Footprintの手頃なソリューションを選択することで、時間、リソース、コストを節約できます。
ブロックチェーンデータをバックテスト戦略で使用するのに適した形式に変換することは困難な場合があります。Footprintのバッチダウンロードソリューションでは、お客様のモデリングをサポートするために、30種類以上のクリーニングされた構造化ヒストリカルデータにアクセスできます。 このソリューションの詳細については、当社のウェブサイトをご覧になるか、ミーティングをご予約ください。

元のリンク:
 <a href="https://cutt.ly/DwPvqhmr">Supercharge Your Trading: Footprint’s Batch Download for Easier Backtesting</a>

Footprint Analytics はブロックチェーン・データ・ソリューション・プロバイダーです。 最先端のAI技術を活用し、コード不要のデータ分析をサポートするCrypto分野初のデータ分析プラットフォームや、30を超えるパブリックチェーンエコシステムのNFT、GameFi、ウォレットアドレスのマネーフロー追跡データを迅速に取得できる統合データAPIを提供しています。

Footprint Analytics：<a href="https://www.footprint.network/">https://www.footprint.network</a>
Discord：<a href="https://discord.gg/3HYaR6USM7">https://discord.gg/3HYaR6USM7</a>
Twitter：<a href="https://twitter.com/Footprint_Data">https://twitter.com/Footprint_Data</a>
Telegram：<a href="https://t.me/Footprint_Analytics">https://t.me/Footprint_Analytics</a>
TransformerとGPTとBERTとEncoderとDecoderの関係を整理しておく

# 背景
- LLMの勉強していく時に混乱したのでまとめておく
- この分野の人には当たり前のことすぎてまとまっていることがあまりないので初学者向けに

# Transformerとは？
- 2017年に [Attention is All You Need](https://arxiv.org/pdf/1706.03762.pdf)で紹介されたLLMのアーキテクチャ
- Encoder-Decoderモデル(後述)
![スクリーンショット 2023-11-29 11.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/07c44969-6e3d-4e50-c6ce-37e6012349e6.png)

- 翻訳タスクなどが得意
- GPTやBERTモデルのベースとなった

https://www.youtube.com/watch?v=0_4KEb08xrE

# Encoderとは？
- Encoderへの入力データの特徴・文脈の理解を考慮したアウトプットを生成します

https://www.youtube.com/watch?v=MUqNwgPjJvQ

# Decoderとは？
- Decoderへの入力データから次に出力する最適な単語を類推します
- Transformerの場合はEncoderからの出力を考慮します

https://www.youtube.com/watch?v=d_ixlCubqQw

# BERTとは？
- TransformerのEncoderの部分のみを利用したモデル(Encoder-Onlyモデル)の代表格です
- 入力文章を理解し、分類・感情分析・要約タスクなどが得意です

https://huggingface.co/docs/transformers/model_doc/bert


# GPT
- TransformerのDocoderの部分のみを利用したモデル(Decoder-Onlyモデル)の代表格です
- テキスト生成タスクを得意とします
- 言わずと知れたOpenAIのモデルです

https://huggingface.co/gpt2
IBM Cloud：デフォルトのMonitoring機能でVPC 仮想サーバーを監視・通知する

# はじめに
対象リージョン内にIBM Cloud Monitoringを作成されている場合、以下のVPC サービスではIBM Cloud Monitoring ダッシュボードを使用して、デフォルトでメトリクスのモニターをすることができます。
- VPC Virtual Server Instance
- VPC VPN
- VPC Load Balancer
- VPC Flow Log

本記事では、VPC上のWindows仮想サーバーをデフォルトで備わっているMonitoring機能を利用して監視・通知設定を行います。

## 注意点
本機能を利用するためには、対象リージョンにPlatform metricsを有効にしたCloud Monitoringのサービスが必要です。有効化は以下を参照ください。
https://cloud.ibm.com/docs/monitoring?topic=monitoring-platform_metrics_enabling

また、Platform metricsが有効化されている場合、メトリクス (time-series)分の課金が発生します。
https://cloud.ibm.com/docs/monitoring?topic=monitoring-pricing_plans&locale=en#pricing_example3


# メトリクス表示手順
[IBM Cloudポータルにログイン](https://cloud.ibm.com/)し、ハンバーガーメニューから「VPC Infrastructure」→「Virtual server instances」を選択します。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/1675075f-4812-a012-e153-0d9eb91750eb.png width=80%>

対象のサーバー名をクリックし、詳細画面を開きます。
「Overview」横の「Monitoring」をクリックすると、各種メトリクスが参照できます。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/20b8ebbc-5e36-090e-fad2-3c0f7d3d843f.png width=80%>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/cf3f428e-5425-f809-67bf-c44e9a1161aa.png width=80%>

次に「Launch monitoring」をクリックすると、IBM Cloud Monitoringのダッシュボードを見ることもできます。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/e580ddfc-83b5-3b26-82a0-29ac815bbda3.png width=80%>

:::note warn
注意点
IBM Cloud Monitoringインスタンスが存在しない場合、以下のような「**Add monitoring**」という表示になります。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/d85515d4-f629-04d6-2233-8317cf6dfaab.png width=70%>
:::

以下のように、仮想サーバーの様々なメトリクスを表示することができました。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/1db843d3-ac0b-fd25-b48b-6c61f279b1a8.png width=80%>

# 通知設定手順
メトリクスの各種通知設定は、「︙」→「Create Alert」をクリックすることで可能です。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/27904795-c0e6-0972-837d-a30e6514e545.png width=80%>

「Profile」→「Setting」→「Notification Channels」で通知チャネルを新規作成できます。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/557fd700-7907-e669-f9c7-bbb4cb449d9d.png width=80%>


## ダウンタイムの通知設定
ただし、上記のWindows デフォルト・アラートではダウンタイムの通知を設定することはできません。そこでサーバーから送られてくるデータのステータスが「No Data」の場合、通知を発報するよう設定したいと思います。

「︙」→「Create Alert」をクリックし、通知設定画面を開きます。
「Setting」内の「No Data」を「**Notify**」に設定します。これにより、Monitoringがサーバーからメトリクスを受信できない状態になった場合（**つまり、サーバーがダウンした場合**）に通知が発報されます。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199676/09e527bb-4d54-44c2-225d-046e88249746.png width=80%>

設定は以上となります。
その他の項目はお好みで設定ください
リハビリアプリを作ろう（その４）

こちらの続きです

https://qiita.com/t-yamanashi/items/e1f73e7317b028f3349f

1-25の数字押していくゲームを作りたいです
このコラムの範囲
- 次に押す数字問題の表示

# 問題の表示
問題以外の数字は受けいれしない

```elixir:lib/num_web/live/user_live/index.ex
defmodule NumWeb.UserLive.Index do
  use NumWeb, :live_view

  @impl true
  def mount(_params, _session, socket) do
    num =
    1..25
    |> Enum.shuffle()

    questions =
    num
    |> Enum.shuffle()

    questions = questions ++ [0]
    [question | questions] = questions

    socket = assign(socket, num: num)
    |> assign(ok_num: [])
    |> assign(questions: questions)
    |> assign(question: question)

    {:ok, socket}
  end

  @impl true
  def handle_event("buttno", %{"no" => no}, socket) do
    question = socket.assigns[:question]
    |> Integer.to_string()

    socket = if question == no do
      ok_num = socket.assigns[:ok_num] ++ [no]
      [question | questions] = socket.assigns[:questions]
      assign(socket, ok_num: ok_num)
      |> assign(questions: questions)
      |> assign(question: question)
    else
      socket
    end

    {:noreply, socket}
  end

end


```

```elixir:lib/num_web/live/user_live/index.html.heex
<div  class="w-28 h-28 m-2 bg-red-200 text-center ">
  <p class="pt-7 text-5xl text-red-700 "><%= @question %></p>
</div>
<br>
<%= for {s, i} <- Enum.with_index(@num, 1) do %>
  <%= if Enum.find_index(@ok_num, fn x -> Integer.to_string(s) == x end) == nil do %>
    <div phx-click="buttno" phx-value-no={s}  class="float-left w-28 h-28 m-2 bg-blue-200 text-center ">
      <p class="pt-7 text-5xl text-blue-700 "><%= s %></p>
    </div>
  <% else %>
    <div  class="float-left w-28 h-28 m-2 bg-blue-100 text-center ">
    </div>
  <% end %>
  <%= if rem(i, 5) == 0 do  %>
    <br>
  <% end %>
<% end %>
```

# 現時点結果
数字をクリックすると数字が消え次の問題が表示します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/6f245240-f931-b4d7-4534-2e821505b2b8.png)

14をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/35c02dfa-9e6d-b7bd-8012-765ee602a733.png)

すべてクリック後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/805c83f1-63e6-709f-11ce-29efc5c26d58.png)

https://youtu.be/TYYeYntMVC0

今回はここまで

今後の課題
- 時間測定
- リセットボタン
VScodeでのGUIによるGit操作_stash編

<h1>Git操作_stashについて</h1>
<p>こんにちは！<br>今回はGit操作のstashについての備忘録を記録したいと思います。<br>なぜならVScodeでの操作を検索しても・・・</p>
<h3>ターミナルでの操作しかない！</h3>
<p>と、嘆くに至ったからです（笑）<br><br>ムダにスクロールしてもらうのも悪いので早速記述していきます(｀・ω・´)<br></p>
<hr>
<h4>① Gitのタブから更新、編集したファイルをステージングします。</h4>

![スクリーンショット 2023-11-07 141904.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/f4f880c2-c4dd-1aa6-9ad3-aa0dc65f2b39.png)

<h5>※「＋」ボタンを押してステージング！</h5>

![スクリーンショット 2023-11-07 141929.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/1860055b-5c0a-8030-a108-2de7145319f8.png)

<h4>② 「ステージされている...」の部分を右クリックして、「Stash All Changes」をクリックします。</h4>
<h5>※stash = 隠す、しまう</h5>

![スクリーンショット 2023-11-07 141940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/87c5121c-ae4e-4c25-f480-f99121e94658.png)

<h4>③ 画面上部に入力フォームが出てくるので、適当な保存名を入力します。<br>例として「退避」と入力して、Enterキーを押します。</h4>

![スクリーンショット 2023-11-07 141959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/681ae6da-da9f-652a-7b06-b57962b7f8dd.png)

<h4>④ すると、Gitgraphには先ほど命名した「退避」が出現し、ソース管理の欄から更新したファイルがなくなりました！</h4>

![スクリーンショット 2023-11-07 1421271.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/9efd6a7c-c496-d7c3-2692-77643a54827c.png)

![スクリーンショット 2023-11-07 142127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/85e888e5-9ed8-54ca-4369-b1dd1d175a5f.png)

<hr>

<h4>以下はstashしたファイルの戻し方です。</h4>

<h4>⑤ Gitgraphからstashした履歴を右クリックして「Pop Stash」を選択します。</h4>

![スクリーンショット 2023-11-07 142214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/2495b103-7258-4f67-5efc-b3bda568ce1f.png)

<h4>⑥ ポップアップが表示されるので「Yes」を選択してください。</h4>

![スクリーンショット 2023-12-05 160339.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293353/bdbfff1f-6174-550c-8efd-12a959b9abe0.png)
<h5>※エラーになる場合もありますが、他と競合している場合に出るようなのであとでどちらを取り込むか確認すると良いと思います。</h5>

<p>いかがでしたか？<br>Gitはなにかと厄介なことも多いですがチームで作業するには欠かせないアプリケーションだと思いますので、僕ももっと勉強していきたいと思います。</p>

<h4>皆様のお役に立つと幸いです('ω')</h4>
AWSプレフィックスリストの話

## セキュリティグループが汚い事が許せない

ある日、突然こんな事思いませんか？
**「私のセキュリティグループ汚すぎ！」**
こうなったら四六時中その事を考えてしまい、仕事が手につかなくなりますよね。

原因は色々ありますが、最近の事情だとコロナ禍などを迎えてリモート出社が働き方の主流になっていることが原因の一つなのかなと思います。
複数の開発拠点や個人宅からのIPを、セキュリティグループで許可していると記載量が増大してしまい大変見にくいものになってしまいます。

拠点がある以上、許可するIPが増えるのはしょうがない、でもキレイにしたい！
この記事では、このジレンマを解決していきます。

## AWSプレフィックスリストとは
プレフィックスリストとは、複数のCIDRブロックを束ねたものです。
このプレフィックスリストを事前に作成しておくと、ルートテーブルやセキュリティグループの設定や管理に便利に使う事ができます。

## 設定手順
1. マネジメントコンソールを開く
2. VPCのコンソール画面に移動
3. 左側メニューから「マネージドプレフィックスリスト」を選択
4. 右上の「プレフィックスリストを作成」ボタンを選択
5. 作成画面で、「プレフィックスリスト名」と「最大エントリ数」を入れてIPｖ４かIPｖ６を選択
※最大エントリ数を後から変更するにはCLIで設定する必要があるそうです
6. 「新しいエントリを追加」ボタンを押してCIDRブロックを追加
7. 入力を終えたら「プレフィックスリストを作成」ボタンを押して完成

後は上で設定したプレフィックスリストをセキュリティグループの設定時にCIDRブロックの箇所に作成したプレフィックスリストを割り当てて、逆に直接書かれたIPを削除すればOKです。

Tipsとして、セキュリティグループに割り当てるので、「開発者の拠点」や、「顧客」など役割に合わせてプレフィックスリストを切ることで適切なセキュリティグループを割り当てる事ができます。
例）開発者からはEC2へのsshが必要だけど、顧客には必要ない等

## まとめ
セキュリティグループがIPアドレスで溢れる事ってエンジニアあるあるだと思うんです。
でも、どれも必要なIPアドレスだし、具体的な解決策どうしたら良いんだろう？って方の参考になれば嬉しいです！

ただ、一方で「セキュリティグループの数を減らす」という目的には、今回の記事は役に立たないと思います。
こちらは常日頃から見直しをかけるしかないのかな？
何か良い方法等あればコメント等で教えていただけると助かります！
Android Studioでドットを含むパッケージ名をリファクタリングする

## 背景
`jp.hoge.mobile.fuga.test`のようなパッケージ名を
`jp.hoge.test`に変更したい。

`jp.hoge.mobile.fuga.test`の「mobile」の部分を部分的にリファクタリングすることはできるが、
ドットを含むパッケージ名の部分を変更したかった。

## 対応
[Change Package Name in Android Studio including number of dots](https://stackoverflow.com/questions/58069470/change-package-name-in-android-studio-including-number-of-dots#:~:text=You%20can%20accomplish%20this%20by%20following%20the%20following%204%20steps%3A)を参考に、ディレクトリをドラッグ＆ドロップしてリファクタリングをかけると、

できた
![mobile_ouchien_android__Git_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/f5832584-60df-04cc-5e6a-1dc8e7dfaca2.png)
同じWebアプリを3章と4章のやり方で作った話

こんにちは！
この記事では、**同じ内容のWebアプリを入門コースの3章と4章のやり方で作成した**話をします。ただの感想ですが、よければご覧ください。
まず、3章のやり方で作って昨年度の冬のコンテストに出品（[GitHubリポジトリ](https://github.com/koppepam/favo-log)） → 最近4章のやり方で作りました。※こちらはrenderで動かせていません。（[GitHubリポジトリ](https://github.com/koppepam/favo-log2)）※半年ほど前の話なので、曖昧な部分もあります。

## 3章で一番苦しんだこと
ぱっと思いつくのが、脆弱性の対策です。今でも大変だったな～と思います。CSRF脆弱性のワンタイムトークンとか、XSS脆弱性とか。投稿フォームの入力欄がいくつかあったこともあり、やっと終わった！と思ってもまだ対策すべきところがあって、とりあえず寝ました。
そんな思い出があったのに、4章ではとても早くできて驚きました。フレームワーク最高！！

あと、これは後悔してることですが、GitHub認証にしたかったな～と。いつの間にかコンテストが近くて、4章をやらずに応募しようと思い、READMEファイルに登録したユーザー名とパスワードをのせて出品しました。その後4章をやってみて、GitHub認証がはやく簡単に作れました。これまたびっくりです。うおお、やればよかった。

Expressって素晴らしい。

## 2つで違いが出てしまったところ

>Expressって素晴らしい。

なーーんて言いましたが、やりたかったことと異なる結果になってしまったこともありました。（もうちょい頑張ればできたのかも。。）作りたかったのは、3章の時と同じような、投稿・検索・一覧・削除などが一つのページで完結するものでした。しかしExpressはページを機能ごとに分ける（？）ようで、いくつかのページに分かれるアプリになりました。これの良さを生かしたアプリを作りたくなってしまいますね。

## おわり
何といっても、4章のフレームワークは「早く、簡単に、（変な）ミスなく」できました。（初心者が自分でやろうとすると、いろんな抜け穴ができて大変でした。）自分がすごい人になったような気分です。思い上がりには気を付けます。その分、やりたいこと、作りたいものが増えてワクワクしています。次のコンテストも一参加者として、たくさんの方の作品が見られることを楽しみにしています。
Apex内でナレッジを検索するSOSLを[]で書くときLanguageは動的指定できない

`[FIND :question IN ALL FIELDS RETURNING Knowledge__kav(UrlName, Title WHERE PublishStatus = 'Online' AND Language = :lang)]`
とすると
`Implementation restriction: When searching the Knowledge__kav object, you must include a filter on Language = [language ISO code] as a top-level AND condition.`
とのエラーになってしまう
「:lang」を「'ja'」のように書けば通る

Search.queryもwhereでの変数バインドがうまく行かない場合がある
https://issues.salesforce.com/issue/a028c00000j5kNQAAY/sosl-results-are-inconsistent-when-using-bind-variables

なので以下とする
```xxx.cls
List<String> formattingArguments = new List<String>{
    '{' + String.escapeSingleQuotes(input.question) + '}',
    '\'' + input.language + '\''
};
String searchQuery = String.format(
    'FIND {0} IN ALL FIELDS RETURNING Knowledge__kav(UrlName, Title WHERE PublishStatus = \'Online\' AND Language = {1})',
    formattingArguments
);
List<List<SObject>> queryResults = Search.query(searchQuery);
```
全銀のトラブルについて思うこと

知人も、入金されない、振り込みできないなどで、
大いに、世間を賑わした全銀のトラブル、
その原因報告が、ひっそりとホームページに。

詳細は、全銀のホームページを見てもらった方が良いし、
勝手な原因解釈図などを自前で作っても、
あくまで推測でしかないので、ここでは書きませんよ。

:::note info
高齢技術者のただの独り言だと思って読んでもらうと大変助かります。
:::
ネットなどでは、別な『でかいシステム』に例えて、
全部はテストできないという話もちらほら見受けましたが、
そこは大きな問題点ではない。

*じゃ、何が問題点かと言えば？*
いくつか考察してみました。

# 運用の問題点
ある程度システムに問題があっても、通常は運用で回避（するはずなんだけど）。

## なんで正系・副系同時切替なの？
これほど大きいシステムならば、正副が準備されているはず。
それこそ、日にちを変えて、正を切り替えて稼働確認して、副を切り替える。
障害で、副だけの縮退環境で動作させるにせよ、
ここまで大きくならなかったと思われる。
というか、正正・正副・副正・副副の4wayとかになってないのね。

## 切戻準備はなかったの？
正副の同時期切替になると、移行計画書に、切戻計画なかったの？
いくら、EOLだからといって、切戻は必要だよね？
報告書を読んでいると、どうも、システムとしては、
ハードとソフト一体のようなので、尚更必要なはず。

## 移行日のまずさ
わざわざ、10日なんて、お金の流通が上がる日を選ばなくても。
もしかして、月末と25日だけが集中する日とか思ってた？
まぁ、年末は、銀行は、自前のシステムを切り替えたりで忙しいので、
年末移行は難しかったのかもね。

# 開発の問題点
うーん、どうも、横串テスト（本番前全体テスト）が不足してるような

## 結合テストしたの？
要約すると、4テーブルのうち、1テーブルを拡張したけど、
それに併せたメモリー拡張してませんでした、だからエラー出たよ。
テストしたときは、1テーブル毎だったので、問題なかったです。
え？本番前の結合テストしなかったの？？
それに、拡張した範囲もわかっているので、最初と最後の検索してなかったの？？
一番最初に、結合して最後までアクセス出来るって確認するよね。

## 高速性の担保のため、低水準言語利用してると思うけど
今回の話だと、本番環境起動後に、メモリアロケートした時点で、
メモリー破壊が発生するので、OS側で検知しないのかな？
クライアントゆるふわOSでもないので、何らかの検知方法は無いのかな？
アロケートが番地していなのか、OS任せによるものなのかで、変わってくるけど、
これだけのシステムになると、仮想メモリーなんか使うと、超絶遅くなるから、
きっちりしたサイジングが逆に徒になってるのかもね。

今回、全銀の話を他山の石として、自分の開発でも気をつけないと。

:::note warn
最後まで読んでいただきありがとうございます。
本内容については、公開資料からのあくまで、個人的推測ですので、
不快に思われた方は申し訳ないです。
:::
[Ruby] メソッドとSymbolとProcの関係について

# はじめに

Railsを用いた開発を進めている中で、ブロックを渡すはずのメソッドにシンボル形式のメソッドを渡している処理を見かけました。

今までも同様の記述は見たことがあったのですが、なぜシンボル形式のメソッドを使用するのかよく理解していなかったので、この機会にメソッド・Symbol・Procについて調べてみました。

# Enumerable#collectを使用した例

Rubyリファレンスマニュアルには下記のようなcollectメソッドの使用例が記載されています。

```rb
p (1..3).collect { "cat" } # => ["cat", "cat", "cat"]
```
> 各要素に対してブロックを評価した結果を全て含む配列を返します。

上記の例だと`(1..3)`の各要素に対して`{ "cat" }`を適用するため、戻り値が`["cat", "cat", "cat"]`となるわけです。

一方で、ブロックの記法を用いず、シンボル形式のメソッドを渡す書き方もあります。
```rb
p (1..3).collect(&:to_s) # => ["1", "2", "3"]
```

本来ならばcollectメソッドにはブロックを渡さなければいけないにも関わらず、上記の例ではシンボルを渡しているように見えます。

そこで、

**ブロックを渡すはずのメソッドになぜシンボル形式のメソッドを渡すことができるのか**

**メソッドをシンボルの形で渡すのはなぜなのか**

という2点に着目して調査をしてみました。

# to_procメソッドとの出会い
調査を続けていると、一つのメソッドに遭遇しました。
それが`to_proc`メソッドです。
Rubyリファレンスマニュアルには下記のように説明されています。
>self に対応する Proc オブジェクトを返します。
>生成される Proc オブジェクトを呼びだす(Proc#call)と、 Proc#callの第一引数をレシーバとして、 self という名前のメソッドを残りの引数を渡して呼びだします。
>生成される Proc オブジェクトは lambda です。

下記のように使用します。

```rb
# 明示的に呼ぶ例

:to_i.to_proc["ff", 16]  # => 255 ← "ff".to_i(16)と同じ
```

```rb
# 暗示的に呼ぶ例

# メソッドに & とともにシンボルを渡すと
# to_proc が呼ばれて Proc 化され、
# それがブロックとして渡される。
(1..3).collect(&:to_s)  # => ["1", "2", "3"]
(1..3).select(&:odd?)   # => [1, 3]
```
つまり...
- Symbolで記述されたメソッドはProcオブジェクトに変換可能である。
- 引数に&とともにSymbolを渡す事で、メソッドをブロックとして渡すことができる。

ということがわかりました。

# 実験
ここまでの内容を噛みくだいて理解するため、下記のようなサンプルコードで`to_s`を色々な形で出力してみました。
```rb
puts to_s.class
# => String
#    to_sメソッドの戻り値のクラスを調べている.

puts :to_s.class
# => Symbol
#    to_sメソッドの情報を持ったSymbol

puts :to_s.to_proc.class
# => Proc
#    to_sメソッドをブロックとして持つProcオブジェクト

puts :to_s.to_proc[100].class
# => String
#    Procを実行した結果の戻り値なのでString（今回だと'100'）が返される
```

単に`to_s`メソッドを呼び出した場合はメソッドの戻り値であるStringオブジェクトが返ってきます（当たり前ですが...）。

一方で`:to_s`や`:to_s.to_proc`では、それぞれSymbolオブジェクトやProcオブジェクトを返しています。
`to_s`の実行結果の戻り値ではなく`to_s`メソッドをSymbolやProcの形式で扱うことができていることがわかります。

また、興味本位でメソッド定義部分自体のクラスも調べてみました。
```rb
puts def hoge
      'hoge'
     end.class
# => Symbol
```
この段階ですでにメソッドはSymbolオブジェクトになっているのですね。




# まとめ
前述の疑問点に対して私が出した答えは以下です。

**ブロックを渡すはずのメソッドになぜシンボル形式のメソッドを渡すことができるのか**

- シンボルは`to_proc`メソッドを持っているため、シンボルが持つメソッドの情報をProcオブジェクトに変換してブロックを実行することが可能である。

**メソッドをシンボルの形で渡すのはなぜなのか**

- メソッドを&とともにシンボルの形で引数に渡すことにより、メソッドの戻り値ではなくブロックを渡すことができる。


# 参考
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/collect.html

https://docs.ruby-lang.org/ja/latest/method/Symbol/i/to_proc.html
Github Actionsでのコンテナを用いたサーバー死活チェック

# はじめに

ライブラリのバージョンが上がったことで、ビルドは成功するのに起動時にエラーが出ることがありました。
手動でいちいち動作確認したくないので、Github Actionsでサーバが起動するかチェックするように設定します。

# チェックの流れ
githubにプッシュをしたタイミングで指定したコンテナが存在するかどうかチェック
↓
docker inspect を使ってコンテナが起動しているかステータスをチェック
↓
起動している場合成功、失敗している場合5回リトライ処理を設ける。インターバルは5秒とします。
↓
リトライ回数を超えた場合失敗してエラーコードを返します。

※エラーの場合
以下のようにexitして失敗として処理します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615541/ae4dfa01-03ca-a2e3-3eba-7cc52000ea1f.png)


# GitHub Actionsの設定
```
name: ci

on:
  push:
    branches: [develop]
  

・・・省略・・・


      - name: Run Docker Container
        run: |
          docker-compose up -d

      - name: Check Docker Container
        run: |
          # コンテナ名指定("container1" "container2" "container3"...)
          container_names=("invoice-maker")

          # タイムアウトまでの待機時間（秒）
          timeout_seconds=300
          # リトライ回数
          max_retries=5
          # インターバル（秒）
          retry_interval=5
          # タイムアウトを計算
          end_time=$((SECONDS+timeout_seconds))
            
          #コンテナ存在チェック
          for container_name in "${container_names[@]}"; do
            if ! docker ps -a --format '{{.Names}}' | grep -q "$container_name"; then
            echo "$container_name does not exist."
            exit 1
            fi

            echo "Container: $container_name";
            sleep $retry_interval
            retries=0

            while [ $SECONDS -lt $end_time ]; do
              # Dockerコンテナの状態を確認
              if docker inspect -f '{{.State.Status}}' $container_name | grep -q "running"; then
                echo $container_name "has started successfully!"
                break
              else
                retries=$((retries+1))
                echo "Waiting for Docker container to start...$retries"
                sleep $retry_interval
              fi
              # リトライ回数を超えた場合は失敗として終了
              if [ $retries -ge $max_retries ]; then
                echo "Failed to start Docker container after $max_retries retries."
                exit 1
              fi
            done
          done
 ```

 # まとめ
 リポジトリはGithubの[Dependabot](https://docs.github.com/ja/code-security/dependabot/working-with-dependabot)を使ってライブラリのバージョン修正を自動で行っていたため、今回の設定をすることで自動バージョンアップ後にもサーバーが動くかどうか、手動で確認する手間を省けるという利点があります。